@k2b/ui 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/chat/ChatComposer.js +261 -274
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/ChatPrimitives.js +9 -6
- package/dist/browser/chat/ChatPrimitives.js.map +1 -1
- package/dist/browser/content/FileView.js +62 -36
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/MarkdownView.js +9 -3
- package/dist/browser/content/MarkdownView.js.map +1 -1
- package/dist/browser/content/VideoPlayer.js +279 -0
- package/dist/browser/content/VideoPlayer.js.map +1 -0
- package/dist/browser/content/file-view-preview.js +2 -2
- package/dist/browser/content/file-view-preview.js.map +1 -1
- package/dist/browser/content/index.js +2 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/markdown-links.js +178 -0
- package/dist/browser/content/markdown-links.js.map +1 -0
- package/dist/browser/inputs/FileDropTarget.js +129 -0
- package/dist/browser/inputs/FileDropTarget.js.map +1 -0
- package/dist/browser/inputs/FileInputs.js +37 -11
- package/dist/browser/inputs/FileInputs.js.map +1 -1
- package/dist/browser/inputs/file-drop.js +338 -0
- package/dist/browser/inputs/file-drop.js.map +1 -0
- package/dist/browser/inputs/index.js +1 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/markdown/MarkdownEditor.js +72 -78
- package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/browser/intl/messages.js +97 -4
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +210 -44
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/Navigation.js +274 -197
- package/dist/browser/layout/Navigation.js.map +1 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/navigation-model.js +2 -0
- package/dist/browser/layout/navigation-model.js.map +1 -1
- package/dist/browser/surfaces/NoticeCard.js +47 -44
- package/dist/browser/surfaces/NoticeCard.js.map +1 -1
- package/dist/ssr/chat/ChatComposer.js +59 -48
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/ChatPrimitives.js +9 -6
- package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
- package/dist/ssr/content/FileView.js +30 -6
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/MarkdownView.js +9 -3
- package/dist/ssr/content/MarkdownView.js.map +1 -1
- package/dist/ssr/content/VideoPlayer.js +208 -0
- package/dist/ssr/content/VideoPlayer.js.map +1 -0
- package/dist/ssr/content/file-view-preview.js +2 -2
- package/dist/ssr/content/file-view-preview.js.map +1 -1
- package/dist/ssr/content/index.js +2 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/markdown-links.js +178 -0
- package/dist/ssr/content/markdown-links.js.map +1 -0
- package/dist/ssr/inputs/FileDropTarget.js +103 -0
- package/dist/ssr/inputs/FileDropTarget.js.map +1 -0
- package/dist/ssr/inputs/FileInputs.js +32 -10
- package/dist/ssr/inputs/FileInputs.js.map +1 -1
- package/dist/ssr/inputs/file-drop.js +338 -0
- package/dist/ssr/inputs/file-drop.js.map +1 -0
- package/dist/ssr/inputs/index.js +1 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/markdown/MarkdownEditor.js +14 -2
- package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/ssr/intl/messages.js +97 -4
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +173 -27
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/Navigation.js +169 -122
- package/dist/ssr/layout/Navigation.js.map +1 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/navigation-model.js +2 -0
- package/dist/ssr/layout/navigation-model.js.map +1 -1
- package/dist/ssr/surfaces/NoticeCard.js +17 -12
- package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/chat/ChatPrimitives.d.ts +1 -1
- package/dist/types/content/VideoPlayer.d.ts +41 -0
- package/dist/types/content/index.d.ts +2 -0
- package/dist/types/content/markdown-links.d.ts +66 -0
- package/dist/types/inputs/FileDropTarget.d.ts +23 -0
- package/dist/types/inputs/FileInputs.d.ts +2 -0
- package/dist/types/inputs/file-drop.d.ts +80 -0
- package/dist/types/inputs/index.d.ts +2 -0
- package/dist/types/intl/messages.d.ts +47 -0
- package/dist/types/layout/AppWorkspace.d.ts +21 -0
- package/dist/types/layout/index.d.ts +2 -2
- package/dist/types/layout/navigation-model.d.ts +18 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["content/markdown-links.ts"],"sourcesContent":["import { fileIcons } from \"@k2b/stdlib\";\nimport type { Token, Tokens } from \"marked\";\nimport { resolveUiMessages, type UiMessages } from \"../intl/messages\";\n\n/** What a reference points to inside the host application. */\nexport type MarkdownReferenceKind = \"file\" | \"note\" | \"heading\" | \"task\" | \"page\";\n\n/** The type a reference shows: a file's type from its extension, or the kind of the referenced content. */\nexport type MarkdownReferenceType = \"pdf\" | \"image\" | \"design\" | \"file\" | \"note\" | \"heading\" | \"task\" | \"page\";\n\n/**\n * A link to content inside the host application, as opposed to a web or mail link.\n * References render as a calm pill whose icon names the type.\n */\nexport type MarkdownReference = {\n kind: MarkdownReferenceKind;\n /** The file's name, which decides its type and icon. Defaults to the link text. */\n fileName?: string;\n /** The file's formatted size. It shows only when the link stands alone on its line. */\n size?: string;\n /** Plain-text title of the document that holds a heading, for a heading in another document. */\n document?: string;\n};\n\nexport type MarkdownLinkInput = {\n /** The final, already validated link destination. */\n href: string;\n /** The rendered link text. It crosses a trust boundary: the caller sanitizes it. */\n html: string;\n /** The link text as plain text, for the accessible name. Defaults to the text of `html`. */\n text?: string;\n title?: string;\n target?: \"_blank\";\n /** Link relations without a new tab, such as `noreferrer`. `target: \"_blank\"` always sets `noopener noreferrer`. */\n rel?: string;\n /** A reference inside the host. Without one, the link is a web link, or a mail link for `mailto:` and `tel:`. */\n reference?: MarkdownReference | null;\n /** The link is the only content of its line. Only then does a file show its size. */\n standalone?: boolean;\n /** Locale of the type name in the accessible name. Defaults to English on the server and the page language in the browser. */\n locale?: string;\n};\n\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\").replaceAll(\"'\", \"'\");\n\nconst IMAGE_EXTENSIONS = new Set([\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"avif\", \"bmp\", \"ico\", \"svg\", \"heic\", \"heif\", \"tif\", \"tiff\"]);\nconst DESIGN_EXTENSIONS = new Set([\"afdesign\", \"afphoto\", \"afpub\", \"psd\", \"psb\", \"ai\", \"eps\", \"indd\", \"idml\", \"fig\", \"sketch\", \"xd\"]);\n\nconst extensionOf = (name: string): string | null => {\n const match = /\\.([a-z0-9]{1,10})$/i.exec(name.trim());\n return match && /[a-z]/i.test(match[1]!) ? match[1]!.toLowerCase() : null;\n};\n\n/** The type of a file reference, from the extension of its name. */\nexport const markdownFileType = (fileName: string): \"pdf\" | \"image\" | \"design\" | \"file\" => {\n const extension = extensionOf(fileName);\n if (extension === \"pdf\") return \"pdf\";\n if (extension && IMAGE_EXTENSIONS.has(extension)) return \"image\";\n if (extension && DESIGN_EXTENSIONS.has(extension)) return \"design\";\n return \"file\";\n};\n\nconst REFERENCE_BASE = \"https://reference.invalid/\";\n\n/**\n * The reference a link destination names on its own: `#anchor` is a heading in the same document, and any other\n * relative URL is a page of the host, or a file when its last path segment has a file extension. Absolute URLs,\n * every scheme, and relative URLs that a browser resolves to another host, such as `//host` or `/\\host`, are web\n * or mail links; the result is then `null`.\n */\nexport const markdownLinkReference = (href: string): MarkdownReference | null => {\n const url = href.trim();\n if (!url || /^[a-z][a-z\\d+.-]*:/i.test(url)) return null;\n try {\n if (new URL(url, REFERENCE_BASE).origin !== new URL(REFERENCE_BASE).origin) return null;\n } catch {\n return null;\n }\n if (url.startsWith(\"#\")) return { kind: \"heading\" };\n const segment = url.split(/[?#]/, 1)[0]!.split(\"/\").pop() ?? \"\";\n let fileName = segment;\n try {\n fileName = decodeURIComponent(segment);\n } catch {\n /* A malformed escape stays literal text. */\n }\n return extensionOf(fileName) ? { kind: \"file\", fileName } : { kind: \"page\" };\n};\n\n/** The type a reference shows. */\nexport const markdownReferenceType = (reference: MarkdownReference, text: string): MarkdownReferenceType =>\n reference.kind === \"file\" ? markdownFileType(reference.fileName ?? text) : reference.kind;\n\nconst TYPE_ICONS: Record<Exclude<MarkdownReferenceType, \"file\">, string> = {\n pdf: \"ti-file-type-pdf\",\n image: \"ti-photo\",\n design: \"ti-vector-bezier-2\",\n note: \"ti-file-text\",\n heading: \"ti-hash\",\n task: \"ti-circle-check\",\n page: \"ti-link\",\n};\n\n/** The Tabler glyph of a reference type; any other file keeps the glyph of its file family. */\nexport const markdownReferenceIcon = (type: MarkdownReferenceType, fileName = \"\"): string =>\n type === \"file\" ? (fileIcons.getFileIcon({ name: fileName, type: \"file\" }).split(/\\s+/)[0] ?? \"ti-file\") : TYPE_ICONS[type];\n\nconst TYPE_LABELS: Record<MarkdownReferenceType, keyof UiMessages> = {\n pdf: \"referencePdf\",\n image: \"referenceImage\",\n design: \"referenceDesign\",\n file: \"referenceFile\",\n note: \"referenceNote\",\n heading: \"referenceHeading\",\n task: \"referenceTask\",\n page: \"referencePage\",\n};\n\n/** The localized name of a reference type, such as \"PDF\" or \"Überschrift\". */\nexport const markdownReferenceTypeLabel = (type: MarkdownReferenceType, locale?: string): string =>\n String(resolveUiMessages(locale)[TYPE_LABELS[type]]);\n\n/**\n * The text of rendered inline HTML, still as HTML: tags go, character references such as `©` stay. One pass,\n * so a label full of `<` stays linear. The result only ever reaches `textAttribute`, which escapes what is left.\n */\nconst htmlText = (html: string): string => {\n let text = \"\";\n let index = 0;\n for (let open = html.indexOf(\"<\"); open !== -1; open = html.indexOf(\"<\", index)) {\n const close = html.indexOf(\">\", open + 1);\n if (close === -1) break;\n text += html.slice(index, open);\n index = close + 1;\n }\n return text + html.slice(index);\n};\n\n/** HTML text as an attribute value. Character references stay for the browser to decode; nothing can end the value. */\nconst textAttribute = (text: string): string =>\n text\n .replace(/&(?!#\\d+;|#x[\\da-f]+;|[a-z][a-z\\d]*;)/gi, \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\");\n\nconst isMailHref = (href: string) => /^(?:mailto|tel):/i.test(href.trim());\n\n/**\n * One link of rendered Markdown. A reference to content of the host renders as a calm pill: a neutral fill, the\n * text in the prose colour, and an icon whose colour names the type. Its accessible name starts with the type, as\n * in \"PDF: Brand-2026.pdf\". A heading in another document shows that document first (\"Notes › Heading\"). A web\n * link stays prose text with a thin underline in the link accent and a small ↗; a mail link has no arrow. A link\n * around an image is the image: a plain anchor that the image's own text names.\n */\nexport const renderMarkdownLink = (input: MarkdownLinkInput): string => {\n const titleAttribute = input.title ? ` title=\"${escapeHtml(input.title)}\"` : \"\";\n const targetAttributes =\n input.target === \"_blank\" ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : input.rel ? ` rel=\"${escapeHtml(input.rel)}\"` : \"\";\n const href = escapeHtml(input.href);\n if (/<img\\b/i.test(input.html)) return `<a href=\"${href}\"${titleAttribute}${targetAttributes}>${input.html}</a>`;\n const reference = input.reference;\n if (!reference) {\n const mail = isMailHref(input.href);\n const arrow = mail ? \"\" : '<i class=\"k2b-text-link__external ti ti-arrow-up-right\" aria-hidden=\"true\"></i>';\n return `<a href=\"${href}\" class=\"k2b-text-link\" data-link=\"${mail ? \"mail\" : \"web\"}\"${titleAttribute}${targetAttributes}>${input.html}${arrow}</a>`;\n }\n const text = (input.text ?? htmlText(input.html)).trim();\n const type = markdownReferenceType(reference, text);\n const icon = markdownReferenceIcon(type, reference.fileName ?? text);\n const size = input.standalone && reference.kind === \"file\" && reference.size ? reference.size : \"\";\n const document = reference.kind === \"heading\" ? (reference.document?.trim() ?? \"\") : \"\";\n const name =\n escapeHtml(`${markdownReferenceTypeLabel(type, input.locale)}: ${document ? `${document} › ` : \"\"}`) +\n (input.text === undefined ? textAttribute(text) : escapeHtml(text)) +\n (size ? escapeHtml(`, ${size}`) : \"\");\n return (\n `<a href=\"${href}\" class=\"k2b-reference\" data-reference=\"${type}\" aria-label=\"${name}\"${titleAttribute}${targetAttributes}>` +\n `<i class=\"k2b-reference__icon ti ${icon}\" aria-hidden=\"true\"></i>` +\n (document ? `<span class=\"k2b-reference__document\">${escapeHtml(document)} ›</span> ` : \"\") +\n input.html +\n (size ? `<span class=\"k2b-reference__size\">${escapeHtml(size)}</span>` : \"\") +\n `</a>`\n );\n};\n\nconst isBlank = (token: Token) => (token.type === \"text\" || token.type === \"space\") && !token.raw.trim();\nconst isLink = (token: Token | undefined): token is Tokens.Link => token?.type === \"link\";\n\n/**\n * The links among `tokens` that stand alone on their line: the only content of a paragraph or list item line,\n * between line breaks. Pass the result's check as `standalone` to `renderMarkdownLink`, so a file shows its size\n * in a list of files but not inside a sentence. Call it from `walkTokens` of a renderer with GFM line breaks\n * (`breaks: true`), where every source line is a visual line.\n */\nexport const markStandaloneLinks = (token: Token, standalone: WeakSet<Tokens.Link>): void => {\n if ((token.type !== \"paragraph\" && token.type !== \"text\") || !(\"tokens\" in token) || !token.tokens) return;\n let line: Token[] = [];\n const close = () => {\n const content = line.filter((candidate) => !isBlank(candidate));\n if (content.length === 1 && isLink(content[0])) standalone.add(content[0]);\n line = [];\n };\n for (const child of token.tokens) {\n if (child.type === \"br\") {\n close();\n continue;\n }\n const plain = child.type === \"text\" && !(\"tokens\" in child && child.tokens?.length) ? child.raw : \"\";\n if (plain.includes(\"\\n\")) {\n for (const [index, part] of plain.split(\"\\n\").entries()) {\n if (index > 0) close();\n if (part.trim()) line.push({ type: \"text\", raw: part, text: part });\n }\n continue;\n }\n line.push(child);\n }\n close();\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { template as _$template } from "solid-js/web";
|
|
2
|
+
import { className as _$className } from "solid-js/web";
|
|
3
|
+
import { style as _$style } from "solid-js/web";
|
|
4
|
+
import { setAttribute as _$setAttribute } from "solid-js/web";
|
|
5
|
+
import { effect as _$effect } from "solid-js/web";
|
|
6
|
+
import { getNextElement as _$getNextElement } from "solid-js/web";
|
|
7
|
+
import { insert as _$insert } from "solid-js/web";
|
|
8
|
+
import { use as _$use } from "solid-js/web";
|
|
9
|
+
var _tmpl$ = /*#__PURE__*/_$template(`<div popover=manual class=k2b-file-drop aria-hidden=true><span class=k2b-file-drop__message><i></i><span>`);
|
|
10
|
+
import { createEffect, createMemo, createSignal, onCleanup, onMount } from "solid-js";
|
|
11
|
+
import { useLocale } from "../intl/locale";
|
|
12
|
+
import { useUiMessages } from "../intl/messages";
|
|
13
|
+
import { FILE_DROP_DEFAULT_REGION, fileDropEngine, liveDocument } from "./file-drop";
|
|
14
|
+
/**
|
|
15
|
+
* Turns an area into a drop target while files from outside the page are dragged over the window. A calm overlay
|
|
16
|
+
* covers the area without moving anything and says what dropping does; a more specific target inside it, such as a
|
|
17
|
+
* folder row or a `FileDropzone`, takes the drop and its sentence while the pointer is over it. Text, links, and
|
|
18
|
+
* elements dragged within the page never show it. Keep a visible upload button for keyboard and touch users.
|
|
19
|
+
*/
|
|
20
|
+
export function FileDropTarget(props) {
|
|
21
|
+
const messages = useUiMessages();
|
|
22
|
+
const locale = useLocale();
|
|
23
|
+
let overlay;
|
|
24
|
+
const [rect, setRect] = createSignal();
|
|
25
|
+
const region = () => props.for ?? overlay?.parentElement?.closest(FILE_DROP_DEFAULT_REGION) ?? overlay?.ownerDocument.documentElement;
|
|
26
|
+
const entry = {
|
|
27
|
+
options: props,
|
|
28
|
+
messages,
|
|
29
|
+
locale,
|
|
30
|
+
region,
|
|
31
|
+
host: () => overlay?.parentElement ?? undefined
|
|
32
|
+
};
|
|
33
|
+
const [engine, setEngine] = createSignal();
|
|
34
|
+
onMount(() => {
|
|
35
|
+
if (!overlay) return;
|
|
36
|
+
const drop = fileDropEngine(liveDocument(overlay));
|
|
37
|
+
onCleanup(drop.addRegion(entry));
|
|
38
|
+
setEngine(drop);
|
|
39
|
+
});
|
|
40
|
+
const shown = createMemo(() => engine()?.session()?.shown.includes(entry) ?? false);
|
|
41
|
+
const hover = createMemo(() => {
|
|
42
|
+
const current = engine()?.session()?.hover;
|
|
43
|
+
const element = region();
|
|
44
|
+
return current && element && (current.element === element || element.contains(current.element)) ? current : null;
|
|
45
|
+
});
|
|
46
|
+
const state = () => hover() ? hover().invalid ? "invalid" : "over" : "available";
|
|
47
|
+
const sentence = () => {
|
|
48
|
+
const current = hover();
|
|
49
|
+
if (current?.invalid) return messages().fileTypeNotAccepted;
|
|
50
|
+
return current ? current.entry.options.label : props.label;
|
|
51
|
+
};
|
|
52
|
+
createEffect(() => {
|
|
53
|
+
if (!shown()) return;
|
|
54
|
+
engine()?.frame();
|
|
55
|
+
const element = region();
|
|
56
|
+
const view = overlay?.ownerDocument.defaultView;
|
|
57
|
+
if (!element || !view) return;
|
|
58
|
+
// The overlay keeps to the visible part of its area, so its sentence stays on screen.
|
|
59
|
+
const bounds = element === element.ownerDocument.documentElement ? new DOMRect(0, 0, view.innerWidth, view.innerHeight) : element.getBoundingClientRect();
|
|
60
|
+
const top = Math.max(0, bounds.top);
|
|
61
|
+
const left = Math.max(0, bounds.left);
|
|
62
|
+
const next = {
|
|
63
|
+
top,
|
|
64
|
+
left,
|
|
65
|
+
width: Math.max(0, Math.min(view.innerWidth, bounds.right) - left),
|
|
66
|
+
height: Math.max(0, Math.min(view.innerHeight, bounds.bottom) - top),
|
|
67
|
+
radius: view.getComputedStyle(element).borderRadius
|
|
68
|
+
};
|
|
69
|
+
const previous = rect();
|
|
70
|
+
if (!previous || previous.top !== next.top || previous.left !== next.left || previous.width !== next.width || previous.height !== next.height || previous.radius !== next.radius) setRect(next);
|
|
71
|
+
});
|
|
72
|
+
createEffect(() => {
|
|
73
|
+
if (!overlay?.showPopover) return;
|
|
74
|
+
const open = overlay.matches(":popover-open");
|
|
75
|
+
if (shown() && !open) overlay.showPopover();else if (!shown() && open) overlay.hidePopover();
|
|
76
|
+
});
|
|
77
|
+
onCleanup(() => {
|
|
78
|
+
if (overlay?.matches?.(":popover-open")) overlay.hidePopover();
|
|
79
|
+
});
|
|
80
|
+
return (() => {
|
|
81
|
+
var _el$ = _$getNextElement(_tmpl$),
|
|
82
|
+
_el$2 = _el$.firstChild,
|
|
83
|
+
_el$3 = _el$2.firstChild,
|
|
84
|
+
_el$4 = _el$3.nextSibling;
|
|
85
|
+
var _ref$ = overlay;
|
|
86
|
+
typeof _ref$ === "function" ? _$use(_ref$, _el$) : overlay = _el$;
|
|
87
|
+
_$insert(_el$4, sentence);
|
|
88
|
+
_$effect(_p$ => {
|
|
89
|
+
var _v$ = state(),
|
|
90
|
+
_v$2 = rect() ? {
|
|
91
|
+
top: `${rect().top}px`,
|
|
92
|
+
left: `${rect().left}px`,
|
|
93
|
+
width: `${rect().width}px`,
|
|
94
|
+
height: `${rect().height}px`,
|
|
95
|
+
"border-radius": rect().radius
|
|
96
|
+
} : undefined,
|
|
97
|
+
_v$3 = state() === "invalid" ? "ti ti-file-x" : "ti ti-upload";
|
|
98
|
+
_v$ !== _p$.e && _$setAttribute(_el$, "data-state", _p$.e = _v$);
|
|
99
|
+
_p$.t = _$style(_el$, _v$2, _p$.t);
|
|
100
|
+
_v$3 !== _p$.a && _$className(_el$3, _p$.a = _v$3);
|
|
101
|
+
return _p$;
|
|
102
|
+
}, {
|
|
103
|
+
e: undefined,
|
|
104
|
+
t: undefined,
|
|
105
|
+
a: undefined
|
|
106
|
+
});
|
|
107
|
+
return _el$;
|
|
108
|
+
})();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Makes one element a specific drop target, such as a folder row inside a `FileDropTarget` area: pass the result as
|
|
113
|
+
* the element's `ref`. It wins over the area around it while the pointer is over it, and the area's overlay shows its
|
|
114
|
+
* sentence. Calling the ref again with new options replaces them.
|
|
115
|
+
*/
|
|
116
|
+
export function fileDropTarget(options) {
|
|
117
|
+
const messages = useUiMessages();
|
|
118
|
+
const locale = useLocale();
|
|
119
|
+
return element => {
|
|
120
|
+
const entry = {
|
|
121
|
+
options,
|
|
122
|
+
messages,
|
|
123
|
+
locale
|
|
124
|
+
};
|
|
125
|
+
// A ref runs before its element is inserted; registering after insertion finds the document it ends up in.
|
|
126
|
+
queueMicrotask(() => fileDropEngine(liveDocument(element)).setTarget(element, entry));
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=FileDropTarget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/FileDropTarget.tsx"],"sourcesContent":["import { createEffect, createMemo, createSignal, type JSX, onCleanup, onMount } from \"solid-js\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { FILE_DROP_DEFAULT_REGION, type FileDropOptions, type FileDropTargetEntry, fileDropEngine, liveDocument } from \"./file-drop\";\n\nexport type { FileDropDetails, FileDropOptions, FileDropRejection } from \"./file-drop\";\n\nexport type FileDropTargetProps = FileDropOptions & {\n /**\n * The area that takes the files. Defaults to the nearest dialog, `AppWorkspace.Detail`, or `AppWorkspace.Main`\n * around the component, and to the whole window outside of them.\n */\n for?: Element;\n};\n\ntype Rect = { top: number; left: number; width: number; height: number; radius: string };\n\n/**\n * Turns an area into a drop target while files from outside the page are dragged over the window. A calm overlay\n * covers the area without moving anything and says what dropping does; a more specific target inside it, such as a\n * folder row or a `FileDropzone`, takes the drop and its sentence while the pointer is over it. Text, links, and\n * elements dragged within the page never show it. Keep a visible upload button for keyboard and touch users.\n */\nexport function FileDropTarget(props: FileDropTargetProps): JSX.Element {\n const messages = useUiMessages();\n const locale = useLocale();\n let overlay: HTMLDivElement | undefined;\n const [rect, setRect] = createSignal<Rect>();\n const region = () => props.for ?? overlay?.parentElement?.closest(FILE_DROP_DEFAULT_REGION) ?? overlay?.ownerDocument.documentElement;\n const entry: FileDropTargetEntry = { options: props, messages, locale, region, host: () => overlay?.parentElement ?? undefined };\n const [engine, setEngine] = createSignal<ReturnType<typeof fileDropEngine>>();\n\n onMount(() => {\n if (!overlay) return;\n const drop = fileDropEngine(liveDocument(overlay));\n onCleanup(drop.addRegion(entry));\n setEngine(drop);\n });\n\n const shown = createMemo(() => engine()?.session()?.shown.includes(entry) ?? false);\n const hover = createMemo(() => {\n const current = engine()?.session()?.hover;\n const element = region();\n return current && element && (current.element === element || element.contains(current.element)) ? current : null;\n });\n const state = () => (hover() ? (hover()!.invalid ? \"invalid\" : \"over\") : \"available\");\n const sentence = () => {\n const current = hover();\n if (current?.invalid) return messages().fileTypeNotAccepted;\n return current ? current.entry.options.label : props.label;\n };\n\n createEffect(() => {\n if (!shown()) return;\n engine()?.frame();\n const element = region();\n const view = overlay?.ownerDocument.defaultView;\n if (!element || !view) return;\n // The overlay keeps to the visible part of its area, so its sentence stays on screen.\n const bounds =\n element === element.ownerDocument.documentElement\n ? new DOMRect(0, 0, view.innerWidth, view.innerHeight)\n : element.getBoundingClientRect();\n const top = Math.max(0, bounds.top);\n const left = Math.max(0, bounds.left);\n const next = {\n top,\n left,\n width: Math.max(0, Math.min(view.innerWidth, bounds.right) - left),\n height: Math.max(0, Math.min(view.innerHeight, bounds.bottom) - top),\n radius: view.getComputedStyle(element).borderRadius,\n };\n const previous = rect();\n if (\n !previous ||\n previous.top !== next.top ||\n previous.left !== next.left ||\n previous.width !== next.width ||\n previous.height !== next.height ||\n previous.radius !== next.radius\n )\n setRect(next);\n });\n\n createEffect(() => {\n if (!overlay?.showPopover) return;\n const open = overlay.matches(\":popover-open\");\n if (shown() && !open) overlay.showPopover();\n else if (!shown() && open) overlay.hidePopover();\n });\n onCleanup(() => {\n if (overlay?.matches?.(\":popover-open\")) overlay.hidePopover();\n });\n\n return (\n <div\n ref={overlay}\n popover=\"manual\"\n class=\"k2b-file-drop\"\n data-state={state()}\n aria-hidden=\"true\"\n style={\n rect()\n ? {\n top: `${rect()!.top}px`,\n left: `${rect()!.left}px`,\n width: `${rect()!.width}px`,\n height: `${rect()!.height}px`,\n \"border-radius\": rect()!.radius,\n }\n : undefined\n }\n >\n <span class=\"k2b-file-drop__message\">\n <i class={state() === \"invalid\" ? \"ti ti-file-x\" : \"ti ti-upload\"} />\n <span>{sentence()}</span>\n </span>\n </div>\n );\n}\n\n/**\n * Makes one element a specific drop target, such as a folder row inside a `FileDropTarget` area: pass the result as\n * the element's `ref`. It wins over the area around it while the pointer is over it, and the area's overlay shows its\n * sentence. Calling the ref again with new options replaces them.\n */\nexport function fileDropTarget(options: FileDropOptions): (element: Element) => void {\n const messages = useUiMessages();\n const locale = useLocale();\n return (element) => {\n const entry = { options, messages, locale };\n // A ref runs before its element is inserted; registering after insertion finds the document it ends up in.\n queueMicrotask(() => fileDropEngine(liveDocument(element)).setTarget(element, entry));\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,7 +3,6 @@ import { delegateEvents as _$delegateEvents } from "solid-js/web";
|
|
|
3
3
|
import { style as _$style } from "solid-js/web";
|
|
4
4
|
import { setProperty as _$setProperty } from "solid-js/web";
|
|
5
5
|
import { setAttribute as _$setAttribute } from "solid-js/web";
|
|
6
|
-
import { use as _$use } from "solid-js/web";
|
|
7
6
|
import { className as _$className } from "solid-js/web";
|
|
8
7
|
import { effect as _$effect } from "solid-js/web";
|
|
9
8
|
import { runHydrationEvents as _$runHydrationEvents } from "solid-js/web";
|
|
@@ -11,6 +10,7 @@ import { getNextMarker as _$getNextMarker } from "solid-js/web";
|
|
|
11
10
|
import { createComponent as _$createComponent } from "solid-js/web";
|
|
12
11
|
import { getNextElement as _$getNextElement } from "solid-js/web";
|
|
13
12
|
import { insert as _$insert } from "solid-js/web";
|
|
13
|
+
import { use as _$use } from "solid-js/web";
|
|
14
14
|
import { spread as _$spread } from "solid-js/web";
|
|
15
15
|
import { mergeProps as _$mergeProps } from "solid-js/web";
|
|
16
16
|
import { memo as _$memo } from "solid-js/web";
|
|
@@ -29,13 +29,14 @@ var _tmpl$ = /*#__PURE__*/_$template(`<span class=k2b-dropzone__subtitle>`),
|
|
|
29
29
|
_tmpl$11 = /*#__PURE__*/_$template(`<small>`),
|
|
30
30
|
_tmpl$12 = /*#__PURE__*/_$template(`<small class=k2b-image-cropper__error>`),
|
|
31
31
|
_tmpl$13 = /*#__PURE__*/_$template(`<button type=button class=k2b-image-cropper__handle>`);
|
|
32
|
-
import {
|
|
33
|
-
import { createEffect, createSignal, For, onCleanup, Show } from "solid-js";
|
|
32
|
+
import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show } from "solid-js";
|
|
34
33
|
import { Button, IconButton } from "../actions/Button";
|
|
35
34
|
import { Tooltip } from "../feedback/Tooltip";
|
|
36
35
|
import { createFieldMeta, Field, fieldControlAria } from "../internal/field";
|
|
37
36
|
import { useUiMessages } from "../intl/messages";
|
|
37
|
+
import { fileDropTarget } from "./FileDropTarget";
|
|
38
38
|
import { commitFieldValue, resolveMaybeAccessor } from "./field-contract";
|
|
39
|
+
import { fileDropEngine, liveDocument } from "./file-drop";
|
|
39
40
|
import { clampImageCropRect, getInitialImageCropRect, resizeImageCropFromCorner, rotateImageCropRight } from "./image-crop";
|
|
40
41
|
export function FileDropzone(props) {
|
|
41
42
|
const messages = useUiMessages();
|
|
@@ -43,17 +44,41 @@ export function FileDropzone(props) {
|
|
|
43
44
|
const disabled = () => Boolean(props.disabled || props.busy);
|
|
44
45
|
const error = () => resolveMaybeAccessor(props.error);
|
|
45
46
|
let input;
|
|
47
|
+
const [button, setButton] = createSignal();
|
|
46
48
|
const emit = files => {
|
|
47
49
|
if (disabled() || files.length === 0) return;
|
|
48
50
|
void props.onDrop(props.multiple === false ? files.slice(0, 1) : files);
|
|
49
51
|
};
|
|
50
|
-
|
|
52
|
+
// Drops take the same path as every other file drop target: files only, the most specific target wins, and files
|
|
53
|
+
// that do not fit `accept` are left out with a message.
|
|
54
|
+
const dropLabel = () => props.dropLabel ?? messages().dropToUpload;
|
|
55
|
+
const dropRef = fileDropTarget({
|
|
56
|
+
get label() {
|
|
57
|
+
return dropLabel();
|
|
58
|
+
},
|
|
51
59
|
get accept() {
|
|
52
60
|
return props.accept;
|
|
53
61
|
},
|
|
62
|
+
get multiple() {
|
|
63
|
+
return props.multiple;
|
|
64
|
+
},
|
|
65
|
+
get disabled() {
|
|
66
|
+
return disabled();
|
|
67
|
+
},
|
|
54
68
|
onDrop: emit
|
|
55
69
|
});
|
|
56
|
-
const
|
|
70
|
+
const [engine, setEngine] = createSignal();
|
|
71
|
+
onMount(() => {
|
|
72
|
+
const element = button();
|
|
73
|
+
if (element) setEngine(fileDropEngine(liveDocument(element)));
|
|
74
|
+
});
|
|
75
|
+
const dragState = createMemo(() => {
|
|
76
|
+
const element = button();
|
|
77
|
+
const hover = engine()?.session()?.hover;
|
|
78
|
+
if (!hover || hover.element !== element) return undefined;
|
|
79
|
+
return hover.invalid ? "invalid" : "over";
|
|
80
|
+
});
|
|
81
|
+
const title = () => props.busy ? messages().uploading : dragState() === "invalid" ? messages().fileTypeNotAccepted : dragState() === "over" ? dropLabel() : props.title ?? messages().dropFiles;
|
|
57
82
|
return _$createComponent(Field, {
|
|
58
83
|
get ["class"]() {
|
|
59
84
|
return props.class;
|
|
@@ -85,26 +110,27 @@ export function FileDropzone(props) {
|
|
|
85
110
|
[_el$9, _co$] = _$getNextMarker(_el$8.nextSibling),
|
|
86
111
|
_el$0 = _el$9.nextSibling,
|
|
87
112
|
[_el$1, _co$2] = _$getNextMarker(_el$0.nextSibling);
|
|
113
|
+
_$use(element => {
|
|
114
|
+
setButton(element);
|
|
115
|
+
dropRef(element);
|
|
116
|
+
}, _el$);
|
|
88
117
|
_$spread(_el$, _$mergeProps({
|
|
89
118
|
get id() {
|
|
90
119
|
return meta.controlId;
|
|
91
120
|
},
|
|
92
|
-
get ["data-dragging"]() {
|
|
93
|
-
return zone.isDragging() ? "true" : undefined;
|
|
94
|
-
},
|
|
95
121
|
get ["data-invalid"]() {
|
|
96
|
-
return
|
|
122
|
+
return error() ? "true" : undefined;
|
|
97
123
|
},
|
|
98
124
|
get disabled() {
|
|
99
125
|
return disabled();
|
|
100
126
|
}
|
|
101
127
|
}, () => fieldControlAria(meta, props), {
|
|
102
128
|
"onClick": () => input?.click()
|
|
103
|
-
}
|
|
129
|
+
}), false, true);
|
|
104
130
|
_$insert(_el$5, title);
|
|
105
131
|
_$insert(_el$4, _$createComponent(Show, {
|
|
106
132
|
get when() {
|
|
107
|
-
return
|
|
133
|
+
return dragState() === "invalid";
|
|
108
134
|
},
|
|
109
135
|
get fallback() {
|
|
110
136
|
return _$createComponent(Show, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["inputs/FileInputs.tsx"],"sourcesContent":["import { dropzone } from \"@k2b/stdlib/solid\";\nimport { createEffect, createSignal, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { Tooltip } from \"../feedback/Tooltip\";\nimport { createFieldMeta, Field, fieldControlAria } from \"../internal/field\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { FieldProps, ValueFieldProps } from \"./field-contract\";\nimport { commitFieldValue, resolveMaybeAccessor } from \"./field-contract\";\nimport {\n clampImageCropRect,\n getInitialImageCropRect,\n type ImageCropAspect,\n type ImageCropRect,\n type ImageCropResizeHandle,\n type ImageCropRotation,\n type ImageCropSource,\n type ImageCropState,\n resizeImageCropFromCorner,\n rotateImageCropRight,\n} from \"./image-crop\";\n\nexport type FileDropzoneProps = FieldProps & {\n accept?: string;\n multiple?: boolean;\n busy?: boolean;\n /** Full icon class list, for example `\"ti ti-photo-plus\"`. Defaults to `\"ti ti-cloud-upload\"`. */\n icon?: string;\n title?: JSX.Element;\n subtitle?: JSX.Element;\n hint?: JSX.Element;\n onDrop: (files: File[]) => void | Promise<void>;\n};\n\nexport function FileDropzone(props: FileDropzoneProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n const disabled = () => Boolean(props.disabled || props.busy);\n const error = () => resolveMaybeAccessor(props.error);\n let input: HTMLInputElement | undefined;\n const emit = (files: File[]) => {\n if (disabled() || files.length === 0) return;\n void props.onDrop(props.multiple === false ? files.slice(0, 1) : files);\n };\n const zone = dropzone.create({\n get accept() {\n return props.accept;\n },\n onDrop: emit,\n });\n const title = () =>\n props.busy\n ? messages().uploading\n : zone.invalidDrag()\n ? messages().fileTypeNotAccepted\n : zone.isDragging()\n ? messages().dropToUpload\n : (props.title ?? messages().dropFiles);\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n required={props.required}\n disabled={disabled()}\n >\n <button\n id={meta.controlId}\n type=\"button\"\n class=\"k2b-dropzone\"\n data-dragging={zone.isDragging() ? \"true\" : undefined}\n data-invalid={zone.invalidDrag() || error() ? \"true\" : undefined}\n disabled={disabled()}\n {...fieldControlAria(meta, props)}\n onClick={() => input?.click()}\n {...zone.handlers}\n >\n <span class=\"k2b-dropzone__icon\" aria-hidden=\"true\">\n <i class={props.busy ? \"ti ti-loader-2 k2b-spin\" : (props.icon ?? \"ti ti-cloud-upload\")} />\n </span>\n <span class=\"k2b-dropzone__copy\">\n <strong>{title()}</strong>\n <Show\n when={zone.invalidDrag()}\n fallback={\n <Show when={props.subtitle}>\n <span class=\"k2b-dropzone__subtitle\">{props.subtitle}</span>\n </Show>\n }\n >\n <span class=\"k2b-dropzone__subtitle\">{messages().chooseMatchingFile}</span>\n </Show>\n <Show when={props.hint}>\n <span class=\"k2b-dropzone__hint\">{props.hint}</span>\n </Show>\n </span>\n </button>\n <input\n ref={input}\n class=\"k2b-sr-only\"\n type=\"file\"\n aria-label={\n props[\"aria-label\"] ??\n (typeof props.label === \"string\" ? props.label : props.multiple === false ? messages().chooseFile : messages().chooseFiles)\n }\n accept={props.accept}\n multiple={props.multiple ?? true}\n disabled={disabled()}\n tabIndex={-1}\n onChange={(event) => {\n const files = Array.from(event.currentTarget.files ?? []);\n // Reset before emitting so re-picking the same file still fires change,\n // even when onDrop throws.\n event.currentTarget.value = \"\";\n emit(files);\n }}\n />\n </Field>\n );\n}\n\nexport type ImageInputProps = ValueFieldProps<string | null> & {\n round?: boolean;\n variant?: \"default\" | \"small\";\n transform?: (file: File) => Promise<string>;\n accept?: string;\n fallbackMarker?: string;\n};\n\nconst DEFAULT_IMAGE_ACCEPT = \"image/jpeg,image/png,image/gif,image/webp,image/svg+xml,.jpg,.jpeg,.png,.gif,.webp,.svg\";\n\nconst defaultImageTransform = async (file: File): Promise<string> => {\n const { img } = await import(\"@k2b/stdlib/browser\");\n return img.presets.avatar(file);\n};\n\nexport function ImageInput(props: ImageInputProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n const [busy, setBusy] = createSignal(false);\n const [localError, setLocalError] = createSignal<string>();\n let input: HTMLInputElement | undefined;\n const disabled = () => Boolean(props.disabled || busy() || !props.onValueChange);\n const error = () => resolveMaybeAccessor(props.error) ?? localError();\n const value = () => {\n const current = resolveMaybeAccessor(props.value);\n return current && !current.includes(props.fallbackMarker ?? \"?fallback\") ? current : null;\n };\n const compact = () => props.variant === \"small\";\n const changeLabel = () => (value() ? messages().changeImage : messages().addImage);\n const changeIcon = () => (value() ? \"ti ti-pencil\" : \"ti ti-photo-plus\");\n const select = async (file: File | undefined) => {\n if (!file || disabled()) return;\n setBusy(true);\n setLocalError();\n try {\n const transformed = await (props.transform ?? defaultImageTransform)(file);\n commitFieldValue(props, transformed);\n } catch (error) {\n setLocalError(error instanceof Error ? error.message : messages().imageProcessingFailed);\n } finally {\n setBusy(false);\n if (input) input.value = \"\";\n }\n };\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n required={props.required}\n disabled={disabled()}\n >\n <div\n class=\"k2b-image-input\"\n data-round={props.round ? \"true\" : undefined}\n data-variant={props.variant ?? \"default\"}\n role=\"group\"\n aria-labelledby={props.label ? meta.labelId : undefined}\n aria-label={!props.label ? props[\"aria-label\"] : undefined}\n aria-describedby={fieldControlAria(meta, { ...props, error })[\"aria-describedby\"]}\n >\n <div class=\"k2b-image-input__preview\">\n <Show when={value()} fallback={<i class=\"ti ti-photo-off\" aria-hidden=\"true\" />}>\n {(source) => <img src={source()} alt={typeof props.label === \"string\" ? props.label : messages().selectedImage} />}\n </Show>\n </div>\n <div class=\"k2b-image-input__actions\">\n <Show\n when={compact()}\n fallback={\n <Button\n variant=\"secondary\"\n loading={busy()}\n loadingLabel={messages().processingImage}\n disabled={disabled()}\n onClick={() => input?.click()}\n >\n <i class={changeIcon()} aria-hidden=\"true\" />\n {value() ? messages().change : messages().add}\n </Button>\n }\n >\n <IconButton\n label={changeLabel()}\n loading={busy()}\n loadingLabel={messages().processingImage}\n disabled={disabled()}\n onClick={() => input?.click()}\n >\n <i class={changeIcon()} aria-hidden=\"true\" />\n </IconButton>\n </Show>\n <Show when={value()}>\n <Show\n when={compact()}\n fallback={\n <Button variant=\"ghost\" disabled={disabled()} onClick={() => commitFieldValue(props, null)}>\n <i class=\"ti ti-trash\" aria-hidden=\"true\" /> Remove\n </Button>\n }\n >\n <IconButton label={messages().removeImage} disabled={disabled()} onClick={() => commitFieldValue(props, null)}>\n <i class=\"ti ti-trash\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </Show>\n </div>\n <input\n ref={input}\n id={meta.controlId}\n class=\"k2b-sr-only\"\n type=\"file\"\n accept={props.accept ?? DEFAULT_IMAGE_ACCEPT}\n disabled={disabled()}\n required={props.required && !value()}\n {...fieldControlAria(meta, { ...props, error })}\n onChange={(event) => void select(event.currentTarget.files?.[0])}\n />\n </div>\n </Field>\n );\n}\n\ntype PreviewState = {\n url: string;\n objectUrl: boolean;\n sourceWidth: number;\n sourceHeight: number;\n};\n\ntype DragHandle = \"move\" | ImageCropResizeHandle;\ntype DragState = {\n handle: DragHandle;\n pointerId: number;\n startX: number;\n startY: number;\n startCrop: ImageCropRect;\n};\n\nexport type ImageCropperProps = {\n source: ImageCropSource;\n aspect?: ImageCropAspect;\n previewShape?: \"rect\" | \"circle\";\n disabled?: boolean;\n onValueChange?: (state: ImageCropState | null) => void;\n class?: string;\n};\n\nconst clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(max, value));\n\nconst imageElementReady = async (image: HTMLImageElement): Promise<void> => {\n if (image.complete && image.naturalWidth > 0) return;\n await new Promise<void>((resolve, reject) => {\n image.addEventListener(\"load\", () => resolve(), { once: true });\n image.addEventListener(\"error\", () => reject(new Error(\"Failed to load image.\")), { once: true });\n });\n};\n\nconst loadPreviewState = async (source: ImageCropSource): Promise<PreviewState> => {\n const sourceImage =\n source instanceof HTMLImageElement\n ? source\n : Object.assign(new Image(), {\n crossOrigin: source instanceof Blob ? undefined : \"anonymous\",\n src:\n source instanceof HTMLCanvasElement\n ? source.toDataURL(\"image/png\")\n : source instanceof Blob\n ? URL.createObjectURL(source)\n : source,\n });\n\n try {\n await imageElementReady(sourceImage);\n return {\n url: source instanceof HTMLImageElement ? source.currentSrc || source.src : sourceImage.src,\n objectUrl: source instanceof Blob,\n sourceWidth: sourceImage.naturalWidth || sourceImage.width,\n sourceHeight: sourceImage.naturalHeight || sourceImage.height,\n };\n } catch (error) {\n if (source instanceof Blob) URL.revokeObjectURL(sourceImage.src);\n throw error;\n }\n};\n\nexport function ImageCropper(props: ImageCropperProps): JSX.Element {\n const messages = useUiMessages();\n let frame: HTMLDivElement | undefined;\n let activePreview: PreviewState | null = null;\n const aspect = () => props.aspect ?? \"free\";\n const previewShape = () => props.previewShape ?? \"rect\";\n const disabled = () => props.disabled ?? false;\n const [preview, setPreview] = createSignal<PreviewState | null>(null);\n const [crop, setCrop] = createSignal<ImageCropRect | null>(null);\n const [rotation, setRotation] = createSignal<ImageCropRotation>(0);\n const [loading, setLoading] = createSignal(true);\n const [error, setError] = createSignal<string | null>(null);\n const [drag, setDrag] = createSignal<DragState | null>(null);\n\n const previewSize = (): { width: number; height: number } | null => {\n const currentPreview = preview();\n if (!currentPreview) return null;\n const swapsDimensions = rotation() === 90 || rotation() === 270;\n return {\n width: swapsDimensions ? currentPreview.sourceHeight : currentPreview.sourceWidth,\n height: swapsDimensions ? currentPreview.sourceWidth : currentPreview.sourceHeight,\n };\n };\n\n const replacePreview = (next: PreviewState | null) => {\n if (activePreview?.objectUrl) URL.revokeObjectURL(activePreview.url);\n activePreview = next;\n setPreview(next);\n };\n\n onCleanup(() => {\n if (activePreview?.objectUrl) URL.revokeObjectURL(activePreview.url);\n });\n\n createEffect(() => {\n props.source;\n setRotation(0);\n setCrop(null);\n });\n\n createEffect(() => {\n const source = props.source;\n let disposed = false;\n replacePreview(null);\n setLoading(true);\n setError(null);\n\n void (async () => {\n try {\n const nextPreview = await loadPreviewState(source);\n if (disposed) {\n if (nextPreview.objectUrl) URL.revokeObjectURL(nextPreview.url);\n return;\n }\n replacePreview(nextPreview);\n } catch {\n if (disposed) return;\n replacePreview(null);\n setCrop(null);\n setError(messages().failedLoadImage);\n } finally {\n if (!disposed) setLoading(false);\n }\n })();\n\n onCleanup(() => {\n disposed = true;\n });\n });\n\n createEffect(() => {\n const currentSize = previewSize();\n const currentAspect = aspect();\n if (!currentSize) return;\n setCrop((current) => clampImageCropRect(current ?? getInitialImageCropRect(currentSize, currentAspect), currentSize, currentAspect));\n });\n\n createEffect(() => {\n const currentCrop = crop();\n const currentPreview = preview();\n props.onValueChange?.(currentCrop && currentPreview ? { crop: currentCrop, rotation: rotation() } : null);\n });\n\n const readPointerPosition = (event: PointerEvent) => {\n if (!frame) return { x: 0, y: 0 };\n const rect = frame.getBoundingClientRect();\n return {\n x: (event.clientX - rect.left) / Math.max(1, rect.width),\n y: (event.clientY - rect.top) / Math.max(1, rect.height),\n };\n };\n\n const moveCrop = (event: PointerEvent) => {\n const state = drag();\n const currentSize = previewSize();\n if (!state || !currentSize || state.pointerId !== event.pointerId) return;\n event.preventDefault();\n const point = readPointerPosition(event);\n const dx = point.x - state.startX;\n const dy = point.y - state.startY;\n const start = state.startCrop;\n\n if (state.handle === \"move\") {\n setCrop(\n clampImageCropRect(\n {\n ...start,\n x: start.x + dx,\n y: start.y + dy,\n },\n currentSize,\n aspect(),\n ),\n );\n return;\n }\n\n setCrop(resizeImageCropFromCorner(start, currentSize, aspect(), state.handle, dx, dy));\n };\n\n const endDrag = (event: PointerEvent) => {\n const state = drag();\n if (!state || state.pointerId !== event.pointerId) return;\n window.removeEventListener(\"pointermove\", moveCrop);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n setDrag(null);\n };\n\n const startDrag = (handle: DragHandle, event: PointerEvent) => {\n const currentCrop = crop();\n if (!currentCrop || disabled()) return;\n event.preventDefault();\n event.stopPropagation();\n (event.currentTarget as Element).setPointerCapture?.(event.pointerId);\n const point = readPointerPosition(event);\n setDrag({\n handle,\n pointerId: event.pointerId,\n startX: point.x,\n startY: point.y,\n startCrop: currentCrop,\n });\n window.addEventListener(\"pointermove\", moveCrop);\n window.addEventListener(\"pointerup\", endDrag);\n window.addEventListener(\"pointercancel\", endDrag);\n };\n\n onCleanup(() => {\n if (typeof window === \"undefined\") return;\n window.removeEventListener(\"pointermove\", moveCrop);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n });\n\n const rotateRight = () => {\n if (disabled()) return;\n setRotation((current) => rotateImageCropRight(current));\n };\n\n const nudgeCrop = (handle: DragHandle, event: KeyboardEvent) => {\n if (disabled() || ![\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\"].includes(event.key)) return;\n const current = crop();\n const currentSize = previewSize();\n if (!current || !currentSize) return;\n event.preventDefault();\n const step = event.shiftKey ? 0.05 : 0.01;\n const dx = event.key === \"ArrowLeft\" ? -step : event.key === \"ArrowRight\" ? step : 0;\n const dy = event.key === \"ArrowUp\" ? -step : event.key === \"ArrowDown\" ? step : 0;\n setCrop(\n handle === \"move\"\n ? clampImageCropRect({ ...current, x: current.x + dx, y: current.y + dy }, currentSize, aspect())\n : resizeImageCropFromCorner(current, currentSize, aspect(), handle, dx, dy),\n );\n };\n\n const previewFrameStyle = (): JSX.CSSProperties => {\n const currentSize = previewSize();\n if (!currentSize) return {};\n return {\n \"aspect-ratio\": `${currentSize.width} / ${currentSize.height}`,\n \"max-width\": `min(100%, calc(min(58vh, 24rem) * ${currentSize.width} / ${currentSize.height}))`,\n };\n };\n\n const previewImageStyle = (): JSX.CSSProperties => {\n const currentPreview = preview();\n const currentSize = previewSize();\n if (!currentPreview || !currentSize) return {};\n const swapsDimensions = rotation() === 90 || rotation() === 270;\n return {\n left: \"50%\",\n top: \"50%\",\n width: swapsDimensions ? `${(currentPreview.sourceWidth / currentSize.width) * 100}%` : \"100%\",\n height: swapsDimensions ? `${(currentPreview.sourceHeight / currentSize.height) * 100}%` : \"100%\",\n \"max-width\": \"none\",\n \"object-fit\": \"fill\",\n transform: `translate(-50%, -50%) rotate(${rotation()}deg)`,\n };\n };\n\n const cropStyle = (): JSX.CSSProperties => {\n const currentCrop = crop();\n if (!currentCrop) return {};\n return {\n left: `${currentCrop.x * 100}%`,\n top: `${currentCrop.y * 100}%`,\n width: `${currentCrop.width * 100}%`,\n height: `${currentCrop.height * 100}%`,\n \"box-shadow\": \"0 0 0 9999px rgba(0,0,0,.42)\",\n };\n };\n\n const showResizeHandles = () => previewShape() !== \"circle\";\n\n return (\n <div class={`k2b-image-cropper ${props.class ?? \"\"}`}>\n <div class=\"k2b-image-cropper__stage\">\n <Show when={!loading()} fallback={<small>{messages().preparingImage}</small>}>\n <Show when={!error()} fallback={<small class=\"k2b-image-cropper__error\">{error()}</small>}>\n <Show when={preview() && crop()}>\n <div ref={frame} class=\"k2b-image-cropper__frame\" style={previewFrameStyle()}>\n <img src={preview()!.url} alt={messages().cropPreview} draggable={false} style={previewImageStyle()} />\n <div\n class=\"k2b-image-cropper__selection\"\n data-shape={previewShape()}\n style={cropStyle()}\n role=\"group\"\n tabIndex={disabled() ? undefined : 0}\n aria-label={messages().cropArea}\n onPointerDown={(event) => startDrag(\"move\", event)}\n onKeyDown={(event) => nudgeCrop(\"move\", event)}\n >\n <Show when={showResizeHandles()}>\n <For each={[\"nw\", \"ne\", \"sw\", \"se\"] as const}>\n {(handle) => (\n <button\n type=\"button\"\n class=\"k2b-image-cropper__handle\"\n data-handle={handle}\n aria-label={messages().resizeCrop({ handle })}\n disabled={disabled()}\n onPointerDown={(event) => startDrag(handle, event)}\n onKeyDown={(event) => nudgeCrop(handle, event)}\n />\n )}\n </For>\n </Show>\n </div>\n <Tooltip.Trigger\n type=\"button\"\n class=\"k2b-image-cropper__rotate\"\n content={messages().rotateRight}\n aria-label={messages().rotateRight}\n disabled={disabled() || !crop() || Boolean(error())}\n onClick={rotateRight}\n >\n <i class=\"ti ti-rotate-clockwise\" aria-hidden=\"true\" />\n </Tooltip.Trigger>\n </div>\n </Show>\n </Show>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/FileInputs.tsx"],"sourcesContent":["import { createEffect, createMemo, createSignal, For, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { Tooltip } from \"../feedback/Tooltip\";\nimport { createFieldMeta, Field, fieldControlAria } from \"../internal/field\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { fileDropTarget } from \"./FileDropTarget\";\nimport type { FieldProps, ValueFieldProps } from \"./field-contract\";\nimport { commitFieldValue, resolveMaybeAccessor } from \"./field-contract\";\nimport { fileDropEngine, liveDocument } from \"./file-drop\";\nimport {\n clampImageCropRect,\n getInitialImageCropRect,\n type ImageCropAspect,\n type ImageCropRect,\n type ImageCropResizeHandle,\n type ImageCropRotation,\n type ImageCropSource,\n type ImageCropState,\n resizeImageCropFromCorner,\n rotateImageCropRight,\n} from \"./image-crop\";\n\nexport type FileDropzoneProps = FieldProps & {\n accept?: string;\n multiple?: boolean;\n busy?: boolean;\n /** Full icon class list, for example `\"ti ti-photo-plus\"`. Defaults to `\"ti ti-cloud-upload\"`. */\n icon?: string;\n title?: JSX.Element;\n subtitle?: JSX.Element;\n hint?: JSX.Element;\n /** One sentence that says what dropping does, shown while files are over the zone. Defaults to \"Drop to upload\". */\n dropLabel?: string;\n onDrop: (files: File[]) => void | Promise<void>;\n};\n\nexport function FileDropzone(props: FileDropzoneProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n const disabled = () => Boolean(props.disabled || props.busy);\n const error = () => resolveMaybeAccessor(props.error);\n let input: HTMLInputElement | undefined;\n const [button, setButton] = createSignal<HTMLButtonElement>();\n const emit = (files: File[]) => {\n if (disabled() || files.length === 0) return;\n void props.onDrop(props.multiple === false ? files.slice(0, 1) : files);\n };\n // Drops take the same path as every other file drop target: files only, the most specific target wins, and files\n // that do not fit `accept` are left out with a message.\n const dropLabel = () => props.dropLabel ?? messages().dropToUpload;\n const dropRef = fileDropTarget({\n get label() {\n return dropLabel();\n },\n get accept() {\n return props.accept;\n },\n get multiple() {\n return props.multiple;\n },\n get disabled() {\n return disabled();\n },\n onDrop: emit,\n });\n const [engine, setEngine] = createSignal<ReturnType<typeof fileDropEngine>>();\n onMount(() => {\n const element = button();\n if (element) setEngine(fileDropEngine(liveDocument(element)));\n });\n const dragState = createMemo(() => {\n const element = button();\n const hover = engine()?.session()?.hover;\n if (!hover || hover.element !== element) return undefined;\n return hover.invalid ? \"invalid\" : \"over\";\n });\n const title = () =>\n props.busy\n ? messages().uploading\n : dragState() === \"invalid\"\n ? messages().fileTypeNotAccepted\n : dragState() === \"over\"\n ? dropLabel()\n : (props.title ?? messages().dropFiles);\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n required={props.required}\n disabled={disabled()}\n >\n <button\n id={meta.controlId}\n type=\"button\"\n ref={(element) => {\n setButton(element);\n dropRef(element);\n }}\n class=\"k2b-dropzone\"\n data-invalid={error() ? \"true\" : undefined}\n disabled={disabled()}\n {...fieldControlAria(meta, props)}\n onClick={() => input?.click()}\n >\n <span class=\"k2b-dropzone__icon\" aria-hidden=\"true\">\n <i class={props.busy ? \"ti ti-loader-2 k2b-spin\" : (props.icon ?? \"ti ti-cloud-upload\")} />\n </span>\n <span class=\"k2b-dropzone__copy\">\n <strong>{title()}</strong>\n <Show\n when={dragState() === \"invalid\"}\n fallback={\n <Show when={props.subtitle}>\n <span class=\"k2b-dropzone__subtitle\">{props.subtitle}</span>\n </Show>\n }\n >\n <span class=\"k2b-dropzone__subtitle\">{messages().chooseMatchingFile}</span>\n </Show>\n <Show when={props.hint}>\n <span class=\"k2b-dropzone__hint\">{props.hint}</span>\n </Show>\n </span>\n </button>\n <input\n ref={input}\n class=\"k2b-sr-only\"\n type=\"file\"\n aria-label={\n props[\"aria-label\"] ??\n (typeof props.label === \"string\" ? props.label : props.multiple === false ? messages().chooseFile : messages().chooseFiles)\n }\n accept={props.accept}\n multiple={props.multiple ?? true}\n disabled={disabled()}\n tabIndex={-1}\n onChange={(event) => {\n const files = Array.from(event.currentTarget.files ?? []);\n // Reset before emitting so re-picking the same file still fires change,\n // even when onDrop throws.\n event.currentTarget.value = \"\";\n emit(files);\n }}\n />\n </Field>\n );\n}\n\nexport type ImageInputProps = ValueFieldProps<string | null> & {\n round?: boolean;\n variant?: \"default\" | \"small\";\n transform?: (file: File) => Promise<string>;\n accept?: string;\n fallbackMarker?: string;\n};\n\nconst DEFAULT_IMAGE_ACCEPT = \"image/jpeg,image/png,image/gif,image/webp,image/svg+xml,.jpg,.jpeg,.png,.gif,.webp,.svg\";\n\nconst defaultImageTransform = async (file: File): Promise<string> => {\n const { img } = await import(\"@k2b/stdlib/browser\");\n return img.presets.avatar(file);\n};\n\nexport function ImageInput(props: ImageInputProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n const [busy, setBusy] = createSignal(false);\n const [localError, setLocalError] = createSignal<string>();\n let input: HTMLInputElement | undefined;\n const disabled = () => Boolean(props.disabled || busy() || !props.onValueChange);\n const error = () => resolveMaybeAccessor(props.error) ?? localError();\n const value = () => {\n const current = resolveMaybeAccessor(props.value);\n return current && !current.includes(props.fallbackMarker ?? \"?fallback\") ? current : null;\n };\n const compact = () => props.variant === \"small\";\n const changeLabel = () => (value() ? messages().changeImage : messages().addImage);\n const changeIcon = () => (value() ? \"ti ti-pencil\" : \"ti ti-photo-plus\");\n const select = async (file: File | undefined) => {\n if (!file || disabled()) return;\n setBusy(true);\n setLocalError();\n try {\n const transformed = await (props.transform ?? defaultImageTransform)(file);\n commitFieldValue(props, transformed);\n } catch (error) {\n setLocalError(error instanceof Error ? error.message : messages().imageProcessingFailed);\n } finally {\n setBusy(false);\n if (input) input.value = \"\";\n }\n };\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n required={props.required}\n disabled={disabled()}\n >\n <div\n class=\"k2b-image-input\"\n data-round={props.round ? \"true\" : undefined}\n data-variant={props.variant ?? \"default\"}\n role=\"group\"\n aria-labelledby={props.label ? meta.labelId : undefined}\n aria-label={!props.label ? props[\"aria-label\"] : undefined}\n aria-describedby={fieldControlAria(meta, { ...props, error })[\"aria-describedby\"]}\n >\n <div class=\"k2b-image-input__preview\">\n <Show when={value()} fallback={<i class=\"ti ti-photo-off\" aria-hidden=\"true\" />}>\n {(source) => <img src={source()} alt={typeof props.label === \"string\" ? props.label : messages().selectedImage} />}\n </Show>\n </div>\n <div class=\"k2b-image-input__actions\">\n <Show\n when={compact()}\n fallback={\n <Button\n variant=\"secondary\"\n loading={busy()}\n loadingLabel={messages().processingImage}\n disabled={disabled()}\n onClick={() => input?.click()}\n >\n <i class={changeIcon()} aria-hidden=\"true\" />\n {value() ? messages().change : messages().add}\n </Button>\n }\n >\n <IconButton\n label={changeLabel()}\n loading={busy()}\n loadingLabel={messages().processingImage}\n disabled={disabled()}\n onClick={() => input?.click()}\n >\n <i class={changeIcon()} aria-hidden=\"true\" />\n </IconButton>\n </Show>\n <Show when={value()}>\n <Show\n when={compact()}\n fallback={\n <Button variant=\"ghost\" disabled={disabled()} onClick={() => commitFieldValue(props, null)}>\n <i class=\"ti ti-trash\" aria-hidden=\"true\" /> Remove\n </Button>\n }\n >\n <IconButton label={messages().removeImage} disabled={disabled()} onClick={() => commitFieldValue(props, null)}>\n <i class=\"ti ti-trash\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </Show>\n </div>\n <input\n ref={input}\n id={meta.controlId}\n class=\"k2b-sr-only\"\n type=\"file\"\n accept={props.accept ?? DEFAULT_IMAGE_ACCEPT}\n disabled={disabled()}\n required={props.required && !value()}\n {...fieldControlAria(meta, { ...props, error })}\n onChange={(event) => void select(event.currentTarget.files?.[0])}\n />\n </div>\n </Field>\n );\n}\n\ntype PreviewState = {\n url: string;\n objectUrl: boolean;\n sourceWidth: number;\n sourceHeight: number;\n};\n\ntype DragHandle = \"move\" | ImageCropResizeHandle;\ntype DragState = {\n handle: DragHandle;\n pointerId: number;\n startX: number;\n startY: number;\n startCrop: ImageCropRect;\n};\n\nexport type ImageCropperProps = {\n source: ImageCropSource;\n aspect?: ImageCropAspect;\n previewShape?: \"rect\" | \"circle\";\n disabled?: boolean;\n onValueChange?: (state: ImageCropState | null) => void;\n class?: string;\n};\n\nconst clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(max, value));\n\nconst imageElementReady = async (image: HTMLImageElement): Promise<void> => {\n if (image.complete && image.naturalWidth > 0) return;\n await new Promise<void>((resolve, reject) => {\n image.addEventListener(\"load\", () => resolve(), { once: true });\n image.addEventListener(\"error\", () => reject(new Error(\"Failed to load image.\")), { once: true });\n });\n};\n\nconst loadPreviewState = async (source: ImageCropSource): Promise<PreviewState> => {\n const sourceImage =\n source instanceof HTMLImageElement\n ? source\n : Object.assign(new Image(), {\n crossOrigin: source instanceof Blob ? undefined : \"anonymous\",\n src:\n source instanceof HTMLCanvasElement\n ? source.toDataURL(\"image/png\")\n : source instanceof Blob\n ? URL.createObjectURL(source)\n : source,\n });\n\n try {\n await imageElementReady(sourceImage);\n return {\n url: source instanceof HTMLImageElement ? source.currentSrc || source.src : sourceImage.src,\n objectUrl: source instanceof Blob,\n sourceWidth: sourceImage.naturalWidth || sourceImage.width,\n sourceHeight: sourceImage.naturalHeight || sourceImage.height,\n };\n } catch (error) {\n if (source instanceof Blob) URL.revokeObjectURL(sourceImage.src);\n throw error;\n }\n};\n\nexport function ImageCropper(props: ImageCropperProps): JSX.Element {\n const messages = useUiMessages();\n let frame: HTMLDivElement | undefined;\n let activePreview: PreviewState | null = null;\n const aspect = () => props.aspect ?? \"free\";\n const previewShape = () => props.previewShape ?? \"rect\";\n const disabled = () => props.disabled ?? false;\n const [preview, setPreview] = createSignal<PreviewState | null>(null);\n const [crop, setCrop] = createSignal<ImageCropRect | null>(null);\n const [rotation, setRotation] = createSignal<ImageCropRotation>(0);\n const [loading, setLoading] = createSignal(true);\n const [error, setError] = createSignal<string | null>(null);\n const [drag, setDrag] = createSignal<DragState | null>(null);\n\n const previewSize = (): { width: number; height: number } | null => {\n const currentPreview = preview();\n if (!currentPreview) return null;\n const swapsDimensions = rotation() === 90 || rotation() === 270;\n return {\n width: swapsDimensions ? currentPreview.sourceHeight : currentPreview.sourceWidth,\n height: swapsDimensions ? currentPreview.sourceWidth : currentPreview.sourceHeight,\n };\n };\n\n const replacePreview = (next: PreviewState | null) => {\n if (activePreview?.objectUrl) URL.revokeObjectURL(activePreview.url);\n activePreview = next;\n setPreview(next);\n };\n\n onCleanup(() => {\n if (activePreview?.objectUrl) URL.revokeObjectURL(activePreview.url);\n });\n\n createEffect(() => {\n props.source;\n setRotation(0);\n setCrop(null);\n });\n\n createEffect(() => {\n const source = props.source;\n let disposed = false;\n replacePreview(null);\n setLoading(true);\n setError(null);\n\n void (async () => {\n try {\n const nextPreview = await loadPreviewState(source);\n if (disposed) {\n if (nextPreview.objectUrl) URL.revokeObjectURL(nextPreview.url);\n return;\n }\n replacePreview(nextPreview);\n } catch {\n if (disposed) return;\n replacePreview(null);\n setCrop(null);\n setError(messages().failedLoadImage);\n } finally {\n if (!disposed) setLoading(false);\n }\n })();\n\n onCleanup(() => {\n disposed = true;\n });\n });\n\n createEffect(() => {\n const currentSize = previewSize();\n const currentAspect = aspect();\n if (!currentSize) return;\n setCrop((current) => clampImageCropRect(current ?? getInitialImageCropRect(currentSize, currentAspect), currentSize, currentAspect));\n });\n\n createEffect(() => {\n const currentCrop = crop();\n const currentPreview = preview();\n props.onValueChange?.(currentCrop && currentPreview ? { crop: currentCrop, rotation: rotation() } : null);\n });\n\n const readPointerPosition = (event: PointerEvent) => {\n if (!frame) return { x: 0, y: 0 };\n const rect = frame.getBoundingClientRect();\n return {\n x: (event.clientX - rect.left) / Math.max(1, rect.width),\n y: (event.clientY - rect.top) / Math.max(1, rect.height),\n };\n };\n\n const moveCrop = (event: PointerEvent) => {\n const state = drag();\n const currentSize = previewSize();\n if (!state || !currentSize || state.pointerId !== event.pointerId) return;\n event.preventDefault();\n const point = readPointerPosition(event);\n const dx = point.x - state.startX;\n const dy = point.y - state.startY;\n const start = state.startCrop;\n\n if (state.handle === \"move\") {\n setCrop(\n clampImageCropRect(\n {\n ...start,\n x: start.x + dx,\n y: start.y + dy,\n },\n currentSize,\n aspect(),\n ),\n );\n return;\n }\n\n setCrop(resizeImageCropFromCorner(start, currentSize, aspect(), state.handle, dx, dy));\n };\n\n const endDrag = (event: PointerEvent) => {\n const state = drag();\n if (!state || state.pointerId !== event.pointerId) return;\n window.removeEventListener(\"pointermove\", moveCrop);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n setDrag(null);\n };\n\n const startDrag = (handle: DragHandle, event: PointerEvent) => {\n const currentCrop = crop();\n if (!currentCrop || disabled()) return;\n event.preventDefault();\n event.stopPropagation();\n (event.currentTarget as Element).setPointerCapture?.(event.pointerId);\n const point = readPointerPosition(event);\n setDrag({\n handle,\n pointerId: event.pointerId,\n startX: point.x,\n startY: point.y,\n startCrop: currentCrop,\n });\n window.addEventListener(\"pointermove\", moveCrop);\n window.addEventListener(\"pointerup\", endDrag);\n window.addEventListener(\"pointercancel\", endDrag);\n };\n\n onCleanup(() => {\n if (typeof window === \"undefined\") return;\n window.removeEventListener(\"pointermove\", moveCrop);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n });\n\n const rotateRight = () => {\n if (disabled()) return;\n setRotation((current) => rotateImageCropRight(current));\n };\n\n const nudgeCrop = (handle: DragHandle, event: KeyboardEvent) => {\n if (disabled() || ![\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\"].includes(event.key)) return;\n const current = crop();\n const currentSize = previewSize();\n if (!current || !currentSize) return;\n event.preventDefault();\n const step = event.shiftKey ? 0.05 : 0.01;\n const dx = event.key === \"ArrowLeft\" ? -step : event.key === \"ArrowRight\" ? step : 0;\n const dy = event.key === \"ArrowUp\" ? -step : event.key === \"ArrowDown\" ? step : 0;\n setCrop(\n handle === \"move\"\n ? clampImageCropRect({ ...current, x: current.x + dx, y: current.y + dy }, currentSize, aspect())\n : resizeImageCropFromCorner(current, currentSize, aspect(), handle, dx, dy),\n );\n };\n\n const previewFrameStyle = (): JSX.CSSProperties => {\n const currentSize = previewSize();\n if (!currentSize) return {};\n return {\n \"aspect-ratio\": `${currentSize.width} / ${currentSize.height}`,\n \"max-width\": `min(100%, calc(min(58vh, 24rem) * ${currentSize.width} / ${currentSize.height}))`,\n };\n };\n\n const previewImageStyle = (): JSX.CSSProperties => {\n const currentPreview = preview();\n const currentSize = previewSize();\n if (!currentPreview || !currentSize) return {};\n const swapsDimensions = rotation() === 90 || rotation() === 270;\n return {\n left: \"50%\",\n top: \"50%\",\n width: swapsDimensions ? `${(currentPreview.sourceWidth / currentSize.width) * 100}%` : \"100%\",\n height: swapsDimensions ? `${(currentPreview.sourceHeight / currentSize.height) * 100}%` : \"100%\",\n \"max-width\": \"none\",\n \"object-fit\": \"fill\",\n transform: `translate(-50%, -50%) rotate(${rotation()}deg)`,\n };\n };\n\n const cropStyle = (): JSX.CSSProperties => {\n const currentCrop = crop();\n if (!currentCrop) return {};\n return {\n left: `${currentCrop.x * 100}%`,\n top: `${currentCrop.y * 100}%`,\n width: `${currentCrop.width * 100}%`,\n height: `${currentCrop.height * 100}%`,\n \"box-shadow\": \"0 0 0 9999px rgba(0,0,0,.42)\",\n };\n };\n\n const showResizeHandles = () => previewShape() !== \"circle\";\n\n return (\n <div class={`k2b-image-cropper ${props.class ?? \"\"}`}>\n <div class=\"k2b-image-cropper__stage\">\n <Show when={!loading()} fallback={<small>{messages().preparingImage}</small>}>\n <Show when={!error()} fallback={<small class=\"k2b-image-cropper__error\">{error()}</small>}>\n <Show when={preview() && crop()}>\n <div ref={frame} class=\"k2b-image-cropper__frame\" style={previewFrameStyle()}>\n <img src={preview()!.url} alt={messages().cropPreview} draggable={false} style={previewImageStyle()} />\n <div\n class=\"k2b-image-cropper__selection\"\n data-shape={previewShape()}\n style={cropStyle()}\n role=\"group\"\n tabIndex={disabled() ? undefined : 0}\n aria-label={messages().cropArea}\n onPointerDown={(event) => startDrag(\"move\", event)}\n onKeyDown={(event) => nudgeCrop(\"move\", event)}\n >\n <Show when={showResizeHandles()}>\n <For each={[\"nw\", \"ne\", \"sw\", \"se\"] as const}>\n {(handle) => (\n <button\n type=\"button\"\n class=\"k2b-image-cropper__handle\"\n data-handle={handle}\n aria-label={messages().resizeCrop({ handle })}\n disabled={disabled()}\n onPointerDown={(event) => startDrag(handle, event)}\n onKeyDown={(event) => nudgeCrop(handle, event)}\n />\n )}\n </For>\n </Show>\n </div>\n <Tooltip.Trigger\n type=\"button\"\n class=\"k2b-image-cropper__rotate\"\n content={messages().rotateRight}\n aria-label={messages().rotateRight}\n disabled={disabled() || !crop() || Boolean(error())}\n onClick={rotateRight}\n >\n <i class=\"ti ti-rotate-clockwise\" aria-hidden=\"true\" />\n </Tooltip.Trigger>\n </div>\n </Show>\n </Show>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,EAAY,SAAS,EAAE,OAAO,EAAE,IAAI,QAAQ,UAAU;AAC1G,SAAS,MAAM,EAAE,UAAU,QAAQ,mBAAmB;AACtD,SAAS,OAAO,QAAQ,qBAAqB;AAC7C,SAAS,eAAe,EAAE,KAAK,EAAE,gBAAgB,QAAQ,mBAAmB;AAC5E,SAAS,aAAa,QAAQ,kBAAkB;AAChD,SAAS,cAAc,QAAQ,kBAAkB;AAEjD,SAAS,gBAAgB,EAAE,oBAAoB,QAAQ,kBAAkB;AACzE,SAAS,cAAc,EAAE,YAAY,QAAQ,aAAa;AAC1D,SACE,kBAAkB,EAClB,uBAAuB,EAOvB,yBAAyB,EACzB,oBAAoB,QACf,cAAc;AAgBrB,OAAO,SAAS,YAAY,CAAC,KAAwB,EAAe;EAClE,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;EACtC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC;EAC5D,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC;EACrD,IAAI,KAAmC;EACvC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,YAAY,CAAoB,CAAC;EAC7D,MAAM,IAAI,GAAI,KAAa,IAAK;IAC9B,IAAI,QAAQ,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;IACtC,KAAK,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,KAAK,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;EACzE,CAAC;EACD;EACA;EACA,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC,YAAY;EAClE,MAAM,OAAO,GAAG,cAAc,CAAC;IAC7B,IAAI,KAAK,GAAG;MACV,OAAO,SAAS,CAAC,CAAC;IACpB,CAAC;IACD,IAAI,MAAM,GAAG;MACX,OAAO,KAAK,CAAC,MAAM;IACrB,CAAC;IACD,IAAI,QAAQ,GAAG;MACb,OAAO,KAAK,CAAC,QAAQ;IACvB,CAAC;IACD,IAAI,QAAQ,GAAG;MACb,OAAO,QAAQ,CAAC,CAAC;IACnB,CAAC;IACD,MAAM,EAAE;EACV,CAAC,CAAC;EACF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,YAAY,CAAoC,CAAC;EAC7E,OAAO,CAAC,MAAM;IACZ,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC;IACxB,IAAI,OAAO,EAAE,SAAS,CAAC,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;EAC/D,CAAC,CAAC;EACF,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM;IACjC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC;IACxB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK;IACxC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,OAAO,SAAS;IACzD,OAAO,KAAK,CAAC,OAAO,GAAG,SAAS,GAAG,MAAM;EAC3C,CAAC,CAAC;EACF,MAAM,KAAK,GAAG,MACZ,KAAK,CAAC,IAAI,GACN,QAAQ,CAAC,CAAC,CAAC,SAAS,GACpB,SAAS,CAAC,CAAC,KAAK,SAAS,GACvB,QAAQ,CAAC,CAAC,CAAC,mBAAmB,GAC9B,SAAS,CAAC,CAAC,KAAK,MAAM,GACpB,SAAS,CAAC,CAAC,GACV,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,SAAU;EAE/C,yBACG,KAAK;IAAA;MAAA,OACG,KAAK,CAAC,KAAK;IAAA;IAAA,IAClB,KAAK;MAAA,OAAE,KAAK,CAAC,KAAK;IAAA;IAAA,IAClB,WAAW;MAAA,OAAE,KAAK,CAAC,WAAW;IAAA;IAAA,IAC9B,KAAK;MAAA,OAAE,KAAK,CAAC,CAAC;IAAA;IACd,IAAI,EAAE,IAAI;IAAA,IACV,QAAQ;MAAA,OAAE,KAAK,CAAC,QAAQ;IAAA;IAAA,IACxB,QAAQ;MAAA,OAAE,QAAQ,CAAC,CAAC;IAAA;IAAA;MAAA;QAAA;UAAA;UAAA;UAAA;UAAA;UAAA;UAAA;UAAA;UAAA;QAAA,MAKZ,OAAO,IAAK;UAChB,SAAS,CAAC,OAAO,CAAC;UAClB,OAAO,CAAC,OAAO,CAAC;QAClB,CAAC;QAAA;UAAA,IALD,EAAE;YAAA,OAAE,IAAI,CAAC,SAAS;UAAA;UAAA;YAAA,OAOJ,KAAK,CAAC,CAAC,GAAG,MAAM,GAAG,SAAS;UAAA;UAAA,IAC1C,QAAQ;YAAA,OAAE,QAAQ,CAAC,CAAC;UAAA;QAAA,SAChB,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC;UAAA,WACxB,MAAM,KAAK,EAAE,KAAK,CAAC;QAAC;QAAA,gBAMlB,KAAK;QAAA,kCACb,IAAI;UAAA,IACH,IAAI;YAAA,OAAE,SAAS,CAAC,CAAC,KAAK,SAAS;UAAA;UAAA,IAC/B,QAAQ;YAAA,yBACL,IAAI;cAAA,IAAC,IAAI;gBAAA,OAAE,KAAK,CAAC,QAAQ;cAAA;cAAA;gBAAA;gBAAA,uBACc,KAAK,CAAC,QAAQ;gBAAA;cAAA;YAAA;UAAA;UAAA;YAAA;YAAA,sBAIlB,QAAQ,CAAC,CAAC,CAAC,kBAAkB;YAAA;UAAA;QAAA;QAAA,kCAEpE,IAAI;UAAA,IAAC,IAAI;YAAA,OAAE,KAAK,CAAC,IAAI;UAAA;UAAA;YAAA;YAAA,sBACc,KAAK,CAAC,IAAI;YAAA;UAAA;QAAA;QAAA,kCAfpC,KAAK,CAAC,IAAI,GAAG,yBAAyB,GAAI,KAAK,CAAC,IAAI,IAAI,oBAAqB;QAAA;QAAA;MAAA;QAAA;QAAA,kCA+B9E,KAAK,IAAK;UACnB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,IAAI,EAAE,CAAC;UACzD;UACA;UACA,KAAK,CAAC,aAAa,CAAC,KAAK,GAAG,EAAE;UAC9B,IAAI,CAAC,KAAK,CAAC;QACb,CAAC;QAAA,YAjBI,KAAK;QAAA,qDAAL,KAAK;QAAA;UAAA,UAIR,KAAK,CAAC,YAAY,CAAC,KAClB,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC;YAAA,OAErH,KAAK,CAAC,MAAM;YAAA,OACV,KAAK,CAAC,QAAQ,IAAI,IAAI;YAAA,OACtB,QAAQ,CAAC,CAAC;UAAA;UAAA;UAAA;UAAA;UAAA;QAAA;UAAA;UAAA;UAAA;UAAA;QAAA;QAAA;MAAA;IAAA;EAAA;AAY5B;AAUA,MAAM,oBAAoB,GAAG,yFAAyF;AAEtH,MAAM,qBAAqB,GAAG,MAAO,IAAU,IAAsB;EACnE,MAAM;IAAE;EAAI,CAAC,GAAG,MAAM,OAAO,qBAAqB,CAAC;EACnD,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,OAAO,SAAS,UAAU,CAAC,KAAsB,EAAe;EAC9D,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;EACtC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EAC3C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,YAAY,CAAS,CAAC;EAC1D,IAAI,KAAmC;EACvC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;EAChF,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC;EACrE,MAAM,KAAK,GAAG,MAAM;IAClB,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC;IACjD,OAAO,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,IAAI,WAAW,CAAC,GAAG,OAAO,GAAG,IAAI;EAC3F,CAAC;EACD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,KAAK,OAAO;EAC/C,MAAM,WAAW,GAAG,MAAO,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAS;EAClF,MAAM,UAAU,GAAG,MAAO,KAAK,CAAC,CAAC,GAAG,cAAc,GAAG,kBAAmB;EACxE,MAAM,MAAM,GAAG,MAAO,IAAsB,IAAK;IAC/C,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,EAAE;IACzB,OAAO,CAAC,IAAI,CAAC;IACb,aAAa,CAAC,CAAC;IACf,IAAI;MACF,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,qBAAqB,EAAE,IAAI,CAAC;MAC1E,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC;IACtC,CAAC,CAAC,OAAO,KAAK,EAAE;MACd,aAAa,CAAC,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAC1F,CAAC,SAAS;MACR,OAAO,CAAC,KAAK,CAAC;MACd,IAAI,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,EAAE;IAC7B;EACF,CAAC;EAED,yBACG,KAAK;IAAA;MAAA,OACG,KAAK,CAAC,KAAK;IAAA;IAAA,IAClB,KAAK;MAAA,OAAE,KAAK,CAAC,KAAK;IAAA;IAAA,IAClB,WAAW;MAAA,OAAE,KAAK,CAAC,WAAW;IAAA;IAAA,IAC9B,KAAK;MAAA,OAAE,KAAK,CAAC,CAAC;IAAA;IACd,IAAI,EAAE,IAAI;IAAA,IACV,QAAQ;MAAA,OAAE,KAAK,CAAC,QAAQ;IAAA;IAAA,IACxB,QAAQ;MAAA,OAAE,QAAQ,CAAC,CAAC;IAAA;IAAA;MAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;MAAA,mCAYf,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,CAAC;QAAA;QAAA,IAAE,QAAQ;UAAA;QAAA;QAAA,UACzB,MAAM;UAAA;UAAA;YAAA,WAAe,MAAM,CAAC,CAAC;cAAA,OAAO,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa;YAAA;YAAA;YAAA;UAAA;YAAA;YAAA;UAAA;UAAA;QAAA;MAAI;MAAA,mCAInH,IAAI;QAAA,IACH,IAAI;UAAA,OAAE,OAAO,CAAC,CAAC;QAAA;QAAA,IACf,QAAQ;UAAA,yBACL,MAAM;YACL,OAAO;YAAA,IACP,OAAO;cAAA,OAAE,IAAI,CAAC,CAAC;YAAA;YAAA,IACf,YAAY;cAAA,OAAE,QAAQ,CAAC,CAAC,CAAC,eAAe;YAAA;YAAA,IACxC,QAAQ;cAAA,OAAE,QAAQ,CAAC,CAAC;YAAA;YACpB,OAAO,EAAE,MAAM,KAAK,EAAE,KAAK,CAAC,CAAC;YAAA;cAAA;gBAAA;gBAAA,mCAEnB,UAAU,CAAC,CAAC;gBAAA;cAAA,mBACrB,oBAAK,CAAC,CAAC,MAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG;YAAA;UAAA;QAAA;QAAA;UAAA,yBAIhD,UAAU;YAAA,IACT,KAAK;cAAA,OAAE,WAAW,CAAC,CAAC;YAAA;YAAA,IACpB,OAAO;cAAA,OAAE,IAAI,CAAC,CAAC;YAAA;YAAA,IACf,YAAY;cAAA,OAAE,QAAQ,CAAC,CAAC,CAAC,eAAe;YAAA;YAAA,IACxC,QAAQ;cAAA,OAAE,QAAQ,CAAC,CAAC;YAAA;YACpB,OAAO,EAAE,MAAM,KAAK,EAAE,KAAK,CAAC,CAAC;YAAA;cAAA;cAAA,mCAEnB,UAAU,CAAC,CAAC;cAAA;YAAA;UAAA;QAAA;MAAA;MAAA,mCAGzB,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,CAAC;QAAA;QAAA;UAAA,yBAChB,IAAI;YAAA,IACH,IAAI;cAAA,OAAE,OAAO,CAAC,CAAC;YAAA;YAAA,IACf,QAAQ;cAAA,yBACL,MAAM;gBAAC,OAAO;gBAAA,IAAS,QAAQ;kBAAA,OAAE,QAAQ,CAAC,CAAC;gBAAA;gBAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC;gBAAA;kBAAA;gBAAA;cAAA;YAAA;YAAA;cAAA,yBAK3F,UAAU;gBAAA,IAAC,KAAK;kBAAA,OAAE,QAAQ,CAAC,CAAC,CAAC,WAAW;gBAAA;gBAAA,IAAE,QAAQ;kBAAA,OAAE,QAAQ,CAAC,CAAC;gBAAA;gBAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC;gBAAA;kBAAA;gBAAA;cAAA;YAAA;UAAA;QAAA;MAAA;MAAA,aAO5G,KAAK;MAAA,uDAAL,KAAK;MAAA;QAAA,IACV,EAAE;UAAA,OAAE,IAAI,CAAC,SAAS;QAAA;QAAA,IAGlB,MAAM;UAAA,OAAE,KAAK,CAAC,MAAM,IAAI,oBAAoB;QAAA;QAAA,IAC5C,QAAQ;UAAA,OAAE,QAAQ,CAAC,CAAC;QAAA;QAAA,IACpB,QAAQ;UAAA,OAAE,oBAAK,CAAC,QAAQ,OAAI,CAAC,KAAK,CAAC,CAAC;QAAA;MAAA,SAChC,gBAAgB,CAAC,IAAI,EAAE;QAAE,GAAG,KAAK;QAAE;MAAM,CAAC,CAAC;QAAA,YACpC,KAAK,IAAK,KAAK,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,GAAG,CAAC,CAAC;MAAC;MAAA;QAAA,WA9DtD,KAAK,CAAC,KAAK,GAAG,MAAM,GAAG,SAAS;UAAA,OAC9B,KAAK,CAAC,OAAO,IAAI,SAAS;UAAA,OAEvB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,GAAG,SAAS;UAAA,OAC3C,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,GAAG,SAAS;UAAA,OACxC,gBAAgB,CAAC,IAAI,EAAE;YAAE,GAAG,KAAK;YAAE;UAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC;QAAA;QAAA;QAAA;QAAA;QAAA;QAAA;MAAA;QAAA;QAAA;QAAA;QAAA;QAAA;MAAA;MAAA;MAAA;IAAA;EAAA;AA8DzF;AA2BA,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAE9F,MAAM,iBAAiB,GAAG,MAAO,KAAuB,IAAoB;EAC1E,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,EAAE;EAC9C,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAK;IAC3C,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,EAAE;MAAE,IAAI,EAAE;IAAK,CAAC,CAAC;IAC/D,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,EAAE;MAAE,IAAI,EAAE;IAAK,CAAC,CAAC;EACnG,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,gBAAgB,GAAG,MAAO,MAAuB,IAA4B;EACjF,MAAM,WAAW,GACf,MAAM,YAAY,gBAAgB,GAC9B,MAAM,GACN,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE;IACzB,WAAW,EAAE,MAAM,YAAY,IAAI,GAAG,SAAS,GAAG,WAAW;IAC7D,GAAG,EACD,MAAM,YAAY,iBAAiB,GAC/B,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,GAC7B,MAAM,YAAY,IAAI,GACpB,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,GAC3B;EACV,CAAC,CAAC;EAER,IAAI;IACF,MAAM,iBAAiB,CAAC,WAAW,CAAC;IACpC,OAAO;MACL,GAAG,EAAE,MAAM,YAAY,gBAAgB,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,GAAG,GAAG,WAAW,CAAC,GAAG;MAC3F,SAAS,EAAE,MAAM,YAAY,IAAI;MACjC,WAAW,EAAE,WAAW,CAAC,YAAY,IAAI,WAAW,CAAC,KAAK;MAC1D,YAAY,EAAE,WAAW,CAAC,aAAa,IAAI,WAAW,CAAC;IACzD,CAAC;EACH,CAAC,CAAC,OAAO,KAAK,EAAE;IACd,IAAI,MAAM,YAAY,IAAI,EAAE,GAAG,CAAC,eAAe,CAAC,WAAW,CAAC,GAAG,CAAC;IAChE,MAAM,KAAK;EACb;AACF,CAAC;AAED,OAAO,SAAS,YAAY,CAAC,KAAwB,EAAe;EAClE,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,IAAI,KAAiC;EACrC,IAAI,aAAkC,GAAG,IAAI;EAC7C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,IAAI,MAAM;EAC3C,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,YAAY,IAAI,MAAM;EACvD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,IAAI,KAAK;EAC9C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,YAAY,CAAsB,IAAI,CAAC;EACrE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,YAAY,CAAuB,IAAI,CAAC;EAChE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,YAAY,CAAoB,CAAC,CAAC;EAClE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC;EAChD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAgB,IAAI,CAAC;EAC3D,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,YAAY,CAAmB,IAAI,CAAC;EAE5D,MAAM,WAAW,GAAG,MAAgD;IAClE,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,cAAc,EAAE,OAAO,IAAI;IAChC,MAAM,eAAe,GAAG,QAAQ,CAAC,CAAC,KAAK,EAAE,IAAI,QAAQ,CAAC,CAAC,KAAK,GAAG;IAC/D,OAAO;MACL,KAAK,EAAE,eAAe,GAAG,cAAc,CAAC,YAAY,GAAG,cAAc,CAAC,WAAW;MACjF,MAAM,EAAE,eAAe,GAAG,cAAc,CAAC,WAAW,GAAG,cAAc,CAAC;IACxE,CAAC;EACH,CAAC;EAED,MAAM,cAAc,GAAI,IAAyB,IAAK;IACpD,IAAI,aAAa,EAAE,SAAS,EAAE,GAAG,CAAC,eAAe,CAAC,aAAa,CAAC,GAAG,CAAC;IACpE,aAAa,GAAG,IAAI;IACpB,UAAU,CAAC,IAAI,CAAC;EAClB,CAAC;EAED,SAAS,CAAC,MAAM;IACd,IAAI,aAAa,EAAE,SAAS,EAAE,GAAG,CAAC,eAAe,CAAC,aAAa,CAAC,GAAG,CAAC;EACtE,CAAC,CAAC;EAEF,YAAY,CAAC,MAAM;IACjB,KAAK,CAAC,MAAM;IACZ,WAAW,CAAC,CAAC,CAAC;IACd,OAAO,CAAC,IAAI,CAAC;EACf,CAAC,CAAC;EAEF,YAAY,CAAC,MAAM;IACjB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM;IAC3B,IAAI,QAAQ,GAAG,KAAK;IACpB,cAAc,CAAC,IAAI,CAAC;IACpB,UAAU,CAAC,IAAI,CAAC;IAChB,QAAQ,CAAC,IAAI,CAAC;IAEd,KAAK,CAAC,YAAY;MAChB,IAAI;QACF,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC;QAClD,IAAI,QAAQ,EAAE;UACZ,IAAI,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,eAAe,CAAC,WAAW,CAAC,GAAG,CAAC;UAC/D;QACF;QACA,cAAc,CAAC,WAAW,CAAC;MAC7B,CAAC,CAAC,MAAM;QACN,IAAI,QAAQ,EAAE;QACd,cAAc,CAAC,IAAI,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC;QACb,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC;MACtC,CAAC,SAAS;QACR,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC;MAClC;IACF,CAAC,EAAE,CAAC;IAEJ,SAAS,CAAC,MAAM;MACd,QAAQ,GAAG,IAAI;IACjB,CAAC,CAAC;EACJ,CAAC,CAAC;EAEF,YAAY,CAAC,MAAM;IACjB,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC;IACjC,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC;IAC9B,IAAI,CAAC,WAAW,EAAE;IAClB,OAAO,CAAE,OAAO,IAAK,kBAAkB,CAAC,OAAO,IAAI,uBAAuB,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;EACtI,CAAC,CAAC;EAEF,YAAY,CAAC,MAAM;IACjB,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC;IAC1B,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC;IAChC,KAAK,CAAC,aAAa,GAAG,WAAW,IAAI,cAAc,GAAG;MAAE,IAAI,EAAE,WAAW;MAAE,QAAQ,EAAE,QAAQ,CAAC;IAAE,CAAC,GAAG,IAAI,CAAC;EAC3G,CAAC,CAAC;EAEF,MAAM,mBAAmB,GAAI,KAAmB,IAAK;IACnD,IAAI,CAAC,KAAK,EAAE,OAAO;MAAE,CAAC,EAAE,CAAC;MAAE,CAAC,EAAE;IAAE,CAAC;IACjC,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC1C,OAAO;MACL,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;MACxD,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM;IACzD,CAAC;EACH,CAAC;EAED,MAAM,QAAQ,GAAI,KAAmB,IAAK;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC;IACpB,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,EAAE;IACnE,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC;IACxC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM;IACjC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS;IAE7B,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE;MAC3B,OAAO,CACL,kBAAkB,CAChB;QACE,GAAG,KAAK;QACR,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE;QACf,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG;MACf,CAAC,EACD,WAAW,EACX,MAAM,CAAC,CACT,CACF,CAAC;MACD;IACF;IAEA,OAAO,CAAC,yBAAyB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;EACxF,CAAC;EAED,MAAM,OAAO,GAAI,KAAmB,IAAK;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC;IACpB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,EAAE;IACnD,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,QAAQ,CAAC;IACnD,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC;IAChD,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,OAAO,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC;EACf,CAAC;EAED,MAAM,SAAS,GAAG,CAAC,MAAkB,EAAE,KAAmB,KAAK;IAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC,CAAC,EAAE;IAChC,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,KAAK,CAAC,eAAe,CAAC,CAAC;IACtB,KAAK,CAAC,aAAa,CAAa,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAC;IACrE,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC;IACxC,OAAO,CAAC;MACN,MAAM;MACN,SAAS,EAAE,KAAK,CAAC,SAAS;MAC1B,MAAM,EAAE,KAAK,CAAC,CAAC;MACf,MAAM,EAAE,KAAK,CAAC,CAAC;MACf,SAAS,EAAE;IACb,CAAC,CAAC;IACF,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,QAAQ,CAAC;IAChD,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC;IAC7C,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,OAAO,CAAC;EACnD,CAAC;EAED,SAAS,CAAC,MAAM;IACd,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IACnC,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,QAAQ,CAAC;IACnD,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC;IAChD,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,OAAO,CAAC;EACtD,CAAC,CAAC;EAEF,MAAM,WAAW,GAAG,MAAM;IACxB,IAAI,QAAQ,CAAC,CAAC,EAAE;IAChB,WAAW,CAAE,OAAO,IAAK,oBAAoB,CAAC,OAAO,CAAC,CAAC;EACzD,CAAC;EAED,MAAM,SAAS,GAAG,CAAC,MAAkB,EAAE,KAAoB,KAAK;IAC9D,IAAI,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC;IACtB,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC;IACjC,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE;IAC9B,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI;IACzC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,YAAY,GAAG,IAAI,GAAG,CAAC;IACpF,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,KAAK,SAAS,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,GAAG,IAAI,GAAG,CAAC;IACjF,OAAO,CACL,MAAM,KAAK,MAAM,GACb,kBAAkB,CAAC;MAAE,GAAG,OAAO;MAAE,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE;MAAE,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG;IAAG,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,GAC/F,yBAAyB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAC9E,CAAC;EACH,CAAC;EAED,MAAM,iBAAiB,GAAG,MAAyB;IACjD,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC;IACjC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC3B,OAAO;MACL,cAAc,EAAE,GAAG,WAAW,CAAC,KAAK,MAAM,WAAW,CAAC,MAAM,EAAE;MAC9D,WAAW,EAAE,qCAAqC,WAAW,CAAC,KAAK,MAAM,WAAW,CAAC,MAAM;IAC7F,CAAC;EACH,CAAC;EAED,MAAM,iBAAiB,GAAG,MAAyB;IACjD,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC;IAChC,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC;IACjC,IAAI,CAAC,cAAc,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,CAAC,KAAK,EAAE,IAAI,QAAQ,CAAC,CAAC,KAAK,GAAG;IAC/D,OAAO;MACL,IAAI,EAAE,KAAK;MACX,GAAG,EAAE,KAAK;MACV,KAAK,EAAE,eAAe,GAAG,GAAI,cAAc,CAAC,WAAW,GAAG,WAAW,CAAC,KAAK,GAAI,GAAG,GAAG,GAAG,MAAM;MAC9F,MAAM,EAAE,eAAe,GAAG,GAAI,cAAc,CAAC,YAAY,GAAG,WAAW,CAAC,MAAM,GAAI,GAAG,GAAG,GAAG,MAAM;MACjG,WAAW,EAAE,MAAM;MACnB,YAAY,EAAE,MAAM;MACpB,SAAS,EAAE,gCAAgC,QAAQ,CAAC,CAAC;IACvD,CAAC;EACH,CAAC;EAED,MAAM,SAAS,GAAG,MAAyB;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC3B,OAAO;MACL,IAAI,EAAE,GAAG,WAAW,CAAC,CAAC,GAAG,GAAG,GAAG;MAC/B,GAAG,EAAE,GAAG,WAAW,CAAC,CAAC,GAAG,GAAG,GAAG;MAC9B,KAAK,EAAE,GAAG,WAAW,CAAC,KAAK,GAAG,GAAG,GAAG;MACpC,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,GAAG,GAAG,GAAG;MACtC,YAAY,EAAE;IAChB,CAAC;EACH,CAAC;EAED,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,CAAC,KAAK,QAAQ;EAE3D;IAAA;MAAA;IAAA,mCAGO,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,CAAC,OAAO,CAAC,CAAC;MAAA;MAAA,IAAE,QAAQ;QAAA;UAAA;UAAA,uBAAU,QAAQ,CAAC,CAAC,CAAC,cAAc;UAAA;QAAA;MAAA;MAAA;QAAA,yBAChE,IAAI;UAAA,IAAC,IAAI;YAAA,OAAE,CAAC,KAAK,CAAC,CAAC;UAAA;UAAA,IAAE,QAAQ;YAAA;cAAA;cAAA,iBAA2C,KAAK;cAAA;YAAA;UAAA;UAAA;YAAA,yBAC3E,IAAI;cAAA,IAAC,IAAI;gBAAA,OAAE,sBAAO,CAAC,CAAC,OAAI,IAAI,CAAC,CAAC;cAAA;cAAA;gBAAA;kBAAA;kBAAA;kBAAA;kBAAA;gBAAA,aACnB,KAAK;gBAAA,uDAAL,KAAK;gBAAA,oCACqD,KAAK;gBAAA,mBASzD,KAAK,IAAK,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;gBAAA,uBAD9B,KAAK,IAAK,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;gBAAA,mCAGjD,IAAI;kBAAA,IAAC,IAAI;oBAAA,OAAE,iBAAiB,CAAC,CAAC;kBAAA;kBAAA;oBAAA,yBAC5B,GAAG;sBAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;sBAAA,UAC/B,MAAM;wBAAA;wBAAA,mBAQQ,KAAK,IAAK,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;wBAAA,uBAD9B,KAAK,IAAK,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;wBAAA,sCAHrC,MAAM;wBAAA;0BAAA,YACP,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;8BAAE;4BAAO,CAAC,CAAC;4BAAA,QACnC,QAAQ,CAAC,CAAC;0BAAA;0BAAA;0BAAA;wBAAA;0BAAA;0BAAA;wBAAA;wBAAA;wBAAA;sBAAA;oBAIvB;kBAAA;gBAAA;gBAAA,mCAIN,OAAO,CAAC,OAAO;kBACd,IAAI;kBAAA;kBAAA,IAEJ,OAAO;oBAAA,OAAE,QAAQ,CAAC,CAAC,CAAC,WAAW;kBAAA;kBAAA;oBAAA,OACnB,QAAQ,CAAC,CAAC,CAAC,WAAW;kBAAA;kBAAA,IAClC,QAAQ;oBAAA,OAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;kBAAA;kBACnD,OAAO,EAAE,WAAW;kBAAA;oBAAA;kBAAA;gBAAA;gBAAA;kBAAA,YAlCiC,iBAAiB,CAAC,CAAC;oBAAA,QAChE,OAAO,CAAC,CAAC,CAAE,GAAG;oBAAA,QAAO,QAAQ,CAAC,CAAC,CAAC,WAAW;oBAAA,QAA2B,iBAAiB,CAAC,CAAC;oBAAA,QAGrF,YAAY,CAAC,CAAC;oBAAA,QACnB,SAAS,CAAC,CAAC;oBAAA,QAER,QAAQ,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC;oBAAA,QACxB,QAAQ,CAAC,CAAC,CAAC,QAAQ;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;gBAAA;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;kBAAA;gBAAA;gBAAA;gBAAA;cAAA;YAAA;UAAA;QAAA;MAAA;IAAA;IAAA,mCAbjC,qBAAqB,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;IAAA;EAAA;AAkDxD;AAAC","ignoreList":[]}
|