UNPKG

18.5 kBSource Map (JSON)View Raw
1{"version":3,"file":"VideoResource.mjs","sources":["../../../src/textures/resources/VideoResource.ts"],"sourcesContent":["import { Ticker } from '@pixi/ticker';\nimport { BaseImageResource } from './BaseImageResource';\n\nimport type { Dict } from '@pixi/utils';\n\nexport interface IVideoResourceOptions\n{\n autoLoad?: boolean;\n autoPlay?: boolean;\n updateFPS?: number;\n crossorigin?: boolean | string;\n}\n\nexport interface IVideoResourceOptionsElement\n{\n src: string;\n mime: string;\n}\n\n/**\n * Resource type for {@link HTMLVideoElement}.\n * @memberof PIXI\n */\nexport class VideoResource extends BaseImageResource\n{\n /** Override the source to be the video element. */\n public source: HTMLVideoElement;\n\n /**\n * `true` to use Ticker.shared to auto update the base texture.\n * @default true\n */\n protected _autoUpdate: boolean;\n\n /**\n * `true` if the instance is currently connected to PIXI.Ticker.shared to auto update the base texture.\n * @default false\n */\n protected _isConnectedToTicker: boolean;\n protected _updateFPS: number;\n protected _msToNextUpdate: number;\n\n /**\n * When set to true will automatically play videos used by this texture once\n * they are loaded. If false, it will not modify the playing state.\n * @default true\n */\n protected autoPlay: boolean;\n\n /**\n * Promise when loading.\n * @default null\n */\n private _load: Promise<VideoResource>;\n\n /** Callback when completed with load. */\n private _resolve: (value?: VideoResource | PromiseLike<VideoResource>) => void;\n\n /**\n * @param {HTMLVideoElement|object|string|Array<string|object>} source - Video element to use.\n * @param {object} [options] - Options to use\n * @param {boolean} [options.autoLoad=true] - Start loading the video immediately\n * @param {boolean} [options.autoPlay=true] - Start playing video immediately\n * @param {number} [options.updateFPS=0] - How many times a second to update the texture from the video.\n * Leave at 0 to update at every render.\n * @param {boolean} [options.crossorigin=true] - Load image using cross origin\n */\n constructor(\n source?: HTMLVideoElement | Array<string | IVideoResourceOptionsElement> | string, options?: IVideoResourceOptions\n )\n {\n options = options || {};\n\n if (!(source instanceof HTMLVideoElement))\n {\n const videoElement = document.createElement('video');\n\n // workaround for https://github.com/pixijs/pixijs/issues/5996\n videoElement.setAttribute('preload', 'auto');\n videoElement.setAttribute('webkit-playsinline', '');\n videoElement.setAttribute('playsinline', '');\n\n if (typeof source === 'string')\n {\n source = [source];\n }\n\n const firstSrc = (source[0] as IVideoResourceOptionsElement).src || source[0] as string;\n\n BaseImageResource.crossOrigin(videoElement, firstSrc, options.crossorigin);\n\n // array of objects or strings\n for (let i = 0; i < source.length; ++i)\n {\n const sourceElement = document.createElement('source');\n\n let { src, mime } = source[i] as IVideoResourceOptionsElement;\n\n src = src || source[i] as string;\n\n const baseSrc = src.split('?').shift().toLowerCase();\n const ext = baseSrc.slice(baseSrc.lastIndexOf('.') + 1);\n\n mime = mime || VideoResource.MIME_TYPES[ext] || `video/${ext}`;\n\n sourceElement.src = src;\n sourceElement.type = mime;\n\n videoElement.appendChild(sourceElement);\n }\n\n // Override the source\n source = videoElement;\n }\n\n super(source);\n\n this.noSubImage = true;\n\n this._autoUpdate = true;\n this._isConnectedToTicker = false;\n\n this._updateFPS = options.updateFPS || 0;\n this._msToNextUpdate = 0;\n this.autoPlay = options.autoPlay !== false;\n\n this._load = null;\n this._resolve = null;\n\n // Bind for listeners\n this._onCanPlay = this._onCanPlay.bind(this);\n this._onError = this._onError.bind(this);\n\n if (options.autoLoad !== false)\n {\n this.load();\n }\n }\n\n /**\n * Trigger updating of the texture.\n * @param _deltaTime - time delta since last tick\n */\n update(_deltaTime = 0): void\n {\n if (!this.destroyed)\n {\n // account for if video has had its playbackRate changed\n const elapsedMS = Ticker.shared.elapsedMS * (this.source as HTMLVideoElement).playbackRate;\n\n this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS);\n if (!this._updateFPS || this._msToNextUpdate <= 0)\n {\n super.update(/* deltaTime*/);\n this._msToNextUpdate = this._updateFPS ? Math.floor(1000 / this._updateFPS) : 0;\n }\n }\n }\n\n /**\n * Start preloading the video resource.\n * @returns {Promise<void>} Handle the validate event\n */\n load(): Promise<VideoResource>\n {\n if (this._load)\n {\n return this._load;\n }\n\n const source = this.source as HTMLVideoElement;\n\n if ((source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA)\n && source.width && source.height)\n {\n (source as any).complete = true;\n }\n\n source.addEventListener('play', this._onPlayStart.bind(this));\n source.addEventListener('pause', this._onPlayStop.bind(this));\n\n if (!this._isSourceReady())\n {\n source.addEventListener('canplay', this._onCanPlay);\n source.addEventListener('canplaythrough', this._onCanPlay);\n source.addEventListener('error', this._onError, true);\n }\n else\n {\n this._onCanPlay();\n }\n\n this._load = new Promise((resolve): void =>\n {\n if (this.valid)\n {\n resolve(this);\n }\n else\n {\n this._resolve = resolve;\n\n source.load();\n }\n });\n\n return this._load;\n }\n\n /**\n * Handle video error events.\n * @param event\n */\n private _onError(event: ErrorEvent): void\n {\n (this.source as HTMLVideoElement).removeEventListener('error', this._onError, true);\n this.onError.emit(event);\n }\n\n /**\n * Returns true if the underlying source is playing.\n * @returns - True if playing.\n */\n private _isSourcePlaying(): boolean\n {\n const source = this.source as HTMLVideoElement;\n\n return (!source.paused && !source.ended && this._isSourceReady());\n }\n\n /**\n * Returns true if the underlying source is ready for playing.\n * @returns - True if ready.\n */\n private _isSourceReady(): boolean\n {\n const source = this.source as HTMLVideoElement;\n\n return source.readyState > 2;\n }\n\n /** Runs the update loop when the video is ready to play. */\n private _onPlayStart(): void\n {\n // Just in case the video has not received its can play even yet..\n if (!this.valid)\n {\n this._onCanPlay();\n }\n\n if (this.autoUpdate && !this._isConnectedToTicker)\n {\n Ticker.shared.add(this.update, this);\n this._isConnectedToTicker = true;\n }\n }\n\n /** Fired when a pause event is triggered, stops the update loop. */\n private _onPlayStop(): void\n {\n if (this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.update, this);\n this._isConnectedToTicker = false;\n }\n }\n\n /** Fired when the video is loaded and ready to play. */\n private _onCanPlay(): void\n {\n const source = this.source as HTMLVideoElement;\n\n source.removeEventListener('canplay', this._onCanPlay);\n source.removeEventListener('canplaythrough', this._onCanPlay);\n\n const valid = this.valid;\n\n this.resize(source.videoWidth, source.videoHeight);\n\n // prevent multiple loaded dispatches..\n if (!valid && this._resolve)\n {\n this._resolve(this);\n this._resolve = null;\n }\n\n if (this._isSourcePlaying())\n {\n this._onPlayStart();\n }\n else if (this.autoPlay)\n {\n source.play();\n }\n }\n\n /** Destroys this texture. */\n dispose(): void\n {\n if (this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.update, this);\n this._isConnectedToTicker = false;\n }\n\n const source = this.source as HTMLVideoElement;\n\n if (source)\n {\n source.removeEventListener('error', this._onError, true);\n source.pause();\n source.src = '';\n source.load();\n }\n super.dispose();\n }\n\n /** Should the base texture automatically update itself, set to true by default. */\n get autoUpdate(): boolean\n {\n return this._autoUpdate;\n }\n\n set autoUpdate(value: boolean)\n {\n if (value !== this._autoUpdate)\n {\n this._autoUpdate = value;\n\n if (!this._autoUpdate && this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.update, this);\n this._isConnectedToTicker = false;\n }\n else if (this._autoUpdate && !this._isConnectedToTicker && this._isSourcePlaying())\n {\n Ticker.shared.add(this.update, this);\n this._isConnectedToTicker = true;\n }\n }\n }\n\n /**\n * How many times a second to update the texture from the video. Leave at 0 to update at every render.\n * A lower fps can help performance, as updating the texture at 60fps on a 30ps video may not be efficient.\n */\n get updateFPS(): number\n {\n return this._updateFPS;\n }\n\n set updateFPS(value: number)\n {\n if (value !== this._updateFPS)\n {\n this._updateFPS = value;\n }\n }\n\n /**\n * Used to auto-detect the type of resource.\n * @param {*} source - The source object\n * @param {string} extension - The extension of source, if set\n * @returns {boolean} `true` if video source\n */\n static test(source: unknown, extension?: string): source is HTMLVideoElement\n {\n return (globalThis.HTMLVideoElement && source instanceof HTMLVideoElement)\n || VideoResource.TYPES.includes(extension);\n }\n\n /**\n * List of common video file extensions supported by VideoResource.\n * @readonly\n */\n static TYPES: Array<string> = ['mp4', 'm4v', 'webm', 'ogg', 'ogv', 'h264', 'avi', 'mov'];\n\n /**\n * Map of video MIME types that can't be directly derived from file extensions.\n * @readonly\n */\n static MIME_TYPES: Dict<string> = {\n ogv: 'video/ogg',\n mov: 'video/quicktime',\n m4v: 'video/mp4',\n };\n}\n"],"names":[],"mappings":";;;AAuBO,MAAM,cAAA,GAAN,cAA4B,iBACnC,CAAA;AAAA,EA2CI,WAAA,CACI,QAAmF,OAEvF,EAAA;AACI,IAAA,OAAA,GAAU,WAAW,EAAC,CAAA;AAEtB,IAAI,IAAA,oBAAoB,gBACxB,CAAA,EAAA;AACI,MAAM,MAAA,YAAA,GAAe,QAAS,CAAA,aAAA,CAAc,OAAO,CAAA,CAAA;AAGnD,MAAa,YAAA,CAAA,YAAA,CAAa,WAAW,MAAM,CAAA,CAAA;AAC3C,MAAa,YAAA,CAAA,YAAA,CAAa,sBAAsB,EAAE,CAAA,CAAA;AAClD,MAAa,YAAA,CAAA,YAAA,CAAa,eAAe,EAAE,CAAA,CAAA;AAE3C,MAAI,IAAA,OAAO,WAAW,QACtB,EAAA;AACI,QAAA,MAAA,GAAS,CAAC,MAAM,CAAA,CAAA;AAAA,OACpB;AAEA,MAAA,MAAM,QAAY,GAAA,MAAA,CAAO,CAAoC,CAAA,CAAA,GAAA,IAAO,MAAO,CAAA,CAAA,CAAA,CAAA;AAE3E,MAAA,iBAAA,CAAkB,WAAY,CAAA,YAAA,EAAc,QAAU,EAAA,OAAA,CAAQ,WAAW,CAAA,CAAA;AAGzE,MAAA,KAAA,IAAS,IAAI,CAAG,EAAA,CAAA,GAAI,MAAO,CAAA,MAAA,EAAQ,EAAE,CACrC,EAAA;AACI,QAAM,MAAA,aAAA,GAAgB,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA,CAAA;AAErD,QAAI,IAAA,EAAE,GAAK,EAAA,IAAA,EAAA,GAAS,MAAO,CAAA,CAAA,CAAA,CAAA;AAE3B,QAAA,GAAA,GAAM,OAAO,MAAO,CAAA,CAAA,CAAA,CAAA;AAEpB,QAAA,MAAM,UAAU,GAAI,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,KAAA,GAAQ,WAAY,EAAA,CAAA;AACnD,QAAA,MAAM,MAAM,OAAQ,CAAA,KAAA,CAAM,QAAQ,WAAY,CAAA,GAAG,IAAI,CAAC,CAAA,CAAA;AAEtD,QAAA,IAAA,GAAO,IAAQ,IAAA,cAAA,CAAc,UAAW,CAAA,GAAA,CAAA,IAAQ,CAAS,MAAA,EAAA,GAAA,CAAA,CAAA,CAAA;AAEzD,QAAA,aAAA,CAAc,GAAM,GAAA,GAAA,CAAA;AACpB,QAAA,aAAA,CAAc,IAAO,GAAA,IAAA,CAAA;AAErB,QAAA,YAAA,CAAa,YAAY,aAAa,CAAA,CAAA;AAAA,OAC1C;AAGA,MAAS,MAAA,GAAA,YAAA,CAAA;AAAA,KACb;AAEA,IAAA,KAAA,CAAM,MAAM,CAAA,CAAA;AAEZ,IAAA,IAAA,CAAK,UAAa,GAAA,IAAA,CAAA;AAElB,IAAA,IAAA,CAAK,WAAc,GAAA,IAAA,CAAA;AACnB,IAAA,IAAA,CAAK,oBAAuB,GAAA,KAAA,CAAA;AAE5B,IAAK,IAAA,CAAA,UAAA,GAAa,QAAQ,SAAa,IAAA,CAAA,CAAA;AACvC,IAAA,IAAA,CAAK,eAAkB,GAAA,CAAA,CAAA;AACvB,IAAK,IAAA,CAAA,QAAA,GAAW,QAAQ,QAAa,KAAA,KAAA,CAAA;AAErC,IAAA,IAAA,CAAK,KAAQ,GAAA,IAAA,CAAA;AACb,IAAA,IAAA,CAAK,QAAW,GAAA,IAAA,CAAA;AAGhB,IAAA,IAAA,CAAK,UAAa,GAAA,IAAA,CAAK,UAAW,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAC3C,IAAA,IAAA,CAAK,QAAW,GAAA,IAAA,CAAK,QAAS,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAEvC,IAAI,IAAA,OAAA,CAAQ,aAAa,KACzB,EAAA;AACI,MAAA,IAAA,CAAK,IAAK,EAAA,CAAA;AAAA,KACd;AAAA,GACJ;AAAA,EAMA,MAAA,CAAO,aAAa,CACpB,EAAA;AACI,IAAI,IAAA,CAAC,KAAK,SACV,EAAA;AAEI,MAAA,MAAM,SAAY,GAAA,MAAA,CAAO,MAAO,CAAA,SAAA,GAAa,KAAK,MAA4B,CAAA,YAAA,CAAA;AAE9E,MAAA,IAAA,CAAK,eAAkB,GAAA,IAAA,CAAK,KAAM,CAAA,IAAA,CAAK,kBAAkB,SAAS,CAAA,CAAA;AAClE,MAAA,IAAI,CAAC,IAAA,CAAK,UAAc,IAAA,IAAA,CAAK,mBAAmB,CAChD,EAAA;AACI,QAAA,KAAA,CAAM,MAAqB,EAAA,CAAA;AAC3B,QAAK,IAAA,CAAA,eAAA,GAAkB,KAAK,UAAa,GAAA,IAAA,CAAK,MAAM,GAAO,GAAA,IAAA,CAAK,UAAU,CAAI,GAAA,CAAA,CAAA;AAAA,OAClF;AAAA,KACJ;AAAA,GACJ;AAAA,EAMA,IACA,GAAA;AACI,IAAA,IAAI,KAAK,KACT,EAAA;AACI,MAAA,OAAO,IAAK,CAAA,KAAA,CAAA;AAAA,KAChB;AAEA,IAAA,MAAM,SAAS,IAAK,CAAA,MAAA,CAAA;AAEpB,IAAK,IAAA,CAAA,MAAA,CAAO,UAAe,KAAA,MAAA,CAAO,gBAAoB,IAAA,MAAA,CAAO,UAAe,KAAA,MAAA,CAAO,gBAC5E,KAAA,MAAA,CAAO,KAAS,IAAA,MAAA,CAAO,MAC9B,EAAA;AACI,MAAC,OAAe,QAAW,GAAA,IAAA,CAAA;AAAA,KAC/B;AAEA,IAAA,MAAA,CAAO,iBAAiB,MAAQ,EAAA,IAAA,CAAK,YAAa,CAAA,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAC5D,IAAA,MAAA,CAAO,iBAAiB,OAAS,EAAA,IAAA,CAAK,WAAY,CAAA,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAE5D,IAAI,IAAA,CAAC,IAAK,CAAA,cAAA,EACV,EAAA;AACI,MAAO,MAAA,CAAA,gBAAA,CAAiB,SAAW,EAAA,IAAA,CAAK,UAAU,CAAA,CAAA;AAClD,MAAO,MAAA,CAAA,gBAAA,CAAiB,gBAAkB,EAAA,IAAA,CAAK,UAAU,CAAA,CAAA;AACzD,MAAA,MAAA,CAAO,gBAAiB,CAAA,OAAA,EAAS,IAAK,CAAA,QAAA,EAAU,IAAI,CAAA,CAAA;AAAA,KAGxD,MAAA;AACI,MAAA,IAAA,CAAK,UAAW,EAAA,CAAA;AAAA,KACpB;AAEA,IAAA,IAAA,CAAK,KAAQ,GAAA,IAAI,OAAQ,CAAA,CAAC,OAC1B,KAAA;AACI,MAAA,IAAI,KAAK,KACT,EAAA;AACI,QAAA,OAAA,CAAQ,IAAI,CAAA,CAAA;AAAA,OAGhB,MAAA;AACI,QAAA,IAAA,CAAK,QAAW,GAAA,OAAA,CAAA;AAEhB,QAAA,MAAA,CAAO,IAAK,EAAA,CAAA;AAAA,OAChB;AAAA,KACH,CAAA,CAAA;AAED,IAAA,OAAO,IAAK,CAAA,KAAA,CAAA;AAAA,GAChB;AAAA,EAMQ,SAAS,KACjB,EAAA;AACI,IAAC,KAAK,MAA4B,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,UAAU,IAAI,CAAA,CAAA;AAClF,IAAK,IAAA,CAAA,OAAA,CAAQ,KAAK,KAAK,CAAA,CAAA;AAAA,GAC3B;AAAA,EAMA,gBACA,GAAA;AACI,IAAA,MAAM,SAAS,IAAK,CAAA,MAAA,CAAA;AAEpB,IAAA,OAAQ,CAAC,MAAO,CAAA,MAAA,IAAU,CAAC,MAAO,CAAA,KAAA,IAAS,KAAK,cAAe,EAAA,CAAA;AAAA,GACnE;AAAA,EAMA,cACA,GAAA;AACI,IAAA,MAAM,SAAS,IAAK,CAAA,MAAA,CAAA;AAEpB,IAAA,OAAO,OAAO,UAAa,GAAA,CAAA,CAAA;AAAA,GAC/B;AAAA,EAGA,YACA,GAAA;AAEI,IAAI,IAAA,CAAC,KAAK,KACV,EAAA;AACI,MAAA,IAAA,CAAK,UAAW,EAAA,CAAA;AAAA,KACpB;AAEA,IAAA,IAAI,IAAK,CAAA,UAAA,IAAc,CAAC,IAAA,CAAK,oBAC7B,EAAA;AACI,MAAA,MAAA,CAAO,MAAO,CAAA,GAAA,CAAI,IAAK,CAAA,MAAA,EAAQ,IAAI,CAAA,CAAA;AACnC,MAAA,IAAA,CAAK,oBAAuB,GAAA,IAAA,CAAA;AAAA,KAChC;AAAA,GACJ;AAAA,EAGA,WACA,GAAA;AACI,IAAA,IAAI,KAAK,oBACT,EAAA;AACI,MAAA,MAAA,CAAO,MAAO,CAAA,MAAA,CAAO,IAAK,CAAA,MAAA,EAAQ,IAAI,CAAA,CAAA;AACtC,MAAA,IAAA,CAAK,oBAAuB,GAAA,KAAA,CAAA;AAAA,KAChC;AAAA,GACJ;AAAA,EAGA,UACA,GAAA;AACI,IAAA,MAAM,SAAS,IAAK,CAAA,MAAA,CAAA;AAEpB,IAAO,MAAA,CAAA,mBAAA,CAAoB,SAAW,EAAA,IAAA,CAAK,UAAU,CAAA,CAAA;AACrD,IAAO,MAAA,CAAA,mBAAA,CAAoB,gBAAkB,EAAA,IAAA,CAAK,UAAU,CAAA,CAAA;AAE5D,IAAA,MAAM,QAAQ,IAAK,CAAA,KAAA,CAAA;AAEnB,IAAA,IAAA,CAAK,MAAO,CAAA,MAAA,CAAO,UAAY,EAAA,MAAA,CAAO,WAAW,CAAA,CAAA;AAGjD,IAAI,IAAA,CAAC,KAAS,IAAA,IAAA,CAAK,QACnB,EAAA;AACI,MAAA,IAAA,CAAK,SAAS,IAAI,CAAA,CAAA;AAClB,MAAA,IAAA,CAAK,QAAW,GAAA,IAAA,CAAA;AAAA,KACpB;AAEA,IAAI,IAAA,IAAA,CAAK,kBACT,EAAA;AACI,MAAA,IAAA,CAAK,YAAa,EAAA,CAAA;AAAA,KACtB,MAAA,IACS,KAAK,QACd,EAAA;AACI,MAAA,MAAA,CAAO,IAAK,EAAA,CAAA;AAAA,KAChB;AAAA,GACJ;AAAA,EAGA,OACA,GAAA;AACI,IAAA,IAAI,KAAK,oBACT,EAAA;AACI,MAAA,MAAA,CAAO,MAAO,CAAA,MAAA,CAAO,IAAK,CAAA,MAAA,EAAQ,IAAI,CAAA,CAAA;AACtC,MAAA,IAAA,CAAK,oBAAuB,GAAA,KAAA,CAAA;AAAA,KAChC;AAEA,IAAA,MAAM,SAAS,IAAK,CAAA,MAAA,CAAA;AAEpB,IAAA,IAAI,MACJ,EAAA;AACI,MAAA,MAAA,CAAO,mBAAoB,CAAA,OAAA,EAAS,IAAK,CAAA,QAAA,EAAU,IAAI,CAAA,CAAA;AACvD,MAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AACb,MAAA,MAAA,CAAO,GAAM,GAAA,EAAA,CAAA;AACb,MAAA,MAAA,CAAO,IAAK,EAAA,CAAA;AAAA,KAChB;AACA,IAAA,KAAA,CAAM,OAAQ,EAAA,CAAA;AAAA,GAClB;AAAA,EAGA,IAAI,UACJ,GAAA;AACI,IAAA,OAAO,IAAK,CAAA,WAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,WAAW,KACf,EAAA;AACI,IAAI,IAAA,KAAA,KAAU,KAAK,WACnB,EAAA;AACI,MAAA,IAAA,CAAK,WAAc,GAAA,KAAA,CAAA;AAEnB,MAAA,IAAI,CAAC,IAAA,CAAK,WAAe,IAAA,IAAA,CAAK,oBAC9B,EAAA;AACI,QAAA,MAAA,CAAO,MAAO,CAAA,MAAA,CAAO,IAAK,CAAA,MAAA,EAAQ,IAAI,CAAA,CAAA;AACtC,QAAA,IAAA,CAAK,oBAAuB,GAAA,KAAA,CAAA;AAAA,OAChC,MAAA,IACS,KAAK,WAAe,IAAA,CAAC,KAAK,oBAAwB,IAAA,IAAA,CAAK,kBAChE,EAAA;AACI,QAAA,MAAA,CAAO,MAAO,CAAA,GAAA,CAAI,IAAK,CAAA,MAAA,EAAQ,IAAI,CAAA,CAAA;AACnC,QAAA,IAAA,CAAK,oBAAuB,GAAA,IAAA,CAAA;AAAA,OAChC;AAAA,KACJ;AAAA,GACJ;AAAA,EAMA,IAAI,SACJ,GAAA;AACI,IAAA,OAAO,IAAK,CAAA,UAAA,CAAA;AAAA,GAChB;AAAA,EAEA,IAAI,UAAU,KACd,EAAA;AACI,IAAI,IAAA,KAAA,KAAU,KAAK,UACnB,EAAA;AACI,MAAA,IAAA,CAAK,UAAa,GAAA,KAAA,CAAA;AAAA,KACtB;AAAA,GACJ;AAAA,EAQA,OAAO,IAAK,CAAA,MAAA,EAAiB,SAC7B,EAAA;AACI,IAAA,OAAQ,WAAW,gBAAoB,IAAA,MAAA,YAAkB,oBAClD,cAAc,CAAA,KAAA,CAAM,SAAS,SAAS,CAAA,CAAA;AAAA,GACjD;AAiBJ,CAAA,CAAA;AA3WO,IAAM,aAAN,GAAA,eAAA;AAgWH,aAhWS,CAgWF,KAAuB,GAAA,CAAC,KAAO,EAAA,KAAA,EAAO,QAAQ,KAAO,EAAA,KAAA,EAAO,MAAQ,EAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AAhW9E,cAsWF,UAA2B,GAAA;AAAA,EAC9B,GAAK,EAAA,WAAA;AAAA,EACL,GAAK,EAAA,iBAAA;AAAA,EACL,GAAK,EAAA,WAAA;AACT,CAAA;;;;"}
\No newline at end of file