@hyperframes/studio-server 0.7.60 → 0.7.61

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.
Files changed (40) hide show
  1. package/dist/chunk-4ETS2LXI.js +192 -0
  2. package/dist/chunk-4ETS2LXI.js.map +1 -0
  3. package/dist/chunk-6XMC64FJ.js +584 -0
  4. package/dist/chunk-6XMC64FJ.js.map +1 -0
  5. package/dist/chunk-LVXVG4V6.js +282 -0
  6. package/dist/chunk-LVXVG4V6.js.map +1 -0
  7. package/dist/chunk-W2SBTCO2.js +32 -0
  8. package/dist/chunk-W2SBTCO2.js.map +1 -0
  9. package/dist/chunk-X62ASOGO.js +30 -0
  10. package/dist/chunk-X62ASOGO.js.map +1 -0
  11. package/dist/chunk-XVQX2JHE.js +422 -0
  12. package/dist/chunk-XVQX2JHE.js.map +1 -0
  13. package/dist/chunk-YBR7MXIO.js +459 -0
  14. package/dist/chunk-YBR7MXIO.js.map +1 -0
  15. package/dist/chunk-ZUW4PULZ.js +66 -0
  16. package/dist/chunk-ZUW4PULZ.js.map +1 -0
  17. package/dist/helpers/finiteMutation.js +4 -24
  18. package/dist/helpers/finiteMutation.js.map +1 -1
  19. package/dist/helpers/manualEditsRenderScript.js +5 -577
  20. package/dist/helpers/manualEditsRenderScript.js.map +1 -1
  21. package/dist/helpers/mediaCodecMap.d.ts +100 -0
  22. package/dist/helpers/mediaCodecMap.js +25 -0
  23. package/dist/helpers/mediaCodecMap.js.map +1 -0
  24. package/dist/helpers/mediaProxyPreview.d.ts +4 -0
  25. package/dist/helpers/mediaProxyPreview.js +17 -0
  26. package/dist/helpers/mediaProxyPreview.js.map +1 -0
  27. package/dist/helpers/proxyTranscoder.d.ts +61 -0
  28. package/dist/helpers/proxyTranscoder.js +30 -0
  29. package/dist/helpers/proxyTranscoder.js.map +1 -0
  30. package/dist/helpers/screenshotClip.js +3 -22
  31. package/dist/helpers/screenshotClip.js.map +1 -1
  32. package/dist/helpers/sourceMutation.js +9 -419
  33. package/dist/helpers/sourceMutation.js.map +1 -1
  34. package/dist/helpers/studioMotionRenderScript.js +4 -186
  35. package/dist/helpers/studioMotionRenderScript.js.map +1 -1
  36. package/dist/index.d.ts +6 -202
  37. package/dist/index.js +172 -1373
  38. package/dist/index.js.map +1 -1
  39. package/dist/mediaProxyPreview-CeshDUjE.d.ts +259 -0
  40. package/package.json +15 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/helpers/manualEditsRenderScript.ts"],"sourcesContent":["// fallow-ignore-file code-duplication\nexport interface StudioManualEditsRenderScriptOptions {\n activeCompositionPath?: string | null;\n}\n\nexport const STUDIO_MANUAL_EDITS_PATH = \".hyperframes/studio-manual-edits.json\";\n\nexport function createStudioManualEditsRenderBodyScript(\n manifestContent: string,\n options: StudioManualEditsRenderScriptOptions = {},\n): string | null {\n if (!manifestContent.trim()) return null;\n return `(${studioManualEditsRenderRuntime.toString()})(${JSON.stringify(manifestContent)}, ${JSON.stringify(options.activeCompositionPath ?? null)});`;\n}\n\n/**\n * Returns a self-contained IIFE string that re-applies studio position edits\n * (translate, rotate) after every GSAP seek by querying data attributes baked\n * into the HTML. Works without a JSON manifest — positions are already inlined\n * as CSS custom properties on the elements.\n */\nexport function createStudioPositionSeekReapplyScript(): string {\n return `(${studioPositionSeekReapplyRuntime.toString()})();`;\n}\n\nfunction studioPositionSeekReapplyRuntime(): void {\n const OFFSET_X_PROP = \"--hf-studio-offset-x\";\n const OFFSET_Y_PROP = \"--hf-studio-offset-y\";\n const WIDTH_PROP = \"--hf-studio-width\";\n const HEIGHT_PROP = \"--hf-studio-height\";\n const ROTATION_PROP = \"--hf-studio-rotation\";\n const PATH_OFFSET_ATTR = \"data-hf-studio-path-offset\";\n const BOX_SIZE_ATTR = \"data-hf-studio-box-size\";\n const ROTATION_ATTR = \"data-hf-studio-rotation\";\n const ORIGINAL_TRANSLATE_ATTR = \"data-hf-studio-original-translate\";\n const ORIGINAL_ROTATE_ATTR = \"data-hf-studio-original-rotate\";\n const MOTION_ATTR = \"data-hf-studio-motion\";\n const MOTION_TL_KEY = \"studio-motion\";\n const WRAPPED_PROP = \"__hfStudioPositionSeekReapplyWrapped\";\n\n if (\n !document.querySelector(\"[\" + PATH_OFFSET_ATTR + '=\"true\"]') &&\n !document.querySelector(\"[\" + BOX_SIZE_ATTR + '=\"true\"]') &&\n !document.querySelector(\"[\" + ROTATION_ATTR + '=\"true\"]') &&\n !document.querySelector(\"[\" + MOTION_ATTR + \"]\")\n )\n return;\n\n const splitTopLevelWhitespace = (value: string): string[] => {\n const parts: string[] = [];\n let depth = 0;\n let current = \"\";\n for (const char of value.trim()) {\n if (char === \"(\") depth += 1;\n if (char === \")\") depth = Math.max(0, depth - 1);\n if (/\\s/.test(char) && depth === 0) {\n if (current) parts.push(current);\n current = \"\";\n } else {\n current += char;\n }\n }\n if (current) parts.push(current);\n return parts;\n };\n\n const composeTranslate = (element: HTMLElement, x: string, y: string): string => {\n const original = element.getAttribute(ORIGINAL_TRANSLATE_ATTR)?.trim();\n if (!original || original === \"none\") return x + \" \" + y;\n const parts = splitTopLevelWhitespace(original);\n if (parts.length === 1) return \"calc(\" + parts[0] + \" + \" + x + \") \" + y;\n if (parts.length >= 2) {\n const z = parts.length >= 3 ? \" \" + parts[2] : \"\";\n return \"calc(\" + parts[0] + \" + \" + x + \") calc(\" + parts[1] + \" + \" + y + \")\" + z;\n }\n return x + \" \" + y;\n };\n\n const isSimpleRotateAngle = (value: string): boolean =>\n /^-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:deg|rad|turn|grad)$/.test(value.trim());\n\n const composeRotation = (element: HTMLElement, rotationValue: string): string => {\n const original = element.getAttribute(ORIGINAL_ROTATE_ATTR)?.trim();\n if (!original || original === \"none\" || !isSimpleRotateAngle(original)) return rotationValue;\n return \"calc(\" + original + \" + \" + rotationValue + \")\";\n };\n\n let lastSeekTime = 0;\n let cachedMotionKey = \"\";\n\n const finiteNum = (v: unknown): number | null =>\n typeof v === \"number\" && Number.isFinite(v) ? v : null;\n\n const computeMotionKey = (motionEls: NodeListOf<Element>): string => {\n let key = \"\";\n for (let i = 0; i < motionEls.length; i++) {\n const json = (motionEls[i] as HTMLElement).getAttribute?.(MOTION_ATTR);\n if (json) key += (key ? \"\\n\" : \"\") + json;\n }\n return key;\n };\n\n const reapplyMotionTimeline = (): void => {\n const motionEls = document.querySelectorAll(\"[\" + MOTION_ATTR + \"]\");\n if (motionEls.length === 0) {\n cachedMotionKey = \"\";\n return;\n }\n const win = window as Window & {\n gsap?: {\n timeline?: (opts: Record<string, unknown>) => Record<string, unknown>;\n set?: (el: HTMLElement, vars: Record<string, unknown>) => void;\n registerPlugin?: (plugin: unknown) => void;\n };\n CustomEase?: { create?: (id: string, data: string) => void };\n __timelines?: Record<string, Record<string, unknown>>;\n };\n const gsap = win.gsap;\n if (!gsap || typeof gsap.timeline !== \"function\") return;\n win.__timelines = win.__timelines || {};\n\n // Cache the timeline keyed by the concatenated motion JSON strings.\n // On each seek, if the key hasn't changed, just seek the existing timeline\n // instead of rebuilding it (avoids kill+recreate on every frame).\n const motionKey = computeMotionKey(motionEls);\n const existing = win.__timelines[MOTION_TL_KEY];\n if (\n motionKey &&\n motionKey === cachedMotionKey &&\n existing &&\n typeof existing.totalTime === \"function\"\n ) {\n (existing.totalTime as (t: number, s: boolean) => void)(lastSeekTime, false);\n return;\n }\n\n if (existing && typeof existing.kill === \"function\") (existing.kill as () => void)();\n const tl = gsap.timeline({ paused: true, defaults: { overwrite: \"auto\" } });\n const fromTo = tl.fromTo as (\n el: HTMLElement,\n from: Record<string, unknown>,\n to: Record<string, unknown>,\n pos: number,\n ) => void;\n if (typeof fromTo !== \"function\") return;\n let applied = 0;\n for (let i = 0; i < motionEls.length; i++) {\n const el = motionEls[i] as HTMLElement;\n if (!(el instanceof HTMLElement)) continue;\n const json = el.getAttribute(MOTION_ATTR);\n if (!json) continue;\n try {\n const m = JSON.parse(json) as Record<string, unknown>;\n const start = finiteNum(m.start);\n const duration = finiteNum(m.duration);\n if (start == null || duration == null || duration <= 0) continue;\n const ease = typeof m.ease === \"string\" ? m.ease : \"none\";\n const from = (m.from && typeof m.from === \"object\" ? m.from : {}) as Record<\n string,\n unknown\n >;\n const to = (m.to && typeof m.to === \"object\" ? m.to : {}) as Record<string, unknown>;\n const customEase = m.customEase as { id?: string; data?: string } | null | undefined;\n let resolvedEase = ease;\n if (customEase?.id && customEase?.data && win.CustomEase?.create) {\n try {\n gsap.registerPlugin?.(win.CustomEase);\n win.CustomEase.create(customEase.id, customEase.data);\n resolvedEase = customEase.id;\n } catch {\n /* use default ease */\n }\n }\n fromTo.call(\n tl,\n el,\n { ...from },\n { ...to, duration, ease: resolvedEase, overwrite: \"auto\", immediateRender: false },\n start,\n );\n applied += 1;\n } catch {\n /* malformed JSON — skip */\n }\n }\n if (applied === 0) {\n cachedMotionKey = \"\";\n if (typeof (tl as { kill?: () => void }).kill === \"function\")\n (tl as { kill: () => void }).kill();\n return;\n }\n cachedMotionKey = motionKey;\n win.__timelines[MOTION_TL_KEY] = tl;\n if (typeof tl.pause === \"function\") (tl.pause as () => void)();\n if (typeof tl.totalTime === \"function\")\n (tl.totalTime as (t: number, s: boolean) => void)(lastSeekTime, false);\n };\n\n const stripGsapTranslateFromTransform = (el: HTMLElement): void => {\n const transform = el.style.getPropertyValue(\"transform\");\n if (!transform || transform === \"none\") return;\n const win = el.ownerDocument.defaultView as (Window & typeof globalThis) | null;\n const MatrixCtor = (win as unknown as { DOMMatrix?: typeof DOMMatrix })?.DOMMatrix;\n if (!MatrixCtor) return;\n try {\n const m = new MatrixCtor(transform);\n if (m.m41 === 0 && m.m42 === 0) return;\n m.m41 = 0;\n m.m42 = 0;\n if (m.is2D && m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1) {\n el.style.removeProperty(\"transform\");\n } else {\n el.style.setProperty(\"transform\", m.toString());\n }\n } catch {\n /* non-parseable transform — leave as-is */\n }\n };\n\n const reapplyAll = (): void => {\n const offsetEls = document.querySelectorAll(\"[\" + PATH_OFFSET_ATTR + '=\"true\"]');\n for (let i = 0; i < offsetEls.length; i++) {\n const el = offsetEls[i] as HTMLElement;\n if (!(el instanceof HTMLElement)) continue;\n const x = el.style.getPropertyValue(OFFSET_X_PROP);\n const y = el.style.getPropertyValue(OFFSET_Y_PROP);\n if (x || y) {\n el.style.setProperty(\n \"translate\",\n composeTranslate(\n el,\n \"var(\" + OFFSET_X_PROP + \", 0px)\",\n \"var(\" + OFFSET_Y_PROP + \", 0px)\",\n ),\n );\n stripGsapTranslateFromTransform(el);\n }\n }\n const boxSizeEls = document.querySelectorAll(\"[\" + BOX_SIZE_ATTR + '=\"true\"]');\n for (let i = 0; i < boxSizeEls.length; i++) {\n const el = boxSizeEls[i] as HTMLElement;\n if (!(el instanceof HTMLElement)) continue;\n const w = el.style.getPropertyValue(WIDTH_PROP);\n const h = el.style.getPropertyValue(HEIGHT_PROP);\n if (w) el.style.setProperty(\"width\", w);\n if (h) el.style.setProperty(\"height\", h);\n }\n const rotEls = document.querySelectorAll(\"[\" + ROTATION_ATTR + '=\"true\"]');\n for (let i = 0; i < rotEls.length; i++) {\n const el = rotEls[i] as HTMLElement;\n if (!(el instanceof HTMLElement)) continue;\n const rot = el.style.getPropertyValue(ROTATION_PROP);\n if (rot) {\n el.style.setProperty(\"rotate\", composeRotation(el, \"var(\" + ROTATION_PROP + \", 0deg)\"));\n stripGsapTranslateFromTransform(el);\n }\n }\n reapplyMotionTimeline();\n };\n\n const runtimeWindow = window as Window & {\n __hf?: Record<string, unknown>;\n __player?: Record<string, unknown>;\n };\n\n const isWrapped = (fn: (time: number) => unknown): boolean =>\n Boolean((fn as unknown as Record<string, unknown>)[WRAPPED_PROP]);\n\n const markWrapped = (fn: (time: number) => unknown): void => {\n try {\n Object.defineProperty(fn, WRAPPED_PROP, {\n configurable: false,\n enumerable: false,\n value: true,\n });\n } catch {\n try {\n (fn as unknown as Record<string, unknown>)[WRAPPED_PROP] = true;\n } catch {\n /* ignore */\n }\n }\n };\n\n const wrapFn = (get: () => unknown, set: (fn: (time: number) => unknown) => void): boolean => {\n const fn = get();\n if (typeof fn !== \"function\") return false;\n const seek = fn as (time: number) => unknown;\n if (isWrapped(seek)) {\n reapplyAll();\n return true;\n }\n const wrapped = function (this: unknown, time: number): unknown {\n lastSeekTime = typeof time === \"number\" && Number.isFinite(time) ? Math.max(0, time) : 0;\n const result = seek.call(this, time);\n reapplyAll();\n return result;\n };\n markWrapped(wrapped);\n set(wrapped);\n reapplyAll();\n return true;\n };\n\n const wrapSeekFunctions = (): boolean => {\n const a = wrapFn(\n () => runtimeWindow.__hf?.[\"seek\"],\n (fn) => {\n if (runtimeWindow.__hf) runtimeWindow.__hf[\"seek\"] = fn;\n },\n );\n const b = wrapFn(\n () => runtimeWindow.__player?.[\"renderSeek\"],\n (fn) => {\n if (runtimeWindow.__player) runtimeWindow.__player[\"renderSeek\"] = fn;\n },\n );\n return a || b;\n };\n\n const installSeekTrap = (\n obj: Record<string, unknown> | undefined,\n key: string,\n getter: () => unknown,\n setter: (fn: (time: number) => unknown) => void,\n ): void => {\n if (!obj) return;\n try {\n let current = obj[key];\n Object.defineProperty(obj, key, {\n configurable: true,\n enumerable: true,\n get() {\n return current;\n },\n set(value: unknown) {\n current = value;\n if (typeof value === \"function\" && !isWrapped(value as (time: number) => unknown)) {\n wrapFn(getter, setter);\n }\n },\n });\n } catch {\n /* non-configurable — fall back to polling */\n }\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => reapplyAll(), { once: true });\n } else {\n reapplyAll();\n }\n\n wrapSeekFunctions();\n installSeekTrap(\n runtimeWindow.__hf,\n \"seek\",\n () => runtimeWindow.__hf?.[\"seek\"],\n (fn) => {\n if (runtimeWindow.__hf) runtimeWindow.__hf[\"seek\"] = fn;\n },\n );\n installSeekTrap(\n runtimeWindow.__player as Record<string, unknown> | undefined,\n \"renderSeek\",\n () => runtimeWindow.__player?.[\"renderSeek\"],\n (fn) => {\n if (runtimeWindow.__player) runtimeWindow.__player[\"renderSeek\"] = fn;\n },\n );\n let remaining = 120;\n const interval = setInterval(() => {\n wrapSeekFunctions();\n remaining -= 1;\n if (remaining <= 0) clearInterval(interval);\n }, 50);\n}\n\nfunction studioManualEditsRenderRuntime(\n manifestContent: string,\n activeCompositionPath: string | null,\n): void {\n const OFFSET_X_PROP = \"--hf-studio-offset-x\";\n const OFFSET_Y_PROP = \"--hf-studio-offset-y\";\n const WIDTH_PROP = \"--hf-studio-width\";\n const HEIGHT_PROP = \"--hf-studio-height\";\n const ROTATION_PROP = \"--hf-studio-rotation\";\n const PATH_OFFSET_ATTR = \"data-hf-studio-path-offset\";\n const BOX_SIZE_ATTR = \"data-hf-studio-box-size\";\n const ROTATION_ATTR = \"data-hf-studio-rotation\";\n const ORIGINAL_TRANSLATE_ATTR = \"data-hf-studio-original-translate\";\n const ORIGINAL_ROTATE_ATTR = \"data-hf-studio-original-rotate\";\n const WRAPPED_SEEK_PROP = \"__hfStudioManualEditsWrapped\";\n const ROTATION_TRANSFORM_ORIGIN = \"center center\";\n\n const finiteNumber = (value: unknown): number | null =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n\n const objectRecord = (value: unknown): Record<string, unknown> | null =>\n value && typeof value === \"object\" ? (value as Record<string, unknown>) : null;\n\n const runtimeWindow = window as Window & {\n __hf?: { seek?: (time: number) => unknown };\n __hfStudioManualEditsApply?: () => number;\n __player?: { renderSeek?: (time: number) => unknown };\n };\n\n const parsedManifest = (() => {\n try {\n return objectRecord(JSON.parse(manifestContent));\n } catch {\n return null;\n }\n })();\n const manifestEdits = Array.isArray(parsedManifest?.edits) ? parsedManifest.edits : [];\n if (manifestEdits.length === 0) return;\n\n const sourceFileForElement = (element: HTMLElement): string => {\n let current: HTMLElement | null = element;\n while (current) {\n const sourceFile =\n current.getAttribute(\"data-composition-file\") ??\n current.getAttribute(\"data-composition-src\");\n if (sourceFile) return sourceFile;\n current = current.parentElement;\n }\n return activeCompositionPath ?? \"index.html\";\n };\n\n const elementMatchesSourceFile = (element: HTMLElement, sourceFile: string): boolean =>\n sourceFileForElement(element) === sourceFile;\n\n const styleUsesStudioOffset = (value: string): boolean =>\n value.includes(OFFSET_X_PROP) || value.includes(OFFSET_Y_PROP);\n\n const styleUsesStudioRotation = (value: string): boolean => value.includes(ROTATION_PROP);\n\n const splitTopLevelWhitespace = (value: string): string[] => {\n const parts: string[] = [];\n let depth = 0;\n let current = \"\";\n for (const char of value.trim()) {\n if (char === \"(\") depth += 1;\n if (char === \")\") depth = Math.max(0, depth - 1);\n if (/\\s/.test(char) && depth === 0) {\n if (current) parts.push(current);\n current = \"\";\n } else {\n current += char;\n }\n }\n if (current) parts.push(current);\n return parts;\n };\n\n const composeTranslate = (element: HTMLElement, x: string, y: string): string => {\n const original = element.getAttribute(ORIGINAL_TRANSLATE_ATTR)?.trim();\n if (!original || original === \"none\") return `${x} ${y}`;\n\n const parts = splitTopLevelWhitespace(original);\n if (parts.length === 1) return `calc(${parts[0]} + ${x}) ${y}`;\n if (parts.length === 2) return `calc(${parts[0]} + ${x}) calc(${parts[1]} + ${y})`;\n if (parts.length === 3) {\n return `calc(${parts[0]} + ${x}) calc(${parts[1]} + ${y}) ${parts[2]}`;\n }\n return `${x} ${y}`;\n };\n\n const readStyleOrComputed = (element: HTMLElement, property: string): string => {\n try {\n return (\n element.style.getPropertyValue(property) ||\n getComputedStyle(element).getPropertyValue(property)\n );\n } catch {\n return element.style.getPropertyValue(property);\n }\n };\n\n const readTransformLonghandBase = (\n element: HTMLElement,\n property: \"translate\" | \"rotate\",\n ): string => {\n const value = readStyleOrComputed(element, property).trim();\n return value === \"none\" ? \"\" : value;\n };\n\n const preparePathOffsetBase = (element: HTMLElement): void => {\n const currentTranslate = readTransformLonghandBase(element, \"translate\");\n const hasMarker = element.hasAttribute(PATH_OFFSET_ATTR);\n const wasResetByAnimation = !styleUsesStudioOffset(currentTranslate);\n if (!hasMarker) {\n element.setAttribute(ORIGINAL_TRANSLATE_ATTR, wasResetByAnimation ? currentTranslate : \"\");\n } else if (wasResetByAnimation) {\n element.setAttribute(ORIGINAL_TRANSLATE_ATTR, currentTranslate);\n }\n };\n\n const prepareRotationBase = (element: HTMLElement): void => {\n const currentRotate = readTransformLonghandBase(element, \"rotate\");\n const hasMarker = element.hasAttribute(ROTATION_ATTR);\n const wasResetByAnimation = !styleUsesStudioRotation(currentRotate);\n if (!hasMarker) {\n element.setAttribute(ORIGINAL_ROTATE_ATTR, wasResetByAnimation ? currentRotate : \"\");\n } else if (wasResetByAnimation) {\n element.setAttribute(ORIGINAL_ROTATE_ATTR, currentRotate);\n }\n };\n\n const querySelectorCandidates = (selector: string): HTMLElement[] => {\n const isCandidate = (element: Element): element is HTMLElement =>\n element instanceof HTMLElement;\n\n const className = selector.match(/^\\.([A-Za-z0-9_-]+)$/)?.[1];\n if (className) {\n return Array.from(document.getElementsByTagName(\"*\")).filter(\n (element): element is HTMLElement =>\n isCandidate(element) && element.classList.contains(className),\n );\n }\n\n if (/^[A-Za-z][A-Za-z0-9-]*$/.test(selector)) {\n return Array.from(document.getElementsByTagName(selector)).filter(isCandidate);\n }\n\n return Array.from(document.querySelectorAll(selector)).filter(isCandidate);\n };\n\n const resolveTarget = (edit: Record<string, unknown>): HTMLElement | null => {\n const targetRecord = objectRecord(edit.target);\n if (!targetRecord) return null;\n\n const sourceFile = typeof targetRecord.sourceFile === \"string\" ? targetRecord.sourceFile : \"\";\n if (!sourceFile) return null;\n\n const id = typeof targetRecord.id === \"string\" ? targetRecord.id : \"\";\n if (id) {\n const byId = document.getElementById(id);\n if (byId instanceof HTMLElement && elementMatchesSourceFile(byId, sourceFile)) return byId;\n\n const matchesById = [\n document.documentElement,\n ...Array.from(document.getElementsByTagName(\"*\")),\n ].filter(\n (element): element is HTMLElement =>\n element instanceof HTMLElement &&\n element.id === id &&\n elementMatchesSourceFile(element, sourceFile),\n );\n if (matchesById[0]) return matchesById[0];\n }\n\n const selector = typeof targetRecord.selector === \"string\" ? targetRecord.selector : \"\";\n if (!selector) return null;\n\n try {\n const matches = querySelectorCandidates(selector).filter((element) =>\n elementMatchesSourceFile(element, sourceFile),\n );\n const selectorIndex = finiteNumber(targetRecord.selectorIndex) ?? 0;\n return matches[Math.max(0, Math.floor(selectorIndex))] ?? null;\n } catch {\n return null;\n }\n };\n\n const roundRotationAngle = (angle: number): number => Math.round(angle * 10) / 10;\n\n const isSimpleRotateAngle = (value: string): boolean =>\n /^-?(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:deg|rad|turn|grad)$/.test(value.trim());\n\n const composeRotation = (element: HTMLElement, rotationValue: string): string => {\n const original = element.getAttribute(ORIGINAL_ROTATE_ATTR)?.trim();\n if (!original || original === \"none\" || !isSimpleRotateAngle(original)) {\n return rotationValue;\n }\n return `calc(${original} + ${rotationValue})`;\n };\n\n const applyPathOffset = (element: HTMLElement, edit: Record<string, unknown>): void => {\n const x = finiteNumber(edit.x);\n const y = finiteNumber(edit.y);\n if (x == null || y == null) return;\n preparePathOffsetBase(element);\n element.setAttribute(PATH_OFFSET_ATTR, \"true\");\n element.style.setProperty(OFFSET_X_PROP, `${Math.round(x)}px`);\n element.style.setProperty(OFFSET_Y_PROP, `${Math.round(y)}px`);\n element.style.setProperty(\n \"translate\",\n composeTranslate(element, `var(${OFFSET_X_PROP}, 0px)`, `var(${OFFSET_Y_PROP}, 0px)`),\n );\n };\n\n const readParentFlexBasisPixels = (\n element: HTMLElement,\n size: { width: number; height: number },\n ): number | null => {\n const parent = element.parentElement;\n if (!parent) return null;\n const styles = getComputedStyle(parent);\n if (styles.display !== \"flex\" && styles.display !== \"inline-flex\") return null;\n return Math.round(\n Math.max(1, styles.flexDirection.startsWith(\"column\") ? size.height : size.width),\n );\n };\n\n const applyBoxSize = (element: HTMLElement, edit: Record<string, unknown>): void => {\n const width = finiteNumber(edit.width);\n const height = finiteNumber(edit.height);\n if (width == null || height == null || width <= 0 || height <= 0) return;\n\n const rounded = {\n width: Math.round(Math.max(1, width)),\n height: Math.round(Math.max(1, height)),\n };\n element.setAttribute(BOX_SIZE_ATTR, \"true\");\n element.style.setProperty(WIDTH_PROP, `${rounded.width}px`);\n element.style.setProperty(HEIGHT_PROP, `${rounded.height}px`);\n element.style.setProperty(\"box-sizing\", \"border-box\");\n element.style.setProperty(\"width\", `${rounded.width}px`);\n element.style.setProperty(\"height\", `${rounded.height}px`);\n element.style.setProperty(\"min-width\", \"0px\");\n element.style.setProperty(\"min-height\", \"0px\");\n element.style.setProperty(\"max-width\", \"none\");\n element.style.setProperty(\"max-height\", \"none\");\n\n const flexBasis = readParentFlexBasisPixels(element, rounded);\n if (flexBasis != null) {\n element.style.setProperty(\"flex-basis\", `${flexBasis}px`);\n element.style.setProperty(\"flex-grow\", \"0\");\n element.style.setProperty(\"flex-shrink\", \"0\");\n }\n if (getComputedStyle(element).display === \"inline\") {\n element.style.setProperty(\"display\", \"inline-block\");\n }\n };\n\n const applyRotation = (element: HTMLElement, edit: Record<string, unknown>): void => {\n const angle = finiteNumber(edit.angle);\n if (angle == null) return;\n prepareRotationBase(element);\n element.setAttribute(ROTATION_ATTR, \"true\");\n element.style.setProperty(ROTATION_PROP, `${roundRotationAngle(angle)}deg`);\n element.style.setProperty(\"transform-origin\", ROTATION_TRANSFORM_ORIGIN);\n element.style.setProperty(\"rotate\", composeRotation(element, `var(${ROTATION_PROP}, 0deg)`));\n };\n\n const applyManifest = (): number => {\n let applied = 0;\n for (const edit of manifestEdits) {\n const editRecord = objectRecord(edit);\n if (!editRecord) continue;\n const element = resolveTarget(editRecord);\n if (!element) continue;\n if (editRecord.kind === \"path-offset\") applyPathOffset(element, editRecord);\n if (editRecord.kind === \"box-size\") applyBoxSize(element, editRecord);\n if (editRecord.kind === \"rotation\") applyRotation(element, editRecord);\n applied += 1;\n }\n return applied;\n };\n runtimeWindow.__hfStudioManualEditsApply = applyManifest;\n\n const markWrapped = (fn: (time: number) => unknown): void => {\n try {\n Object.defineProperty(fn, WRAPPED_SEEK_PROP, {\n configurable: false,\n enumerable: false,\n value: true,\n });\n } catch {\n try {\n (fn as unknown as Record<string, unknown>)[WRAPPED_SEEK_PROP] = true;\n } catch {\n // Ignore non-extensible functions.\n }\n }\n };\n\n const isWrapped = (fn: (time: number) => unknown): boolean =>\n Boolean((fn as unknown as Record<string, unknown>)[WRAPPED_SEEK_PROP]);\n\n const wrapFunction = (\n get: () => ((time: number) => unknown) | undefined,\n set: (fn: (time: number) => unknown) => void,\n ): boolean => {\n const fn = get();\n if (!fn) return false;\n const seek = fn as (time: number) => unknown;\n if (isWrapped(seek)) {\n applyManifest();\n return true;\n }\n\n const wrappedSeek = function (this: unknown, time: number): unknown {\n const result = seek.call(this, time);\n applyManifest();\n return result;\n };\n markWrapped(wrappedSeek);\n set(wrappedSeek);\n applyManifest();\n return true;\n };\n\n const wrapSeekFunctions = (): boolean => {\n const wrappedHfSeek = wrapFunction(\n () => runtimeWindow.__hf?.seek,\n (fn) => {\n if (runtimeWindow.__hf) runtimeWindow.__hf.seek = fn;\n },\n );\n const wrappedPlayerRenderSeek = wrapFunction(\n () => runtimeWindow.__player?.renderSeek,\n (fn) => {\n if (runtimeWindow.__player) runtimeWindow.__player.renderSeek = fn;\n },\n );\n return wrappedHfSeek || wrappedPlayerRenderSeek;\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => applyManifest(), { once: true });\n } else {\n applyManifest();\n }\n\n wrapSeekFunctions();\n let remainingSeekWrapAttempts = 120;\n const seekWrapInterval = setInterval(() => {\n wrapSeekFunctions();\n remainingSeekWrapAttempts -= 1;\n if (remainingSeekWrapAttempts <= 0) clearInterval(seekWrapInterval);\n }, 50);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,100 @@
1
+ interface FfprobeRunResult {
2
+ status: number | null;
3
+ stdout: string | Buffer;
4
+ stderr: string | Buffer;
5
+ /** Spawn-level failure (covers both `NodeJS.ErrnoException` and
6
+ * `ExecFileException`); only `code === "ENOENT"` is ever inspected. */
7
+ error?: {
8
+ code?: string | number | null | undefined;
9
+ };
10
+ }
11
+ /** Injectable ffprobe runner. May be synchronous (tests) or async (the
12
+ * default `execFile`-based runner below), so cold scans can run many probes
13
+ * concurrently off the event loop. */
14
+ type FfprobeRunner = (command: string, args: string[], options?: {
15
+ timeout?: number;
16
+ maxBuffer?: number;
17
+ }) => FfprobeRunResult | Promise<FfprobeRunResult>;
18
+
19
+ /**
20
+ * One reusable answer to "what codec is this asset, and is it browser-hostile?",
21
+ * built on top of `mediaMetadata.ts`'s ffprobe-backed prober so studio-server
22
+ * probes each asset once instead of running a second prober.
23
+ */
24
+ interface AssetCodecFacts {
25
+ codecName: string;
26
+ browserHostile: boolean;
27
+ /** Coarse `canPlayType()` input; `null` when not applicable (safe codec) or
28
+ * when no representative mime exists (ProRes: browsers never decode it, so
29
+ * the runtime always proxies rather than probing `canPlayType`). */
30
+ representativeMime: string | null;
31
+ /** Source carries an alpha channel (ffprobe pix_fmt). Alpha sources use a
32
+ * VP9/WebM proxy so their transparency is preserved. */
33
+ hasAlpha: boolean;
34
+ }
35
+ /** Server-root-relative URL pathname -> that asset's codec facts. */
36
+ type MediaCodecMap = Record<string, AssetCodecFacts>;
37
+ /**
38
+ * Browser-hostile codec table v1. One exported constant so extending it is a
39
+ * one-line change. `ffprobe` cannot emit exact RFC 6381 codec strings, so
40
+ * these `representativeMime` values are deliberately coarse (a false
41
+ * positive costs one proxy transcode, never correctness; a false negative is
42
+ * rescued by the runtime's reactive zero-videoWidth swap).
43
+ */
44
+ declare const BROWSER_HOSTILE_CODECS: Record<string, string | null>;
45
+ type ProxyVariant = "h264" | "vp9";
46
+ type ProxyVariantRequest = ProxyVariant | "auto";
47
+ declare const PROXY_VARIANT_CONFIG: Record<ProxyVariant, {
48
+ extension: ".mp4" | ".webm";
49
+ contentType: "video/mp4" | "video/webm";
50
+ }>;
51
+ declare function isProxyVariant(value: string): value is ProxyVariant;
52
+ declare function isProxyVariantRequest(value: string): value is ProxyVariantRequest;
53
+ declare function proxyVariantFor(facts: AssetCodecFacts): ProxyVariant;
54
+ declare function resolveProxyVariantRequest(request: ProxyVariantRequest, facts: AssetCodecFacts): ProxyVariant | null;
55
+ type MediaProxyIneligibilityReason = "browser_safe_codec" | "proxy_target_codec" | "unknown_codec";
56
+ type MediaProxyEligibility = {
57
+ eligible: true;
58
+ } | {
59
+ eligible: false;
60
+ reason: MediaProxyIneligibilityReason;
61
+ };
62
+ /** Single policy gate shared by proactive scans and on-demand proxy routes. */
63
+ declare function decideMediaProxyEligibility(facts: AssetCodecFacts | null): MediaProxyEligibility;
64
+ /**
65
+ * Probe a single video asset. Best-effort: ffprobe missing, erroring, or
66
+ * finding no video stream resolves to `null` (asset omitted by the caller),
67
+ * never a throw. Async so a pool of probes runs concurrently (the default
68
+ * runner is `execFile`-based).
69
+ */
70
+ declare function probeAssetCodec(filePath: string, runner?: FfprobeRunner): Promise<AssetCodecFacts | null>;
71
+ interface CachedAssetProbe {
72
+ mtimeMs: number;
73
+ size: number;
74
+ facts: AssetCodecFacts | null;
75
+ }
76
+ /** Per (path, mtime) probe cache. Construct one per project/server lifetime
77
+ * and reuse it across scans; a fresh instance defeats the caching benefit. */
78
+ type MediaCodecProbeCache = Map<string, CachedAssetProbe>;
79
+ declare function createMediaCodecProbeCache(): MediaCodecProbeCache;
80
+ /** Structurally compatible with `packages/lint/src/hevcPreviewLint.ts`'s
81
+ * (unexported) `HtmlSourceLike`. */
82
+ interface HtmlSourceLike {
83
+ html: string;
84
+ compSrcPath?: string;
85
+ }
86
+ interface ScanProjectMediaCodecMapOptions {
87
+ /** Persisted across calls by the caller for the mtime-cache benefit;
88
+ * defaults to a shared module-level cache when omitted. */
89
+ cache?: MediaCodecProbeCache;
90
+ runner?: FfprobeRunner;
91
+ }
92
+ /**
93
+ * Scans a project's composition HTML for local `<video src>` references and
94
+ * returns the injection map: root-relative URL pathname -> codec facts.
95
+ * Best-effort throughout — a video whose codec can't be determined (missing
96
+ * ffprobe, probe error, no video stream) is simply omitted, never thrown.
97
+ */
98
+ declare function scanProjectMediaCodecMap(projectDir: string, htmlSources: HtmlSourceLike[], options?: ScanProjectMediaCodecMapOptions): Promise<MediaCodecMap>;
99
+
100
+ export { type AssetCodecFacts, BROWSER_HOSTILE_CODECS, type HtmlSourceLike, type MediaCodecMap, type MediaCodecProbeCache, type MediaProxyEligibility, type MediaProxyIneligibilityReason, PROXY_VARIANT_CONFIG, type ProxyVariant, type ProxyVariantRequest, type ScanProjectMediaCodecMapOptions, createMediaCodecProbeCache, decideMediaProxyEligibility, isProxyVariant, isProxyVariantRequest, probeAssetCodec, proxyVariantFor, resolveProxyVariantRequest, scanProjectMediaCodecMap };
@@ -0,0 +1,25 @@
1
+ import {
2
+ BROWSER_HOSTILE_CODECS,
3
+ PROXY_VARIANT_CONFIG,
4
+ createMediaCodecProbeCache,
5
+ decideMediaProxyEligibility,
6
+ isProxyVariant,
7
+ isProxyVariantRequest,
8
+ probeAssetCodec,
9
+ proxyVariantFor,
10
+ resolveProxyVariantRequest,
11
+ scanProjectMediaCodecMap
12
+ } from "../chunk-LVXVG4V6.js";
13
+ export {
14
+ BROWSER_HOSTILE_CODECS,
15
+ PROXY_VARIANT_CONFIG,
16
+ createMediaCodecProbeCache,
17
+ decideMediaProxyEligibility,
18
+ isProxyVariant,
19
+ isProxyVariantRequest,
20
+ probeAssetCodec,
21
+ proxyVariantFor,
22
+ resolveProxyVariantRequest,
23
+ scanProjectMediaCodecMap
24
+ };
25
+ //# sourceMappingURL=mediaCodecMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,4 @@
1
+ export { P as PreviewApiAdapter, i as injectMediaCodecMap, e as injectMediaCodecMapIntoHtml, f as isAutoProxyEnabled, p as proxyEtagSalt, r as resolvePreviewMediaCodecProbeCache } from '../mediaProxyPreview-CeshDUjE.js';
2
+ import './mediaCodecMap.js';
3
+ import '@hyperframes/core';
4
+ import '@hyperframes/parsers';
@@ -0,0 +1,17 @@
1
+ import {
2
+ injectMediaCodecMap,
3
+ injectMediaCodecMapIntoHtml,
4
+ isAutoProxyEnabled,
5
+ proxyEtagSalt,
6
+ resolvePreviewMediaCodecProbeCache
7
+ } from "../chunk-ZUW4PULZ.js";
8
+ import "../chunk-YBR7MXIO.js";
9
+ import "../chunk-LVXVG4V6.js";
10
+ export {
11
+ injectMediaCodecMap,
12
+ injectMediaCodecMapIntoHtml,
13
+ isAutoProxyEnabled,
14
+ proxyEtagSalt,
15
+ resolvePreviewMediaCodecProbeCache
16
+ };
17
+ //# sourceMappingURL=mediaProxyPreview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,61 @@
1
+ import { ProxyVariant } from './mediaCodecMap.js';
2
+
3
+ /**
4
+ * Transcodes browser-hostile local video sources (HEVC, ProRes, ...) into a
5
+ * cached, seekable authoring proxy. Consumed by the preview/play/static
6
+ * project routes (U3/U4) to serve a `?hf-proxy=` request; never used on
7
+ * the render path (render always sees the original file).
8
+ *
9
+ * IMPORTANT — request-lifecycle detachment: nothing here accepts or wires an
10
+ * AbortSignal. `resolveProxy` returns a promise shared by every concurrent
11
+ * caller for the same cache key (in-flight dedupe below); if a route handler
12
+ * killed the ffmpeg child on client abort (page reload, HMR), every other
13
+ * caller waiting on that same promise would fail too, and the next request
14
+ * would restart a transcode that may have been minutes into a long asset.
15
+ * Callers MUST let the child run to completion regardless of request
16
+ * cancellation and simply let the held response also abort — the cache
17
+ * entry still lands for the next request.
18
+ */
19
+ declare const PROXY_PARAMS_VERSION = "v3";
20
+ declare const TRANSCODE_TIMEOUT_MS: number;
21
+ declare const DEFAULT_PROXY_WAIT_TIMEOUT_MS: number;
22
+ declare class ProxyTranscodeError extends Error {
23
+ readonly exitCode: number | null;
24
+ readonly stderrTail: string;
25
+ constructor(message: string, exitCode: number | null, stderrTail: string);
26
+ }
27
+ declare class FfmpegMissingFilterError extends ProxyTranscodeError {
28
+ constructor();
29
+ }
30
+ declare class ProxyCapacityError extends ProxyTranscodeError {
31
+ constructor();
32
+ }
33
+ declare class ProxySourceOutsideProjectError extends ProxyTranscodeError {
34
+ constructor();
35
+ }
36
+ declare class ProxyWaitTimeoutError extends ProxyTranscodeError {
37
+ constructor(timeoutMs: number);
38
+ }
39
+ /** Bounds one caller's wait without cancelling the shared in-flight ffmpeg
40
+ * job. Other preview/publish callers still receive the completed cache entry. */
41
+ declare function waitForProxy<T>(promise: Promise<T>, timeoutMs?: number): Promise<T>;
42
+ /**
43
+ * Computes the absolute path a proxy for this source would live at, without
44
+ * transcoding anything. Route handlers use this to check cache state (e.g.
45
+ * for ETag/If-None-Match) before deciding whether to await a transcode.
46
+ */
47
+ declare function getProxyCachePath(projectDir: string, absoluteSourcePath: string, variant?: ProxyVariant): string;
48
+ /** Test hook: forget remembered transcode failures (module state persists
49
+ * across tests that don't reload the module). */
50
+ declare function clearFailedTranscodesForTest(): void;
51
+ /**
52
+ * Resolves the cached proxy variant for `absoluteSourcePath`, transcoding it at
53
+ * most once per cache key. Concurrent calls for the same key (including a
54
+ * pre-warm call racing an element-triggered one) share one ffmpeg child and
55
+ * one promise; calls for different keys queue through the global concurrency
56
+ * limiter above. Throws `ProxyTranscodeError` on failure (missing ffmpeg or a
57
+ * nonzero exit) — callers (route handlers) decide how to surface that (502).
58
+ */
59
+ declare function resolveProxy(projectDir: string, absoluteSourcePath: string, variant?: ProxyVariant): Promise<string>;
60
+
61
+ export { DEFAULT_PROXY_WAIT_TIMEOUT_MS, FfmpegMissingFilterError, PROXY_PARAMS_VERSION, ProxyCapacityError, ProxySourceOutsideProjectError, ProxyTranscodeError, ProxyWaitTimeoutError, TRANSCODE_TIMEOUT_MS, clearFailedTranscodesForTest, getProxyCachePath, resolveProxy, waitForProxy };
@@ -0,0 +1,30 @@
1
+ import {
2
+ DEFAULT_PROXY_WAIT_TIMEOUT_MS,
3
+ FfmpegMissingFilterError,
4
+ PROXY_PARAMS_VERSION,
5
+ ProxyCapacityError,
6
+ ProxySourceOutsideProjectError,
7
+ ProxyTranscodeError,
8
+ ProxyWaitTimeoutError,
9
+ TRANSCODE_TIMEOUT_MS,
10
+ clearFailedTranscodesForTest,
11
+ getProxyCachePath,
12
+ resolveProxy,
13
+ waitForProxy
14
+ } from "../chunk-YBR7MXIO.js";
15
+ import "../chunk-LVXVG4V6.js";
16
+ export {
17
+ DEFAULT_PROXY_WAIT_TIMEOUT_MS,
18
+ FfmpegMissingFilterError,
19
+ PROXY_PARAMS_VERSION,
20
+ ProxyCapacityError,
21
+ ProxySourceOutsideProjectError,
22
+ ProxyTranscodeError,
23
+ ProxyWaitTimeoutError,
24
+ TRANSCODE_TIMEOUT_MS,
25
+ clearFailedTranscodesForTest,
26
+ getProxyCachePath,
27
+ resolveProxy,
28
+ waitForProxy
29
+ };
30
+ //# sourceMappingURL=proxyTranscoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,25 +1,6 @@
1
- // src/helpers/screenshotClip.ts
2
- function getElementScreenshotClip(selector, selectorIndex) {
3
- const matches = Array.from(document.querySelectorAll(selector)).filter(
4
- (el2) => el2 instanceof HTMLElement
5
- );
6
- const safeIndex = Math.max(0, Math.min(matches.length - 1, Math.floor(selectorIndex ?? 0)));
7
- const el = matches[safeIndex] ?? null;
8
- if (!(el instanceof HTMLElement)) return void 0;
9
- const rect = el.getBoundingClientRect();
10
- if (rect.width < 4 || rect.height < 4) return void 0;
11
- const pad = 8;
12
- const x = Math.max(0, rect.left - pad);
13
- const y = Math.max(0, rect.top - pad);
14
- const maxWidth = window.innerWidth - x;
15
- const maxHeight = window.innerHeight - y;
16
- return {
17
- x,
18
- y,
19
- width: Math.max(1, Math.min(rect.width + pad * 2, maxWidth)),
20
- height: Math.max(1, Math.min(rect.height + pad * 2, maxHeight))
21
- };
22
- }
1
+ import {
2
+ getElementScreenshotClip
3
+ } from "../chunk-W2SBTCO2.js";
23
4
  export {
24
5
  getElementScreenshotClip
25
6
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/helpers/screenshotClip.ts"],"sourcesContent":["export interface ScreenshotClip {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport function getElementScreenshotClip(\n selector: string,\n selectorIndex?: number,\n): ScreenshotClip | undefined {\n const matches = Array.from(document.querySelectorAll(selector)).filter(\n (el): el is HTMLElement => el instanceof HTMLElement,\n );\n const safeIndex = Math.max(0, Math.min(matches.length - 1, Math.floor(selectorIndex ?? 0)));\n const el = matches[safeIndex] ?? null;\n if (!(el instanceof HTMLElement)) return undefined;\n const rect = el.getBoundingClientRect();\n if (rect.width < 4 || rect.height < 4) return undefined;\n const pad = 8;\n const x = Math.max(0, rect.left - pad);\n const y = Math.max(0, rect.top - pad);\n const maxWidth = window.innerWidth - x;\n const maxHeight = window.innerHeight - y;\n return {\n x,\n y,\n width: Math.max(1, Math.min(rect.width + pad * 2, maxWidth)),\n height: Math.max(1, Math.min(rect.height + pad * 2, maxHeight)),\n };\n}\n"],"mappings":";AAOO,SAAS,yBACd,UACA,eAC4B;AAC5B,QAAM,UAAU,MAAM,KAAK,SAAS,iBAAiB,QAAQ,CAAC,EAAE;AAAA,IAC9D,CAACA,QAA0BA,eAAc;AAAA,EAC3C;AACA,QAAM,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,SAAS,GAAG,KAAK,MAAM,iBAAiB,CAAC,CAAC,CAAC;AAC1F,QAAM,KAAK,QAAQ,SAAS,KAAK;AACjC,MAAI,EAAE,cAAc,aAAc,QAAO;AACzC,QAAM,OAAO,GAAG,sBAAsB;AACtC,MAAI,KAAK,QAAQ,KAAK,KAAK,SAAS,EAAG,QAAO;AAC9C,QAAM,MAAM;AACZ,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,OAAO,GAAG;AACrC,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG;AACpC,QAAM,WAAW,OAAO,aAAa;AACrC,QAAM,YAAY,OAAO,cAAc;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,QAAQ,MAAM,GAAG,QAAQ,CAAC;AAAA,IAC3D,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,SAAS,MAAM,GAAG,SAAS,CAAC;AAAA,EAChE;AACF;","names":["el"]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}