mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-12-23 16:43:24 +03:00
widgets: v0.1
This commit is contained in:
parent
8ee3778878
commit
6e1ede9155
@ -108,10 +108,32 @@ fn get_widget() -> String {
|
||||
return r#"<html>
|
||||
<head>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<style>
|
||||
.app {
|
||||
max-width: 32%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.app-image {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.app-info {
|
||||
max-width: 67%
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="h-screen w-screen">
|
||||
<div id="latest-apps" class="flex flex-col items-center bg-white/25 rounded-lg shadow-lg w-full h-full overflow-y-auto">
|
||||
<h1 class="font-bold text-white">Latest Apps</h1>
|
||||
<body class="text-white overflow-hidden">
|
||||
<div
|
||||
id="latest-apps"
|
||||
class="flex flex-wrap p-2 gap-2 items-center backdrop-brightness-125 rounded-xl shadow-lg h-screen w-screen overflow-y-auto"
|
||||
style="
|
||||
scrollbar-color: transparent transparent;
|
||||
scrollbar-width: none;
|
||||
"
|
||||
>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@ -121,15 +143,12 @@ fn get_widget() -> String {
|
||||
const container = document.getElementById('latest-apps');
|
||||
data.forEach(app => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'm-2 grow self-stretch flex items-stretch m-2 p-2 rounded-lg shadow bg-white/25 font-sans';
|
||||
div.className = 'app p-2 grow self-stretch flex items-stretch rounded-lg shadow bg-white/10 font-sans';
|
||||
div.innerHTML = `${app.metadata.image ? `<div
|
||||
class="rounded mr-2"
|
||||
style="background-image: url('${app.metadata.image}');
|
||||
background-cover: cover;
|
||||
background-position: center;
|
||||
width: 33%"
|
||||
class="app-image rounded mr-2 grow"
|
||||
style="background-image: url('${app.metadata.image}');"
|
||||
></div>` : ''}
|
||||
<div class="flex flex-col grow">
|
||||
<div class="app-info flex flex-col grow">
|
||||
<h2 class="font-bold">${app.metadata.name}</h2>
|
||||
<p>${app.metadata.description}</p>
|
||||
</div>`;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -14,8 +14,8 @@
|
||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" />
|
||||
<script type="module" crossorigin src="/main:app_store:sys/assets/index-rQKf2jeD.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/main:app_store:sys/assets/index-McZbj3o1.css">
|
||||
<script type="module" crossorigin src="/main:app_store:sys/assets/index-C8ofW7WS.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/main:app_store:sys/assets/index-_Aqzph9X.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -5,6 +5,7 @@ import Modal from "./Modal";
|
||||
import { getAppName } from "../utils/app";
|
||||
import Loader from "./Loader";
|
||||
import classNames from "classnames";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
interface ActionButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
app: AppInfo;
|
||||
@ -17,6 +18,7 @@ export default function ActionButton({ app, ...props }: ActionButtonProps) {
|
||||
const [mirror, setMirror] = useState(app.metadata?.properties?.mirrors?.[0] || "Other");
|
||||
const [customMirror, setCustomMirror] = useState("");
|
||||
const [caps, setCaps] = useState<string[]>([]);
|
||||
const [launchPath, setLaunchPath] = useState('');
|
||||
const [loading, setLoading] = useState("");
|
||||
|
||||
const { clean, installed, downloaded, updatable } = useMemo(() => {
|
||||
@ -42,9 +44,27 @@ export default function ActionButton({ app, ...props }: ActionButtonProps) {
|
||||
setMirror(app.metadata?.properties?.mirrors?.[0] || "Other");
|
||||
}, [app.metadata?.properties?.mirrors]);
|
||||
|
||||
useEffect(() => {
|
||||
if (installed) {
|
||||
fetch('/apps').then(data => data.json())
|
||||
.then((data: Array<{ package_name: string, path: string }>) => {
|
||||
// console.log(data)
|
||||
if (Array.isArray(data)) {
|
||||
// console.log('is array')
|
||||
const homepageAppData = data.find(otherApp => app.package === otherApp.package_name)
|
||||
if (homepageAppData) {
|
||||
// console.log('found the good appness', homepageAppData.package_name, homepageAppData.path);
|
||||
setLaunchPath(homepageAppData.path)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [installed])
|
||||
|
||||
const onClick = useCallback(async () => {
|
||||
if (installed && !updatable) {
|
||||
window.alert("App is installed");
|
||||
if (installed && !updatable && launchPath) {
|
||||
window.location.href = `/${launchPath.replace('/', '')}`
|
||||
return;
|
||||
} else {
|
||||
if (downloaded) {
|
||||
getCaps(app).then((manifest) => {
|
||||
@ -53,7 +73,7 @@ export default function ActionButton({ app, ...props }: ActionButtonProps) {
|
||||
}
|
||||
setShowModal(true);
|
||||
}
|
||||
}, [app, installed, downloaded, updatable, setShowModal, getCaps]);
|
||||
}, [app, installed, downloaded, updatable, setShowModal, getCaps, launchPath]);
|
||||
|
||||
const download = useCallback(async (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
@ -137,11 +157,16 @@ export default function ActionButton({ app, ...props }: ActionButtonProps) {
|
||||
<button
|
||||
{...props}
|
||||
type="button"
|
||||
className={classNames("text-sm min-w-[100px] px-2 py-1 self-start", props.className)}
|
||||
className={classNames("text-sm min-w-[100px] px-2 py-1 self-start", props.className, {
|
||||
'bg-orange': installed,
|
||||
'hidden': installed && !updatable && !launchPath
|
||||
})}
|
||||
onClick={onClick}
|
||||
>
|
||||
{installed && updatable
|
||||
? "Update"
|
||||
: installed && launchPath
|
||||
? "Launch"
|
||||
: installed
|
||||
? "Installed"
|
||||
: downloaded
|
||||
|
@ -15,7 +15,7 @@ export default function AppEntry({ app, ...props }: AppEntryProps) {
|
||||
<div {...props} key={appId(app)} className="flex justify-between w-full rounded hover:bg-white/10 card">
|
||||
<AppHeader app={app} size="small" />
|
||||
<div className="flex mr-1 items-start">
|
||||
{!app.state?.caps_approved && <ActionButton app={app} className="mr-2" />}
|
||||
<ActionButton app={app} className="mr-2" />
|
||||
<MoreActions app={app} />
|
||||
</div>
|
||||
</div>
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
87
kinode/packages/homepage/pkg/ui/assets/index-DweJf-tr.js
Normal file
87
kinode/packages/homepage/pkg/ui/assets/index-DweJf-tr.js
Normal file
File diff suppressed because one or more lines are too long
@ -9,8 +9,8 @@
|
||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" />
|
||||
<script type="module" crossorigin src="/assets/index-CrxBodxP.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CUrqWKH8.css">
|
||||
<script type="module" crossorigin src="/assets/index-DweJf-tr.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B_MpocZ4.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
4
kinode/packages/homepage/ui/dist/index.html
vendored
4
kinode/packages/homepage/ui/dist/index.html
vendored
@ -9,8 +9,8 @@
|
||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" />
|
||||
<script type="module" crossorigin src="/assets/index-CrxBodxP.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CUrqWKH8.css">
|
||||
<script type="module" crossorigin src="/assets/index-DweJf-tr.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B_MpocZ4.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -10,7 +10,7 @@ const AppsDock: React.FC = () => {
|
||||
setFavoriteApps(apps.filter(a => a.is_favorite))
|
||||
}, [apps])
|
||||
|
||||
return <div className='flex-center flex-wrap obox border border-orange gap-8'>
|
||||
return <div className='flex-center flex-wrap obox border border-orange gap-8 !rounded-xl'>
|
||||
{favoriteApps.length === 0 ? <div>Favorite an app to pin it to your dock.</div> : favoriteApps.map(app => <AppDisplay app={app} />)}
|
||||
</div>
|
||||
}
|
||||
|
31
kinode/packages/homepage/ui/src/components/Modal.tsx
Normal file
31
kinode/packages/homepage/ui/src/components/Modal.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { FaX } from "react-icons/fa6"
|
||||
import { isMobileCheck } from "../utilities/dimensions"
|
||||
import classNames from "classnames"
|
||||
|
||||
interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||
title: string
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
export const Modal: React.FC<Props> = ({ title, onClose, children }) => {
|
||||
const isMobile = isMobileCheck()
|
||||
return (
|
||||
<div className="flex fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 place-items-center place-content-center backdrop-blur-md">
|
||||
<div className={classNames("flex flex-col rounded-lg bg-black py-4 shadow-lg", {
|
||||
'min-w-[500px] px-8 w-1/2': !isMobile,
|
||||
'px-4 w-full': isMobile
|
||||
})}>
|
||||
<div className="flex">
|
||||
<h1 className="grow">{title}</h1>
|
||||
<button
|
||||
className="icon self-start"
|
||||
onClick={onClose}
|
||||
>
|
||||
<FaX />
|
||||
</button>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
36
kinode/packages/homepage/ui/src/components/Widget.tsx
Normal file
36
kinode/packages/homepage/ui/src/components/Widget.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import classNames from "classnames"
|
||||
import useHomepageStore from "../store/homepageStore"
|
||||
import { FaEye, FaEyeSlash } from "react-icons/fa6"
|
||||
import { useState } from "react"
|
||||
|
||||
interface WidgetProps {
|
||||
package_name: string,
|
||||
widget: string
|
||||
}
|
||||
|
||||
const Widget: React.FC<WidgetProps> = ({ package_name, widget }) => {
|
||||
const { widgetSettings, toggleWidgetVisibility } = useHomepageStore()
|
||||
const [isHovered, setIsHovered] = useState(false)
|
||||
return <div
|
||||
className={classNames("self-stretch flex flex-wrap shadow-lg rounded-lg relative", {
|
||||
"min-w-full": widgetSettings[package_name]?.size === "large",
|
||||
"min-w-1/2": !widgetSettings[package_name]?.size || widgetSettings[package_name]?.size === "small"
|
||||
})}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
>
|
||||
<iframe
|
||||
srcDoc={widget || ""}
|
||||
className="grow self-stretch"
|
||||
data-widget-code={widget}
|
||||
/>
|
||||
{isHovered && <button
|
||||
className="absolute -top-2 -right-2 icon"
|
||||
onClick={() => toggleWidgetVisibility(package_name)}
|
||||
>
|
||||
{widgetSettings[package_name]?.hide ? <FaEye /> : <FaEyeSlash />}
|
||||
</button>}
|
||||
</div>
|
||||
}
|
||||
|
||||
export default Widget
|
@ -1,14 +1,32 @@
|
||||
import { FaGear } from "react-icons/fa6"
|
||||
import useHomepageStore from "../store/homepageStore"
|
||||
import Widget from "./Widget"
|
||||
import WidgetsSettingsModal from "./WidgetsSettingsModal"
|
||||
|
||||
const Widgets = () => {
|
||||
const { apps } = useHomepageStore()
|
||||
return <div className="flex flex-wrap my-4 gap-4 flex-grow">
|
||||
{apps.filter(app => app.widget).map(({ widget }) => <iframe
|
||||
srcDoc={widget || ""}
|
||||
className="min-w-1/4 shadow-lg"
|
||||
data-widget-code={widget}
|
||||
const { apps, showWidgetsSettings, setShowWidgetsSettings, widgetSettings } = useHomepageStore()
|
||||
return <div className="flex-col-center m-4 gap-4 flex-grow self-stretch">
|
||||
<h3 className="flex-center">
|
||||
<span>
|
||||
Widgets
|
||||
</span>
|
||||
<button
|
||||
className="icon ml-4"
|
||||
onClick={() => setShowWidgetsSettings(true)}
|
||||
>
|
||||
<FaGear />
|
||||
</button>
|
||||
</h3>
|
||||
<div className="flex-center flex-wrap gap-4 flex-grow self-stretch">
|
||||
{apps
|
||||
.filter(app => app.widget)
|
||||
.map(({ widget, package_name }) => !widgetSettings[package_name]?.hide && <Widget
|
||||
package_name={package_name}
|
||||
widget={widget!}
|
||||
/>)}
|
||||
</div>
|
||||
{showWidgetsSettings && <WidgetsSettingsModal />}
|
||||
</div>
|
||||
}
|
||||
|
||||
export default Widgets
|
@ -0,0 +1,53 @@
|
||||
import { FaCheck, FaX } from "react-icons/fa6"
|
||||
import useHomepageStore from "../store/homepageStore"
|
||||
import { Modal } from "./Modal"
|
||||
import classNames from "classnames"
|
||||
|
||||
const WidgetsSettingsModal = () => {
|
||||
const { apps, setShowWidgetsSettings, toggleWidgetVisibility, widgetSettings, setWidgetSize } = useHomepageStore()
|
||||
|
||||
return <Modal
|
||||
title='Widget Settings'
|
||||
onClose={() => setShowWidgetsSettings(false)}
|
||||
>
|
||||
<div className="flex-col-center">
|
||||
{apps.filter(app => app.widget).map(({ label, package_name }) => <div className="flex items-start">
|
||||
<h4 className="mr-4">{label}</h4>
|
||||
<div className="flex-col-center gap-6">
|
||||
<div className="flex-center gap-4">
|
||||
<button
|
||||
className="icon"
|
||||
onClick={() => toggleWidgetVisibility(package_name)}
|
||||
>
|
||||
{!widgetSettings[package_name]?.hide ? <FaCheck /> : <FaX />}
|
||||
</button>
|
||||
<label>Show widget</label>
|
||||
</div>
|
||||
<div className="flex-col-center gap-4">
|
||||
<span>Widget size</span>
|
||||
<div className="flex-center items-stretch gap-4">
|
||||
<button
|
||||
className={classNames({
|
||||
'clear': widgetSettings[package_name]?.size === 'large'
|
||||
})}
|
||||
onClick={() => setWidgetSize(package_name, 'small')}
|
||||
>
|
||||
Small
|
||||
</button>
|
||||
<button
|
||||
className={classNames({
|
||||
'clear': widgetSettings[package_name]?.size !== 'large'
|
||||
})}
|
||||
onClick={() => setWidgetSize(package_name, 'large')}
|
||||
>
|
||||
Large
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>)}
|
||||
</div>
|
||||
</Modal>
|
||||
}
|
||||
|
||||
export default WidgetsSettingsModal
|
@ -79,8 +79,8 @@ function Homepage() {
|
||||
<KinodeBird />
|
||||
</div>
|
||||
<AppsDock />
|
||||
<Widgets />
|
||||
<AllApps />
|
||||
<Widgets />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -24,6 +24,17 @@ export interface HomepageStore {
|
||||
|
||||
apps: HomepageApp[]
|
||||
setApps: (apps: HomepageApp[]) => void
|
||||
widgetSettings: {
|
||||
[key: string]: {
|
||||
hide: boolean,
|
||||
size: 'small' | 'large'
|
||||
}
|
||||
}
|
||||
setWidgetSettings: (widgetSettings: HomepageStore['widgetSettings']) => void
|
||||
toggleWidgetVisibility: (package_name: string) => void
|
||||
setWidgetSize: (package_name: string, size: 'small' | 'large') => void
|
||||
showWidgetsSettings: boolean
|
||||
setShowWidgetsSettings: (showWidgetsSettings: boolean) => void
|
||||
}
|
||||
|
||||
const useHomepageStore = create<HomepageStore>()(
|
||||
@ -34,6 +45,28 @@ const useHomepageStore = create<HomepageStore>()(
|
||||
|
||||
apps: [],
|
||||
setApps: (apps: HomepageApp[]) => set({ apps }),
|
||||
widgetSettings: {},
|
||||
setWidgetSettings: (widgetSettings: HomepageStore['widgetSettings']) => set({ widgetSettings }),
|
||||
showWidgetsSettings: false,
|
||||
setShowWidgetsSettings: (showWidgetsSettings: boolean) => set({ showWidgetsSettings }),
|
||||
toggleWidgetVisibility: (package_name: string) => set({
|
||||
widgetSettings: {
|
||||
...get().widgetSettings,
|
||||
[package_name]: {
|
||||
...get().widgetSettings[package_name],
|
||||
hide: !get().widgetSettings[package_name]?.hide
|
||||
}
|
||||
}
|
||||
}),
|
||||
setWidgetSize: (package_name: string, size: 'small' | 'large') => set({
|
||||
widgetSettings: {
|
||||
...get().widgetSettings,
|
||||
[package_name]: {
|
||||
...get().widgetSettings[package_name],
|
||||
size
|
||||
}
|
||||
}
|
||||
}),
|
||||
isHosted: false,
|
||||
setIsHosted: (isHosted: boolean) => set({ isHosted }),
|
||||
fetchHostedStatus: async (our: string) => {
|
||||
|
1
kinode/packages/homepage/ui/src/utilities/dimensions.ts
Normal file
1
kinode/packages/homepage/ui/src/utilities/dimensions.ts
Normal file
@ -0,0 +1 @@
|
||||
export const isMobileCheck = () => window.innerWidth <= 600
|
@ -1 +1 @@
|
||||
data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIiA/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgd2lkdGg9IjEwODAiIGhlaWdodD0iMTA4MCIgdmlld0JveD0iMCAwIDEwODAgMTA4MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxkZXNjPkNyZWF0ZWQgd2l0aCBGYWJyaWMuanMgNS4yLjQ8L2Rlc2M+CjxkZWZzPgo8L2RlZnM+CjxnIHRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIDEgNTQwIDU0MCkiIGlkPSI0MDhjZjk5Ni0xN2M1LTQxOTctYmVhMy1jNTQwZGJhYTlhZGUiICA+CjxyZWN0IHN0eWxlPSJzdHJva2U6IG5vbmU7IHN0cm9rZS13aWR0aDogMTsgc3Ryb2tlLWRhc2hhcnJheTogbm9uZTsgc3Ryb2tlLWxpbmVjYXA6IGJ1dHQ7IHN0cm9rZS1kYXNob2Zmc2V0OiAwOyBzdHJva2UtbGluZWpvaW46IG1pdGVyOyBzdHJva2UtbWl0ZXJsaW1pdDogNDsgZmlsbDogcmdiKDI1NSwyNTUsMjU1KTsgZmlsbC1ydWxlOiBub256ZXJvOyBvcGFjaXR5OiAxOyB2aXNpYmlsaXR5OiBoaWRkZW47IiB2ZWN0b3ItZWZmZWN0PSJub24tc2NhbGluZy1zdHJva2UiICB4PSItNTQwIiB5PSItNTQwIiByeD0iMCIgcnk9IjAiIHdpZHRoPSIxMDgwIiBoZWlnaHQ9IjEwODAiIC8+CjwvZz4KPGcgdHJhbnNmb3JtPSJtYXRyaXgoMSAwIDAgMSA1NDAgNTQwKSIgaWQ9ImM1MzhkOTdkLWFhNjAtNGRmNi05NzM1LTE4N2FlOGU3ODQwYyIgID4KPC9nPgo8ZyB0cmFuc2Zvcm09Im1hdHJpeChOYU4gTmFOIE5hTiBOYU4gMCAwKSIgID4KPGcgc3R5bGU9IiIgICA+CjwvZz4KPC9nPgo8ZyB0cmFuc2Zvcm09Im1hdHJpeCgyLjExIDAgMCAyLjExIDU0MCA1NDApIiAgPgo8cGF0aCBzdHlsZT0ic3Ryb2tlOiByZ2IoMCwwLDApOyBzdHJva2Utd2lkdGg6IDA7IHN0cm9rZS1kYXNoYXJyYXk6IG5vbmU7IHN0cm9rZS1saW5lY2FwOiBidXR0OyBzdHJva2UtZGFzaG9mZnNldDogMDsgc3Ryb2tlLWxpbmVqb2luOiBtaXRlcjsgc3Ryb2tlLW1pdGVybGltaXQ6IDQ7IGZpbGw6IHJnYigwLDAsMCk7IGZpbGwtcnVsZTogbm9uemVybzsgb3BhY2l0eTogMTsiICB0cmFuc2Zvcm09IiB0cmFuc2xhdGUoLTI1NiwgLTI1NikiIGQ9Ik0gNDEzLjk2NyAyNzYuOCBDIDQxNS4wMjcgMjcwLjU2NSA0MTUuMDI3IDI2My4yODIwMDAwMDAwMDAwNCA0MTUuMDI3IDI1NiBDIDQxNS4wMjcgMjQ4LjcxNzk5OTk5OTk5OTk2IDQxMy45NjcgMjQyLjQ4MiA0MTMuOTY3IDIzNS4yIEwgNDU4LjYzNCAyMDAuODgyIEMgNDYyLjg5NCAxOTcuNzY0IDQ2My45NTMwMDAwMDAwMDAwMyAxOTIuNTY1IDQ2MC43NjQgMTg3LjM2NCBMIDQxOC4yMTUgMTE1LjYgQyA0MTYuMDg1OTk5OTk5OTk5OTYgMTExLjQzNTk5OTk5OTk5OTk5IDQwOS43MDc5OTk5OTk5OTk5NyAxMDkuMzY1IDQwNS40NDggMTExLjQzNTk5OTk5OTk5OTk5IEwgMzUyLjI2MiAxMzIuMjM3IEMgMzQxLjYyNCAxMjMuOTE5IDMyOC44NjggMTE2LjYzNiAzMTYuMTAyIDExMS40MzU5OTk5OTk5OTk5OSBMIDMwOC42NTQgNTYuMzE4OTk5OTk5OTk5OTk2IEMgMzA3LjU5NCA1Mi4xNjQ5OTk5OTk5OTk5OSAzMDMuMzM1IDQ4LjAwMSAyOTguMDE2IDQ4LjAwMSBMIDIxMi45MTggNDguMDAxIEMgMjA3LjYgNDguMDAxIDIwMy4zNDEgNTIuMTY1IDIwMi4yODEgNTYuMzE4OTk5OTk5OTk5OTk2IEwgMTkzLjc3MyAxMTEuNDM1OTk5OTk5OTk5OTkgQyAxODEuMDA2IDExNi42MzYgMTY5LjMwOSAxMjMuOTE3OTk5OTk5OTk5OTkgMTU3LjYwMiAxMzIuMjM3IEwgMTA0LjQxNiAxMTEuNDM1OTk5OTk5OTk5OTkgQyA5OS4wOTcgMTA5LjM2NSA5My43Nzc5OTk5OTk5OTk5OSAxMTEuNDM1OTk5OTk5OTk5OTkgOTEuNjQ5IDExNS42IEwgNDkuMSAxODcuMzY1IEMgNDYuOTgxIDE5MS41MTggNDguMDM5IDE5Ny43NjQgNTEuMjI5IDIwMC44ODMgTCA5Ni45NyAyMzUuMiBDIDk2Ljk3IDI0Mi40ODIgOTUuOTEgMjQ4LjcxOCA5NS45MSAyNTYgQyA5NS45MSAyNjMuMjgyMDAwMDAwMDAwMDQgOTYuOTcgMjY5LjUxODAwMDAwMDAwMDAzIDk2Ljk3IDI3Ni44IEwgNTIuMzAyIDMxMS4xMTggQyA0OC4wNDIgMzE0LjIzNiA0Ni45ODQgMzE5LjQzNSA1MC4xNzIgMzI0LjYzNTk5OTk5OTk5OTk3IEwgOTIuNzIxIDM5Ni40IEMgOTQuODUxIDQwMC41NjM5OTk5OTk5OTk5NiAxMDEuMjI5IDQwMi42MzUgMTA1LjQ4OCA0MDAuNTYzOTk5OTk5OTk5OTYgTCAxNTguNjc1IDM3OS43NjMgQyAxNjkuMzEyIDM4OC4wODA5OTk5OTk5OTk5NiAxODIuMDY5MDAwMDAwMDAwMDIgMzk1LjM2NCAxOTQuODM1IDQwMC41NjM5OTk5OTk5OTk5NiBMIDIwMy4zNDMwMDAwMDAwMDAwMiA0NTUuNjgxIEMgMjA0LjQxMiA0NjAuODgxIDIwOC42NjEwMDAwMDAwMDAwMyA0NjMuOTk4OTk5OTk5OTk5OTcgMjEzLjk4MDAwMDAwMDAwMDAyIDQ2My45OTg5OTk5OTk5OTk5NyBMIDI5OS4wNzgwMDAwMDAwMDAwMyA0NjMuOTk4OTk5OTk5OTk5OTcgQyAzMDQuMzk3MDAwMDAwMDAwMDUgNDYzLjk5ODk5OTk5OTk5OTk3IDMwOC42NTYgNDU5LjgzNSAzMDkuNzE2IDQ1NS42ODEgTCAzMTguMjM0MDAwMDAwMDAwMDQgNDAwLjU2Mzk5OTk5OTk5OTk2IEMgMzMwLjk5MTAwMDAwMDAwMDA0IDM5NS4zNjQgMzQyLjY5ODAwMDAwMDAwMDA0IDM4OC4wODIgMzU0LjM5NCAzNzkuNzYzIEwgNDA3LjU4MSA0MDAuNTYzOTk5OTk5OTk5OTYgQyA0MTIuODk5IDQwMi42MzUgNDE4LjIxOCA0MDAuNTYzOTk5OTk5OTk5OTYgNDIwLjM0OCAzOTYuNCBMIDQ2Mi44OTcgMzI0LjYzNSBDIDQ2NS4wMjYgMzIwLjQ4MTk5OTk5OTk5OTk3IDQ2My45NTcgMzE0LjIzNiA0NjAuNzY3IDMxMS4xMTY5OTk5OTk5OTk5NiBMIDQxMy45NjcgMjc2Ljc5OTk5OTk5OTk5OTk1IHogTSAyNTUuNDY4IDMyOC44IEMgMjEzLjk3ODk5OTk5OTk5OTk4IDMyOC44IDE4MS4wMDc5OTk5OTk5OTk5OCAyOTYuNTY1IDE4MS4wMDc5OTk5OTk5OTk5OCAyNTYgQyAxODEuMDA3OTk5OTk5OTk5OTggMjE1LjQzNSAyMTMuOTc4OTk5OTk5OTk5OTggMTgzLjIgMjU1LjQ2Nzk5OTk5OTk5OTk2IDE4My4yIEMgMjk2Ljk1Njk5OTk5OTk5OTk0IDE4My4yIDMyOS45MjkgMjE1LjQzNSAzMjkuOTI5IDI1NiBDIDMyOS45MjkgMjk2LjU2NSAyOTYuOTU3IDMyOC44IDI1NS40Njc5OTk5OTk5OTk5NiAzMjguOCB6IiBzdHJva2UtbGluZWNhcD0icm91bmQiIC8+CjwvZz4KPC9zdmc+
|
||||
data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTM2IiBoZWlnaHQ9IjEzNiIgdmlld0JveD0iMCAwIDEzNiAxMzYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMzYiIGhlaWdodD0iMTM2IiByeD0iNjgiIGZpbGw9IiNGRkY1RDkiIGZpbGwtb3BhY2l0eT0iMC40Ii8+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xODIxXzkwOTMpIj4KPHBhdGggZD0iTTY3LjQ4NTUgOTQuOTg4MUM2NS44MTYxIDk0Ljk4ODEgNjQuMTQ2NyA5NC45NjQzIDYyLjQ3NzIgOTQuOTg4MUM2MS41NjAyIDk1LjAxMTkgNjEuMDQyOSA5NC40MTc0IDYwLjkzNzEgOTMuNjQ0N0M2MC42NjY3IDkxLjU1MjMgNjAuMzQ5MyA4OS40NTk4IDYwLjA2NzEgODcuMzY3NEM2MC4wMjAxIDg3LjAxMDggNTkuODc5IDg2Ljc5NjggNTkuNTM4MSA4Ni42NTQxQzU4LjIzMzEgODYuMDgzNCA1Ny4wMjIyIDg1LjM1ODIgNTUuODgxOCA4NC40OTA0QzU1LjYyMzEgODQuMjg4MiA1NS4zOTk4IDg0LjI2NDUgNTUuMDk0MSA4NC4zOTUyQzUzLjE1NDMgODUuMjAzNyA1MS4yMTQ0IDg1Ljk4ODMgNDkuMjc0NiA4Ni43NzNDNDguMjc1MyA4Ny4xNzcyIDQ3Ljc5MzMgODcuMDIyNyA0Ny4yNTI1IDg2LjA5NTNDNDUuNTcxMyA4My4xNTg4IDQzLjg5MDEgODAuMjEwNCA0Mi4yMDg5IDc3LjI2MkM0MS44MDkyIDc2LjU3MjUgNDEuOTI2NyA3NS45NDIzIDQyLjU0OTggNzUuNDQzQzQ0LjIzMSA3NC4wOTk2IDQ1LjkxMjIgNzIuNzU2MiA0Ny42MDUyIDcxLjQzNjVDNDcuODk5MSA3MS4yMTA2IDQ4LjAwNDkgNzAuOTYxIDQ3Ljk1NzkgNzAuNTkyNEM0Ny43ODE1IDY5LjIwMTQgNDcuNzkzMyA2Ny43OTg2IDQ3Ljk1NzkgNjYuNDA3NkM0OC4wMDQ5IDY2LjA1MDkgNDcuOTEwOCA2NS44MTMxIDQ3LjYyODcgNjUuNTg3M0M0NS45OTQ1IDY0LjMwMzMgNDQuMzYwNCA2My4wMDc0IDQyLjczNzkgNjEuNzExNUM0MS44Nzk3IDYxLjAzMzkgNDEuNzczOSA2MC41MTA4IDQyLjMxNDcgNTkuNTcxNkM0NC4wMDc3IDU2LjYxMTMgNDUuNjg4OCA1My42MzkxIDQ3LjM5MzYgNTAuNjc4OEM0Ny43NDYyIDUwLjA3MjUgNDguMzgxMSA0OS44NTg1IDQ5LjA3NDcgNTAuMTQzOEM1MC40MjY3IDUwLjY5MDcgNTEuNzc4OCA1MS4yMzc1IDUzLjEzMDggNTEuNzk2M0M1My44MjQ0IDUyLjA4MTcgNTQuNTE4IDUyLjM1NTEgNTUuMjExNyA1Mi42NTIzQzU1LjQyMzMgNTIuNzQ3NCA1NS41ODc5IDUyLjczNTUgNTUuNzc2IDUyLjU5MjlDNTYuOTg2OSA1MS42NjU1IDU4LjMwMzYgNTAuODkyOCA1OS43MDI3IDUwLjI4NjVDNTkuOTQ5NiA1MC4xNzk1IDYwLjAyMDEgNDkuOTg5MiA2MC4wNDM2IDQ5Ljc1MTVDNjAuMzE0IDQ3LjgxMzYgNjAuNTg0NCA0NS44NzU3IDYwLjg1NDggNDMuOTM3OUM2MC44OTAxIDQzLjcxMiA2MC45MTM2IDQzLjQ4NjEgNjAuOTQ4OSA0My4yNjAyQzYxLjA5IDQyLjQxNjEgNjEuNTYwMiA0MiA2Mi4zNzE0IDQyQzY0LjQ0MDYgNDIgNjYuNTA5NyA0MiA2OC41Nzg5IDQyQzY5LjkwNzQgNDIgNzEuMjQ3NiA0MiA3Mi41NzYxIDQyQzczLjQ0NjEgNDIgNzMuOTI4MSA0Mi40NTE4IDc0LjA1NzUgNDMuMzMxNUM3NC4zNTE0IDQ1LjQzNTggNzQuNjQ1MyA0Ny41NDAyIDc0LjkyNzQgNDkuNjQ0NUM3NC45NzQ1IDQ5Ljk4OTIgNzUuMTE1NSA1MC4xNzk1IDc1LjQzMyA1MC4zMzRDNzYuNzM4IDUwLjkxNjYgNzcuOTcyNCA1MS42Mjk5IDc5LjExMjggNTIuNTA5NkM3OS4zNTk3IDUyLjY5OTkgNzkuNTU5NSA1Mi43MjM2IDc5Ljg0MTcgNTIuNjA0OEM4MS44MDUgNTEuNzk2MyA4My43Njg0IDUwLjk4NzkgODUuNzQzNSA1MC4xOTEzQzg2LjY3MjMgNDkuODEwOSA4Ny4yMTMxIDUwLjAxMyA4Ny43MTg2IDUwLjg5MjhDODkuMzc2MyA1My44MDU1IDkxLjAzMzkgNTYuNzE4MyA5Mi42OTE2IDU5LjYxOTFDOTMuMTczNiA2MC40NTEzIDkzLjA2NzggNjEuMDIyIDkyLjMxNTQgNjEuNjI4M0M5MC42NDYgNjIuOTU5OCA4OC45NzY1IDY0LjI3OTUgODcuMjk1NCA2NS41ODczQzg3LjAyNDkgNjUuODAxMyA4Ni45NDI3IDY2LjAyNzEgODYuOTc3OSA2Ni4zNkM4Ny4xNTQzIDY3Ljc4NjcgODcuMTU0MyA2OS4yMTMzIDg2Ljk3NzkgNzAuNjRDODYuOTQyNyA3MC45NjEgODcuMDI1IDcxLjE4NjkgODcuMjgzNiA3MS4zODlDODguOTI5NSA3Mi42ODQ4IDkwLjU3NTQgNzMuOTkyNiA5Mi4yMjE0IDc1LjMwMDRDOTMuMDU2MSA3NS45NjYxIDkzLjE2MTkgNzYuNDg5MiA5Mi42MzI4IDc3LjQxNjZDOTAuOTc1MiA4MC4zNDEyIDg5LjMwNTcgODMuMjUzOSA4Ny42MzYzIDg2LjE2NjdDODcuMTg5NSA4Ni45NTEzIDg2LjYwMTcgODcuMTUzNCA4NS43NjcgODYuODA4N0M4My44MDM3IDg2LjAxMjEgODEuODUyMSA4NS4yMTU2IDc5LjkwMDUgODQuNDA3MUM3OS41NzEzIDg0LjI2NDUgNzkuMzI0NCA4NC4yODgyIDc5LjAzMDUgODQuNTE0MUM3Ny45MDE5IDg1LjM5MzkgNzYuNjc5MiA4Ni4wOTUzIDc1LjM3NDIgODYuNjY2Qzc1LjA2ODUgODYuNzk2OCA3NC45MzkyIDg2Ljk4NyA3NC44OTIyIDg3LjMwOEM3NC42MSA4OS40MDA0IDc0LjMxNjEgOTEuNDkyOCA3NC4wMTA0IDkzLjU4NTJDNzMuOTYzNCA5My45MDYyIDczLjgzNDEgOTQuMjI3MiA3My42Njk1IDk0LjUwMDdDNzMuNDM0NCA5NC44NTczIDczLjA1ODEgOTQuOTg4MSA3Mi42MjMxIDk0Ljk4ODFDNzAuOTA2NyA5NC45ODgxIDY5LjE3ODUgOTQuOTg4MSA2Ny40NjIgOTQuOTg4MUg2Ny40ODU1Wk02Ny40NzM4IDU5LjE1NTVDNjIuNDMwMiA1OS4xNTU1IDU4LjI2ODQgNjMuMzUyMiA1OC4yNTY2IDY4LjQ2NDNDNTguMjQ0OSA3My42MDAzIDYyLjQwNjcgNzcuODIwOCA2Ny40ODU1IDc3LjgyMDhDNzIuNTUyNiA3Ny44MjA4IDc2LjcxNDQgNzMuNjEyMiA3Ni43MTQ0IDY4LjQ4ODFDNzYuNzE0NCA2My4zNDAzIDcyLjU2NDQgNTkuMTU1NSA2Ny40NjIgNTkuMTQzNkw2Ny40NzM4IDU5LjE1NTVaIiBmaWxsPSIjRkZGNUQ5Ii8+CjwvZz4KPGRlZnM+CjxjbGlwUGF0aCBpZD0iY2xpcDBfMTgyMV85MDkzIj4KPHJlY3Qgd2lkdGg9IjUxIiBoZWlnaHQ9IjUzIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDIgNDIpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==
|
File diff suppressed because one or more lines are too long
@ -11,7 +11,7 @@
|
||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" />
|
||||
<script type="module" crossorigin src="/assets/index-CHbSl3FU.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-zSMkg4LY.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-UCAeMvu5.css">
|
||||
</head>
|
||||
|
||||
|
@ -1,4 +1,21 @@
|
||||
<svg width="779" height="514" viewBox="0 0 779 514" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M753.092 5.91932C756.557 5.09976 755.962 -0.00012207 752.401 -0.00012207H426.001C424.755 -0.00012207 423.639 0.77027 423.197 1.93535L236.968 492.6C235.729 495.865 240.123 498.255 242.191 495.441L569.357 50.1132C569.778 49.5392 570.391 49.1339 571.084 48.97L753.092 5.91932Z" fill="#FFF5D9"/>
|
||||
<path d="M11.9665 40.2288C9.10949 38.777 10.2135 34.4583 13.4167 34.5557L404.273 46.4367C406.334 46.4993 407.719 48.5749 406.986 50.5023L347.438 206.981C346.804 208.647 344.865 209.396 343.275 208.588L11.9665 40.2288Z" fill="#FFF5D9"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="779"
|
||||
height="514"
|
||||
viewBox="0 0 779 514"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<path
|
||||
d="M753.092 5.91932C756.557 5.09976 755.962 -0.00012207 752.401 -0.00012207H426.001C424.755 -0.00012207 423.639 0.77027 423.197 1.93535L236.968 492.6C235.729 495.865 240.123 498.255 242.191 495.441L569.357 50.1132C569.778 49.5392 570.391 49.1339 571.084 48.97L753.092 5.91932Z"
|
||||
fill="#FFF5D9"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M 12.054907,40.2288 C 9.0444768,38.777 10.207772,34.4583 13.582982,34.5557 l 411.845088,11.881 c 2.17167,0.0626 3.63105,2.1382 2.85869,4.0656 l -62.7457,156.4787 c -0.66805,1.666 -2.71117,2.415 -4.38655,1.607 z"
|
||||
fill="#fff5d9"
|
||||
id="path2"
|
||||
style="stroke-width:1.0265" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 644 B After Width: | Height: | Size: 864 B |
Loading…
Reference in New Issue
Block a user