@webex/ladon-ts 5.6.0 → 5.7.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/CHANGELOG.md +14 -0
- package/build/module/lib/generator-types.d.ts +1 -0
- package/build/module/lib/pipeline.d.ts +1 -10
- package/build/module/lib/pipeline.js +40 -52
- package/build/module/lib/pipeline.js.map +1 -1
- package/build/module/lib/version.d.ts +1 -1
- package/build/module/lib/version.js +1 -1
- package/build/module/lib/version.js.map +1 -1
- package/build/module/lib/worker-generator.d.ts +10 -0
- package/build/module/lib/worker-generator.js +41 -22
- package/build/module/lib/worker-generator.js.map +1 -1
- package/build/module/lib/worker-manager.d.ts +9 -0
- package/build/module/lib/worker-manager.js +30 -18
- package/build/module/lib/worker-manager.js.map +1 -1
- package/build/worker/segmentation.js +327 -327
- package/build/worker/segmentation.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segmentation.js","sources":["../src/shim.ts","../src/console-overrides.ts","../../build/module/lib/util.js","../../build/module/lib/resource-loader.js","../src/util.ts","../src/model-manager.ts","../src/ladon-generator.ts","../src/segmentation.ts"],"sourcesContent":["/**\n * This file is used to provide a shim for the document object in a web worker.\n * The document object is not available in a web worker, so we need to provide a shim\n * to prevent errors when running the code in a web worker.\n * \n * See: https://github.com/vitejs/vite/issues/9879#issuecomment-1372112651\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(self.document as any) = {\n baseURI: location.origin\n};","/**\n * Override console methods to send logs to the main thread for display in the UI.\n */\n\nconst originalConsoleLog = console.log;\nconst originalConsoleWarn = console.warn;\nconst originalConsoleError = console.error;\n\nconsole.log = (...args) => {\n postMessage({ type: 'log', message: args.join(' '), severity: 'log' });\n originalConsoleLog(...args);\n};\n\nconsole.warn = (...args) => {\n postMessage({ type: 'log', message: args.join(' '), severity: 'warn' });\n originalConsoleWarn(...args);\n};\n\nconsole.error = (...args) => {\n postMessage({ type: 'log', message: args.join(' '), severity: 'error' });\n originalConsoleError(...args);\n};","var I = /* @__PURE__ */ ((o) => (o.Nearest = \"nearest\", o))(I || {});\nconst U = (o, n, u, r, e) => {\n const l = new Uint8ClampedArray(r * e * 4), p = n / r, y = u / e, s = n * 4;\n let a = 0;\n for (let t = 0; t < e; t++) {\n const f = Math.floor(t * y) * s;\n for (let c = 0; c < r; c++) {\n const m = f + Math.floor(c * p) * 4;\n l[a++] = o[m], l[a++] = o[m + 1], l[a++] = o[m + 2], l[a++] = o[m + 3];\n }\n }\n return l;\n};\nfunction A(o, n, u, r, e) {\n const l = new Uint8ClampedArray(r * e);\n if (n === r && u === e) {\n for (let s = 0; s < o.length; s++)\n l[s] = Math.min(Math.max(o[s], 0), 255);\n return l;\n }\n const p = (n - 1) / (r - 1), y = (u - 1) / (e - 1);\n for (let s = 0; s < e; s++)\n for (let a = 0; a < r; a++) {\n const t = p * a, f = y * s, c = Math.floor(t), m = Math.floor(f), S = Math.min(Math.ceil(t), n - 1), x = Math.min(Math.ceil(f), u - 1), w = t - c, i = f - m, M = o[m * n + c], h = o[m * n + S], k = o[x * n + c], P = o[x * n + S], E = M * (1 - w) * (1 - i) + h * w * (1 - i) + k * (1 - w) * i + P * w * i;\n l[s * r + a] = Math.min(Math.max(E, 0), 255);\n }\n return l;\n}\nfunction d(o, n, u, r, e) {\n const l = new Uint8ClampedArray(r * e), p = n / r, y = u / e, s = (t, f) => {\n if (t === 0) return 1;\n if (t < 0 && (t = -t), t < f) {\n const c = Math.PI * t;\n return f * Math.sin(c) * Math.sin(c / f) / (c * c);\n }\n return 0;\n }, a = 3;\n for (let t = 0; t < e; t++)\n for (let f = 0; f < r; f++) {\n const c = f * p, m = t * y, S = Math.floor(c), x = Math.floor(m);\n let w = 0, i = 0;\n for (let M = x - a + 1; M <= x + a; M++)\n for (let h = S - a + 1; h <= S + a; h++)\n if (h >= 0 && h < n && M >= 0 && M < u) {\n const k = o[M * n + h], P = s(c - h, a) * s(m - M, a);\n w += k * P, i += P;\n }\n l[t * r + f] = i !== 0 ? Math.round(w / i) : 0;\n }\n return l;\n}\nfunction L(o, n, u) {\n const r = o.createShader(n);\n if (!r)\n throw new Error(\"[ladon-ts] Error creating shader\");\n if (o.shaderSource(r, u), o.compileShader(r), !o.getShaderParameter(r, o.COMPILE_STATUS)) {\n const e = o.getShaderInfoLog(r) ?? \"unknown error compiling shader.\";\n throw new Error(\"[ladon-ts] \" + e);\n }\n return r;\n}\nfunction R(o, n, u) {\n const r = o.createProgram();\n if (!r)\n throw new Error(\"[ladon-ts] Error creating GPU program\");\n if (o.attachShader(r, n), o.attachShader(r, u), o.linkProgram(r), !o.getProgramParameter(r, o.LINK_STATUS)) {\n const e = o.getProgramInfoLog(r) ?? \"unknown error linking program.\";\n throw new Error(\"[ladon-ts] \" + e);\n }\n return r;\n}\nfunction C(o) {\n if (o.startsWith(\"blob:\"))\n return !0;\n try {\n return new URL(o), !0;\n } catch {\n return !1;\n }\n}\nconst T = (o, n) => !n || o.startsWith(\"http\") ? new URL(o).href : o ? n.replace(/\\/+$/, \"\") + \"/\" + o.replace(/^\\/+/, \"\") : n;\nexport {\n I as InterpolationMethod,\n A as bilinearUpsample,\n L as compileShader,\n C as isResolvedUri,\n d as lanczos3Upsample,\n R as linkProgram,\n U as resizeImage,\n T as toAbsoluteURI\n};\n//# sourceMappingURL=util.js.map\n","import { isResolvedUri as l, toAbsoluteURI as s } from \"./util.js\";\nclass t {\n constructor() {\n this.resolvedUriCache = /* @__PURE__ */ new Map();\n }\n /**\n * Resolves the full URL for a given asset. Non-file URIs are treated as paths and resolved\n * using the `toAbsoluteURI` method. If the assetUri is already resolved, or if it's found in\n * cache, it will be returned directly. If an assetUrlResolver function is provided in the\n * configuration, it will be used to resolve the URL if the assetUri is not fully qualified,\n * a blob URL, or in the cache.\n *\n * @param config - The preload configuration.\n * @param assetUri - The asset URI from the config.\n * @returns The resolved full URL.\n */\n async resolveUri(o, e) {\n if (!e)\n throw new Error(\"Asset URI is undefined.\");\n if (this.resolvedUriCache.has(e))\n return this.resolvedUriCache.get(e);\n let r;\n if (l(e) ? r = e : e.match(/\\.[a-z0-9]+$/i) ? typeof o.assetUrlResolver == \"function\" && (r = await o.assetUrlResolver(e, o)) : r = s(e, o.baseUrl), !r)\n throw new Error(`Failed to resolve asset URI: ${e}`);\n return this.resolvedUriCache.set(e, r), r;\n }\n}\nconst d = new t();\nexport {\n t as ResourceLoader,\n d as resourceLoader\n};\n//# sourceMappingURL=resource-loader.js.map\n","export { isResolvedUri, toAbsoluteURI } from '@webex/ladon-ts'\n\nexport async function loadAndCacheFile(fileUrl: string): Promise<ArrayBufferLike | Uint8Array> {\n const cache = await caches.open('ladon-cache');\n\n // Try to get the file from cache using its full URL\n const cachedResponse = await cache.match(fileUrl);\n if (cachedResponse) {\n return cachedResponse.arrayBuffer();\n }\n\n // If not in cache, fetch and cache the file\n const response = await fetch(fileUrl);\n\n // Ensure the response is valid\n if (!response.ok) {\n throw new Error(`Failed to fetch file: ${fileUrl}`);\n }\n\n const contentType = response.headers.get('Content-Type') || 'binary/octet-stream';\n\n // Validate expected MIME types\n if (!contentType.includes('application/wasm') && !contentType.includes('binary/octet-stream')) {\n throw new Error(`Unexpected MIME type: ${contentType} for ${fileUrl}`);\n }\n\n const fileBinary = await response.arrayBuffer();\n\n // Cache the response with proper headers\n const cachedResponseWithHeaders = new Response(fileBinary, {\n headers: {\n 'Content-Type': contentType,\n 'Content-Length': fileBinary.byteLength.toString(),\n },\n });\n\n // Store the response in the cache using the full URL as the key\n await cache.put(fileUrl, cachedResponseWithHeaders);\n\n return fileBinary;\n}\n","import * as ort from 'onnxruntime-web';\nimport { PreloadConfig, ResolutionConfig, resourceLoader } from '@webex/ladon-ts';\n\nimport { loadAndCacheFile } from './util';\n\n// There is only a single WASM file for all WebAssembly binaries now.\nconst ONNX_WASM_FILENAME = 'ort-wasm-simd-threaded.wasm';\n\n/**\n * Resource manager used to load resources for the segmentation worker.\n */\nexport class ModelManager {\n private modelSessions: Record<string, ort.InferenceSession> = {};\n\n /**\n * Load the model using the provided configuration. This gets called by the worker when using\n * the worker generator.\n *\n * @param config - The configuration object.\n * @returns A promise that resolves when the model is preloaded.\n */\n public async loadModel(config: PreloadConfig) {\n const { mask, executionProviders: providers } = config;\n\n // Lock to a single thread to avoid performance issues.\n ort.env.wasm.numThreads = 1;\n\n // Get the resolved paths for the WASM binary.\n const wasmPaths = await resourceLoader.resolveUri(config, config.wasmUri);\n\n if (wasmPaths) {\n try {\n ort.env.wasm.wasmBinary = await loadAndCacheFile(wasmPaths + ONNX_WASM_FILENAME);\n } catch (error) {\n console.warn('Failed to load or cache WASM file. Using WASM paths.', error);\n ort.env.wasm.wasmPaths = wasmPaths;\n }\n }\n\n // Resolve the model URL.\n const modelUrl = await resourceLoader.resolveUri(config, mask.modelUri);\n let modelSession = this.modelSessions[modelUrl];\n\n // If the model session is not already cached, create a new session and cache.\n if (!modelSession) {\n // Allows the user to specify the execution providers to use. The default is the WASM provider.\n // TODO: Add and test support for other execution providers.\n const executionProviders = providers?.length ? providers : ['wasm'];\n const sessionOptions = { executionProviders };\n\n // First try to get the model binary either from cache or by fetching and cacheing it.\n try {\n const modelBinary = await loadAndCacheFile(modelUrl);\n modelSession = await ort.InferenceSession.create(modelBinary, sessionOptions);\n } catch (error) {\n console.warn('Failed to load or cache model file. Using model URL.', error);\n modelSession = await ort.InferenceSession.create(modelUrl, sessionOptions);\n }\n }\n\n // Cache the model session.\n this.modelSessions[modelUrl] = modelSession;\n\n // Warmup the model with a dummy input to avoid latency when running the model for the first time.\n await this.warmupModel(modelSession, mask.inputSize, mask.modelRank);\n\n return modelSession;\n }\n\n /**\n * Warmup the model session with a dummy input to avoid latency when running the model for the first time.\n *\n * @param {ort.InferenceSession} session The model session.\n * @param {ResolutionConfig} inputSize The input size of the model.\n * @param {number} inputChannels The number of input channels (e.g., RGB is 3).\n * @param {ort.Tensor.Type} inputType The input tensor type.\n * @returns {Promise<void>} A promise that resolves when the model is warmed up.\n * @example\n * await warmupModel(session, inputSize, inputChannels, inputType);\n */\n public async warmupModel(\n session: ort.InferenceSession,\n inputSize: ResolutionConfig = { width: 1280, height: 720 },\n inputChannels = 3,\n inputType: ort.Tensor.Type = 'float32'\n ): Promise<void> {\n const numPixels = inputSize.height * inputSize.width;\n const dummyInputData = new Float32Array(inputChannels * numPixels).fill(0);\n const dummyInput = new ort.Tensor(inputType, dummyInputData, [\n 1,\n inputChannels,\n inputSize.height,\n inputSize.width,\n ]);\n const feed = { [session.inputNames[0]]: dummyInput };\n\n // Use an additional dummy tensor if the model expects a previous mask.\n if (inputChannels === 3) {\n const dummyMaskData = new Float32Array(numPixels).fill(0);\n const prevMaskTensor = new ort.Tensor(inputType, dummyMaskData, [\n 1,\n 1,\n inputSize.height,\n inputSize.width,\n ]);\n feed[session.inputNames[1]] = prevMaskTensor;\n }\n\n // Run the model with the dummy input to warm it up.\n await session.run(feed);\n }\n\n /**\n * Get the model session for the provided model URL.\n *\n * @param {string} modelUrl The model URL.\n * @returns {ort.InferenceSession} The model session.\n * @example\n * const session = getModelSession(modelUrl);\n */\n public getModelSession(modelUrl: string) {\n return this.modelSessions[modelUrl];\n }\n\n /**\n * Clear the model sessions cache.\n *\n * @example\n * modelManager.destroyModel();\n */\n public async destroyModel(modelUrl: string) {\n const session = this.modelSessions[modelUrl];\n if (session) {\n await session.release();\n delete this.modelSessions[modelUrl];\n }\n }\n \n}\n\nexport const modelManager = new ModelManager();","import * as ort from 'onnxruntime-web';\n\nimport { LadonOutput, MaskGenerator, PipelineConfig, resourceLoader } from '@webex/ladon-ts';\n\nimport { modelManager } from './model-manager';\n\nexport class LadonGenerator implements MaskGenerator {\n private lastResult: LadonOutput;\n private lastMask: ort.Tensor;\n private maskModel?: ort.InferenceSession;\n private lastMaskGenerationTime = 0;\n private output?: Float32Array;\n private modelUrl?: string;\n\n constructor(public readonly config: PipelineConfig) {\n const { height, width } = this.config.mask.outputSize;\n this.lastMask = new ort.Tensor('float32', new Float32Array(height * width), [\n 1,\n 1,\n height,\n width,\n ]);\n this.lastResult = {\n data: this.lastMask.data,\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n timestamp: 0,\n warm: false,\n };\n }\n\n public isLoaded(): boolean {\n return !!this.maskModel;\n }\n\n /**\n * This method preprocesses an input Uint8ClampedArray to a Float32Array\n * while maintaining memory efficiency by reusing a class-scoped output buffer.\n * If the model rank is 4 (e.g., newer tiny model), it sets an alpha channel value.\n *\n * @param {Uint8ClampedArray} input - The input data to be preprocessed\n * @param {Float32Array} alpha - The alpha channel data\n * @returns {Float32Array} - The processed data\n */\n private preprocess(input: Uint8ClampedArray, alpha: Float32Array): Float32Array {\n const { modelRank, inputSize, outputSize } = this.config.mask;\n const { height, width } = inputSize;\n const numImagePixels = height * width;\n\n // Initialize the output buffer if it is not already set\n this.output ??= new Float32Array(numImagePixels * modelRank);\n\n const numInputPixels = input.length / 4; // Divide by 4 for RGBA\n\n // Directly copy channels (assumes fixed order like BGR or RGB)\n for (let channel = 0; channel < 3; channel++) {\n for (let pixel = 0; pixel < numInputPixels; pixel++) {\n // Map input channels directly to output\n this.output[pixel + channel * numImagePixels] = input[pixel * 4 + (2 - channel)];\n }\n }\n\n // Scaling factors for width and height\n const widthScale = outputSize.width / width;\n const heightScale = outputSize.height / height;\n\n // Process alpha channel\n for (let x = 0; x < width; x++) {\n const nearestNeighborX = Math.floor(x * widthScale);\n for (let y = 0; y < height; y++) {\n const nearestNeighborY = Math.floor(y * heightScale);\n const maskIdx = nearestNeighborX + nearestNeighborY * outputSize.width;\n const outputIdx = x + y * width + 3 * numImagePixels;\n\n // Normalize and scale alpha to [0, 255]\n const normalizedValue = Math.min(Math.max(alpha[maskIdx], 0), 255);\n this.output[outputIdx] = normalizedValue;\n }\n }\n\n return this.output;\n }\n\n public getTimeSinceLastGeneration(): number {\n return Date.now() - this.lastMaskGenerationTime;\n }\n\n public async getLadonOutput(input: Uint8ClampedArray, timestamp: number): Promise<LadonOutput> {\n if (!this.maskModel) {\n throw new Error('[ladon-ts] Mask model not loaded.');\n }\n\n if (this.getTimeSinceLastGeneration() < this.config.mask.generationIntervalMs) {\n return {\n data: this.lastMask.data,\n facesAndLandmarks: this.lastResult.facesAndLandmarks,\n gesture: this.lastResult.gesture,\n motion: this.lastResult.motion,\n timestamp: this.lastResult.timestamp,\n warm: false,\n };\n }\n\n this.lastMaskGenerationTime = Date.now();\n\n const imageTensor = new ort.Tensor('float32', this.preprocess(input, this.lastMask.data), [\n 1,\n this.config.mask.modelRank,\n this.config.mask.inputSize.height,\n this.config.mask.inputSize.width,\n ]);\n\n const results = await this.maskModel.run({ input: imageTensor });\n this.lastMask = results.segmentation;\n\n this.lastResult = {\n data: this.lastMask.data ?? new Float32Array(0),\n facesAndLandmarks: {\n data: results.faces_and_landmarks?.data ?? new Float32Array(0),\n dims: results.faces_and_landmarks?.dims ?? ([] as readonly number[]),\n },\n gesture: results.gesture?.data ?? new Float32Array(0),\n motion: results.motion?.data[0] ?? 0,\n timestamp,\n warm: true,\n };\n\n return this.lastResult;\n }\n\n async load() {\n this.modelUrl = await resourceLoader.resolveUri(this.config, this.config.mask.modelUri);\n\n // Attempt to retrieve a preloaded InferenceSession from the shared resource manager.\n this.maskModel = modelManager.getModelSession(this.modelUrl);\n // If the model is not preloaded, load it from the provided model URL.\n this.maskModel ??= await modelManager.loadModel(this.config);\n\n if (!this.maskModel) {\n throw new Error('Failed to load the ONNX model.');\n }\n }\n\n public async postRender(): Promise<void> {\n // empty for local generator\n }\n\n /**\n * Destroys the model session and releases resources.\n * This method should be called when the generator is no longer needed.\n *\n * @returns A promise that resolves when the model is destroyed.\n */\n public async destroy(): Promise<void> {\n if (!this.modelUrl) {\n throw new Error('[ladon-ts] Generator teardown failed. Model URL is not defined.');\n }\n\n // Clear the model session from the cache.\n await modelManager.destroyModel(this.modelUrl);\n\n // Release the model session.\n this.modelUrl = undefined;\n this.maskModel = undefined;\n this.output = undefined;\n }\n}\n","import './shim';\nimport './console-overrides';\n\nimport { PipelineConfig, PreloadConfig } from '@webex/ladon-ts';\n\nimport { LadonGenerator } from './ladon-generator';\nimport { modelManager } from './model-manager';\n\nlet preloadPromise: Promise<void> | null = null;\nlet generator: LadonGenerator;\nlet busy = false;\n\n// Message handler for worker\nself.addEventListener('message', async (event) => {\n const { type, config, image, timestamp } = event.data;\n\n try {\n switch (type) {\n case 'preload':\n if (config) {\n preloadPromise = handlePreload(config as PreloadConfig);\n await preloadPromise;\n }\n break;\n\n case 'init':\n if (config) {\n // Wait for preload to complete before initializing\n if (preloadPromise) {\n await preloadPromise;\n }\n await handleInit(config as PipelineConfig);\n }\n break;\n\n case 'generate':\n if (image) {\n await handleGenerate(image, timestamp);\n }\n break;\n\n case 'destroy':\n await handleDestroy();\n break;\n\n default:\n console.warn(\n `[ladon-ts] Worker generator recieved unknown message: ${JSON.stringify(\n event.data\n )}`\n );\n }\n } catch (error) {\n console.error(`[ladon-ts] Worker generator error handling message: ${error}`);\n postMessage({ status: 'error', error: error.message });\n }\n});\n\n// Handle preload event\nasync function handlePreload(config: PreloadConfig): Promise<void> {\n await modelManager.loadModel(config);\n postMessage({ status: 'preloaded' });\n}\n\n// Handle initialization\nasync function handleInit(config: PipelineConfig): Promise<void> {\n generator = new LadonGenerator(config);\n await generator.load();\n postMessage({ status: 'initialized' });\n}\n\n// Handle generate event with SharedArrayBuffer support\nasync function handleGenerate(image: Uint8ClampedArray | null, timestamp: number): Promise<void> {\n if (busy) {\n return;\n }\n\n if (!generator || !generator.isLoaded()) {\n console.warn('[ladon-ts] Generator is not initialized');\n return;\n }\n\n busy = true;\n\n if (!image) {\n console.warn('[ladon-ts] No valid input provided for generation');\n busy = false;\n return;\n }\n\n // Run generator\n const maskResult = await generator.getLadonOutput(image, timestamp);\n\n if (maskResult.warm) {\n postMessage({\n facesAndLandmarks: maskResult.facesAndLandmarks,\n gesture: maskResult.gesture,\n mask: maskResult.data, // Transfer mask directly if TypedArray\n motion: maskResult.motion,\n timestamp: maskResult.timestamp,\n status: 'generated',\n });\n }\n\n setTimeout(() => {\n busy = false;\n }, 0);\n}\n\n// Handle destroy event\nasync function handleDestroy(): Promise<void> {\n if (generator) {\n await generator.destroy();\n } else {\n console.warn('[ladon-ts] No generator to destroy');\n }\n postMessage({ status: 'destroyed' });\n}\n"],"names":["args","o","e","r","l","s","fileUrl","cache","cachedResponse","response","contentType","fileBinary","cachedResponseWithHeaders","config","mask","providers","ort.env","wasmPaths","resourceLoader","error","modelUrl","modelSession","sessionOptions","modelBinary","ort.InferenceSession","session","inputSize","inputChannels","inputType","numPixels","dummyInputData","dummyInput","ort.Tensor","feed","dummyMaskData","prevMaskTensor","height","width","input","alpha","modelRank","outputSize","numImagePixels","numInputPixels","channel","pixel","widthScale","heightScale","x","nearestNeighborX","y","nearestNeighborY","maskIdx","outputIdx","normalizedValue","timestamp","imageTensor","results","_a","_b","_c","_d","event","type","image","maskResult"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"segmentation.js","sources":["../src/shim.ts","../src/console-overrides.ts","../../build/module/lib/util.js","../../build/module/lib/resource-loader.js","../src/util.ts","../src/model-manager.ts","../src/ladon-generator.ts","../src/segmentation.ts"],"sourcesContent":["/**\n * This file is used to provide a shim for the document object in a web worker.\n * The document object is not available in a web worker, so we need to provide a shim\n * to prevent errors when running the code in a web worker.\n * \n * See: https://github.com/vitejs/vite/issues/9879#issuecomment-1372112651\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(self.document as any) = {\n baseURI: location.origin\n};","/**\n * Override console methods to send logs to the main thread for display in the UI.\n */\n\nconst originalConsoleLog = console.log;\nconst originalConsoleWarn = console.warn;\nconst originalConsoleError = console.error;\n\nconsole.log = (...args) => {\n postMessage({ type: 'log', message: args.join(' '), severity: 'log' });\n originalConsoleLog(...args);\n};\n\nconsole.warn = (...args) => {\n postMessage({ type: 'log', message: args.join(' '), severity: 'warn' });\n originalConsoleWarn(...args);\n};\n\nconsole.error = (...args) => {\n postMessage({ type: 'log', message: args.join(' '), severity: 'error' });\n originalConsoleError(...args);\n};","var I = /* @__PURE__ */ ((o) => (o.Nearest = \"nearest\", o))(I || {});\nconst U = (o, n, u, r, e) => {\n const l = new Uint8ClampedArray(r * e * 4), p = n / r, y = u / e, s = n * 4;\n let a = 0;\n for (let t = 0; t < e; t++) {\n const f = Math.floor(t * y) * s;\n for (let c = 0; c < r; c++) {\n const m = f + Math.floor(c * p) * 4;\n l[a++] = o[m], l[a++] = o[m + 1], l[a++] = o[m + 2], l[a++] = o[m + 3];\n }\n }\n return l;\n};\nfunction A(o, n, u, r, e) {\n const l = new Uint8ClampedArray(r * e);\n if (n === r && u === e) {\n for (let s = 0; s < o.length; s++)\n l[s] = Math.min(Math.max(o[s], 0), 255);\n return l;\n }\n const p = (n - 1) / (r - 1), y = (u - 1) / (e - 1);\n for (let s = 0; s < e; s++)\n for (let a = 0; a < r; a++) {\n const t = p * a, f = y * s, c = Math.floor(t), m = Math.floor(f), S = Math.min(Math.ceil(t), n - 1), x = Math.min(Math.ceil(f), u - 1), w = t - c, i = f - m, M = o[m * n + c], h = o[m * n + S], k = o[x * n + c], P = o[x * n + S], E = M * (1 - w) * (1 - i) + h * w * (1 - i) + k * (1 - w) * i + P * w * i;\n l[s * r + a] = Math.min(Math.max(E, 0), 255);\n }\n return l;\n}\nfunction d(o, n, u, r, e) {\n const l = new Uint8ClampedArray(r * e), p = n / r, y = u / e, s = (t, f) => {\n if (t === 0) return 1;\n if (t < 0 && (t = -t), t < f) {\n const c = Math.PI * t;\n return f * Math.sin(c) * Math.sin(c / f) / (c * c);\n }\n return 0;\n }, a = 3;\n for (let t = 0; t < e; t++)\n for (let f = 0; f < r; f++) {\n const c = f * p, m = t * y, S = Math.floor(c), x = Math.floor(m);\n let w = 0, i = 0;\n for (let M = x - a + 1; M <= x + a; M++)\n for (let h = S - a + 1; h <= S + a; h++)\n if (h >= 0 && h < n && M >= 0 && M < u) {\n const k = o[M * n + h], P = s(c - h, a) * s(m - M, a);\n w += k * P, i += P;\n }\n l[t * r + f] = i !== 0 ? Math.round(w / i) : 0;\n }\n return l;\n}\nfunction L(o, n, u) {\n const r = o.createShader(n);\n if (!r)\n throw new Error(\"[ladon-ts] Error creating shader\");\n if (o.shaderSource(r, u), o.compileShader(r), !o.getShaderParameter(r, o.COMPILE_STATUS)) {\n const e = o.getShaderInfoLog(r) ?? \"unknown error compiling shader.\";\n throw new Error(\"[ladon-ts] \" + e);\n }\n return r;\n}\nfunction R(o, n, u) {\n const r = o.createProgram();\n if (!r)\n throw new Error(\"[ladon-ts] Error creating GPU program\");\n if (o.attachShader(r, n), o.attachShader(r, u), o.linkProgram(r), !o.getProgramParameter(r, o.LINK_STATUS)) {\n const e = o.getProgramInfoLog(r) ?? \"unknown error linking program.\";\n throw new Error(\"[ladon-ts] \" + e);\n }\n return r;\n}\nfunction C(o) {\n if (o.startsWith(\"blob:\"))\n return !0;\n try {\n return new URL(o), !0;\n } catch {\n return !1;\n }\n}\nconst T = (o, n) => !n || o.startsWith(\"http\") ? new URL(o).href : o ? n.replace(/\\/+$/, \"\") + \"/\" + o.replace(/^\\/+/, \"\") : n;\nexport {\n I as InterpolationMethod,\n A as bilinearUpsample,\n L as compileShader,\n C as isResolvedUri,\n d as lanczos3Upsample,\n R as linkProgram,\n U as resizeImage,\n T as toAbsoluteURI\n};\n//# sourceMappingURL=util.js.map\n","import { isResolvedUri as l, toAbsoluteURI as s } from \"./util.js\";\nclass t {\n constructor() {\n this.resolvedUriCache = /* @__PURE__ */ new Map();\n }\n /**\n * Resolves the full URL for a given asset. Non-file URIs are treated as paths and resolved\n * using the `toAbsoluteURI` method. If the assetUri is already resolved, or if it's found in\n * cache, it will be returned directly. If an assetUrlResolver function is provided in the\n * configuration, it will be used to resolve the URL if the assetUri is not fully qualified,\n * a blob URL, or in the cache.\n *\n * @param config - The preload configuration.\n * @param assetUri - The asset URI from the config.\n * @returns The resolved full URL.\n */\n async resolveUri(o, e) {\n if (!e)\n throw new Error(\"Asset URI is undefined.\");\n if (this.resolvedUriCache.has(e))\n return this.resolvedUriCache.get(e);\n let r;\n if (l(e) ? r = e : e.match(/\\.[a-z0-9]+$/i) ? typeof o.assetUrlResolver == \"function\" && (r = await o.assetUrlResolver(e, o)) : r = s(e, o.baseUrl), !r)\n throw new Error(`Failed to resolve asset URI: ${e}`);\n return this.resolvedUriCache.set(e, r), r;\n }\n}\nconst d = new t();\nexport {\n t as ResourceLoader,\n d as resourceLoader\n};\n//# sourceMappingURL=resource-loader.js.map\n","export { isResolvedUri, toAbsoluteURI } from '@webex/ladon-ts';\n\n/**\n * Helper to strip query params.\n *\n * @param url - The URL to strip query params from.\n * @returns The URL without query params.\n */\nfunction stripQueryParams(url: string): string {\n try {\n const u = new URL(url);\n u.search = '';\n return u.toString();\n } catch {\n return url;\n }\n}\n\n/**\n * Fetches a JavaScript module from the given URL, caches it in the 'ladon-cache' \n * Cache API if the URL is HTTP(S), and returns a Blob URL for use with APIs.\n * \n * @param url - The URL of the JavaScript module to fetch.\n * @returns A promise that resolves to a Blob URL for the fetched module.\n */\nexport async function loadAndCacheFile(fileUrl: string): Promise<ArrayBufferLike | Uint8Array> {\n const cache = await caches.open('ladon-cache');\n\n // Normalize the URL by stripping query parameters\n const normalizedUrl = stripQueryParams(fileUrl);\n\n // Try to get the file from cache using its full URL\n const cachedResponse = await cache.match(normalizedUrl);\n if (cachedResponse) {\n return cachedResponse.arrayBuffer();\n }\n\n // If not in cache, fetch and cache the file\n const response = await fetch(fileUrl);\n\n // Ensure the response is valid\n if (!response.ok) {\n throw new Error(`Failed to fetch file: ${fileUrl}`);\n }\n\n const contentType = response.headers.get('Content-Type') || 'binary/octet-stream';\n\n // Validate expected MIME types\n if (!contentType.includes('application/wasm') && !contentType.includes('binary/octet-stream')) {\n throw new Error(`Unexpected MIME type: ${contentType} for ${normalizedUrl}`);\n }\n\n const fileBinary = await response.arrayBuffer();\n\n // Cache the response with proper headers\n const cachedResponseWithHeaders = new Response(fileBinary, {\n headers: {\n 'Content-Type': contentType,\n 'Content-Length': fileBinary.byteLength.toString(),\n },\n });\n\n // Store the response in the cache using the full URL as the key\n await cache.put(normalizedUrl, cachedResponseWithHeaders);\n\n return fileBinary;\n}\n","import * as ort from 'onnxruntime-web';\nimport { PreloadConfig, ResolutionConfig, resourceLoader } from '@webex/ladon-ts';\n\nimport { loadAndCacheFile } from './util';\n\n// There is only a single WASM file for all WebAssembly binaries now.\nconst ONNX_WASM_FILENAME = 'ort-wasm-simd-threaded.wasm';\n\n/**\n * Resource manager used to load resources for the segmentation worker.\n */\nexport class ModelManager {\n private modelSessions: Record<string, ort.InferenceSession> = {};\n\n /**\n * Load the model using the provided configuration. This gets called by the worker when using\n * the worker generator.\n *\n * @param config - The configuration object.\n * @returns A promise that resolves when the model is preloaded.\n */\n public async loadModel(config: PreloadConfig) {\n const { mask, executionProviders: providers } = config;\n\n // Lock to a single thread to avoid performance issues.\n ort.env.wasm.numThreads = 1;\n\n // Get the resolved paths for the WASM binary.\n const wasmPaths = await resourceLoader.resolveUri(config, config.wasmUri);\n\n if (wasmPaths) {\n try {\n ort.env.wasm.wasmBinary = await loadAndCacheFile(wasmPaths + ONNX_WASM_FILENAME);\n } catch (error) {\n console.warn('Failed to load or cache WASM file. Using WASM paths.', error);\n ort.env.wasm.wasmPaths = wasmPaths;\n }\n }\n\n // Resolve the model URL.\n const modelUrl = await resourceLoader.resolveUri(config, mask.modelUri);\n let modelSession = this.modelSessions[modelUrl];\n\n // If the model session is not already cached, create a new session and cache.\n if (!modelSession) {\n // Allows the user to specify the execution providers to use. The default is the WASM provider.\n // TODO: Add and test support for other execution providers.\n const executionProviders = providers?.length ? providers : ['wasm'];\n const sessionOptions = { executionProviders };\n\n // First try to get the model binary either from cache or by fetching and caching it.\n // If that fails, fall back to the model URL.\n try {\n const modelBinary = await loadAndCacheFile(modelUrl);\n modelSession = await ort.InferenceSession.create(modelBinary, sessionOptions);\n } catch (error) {\n console.warn('Failed to load or cache model file. Using model URL.', error);\n modelSession = await ort.InferenceSession.create(modelUrl, sessionOptions);\n }\n }\n\n // Cache the model session.\n this.modelSessions[modelUrl] = modelSession;\n\n // Warmup the model with a dummy input to avoid latency when running the model for the first time.\n await this.warmupModel(modelSession, mask.inputSize, mask.modelRank);\n\n return modelSession;\n }\n\n /**\n * Warmup the model session with a dummy input to avoid latency when running the model for the first time.\n *\n * @param {ort.InferenceSession} session The model session.\n * @param {ResolutionConfig} inputSize The input size of the model.\n * @param {number} inputChannels The number of input channels (e.g., RGB is 3).\n * @param {ort.Tensor.Type} inputType The input tensor type.\n * @returns {Promise<void>} A promise that resolves when the model is warmed up.\n * @example\n * await warmupModel(session, inputSize, inputChannels, inputType);\n */\n public async warmupModel(\n session: ort.InferenceSession,\n inputSize: ResolutionConfig = { width: 1280, height: 720 },\n inputChannels = 3,\n inputType: ort.Tensor.Type = 'float32'\n ): Promise<void> {\n const numPixels = inputSize.height * inputSize.width;\n const dummyInputData = new Float32Array(inputChannels * numPixels).fill(0);\n const dummyInput = new ort.Tensor(inputType, dummyInputData, [\n 1,\n inputChannels,\n inputSize.height,\n inputSize.width,\n ]);\n const feed = { [session.inputNames[0]]: dummyInput };\n\n // Use an additional dummy tensor if the model expects a previous mask.\n if (inputChannels === 3) {\n const dummyMaskData = new Float32Array(numPixels).fill(0);\n const prevMaskTensor = new ort.Tensor(inputType, dummyMaskData, [\n 1,\n 1,\n inputSize.height,\n inputSize.width,\n ]);\n feed[session.inputNames[1]] = prevMaskTensor;\n }\n\n // Run the model with the dummy input to warm it up.\n await session.run(feed);\n }\n\n /**\n * Get the model session for the provided model URL.\n *\n * @param {string} modelUrl The model URL.\n * @returns {ort.InferenceSession} The model session.\n * @example\n * const session = getModelSession(modelUrl);\n */\n public getModelSession(modelUrl: string) {\n return this.modelSessions[modelUrl];\n }\n\n /**\n * Clear the model sessions cache.\n *\n * @example\n * modelManager.destroyModel();\n */\n public async destroyModel(modelUrl: string) {\n const session = this.modelSessions[modelUrl];\n if (session) {\n await session.release();\n delete this.modelSessions[modelUrl];\n }\n }\n \n}\n\nexport const modelManager = new ModelManager();","import * as ort from 'onnxruntime-web';\n\nimport { LadonOutput, MaskGenerator, PipelineConfig, resourceLoader } from '@webex/ladon-ts';\n\nimport { modelManager } from './model-manager';\n\nexport class LadonGenerator implements MaskGenerator {\n private lastResult: LadonOutput;\n private lastMask: ort.Tensor;\n private maskModel?: ort.InferenceSession;\n private lastMaskGenerationTime = 0;\n private output?: Float32Array;\n private modelUrl?: string;\n\n constructor(public readonly config: PipelineConfig) {\n const { height, width } = this.config.mask.outputSize;\n this.lastMask = new ort.Tensor('float32', new Float32Array(height * width), [\n 1,\n 1,\n height,\n width,\n ]);\n this.lastResult = {\n data: this.lastMask.data,\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n timestamp: 0,\n warm: false,\n };\n }\n\n public isLoaded(): boolean {\n return !!this.maskModel;\n }\n\n /**\n * This method preprocesses an input Uint8ClampedArray to a Float32Array\n * while maintaining memory efficiency by reusing a class-scoped output buffer.\n * If the model rank is 4 (e.g., newer tiny model), it sets an alpha channel value.\n *\n * @param {Uint8ClampedArray} input - The input data to be preprocessed\n * @param {Float32Array} alpha - The alpha channel data\n * @returns {Float32Array} - The processed data\n */\n private preprocess(input: Uint8ClampedArray, alpha: Float32Array): Float32Array {\n const { modelRank, inputSize, outputSize } = this.config.mask;\n const { height, width } = inputSize;\n const numImagePixels = height * width;\n\n // Initialize the output buffer if it is not already set\n this.output ??= new Float32Array(numImagePixels * modelRank);\n\n const numInputPixels = input.length / 4; // Divide by 4 for RGBA\n\n // Directly copy channels (assumes fixed order like BGR or RGB)\n for (let channel = 0; channel < 3; channel++) {\n for (let pixel = 0; pixel < numInputPixels; pixel++) {\n // Map input channels directly to output\n this.output[pixel + channel * numImagePixels] = input[pixel * 4 + (2 - channel)];\n }\n }\n\n // Scaling factors for width and height\n const widthScale = outputSize.width / width;\n const heightScale = outputSize.height / height;\n\n // Process alpha channel\n for (let x = 0; x < width; x++) {\n const nearestNeighborX = Math.floor(x * widthScale);\n for (let y = 0; y < height; y++) {\n const nearestNeighborY = Math.floor(y * heightScale);\n const maskIdx = nearestNeighborX + nearestNeighborY * outputSize.width;\n const outputIdx = x + y * width + 3 * numImagePixels;\n\n // Normalize and scale alpha to [0, 255]\n const normalizedValue = Math.min(Math.max(alpha[maskIdx], 0), 255);\n this.output[outputIdx] = normalizedValue;\n }\n }\n\n return this.output;\n }\n\n public getTimeSinceLastGeneration(): number {\n return Date.now() - this.lastMaskGenerationTime;\n }\n\n public async getLadonOutput(input: Uint8ClampedArray, timestamp: number): Promise<LadonOutput> {\n if (!this.maskModel) {\n throw new Error('[ladon-ts] Mask model not loaded.');\n }\n\n if (this.getTimeSinceLastGeneration() < this.config.mask.generationIntervalMs) {\n return {\n data: this.lastMask.data,\n facesAndLandmarks: this.lastResult.facesAndLandmarks,\n gesture: this.lastResult.gesture,\n motion: this.lastResult.motion,\n warm: false,\n timestamp,\n };\n }\n\n this.lastMaskGenerationTime = Date.now();\n\n const imageTensor = new ort.Tensor('float32', this.preprocess(input, this.lastMask.data), [\n 1,\n this.config.mask.modelRank,\n this.config.mask.inputSize.height,\n this.config.mask.inputSize.width,\n ]);\n\n const results = await this.maskModel.run({ input: imageTensor });\n this.lastMask = results.segmentation;\n\n this.lastResult = {\n data: this.lastMask.data ?? new Float32Array(0),\n facesAndLandmarks: {\n data: results.faces_and_landmarks?.data ?? new Float32Array(0),\n dims: results.faces_and_landmarks?.dims ?? ([] as readonly number[]),\n },\n gesture: results.gesture?.data ?? new Float32Array(0),\n motion: results.motion?.data[0] ?? 0,\n timestamp,\n warm: true,\n };\n\n return this.lastResult;\n }\n\n async load() {\n this.modelUrl = await resourceLoader.resolveUri(this.config, this.config.mask.modelUri);\n\n // Attempt to retrieve a preloaded InferenceSession from the shared resource manager.\n this.maskModel = modelManager.getModelSession(this.modelUrl);\n // If the model is not preloaded, load it from the provided model URL.\n this.maskModel ??= await modelManager.loadModel(this.config);\n\n if (!this.maskModel) {\n throw new Error('Failed to load the ONNX model.');\n }\n }\n\n public async postRender(): Promise<void> {\n // empty for local generator\n }\n\n /**\n * Destroys the model session and releases resources.\n * This method should be called when the generator is no longer needed.\n *\n * @returns A promise that resolves when the model is destroyed.\n */\n public async destroy(): Promise<void> {\n if (!this.modelUrl) {\n throw new Error('[ladon-ts] Generator teardown failed. Model URL is not defined.');\n }\n\n // Clear the model session from the cache.\n await modelManager.destroyModel(this.modelUrl);\n\n // Release the model session.\n this.modelUrl = undefined;\n this.maskModel = undefined;\n this.output = undefined;\n }\n}\n","import './shim';\nimport './console-overrides';\n\nimport { PipelineConfig, PreloadConfig } from '@webex/ladon-ts';\n\nimport { LadonGenerator } from './ladon-generator';\nimport { modelManager } from './model-manager';\n\n\nconst MAX_QUEUE_SIZE = 3;\nconst queue: { image: Uint8ClampedArray; timestamp: number }[] = [];\n\nlet preloadPromise: Promise<void> | null = null;\nlet generator: LadonGenerator;\nlet processing = false;\n\n\nasync function processQueue() {\n if (processing) return;\n processing = true;\n while (queue.length > 0) {\n const { image, timestamp } = queue.shift()!;\n await handleGenerate(image, timestamp);\n }\n setTimeout(() => {\n processing = false;\n }, 0);\n}\n\n\n// Message handler for worker\nself.addEventListener('message', async (event) => {\n const { type, config, image, timestamp } = event.data;\n\n try {\n switch (type) {\n case 'preload':\n if (config) {\n preloadPromise = handlePreload(config as PreloadConfig);\n await preloadPromise;\n }\n break;\n\n case 'init':\n if (config) {\n // Wait for preload to complete before initializing\n if (preloadPromise) {\n await preloadPromise;\n }\n await handleInit(config as PipelineConfig);\n }\n break;\n\n case 'generate':\n if (image) {\n if (queue.length >= MAX_QUEUE_SIZE) {\n // Drop the oldest frame and notify main thread\n const dropped = queue.shift();\n if (dropped) {\n postMessage({\n facesAndLandmarks: null,\n gesture: null,\n mask: null,\n motion: null,\n timestamp: dropped.timestamp,\n status: 'dropped',\n warm: false,\n });\n }\n }\n queue.push({ image, timestamp });\n processQueue();\n }\n break;\n\n case 'destroy':\n await handleDestroy();\n break;\n\n default:\n console.warn(\n `[ladon-ts] Worker generator recieved unknown message: ${JSON.stringify(\n event.data\n )}`\n );\n }\n } catch (error) {\n console.error(`[ladon-ts] Worker generator error handling message: ${error}`);\n postMessage({ status: 'error', error: error.message });\n }\n});\n\n// Handle preload event\nasync function handlePreload(config: PreloadConfig): Promise<void> {\n await modelManager.loadModel(config);\n postMessage({ status: 'preloaded' });\n}\n\n// Handle initialization\nasync function handleInit(config: PipelineConfig): Promise<void> {\n generator = new LadonGenerator(config);\n await generator.load();\n postMessage({ status: 'initialized' });\n}\n\n// Handle generate event with SharedArrayBuffer support\nasync function handleGenerate(image: Uint8ClampedArray | null, timestamp: number): Promise<void> {\n if (!generator || !generator.isLoaded()) {\n console.warn('[ladon-ts] Generator is not initialized');\n return;\n }\n\n if (!image) {\n console.warn('[ladon-ts] No valid input provided for generation');\n return;\n }\n\n // Run generator\n const maskResult = await generator.getLadonOutput(image, timestamp);\n\n postMessage({\n facesAndLandmarks: maskResult.facesAndLandmarks,\n gesture: maskResult.gesture,\n mask: maskResult.data, // Transfer mask directly if TypedArray\n motion: maskResult.motion,\n timestamp: maskResult.timestamp,\n status: 'generated',\n warm: maskResult.warm,\n });\n}\n\n// Handle destroy event\nasync function handleDestroy(): Promise<void> {\n if (generator) {\n await generator.destroy();\n } else {\n console.warn('[ladon-ts] No generator to destroy');\n }\n postMessage({ status: 'destroyed' });\n}\n"],"names":["args","o","e","r","l","s","d","url","u","fileUrl","cache","normalizedUrl","cachedResponse","response","contentType","fileBinary","cachedResponseWithHeaders","config","mask","providers","ort.env","wasmPaths","resourceLoader","error","modelUrl","modelSession","sessionOptions","modelBinary","ort.InferenceSession","session","inputSize","inputChannels","inputType","numPixels","dummyInputData","dummyInput","ort.Tensor","feed","dummyMaskData","prevMaskTensor","height","width","input","alpha","modelRank","outputSize","numImagePixels","numInputPixels","channel","pixel","widthScale","heightScale","x","nearestNeighborX","y","nearestNeighborY","maskIdx","outputIdx","normalizedValue","timestamp","imageTensor","results","_a","_b","_c","_d","image","event","type","dropped","maskResult"],"mappings":"oGAQC,KAAK,SAAoB,CACtB,QAAS,SAAS,MACtB,ECNA,MAAM,mBAAqB,QAAQ,IAC7B,oBAAsB,QAAQ,KAC9B,qBAAuB,QAAQ,MAErC,QAAQ,IAAM,IAAIA,IAAS,CACX,YAAA,CAAE,KAAM,MAAO,QAASA,EAAK,KAAK,GAAG,EAAG,SAAU,MAAO,EACrE,mBAAmB,GAAGA,CAAI,CAC9B,EAEA,QAAQ,KAAO,IAAIA,IAAS,CACZ,YAAA,CAAE,KAAM,MAAO,QAASA,EAAK,KAAK,GAAG,EAAG,SAAU,OAAQ,EACtE,oBAAoB,GAAGA,CAAI,CAC/B,EAEA,QAAQ,MAAQ,IAAIA,IAAS,CACb,YAAA,CAAE,KAAM,MAAO,QAASA,EAAK,KAAK,GAAG,EAAG,SAAU,QAAS,EACvE,qBAAqB,GAAGA,CAAI,CAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MCkDA,SAAS,EAAEC,EAAG,CACZ,GAAIA,EAAE,WAAW,OAAO,EACtB,MAAO,GACT,GAAI,CACF,OAAO,IAAI,IAAIA,CAAC,EAAG,EACvB,MAAU,CACN,MAAO,EACX,CACA,CACA,MAAM,EAAI,CAACA,EAAG,IAAM,CAAC,GAAKA,EAAE,WAAW,MAAM,EAAI,IAAI,IAAIA,CAAC,EAAE,KAAOA,EAAI,EAAE,QAAQ,OAAQ,EAAE,EAAI,IAAMA,EAAE,QAAQ,OAAQ,EAAE,EAAI,EC/E7H,MAAM,CAAE,CACN,aAAc,CACZ,KAAK,iBAAmC,IAAI,GAChD,CAYE,MAAM,WAAWA,EAAGC,EAAG,CACrB,GAAI,CAACA,EACH,MAAM,IAAI,MAAM,yBAAyB,EAC3C,GAAI,KAAK,iBAAiB,IAAIA,CAAC,EAC7B,OAAO,KAAK,iBAAiB,IAAIA,CAAC,EACpC,IAAIC,EACJ,GAAIC,EAAEF,CAAC,EAAIC,EAAID,EAAIA,EAAE,MAAM,eAAe,EAAI,OAAOD,EAAE,kBAAoB,aAAeE,EAAI,MAAMF,EAAE,iBAAiBC,EAAGD,CAAC,GAAKE,EAAIE,EAAEH,EAAGD,EAAE,OAAO,EAAG,CAACE,EACpJ,MAAM,IAAI,MAAM,gCAAgCD,CAAC,EAAE,EACrD,OAAO,KAAK,iBAAiB,IAAIA,EAAGC,CAAC,EAAGA,CAC5C,CACA,CACA,MAAMG,IAAI,IAAI,ECnBd,SAAS,iBAAiBC,EAAqB,CACvC,GAAA,CACM,MAAAC,EAAI,IAAI,IAAID,CAAG,EACrB,OAAAC,EAAE,OAAS,GACJA,EAAE,SAAS,CAAA,MACd,CACG,OAAAD,CAAA,CAEf,CASA,eAAsB,iBAAiBE,EAAwD,CAC3F,MAAMC,EAAQ,MAAM,OAAO,KAAK,aAAa,EAGvCC,EAAgB,iBAAiBF,CAAO,EAGxCG,EAAiB,MAAMF,EAAM,MAAMC,CAAa,EACtD,GAAIC,EACA,OAAOA,EAAe,YAAY,EAIhC,MAAAC,EAAW,MAAM,MAAMJ,CAAO,EAGhC,GAAA,CAACI,EAAS,GACV,MAAM,IAAI,MAAM,yBAAyBJ,CAAO,EAAE,EAGtD,MAAMK,EAAcD,EAAS,QAAQ,IAAI,cAAc,GAAK,sBAGxD,GAAA,CAACC,EAAY,SAAS,kBAAkB,GAAK,CAACA,EAAY,SAAS,qBAAqB,EACxF,MAAM,IAAI,MAAM,yBAAyBA,CAAW,QAAQH,CAAa,EAAE,EAGzE,MAAAI,EAAa,MAAMF,EAAS,YAAY,EAGxCG,EAA4B,IAAI,SAASD,EAAY,CACvD,QAAS,CACL,eAAgBD,EAChB,iBAAkBC,EAAW,WAAW,SAAS,CAAA,CACrD,CACH,EAGK,aAAAL,EAAM,IAAIC,EAAeK,CAAyB,EAEjDD,CACX,CC5DA,MAAM,mBAAqB,8BAKpB,MAAM,YAAa,CAAnB,aAAA,CACH,KAAQ,cAAsD,CAAC,CAAA,CAS/D,MAAa,UAAUE,EAAuB,CAC1C,KAAM,CAAE,KAAAC,EAAM,mBAAoBC,CAAc,EAAAF,EAG5CG,EAAI,KAAK,WAAa,EAG1B,MAAMC,EAAY,MAAMC,IAAe,WAAWL,EAAQA,EAAO,OAAO,EAExE,GAAII,EACI,GAAA,CACAD,EAAQ,KAAK,WAAa,MAAM,iBAAiBC,EAAY,kBAAkB,QAC1EE,EAAO,CACJ,QAAA,KAAK,uDAAwDA,CAAK,EACtEH,EAAI,KAAK,UAAYC,CAAA,CAKjC,MAAMG,EAAW,MAAMF,IAAe,WAAWL,EAAQC,EAAK,QAAQ,EAClE,IAAAO,EAAe,KAAK,cAAcD,CAAQ,EAG9C,GAAI,CAACC,EAAc,CAIT,MAAAC,EAAiB,CAAE,mBADEP,GAAA,MAAAA,EAAW,OAASA,EAAY,CAAC,MAAM,CACtB,EAIxC,GAAA,CACM,MAAAQ,EAAc,MAAM,iBAAiBH,CAAQ,EACnDC,EAAe,MAAMG,GAAqB,OAAOD,EAAaD,CAAc,QACvEH,EAAO,CACJ,QAAA,KAAK,uDAAwDA,CAAK,EAC1EE,EAAe,MAAMG,GAAqB,OAAOJ,EAAUE,CAAc,CAAA,CAC7E,CAIC,YAAA,cAAcF,CAAQ,EAAIC,EAG/B,MAAM,KAAK,YAAYA,EAAcP,EAAK,UAAWA,EAAK,SAAS,EAE5DO,CAAA,CAcX,MAAa,YACTI,EACAC,EAA8B,CAAE,MAAO,KAAM,OAAQ,GAAI,EACzDC,EAAgB,EAChBC,EAA6B,UAChB,CACP,MAAAC,EAAYH,EAAU,OAASA,EAAU,MACzCI,EAAiB,IAAI,aAAaH,EAAgBE,CAAS,EAAE,KAAK,CAAC,EACnEE,EAAa,IAAIC,GAAWJ,EAAWE,EAAgB,CACzD,EACAH,EACAD,EAAU,OACVA,EAAU,KAAA,CACb,EACKO,EAAO,CAAE,CAACR,EAAQ,WAAW,CAAC,CAAC,EAAGM,CAAW,EAGnD,GAAIJ,IAAkB,EAAG,CACrB,MAAMO,EAAgB,IAAI,aAAaL,CAAS,EAAE,KAAK,CAAC,EAClDM,EAAiB,IAAIH,GAAWJ,EAAWM,EAAe,CAC5D,EACA,EACAR,EAAU,OACVA,EAAU,KAAA,CACb,EACDO,EAAKR,EAAQ,WAAW,CAAC,CAAC,EAAIU,CAAA,CAI5B,MAAAV,EAAQ,IAAIQ,CAAI,CAAA,CAWnB,gBAAgBb,EAAkB,CAC9B,OAAA,KAAK,cAAcA,CAAQ,CAAA,CAStC,MAAa,aAAaA,EAAkB,CAClC,MAAAK,EAAU,KAAK,cAAcL,CAAQ,EACvCK,IACA,MAAMA,EAAQ,QAAQ,EACf,OAAA,KAAK,cAAcL,CAAQ,EACtC,CAGR,CAEa,MAAA,aAAe,IAAI,aCvIzB,MAAM,cAAwC,CAQjD,YAA4BP,EAAwB,CAAxB,KAAA,OAAAA,EAJ5B,KAAQ,uBAAyB,EAK7B,KAAM,CAAE,OAAAuB,EAAQ,MAAAC,CAAA,EAAU,KAAK,OAAO,KAAK,WACtC,KAAA,SAAW,IAAIL,GAAW,UAAW,IAAI,aAAaI,EAASC,CAAK,EAAG,CACxE,EACA,EACAD,EACAC,CAAA,CACH,EACD,KAAK,WAAa,CACd,KAAM,KAAK,SAAS,KACpB,kBAAmB,CAAE,KAAM,IAAI,aAAa,CAAC,EAAG,KAAM,EAAG,EACzD,QAAS,IAAI,aAAa,CAAC,EAC3B,OAAQ,EACR,UAAW,EACX,KAAM,EACV,CAAA,CAGG,UAAoB,CAChB,MAAA,CAAC,CAAC,KAAK,SAAA,CAYV,WAAWC,EAA0BC,EAAmC,CAC5E,KAAM,CAAE,UAAAC,EAAW,UAAAd,EAAW,WAAAe,CAAW,EAAI,KAAK,OAAO,KACnD,CAAE,OAAAL,EAAQ,MAAAC,CAAA,EAAUX,EACpBgB,EAAiBN,EAASC,EAGhC,KAAK,SAAL,KAAK,OAAW,IAAI,aAAaK,EAAiBF,CAAS,GAErD,MAAAG,EAAiBL,EAAM,OAAS,EAGtC,QAASM,EAAU,EAAGA,EAAU,EAAGA,IAC/B,QAASC,EAAQ,EAAGA,EAAQF,EAAgBE,IAEnC,KAAA,OAAOA,EAAQD,EAAUF,CAAc,EAAIJ,EAAMO,EAAQ,GAAK,EAAID,EAAQ,EAKjF,MAAAE,EAAaL,EAAW,MAAQJ,EAChCU,EAAcN,EAAW,OAASL,EAGxC,QAASY,EAAI,EAAGA,EAAIX,EAAOW,IAAK,CAC5B,MAAMC,EAAmB,KAAK,MAAMD,EAAIF,CAAU,EAClD,QAASI,EAAI,EAAGA,EAAId,EAAQc,IAAK,CAC7B,MAAMC,EAAmB,KAAK,MAAMD,EAAIH,CAAW,EAC7CK,EAAUH,EAAmBE,EAAmBV,EAAW,MAC3DY,EAAYL,EAAIE,EAAIb,EAAQ,EAAIK,EAGhCY,EAAkB,KAAK,IAAI,KAAK,IAAIf,EAAMa,CAAO,EAAG,CAAC,EAAG,GAAG,EAC5D,KAAA,OAAOC,CAAS,EAAIC,CAAA,CAC7B,CAGJ,OAAO,KAAK,MAAA,CAGT,4BAAqC,CACjC,OAAA,KAAK,MAAQ,KAAK,sBAAA,CAG7B,MAAa,eAAehB,EAA0BiB,EAAyC,aACvF,GAAA,CAAC,KAAK,UACA,MAAA,IAAI,MAAM,mCAAmC,EAGvD,GAAI,KAAK,2BAA2B,EAAI,KAAK,OAAO,KAAK,qBAC9C,MAAA,CACH,KAAM,KAAK,SAAS,KACpB,kBAAmB,KAAK,WAAW,kBACnC,QAAS,KAAK,WAAW,QACzB,OAAQ,KAAK,WAAW,OACxB,KAAM,GACN,UAAAA,CACJ,EAGC,KAAA,uBAAyB,KAAK,IAAI,EAEjC,MAAAC,EAAc,IAAIxB,GAAW,UAAW,KAAK,WAAWM,EAAO,KAAK,SAAS,IAAI,EAAG,CACtF,EACA,KAAK,OAAO,KAAK,UACjB,KAAK,OAAO,KAAK,UAAU,OAC3B,KAAK,OAAO,KAAK,UAAU,KAAA,CAC9B,EAEKmB,EAAU,MAAM,KAAK,UAAU,IAAI,CAAE,MAAOD,EAAa,EAC/D,YAAK,SAAWC,EAAQ,aAExB,KAAK,WAAa,CACd,KAAM,KAAK,SAAS,MAAQ,IAAI,aAAa,CAAC,EAC9C,kBAAmB,CACf,OAAMC,EAAAD,EAAQ,sBAAR,YAAAC,EAA6B,OAAQ,IAAI,aAAa,CAAC,EAC7D,OAAMC,EAAAF,EAAQ,sBAAR,YAAAE,EAA6B,OAAS,CAAA,CAChD,EACA,UAASC,EAAAH,EAAQ,UAAR,YAAAG,EAAiB,OAAQ,IAAI,aAAa,CAAC,EACpD,SAAQC,EAAAJ,EAAQ,SAAR,YAAAI,EAAgB,KAAK,KAAM,EACnC,UAAAN,EACA,KAAM,EACV,EAEO,KAAK,UAAA,CAGhB,MAAM,MAAO,CAQL,GAPC,KAAA,SAAW,MAAMrC,IAAe,WAAW,KAAK,OAAQ,KAAK,OAAO,KAAK,QAAQ,EAGtF,KAAK,UAAY,aAAa,gBAAgB,KAAK,QAAQ,EAE3D,KAAK,YAAL,KAAK,UAAc,MAAM,aAAa,UAAU,KAAK,MAAM,GAEvD,CAAC,KAAK,UACA,MAAA,IAAI,MAAM,gCAAgC,CACpD,CAGJ,MAAa,YAA4B,CAAA,CAUzC,MAAa,SAAyB,CAC9B,GAAA,CAAC,KAAK,SACA,MAAA,IAAI,MAAM,iEAAiE,EAI/E,MAAA,aAAa,aAAa,KAAK,QAAQ,EAG7C,KAAK,SAAW,OAChB,KAAK,UAAY,OACjB,KAAK,OAAS,MAAA,CAEtB,CC9JA,MAAM,eAAiB,EACjB,MAA2D,CAAC,EAElE,IAAI,eAAuC,KACvC,UACA,WAAa,GAGjB,eAAe,cAAe,CAC1B,GAAI,YAEG,KADM,WAAA,GACN,MAAM,OAAS,GAAG,CACrB,KAAM,CAAE,MAAA4C,EAAO,UAAAP,GAAc,MAAM,MAAM,EACnC,MAAA,eAAeO,EAAOP,CAAS,CAAA,CAEzC,WAAW,IAAM,CACA,WAAA,IACd,CAAC,EACR,CAIA,KAAK,iBAAiB,UAAW,MAAOQ,GAAU,CAC9C,KAAM,CAAE,KAAAC,EAAM,OAAAnD,EAAQ,MAAAiD,EAAO,UAAAP,CAAA,EAAcQ,EAAM,KAE7C,GAAA,CACA,OAAQC,EAAM,CACV,IAAK,UACGnD,IACA,eAAiB,cAAcA,CAAuB,EAChD,MAAA,gBAEV,MAEJ,IAAK,OACGA,IAEI,gBACM,MAAA,eAEV,MAAM,WAAWA,CAAwB,GAE7C,MAEJ,IAAK,WACD,GAAIiD,EAAO,CACH,GAAA,MAAM,QAAU,eAAgB,CAE1B,MAAAG,EAAU,MAAM,MAAM,EACxBA,GACY,YAAA,CACR,kBAAmB,KACnB,QAAS,KACT,KAAM,KACN,OAAQ,KACR,UAAWA,EAAQ,UACnB,OAAQ,UACR,KAAM,EAAA,CACT,CACL,CAEJ,MAAM,KAAK,CAAE,MAAAH,EAAO,UAAAP,CAAA,CAAW,EAClB,aAAA,CAAA,CAEjB,MAEJ,IAAK,UACD,MAAM,cAAc,EACpB,MAEJ,QACY,QAAA,KACJ,yDAAyD,KAAK,UAC1DQ,EAAM,IAAA,CACT,EACL,CAAA,QAEH5C,EAAO,CACJ,QAAA,MAAM,uDAAuDA,CAAK,EAAE,EAC5E,YAAY,CAAE,OAAQ,QAAS,MAAOA,EAAM,QAAS,CAAA,CAE7D,CAAC,EAGD,eAAe,cAAcN,EAAsC,CACzD,MAAA,aAAa,UAAUA,CAAM,EACvB,YAAA,CAAE,OAAQ,YAAa,CACvC,CAGA,eAAe,WAAWA,EAAuC,CACjD,UAAA,IAAI,eAAeA,CAAM,EACrC,MAAM,UAAU,KAAK,EACT,YAAA,CAAE,OAAQ,cAAe,CACzC,CAGA,eAAe,eAAeiD,EAAiCP,EAAkC,CAC7F,GAAI,CAAC,WAAa,CAAC,UAAU,WAAY,CACrC,QAAQ,KAAK,yCAAyC,EACtD,MAAA,CAGJ,GAAI,CAACO,EAAO,CACR,QAAQ,KAAK,mDAAmD,EAChE,MAAA,CAIJ,MAAMI,EAAa,MAAM,UAAU,eAAeJ,EAAOP,CAAS,EAEtD,YAAA,CACR,kBAAmBW,EAAW,kBAC9B,QAASA,EAAW,QACpB,KAAMA,EAAW,KACjB,OAAQA,EAAW,OACnB,UAAWA,EAAW,UACtB,OAAQ,YACR,KAAMA,EAAW,IAAA,CACpB,CACL,CAGA,eAAe,eAA+B,CACtC,UACA,MAAM,UAAU,QAAQ,EAExB,QAAQ,KAAK,oCAAoC,EAEzC,YAAA,CAAE,OAAQ,YAAa,CACvC"}
|