{"version":3,"sources":["src/index.ts","src/VisibleRangePlugin.ts"],"sourcesContent":["export * from './model';\nexport { VisibleRangePlugin } from './VisibleRangePlugin';\n","import type { AutorotatePlugin } from '@photo-sphere-viewer/autorotate-plugin';\nimport type { PanoData, PluginConstructor, Position, Viewer } from '@photo-sphere-viewer/core';\nimport { AbstractConfigurablePlugin, events, utils } from '@photo-sphere-viewer/core';\nimport { MathUtils } from 'three';\nimport { Range, UpdatableVisibleRangePluginConfig, VisibleRangePluginConfig } from './model';\n\ntype RangeResult = {\n    rangedPosition: Position;\n    sidesReached: Record<'top' | 'left' | 'bottom' | 'right', boolean>;\n};\n\nconst EPS = 0.000001;\n\nconst getConfig = utils.getConfigParser<VisibleRangePluginConfig>({\n    verticalRange: null,\n    horizontalRange: null,\n    usePanoData: false,\n});\n\n/**\n * Locks the visible angles\n */\nexport class VisibleRangePlugin extends AbstractConfigurablePlugin<\n    VisibleRangePluginConfig,\n    VisibleRangePluginConfig,\n    UpdatableVisibleRangePluginConfig\n> {\n    static override readonly id = 'visible-range';\n    static override readonly VERSION = PKG_VERSION;\n    static override readonly configParser = getConfig;\n    static override readonly readonlyOptions: Array<keyof VisibleRangePluginConfig> = [\n        'horizontalRange',\n        'verticalRange',\n    ];\n\n    private autorotate?: AutorotatePlugin;\n\n    static withConfig(config: VisibleRangePluginConfig): [PluginConstructor, any] {\n        return [VisibleRangePlugin, config];\n    }\n\n    constructor(viewer: Viewer, config: VisibleRangePluginConfig) {\n        super(viewer, config);\n    }\n\n    /**\n     * @internal\n     */\n    override init() {\n        super.init();\n\n        this.autorotate = this.viewer.getPlugin('autorotate');\n\n        this.viewer.addEventListener(events.PanoramaLoadedEvent.type, this);\n        this.viewer.addEventListener(events.PositionUpdatedEvent.type, this);\n        this.viewer.addEventListener(events.ZoomUpdatedEvent.type, this);\n        this.viewer.addEventListener(events.BeforeAnimateEvent.type, this);\n        this.viewer.addEventListener(events.BeforeRotateEvent.type, this);\n\n        this.setVerticalRange(this.config.verticalRange);\n        this.setHorizontalRange(this.config.horizontalRange);\n    }\n\n    /**\n     * @internal\n     */\n    override destroy() {\n        this.viewer.removeEventListener(events.PanoramaLoadedEvent.type, this);\n        this.viewer.removeEventListener(events.PositionUpdatedEvent.type, this);\n        this.viewer.removeEventListener(events.ZoomUpdatedEvent.type, this);\n        this.viewer.removeEventListener(events.BeforeAnimateEvent.type, this);\n        this.viewer.removeEventListener(events.BeforeRotateEvent.type, this);\n\n        super.destroy();\n    }\n\n    /**\n     * @internal\n     */\n    handleEvent(e: Event) {\n        switch (e.type) {\n            case events.PanoramaLoadedEvent.type:\n                if (this.config.usePanoData) {\n                    this.setRangesFromPanoData();\n                } else {\n                    this.__moveToRange();\n                }\n                break;\n\n            case events.BeforeRotateEvent.type:\n            case events.BeforeAnimateEvent.type: {\n                const e2 = e as events.BeforeAnimateEvent;\n                const { rangedPosition, sidesReached } = this.__applyRanges(e2.position, e2.zoomLevel);\n                if (e2.position || Object.keys(sidesReached).length) {\n                    // only redefine position if initially provided or if changed\n                    e2.position = rangedPosition;\n                }\n                break;\n            }\n\n            case events.PositionUpdatedEvent.type: {\n                const currentPosition = (e as events.PositionUpdatedEvent).position;\n                const { sidesReached, rangedPosition } = this.__applyRanges(currentPosition);\n\n                if ((sidesReached.left || sidesReached.right) && this.autorotate?.isEnabled()) {\n                    this.__reverseAutorotate(sidesReached.left, sidesReached.right);\n                } else if (\n                    Math.abs(currentPosition.yaw - rangedPosition.yaw) > EPS\n                    || Math.abs(currentPosition.pitch - rangedPosition.pitch) > EPS\n                ) {\n                    this.viewer.dynamics.position.setValue(rangedPosition);\n                }\n                break;\n            }\n\n            case events.ZoomUpdatedEvent.type: {\n                const currentPosition = this.viewer.getPosition();\n                const { rangedPosition } = this.__applyRanges(currentPosition);\n\n                if (\n                    Math.abs(currentPosition.yaw - rangedPosition.yaw) > EPS\n                    || Math.abs(currentPosition.pitch - rangedPosition.pitch) > EPS\n                ) {\n                    this.viewer.dynamics.position.setValue(rangedPosition);\n                }\n                break;\n            }\n        }\n    }\n\n    /**\n     * Changes the vertical range\n     */\n    setVerticalRange(range: Range | null) {\n        // range must have two values\n        if (range && range.length !== 2) {\n            utils.logWarn('vertical range must have exactly two elements');\n            range = null;\n        }\n\n        // vertical range is between -PI/2 and PI/2\n        if (range) {\n            this.config.verticalRange = range.map(angle => utils.parseAngle(angle, true)) as any;\n\n            if (this.config.verticalRange[0] > this.config.verticalRange[1]) {\n                utils.logWarn('vertical range values must be ordered');\n                this.config.verticalRange = [this.config.verticalRange[1], this.config.verticalRange[0]] as any;\n            }\n\n            if (this.viewer.state.ready) {\n                this.__moveToRange();\n            }\n        } else {\n            this.config.verticalRange = null;\n        }\n    }\n\n    /**\n     * Changes the horizontal range\n     */\n    setHorizontalRange(range: Range | null) {\n        // horizontal range must have two values\n        if (range && range.length !== 2) {\n            utils.logWarn('horizontal range must have exactly two elements');\n            range = null;\n        }\n\n        // horizontal range is between 0 and 2*PI\n        if (range) {\n            this.config.horizontalRange = range.map(angle => utils.parseAngle(angle)) as any;\n\n            if (this.viewer.state.ready) {\n                this.__moveToRange();\n            }\n        } else {\n            this.config.horizontalRange = null;\n        }\n    }\n\n    /**\n     * Changes the ranges according the current panorama cropping data\n     */\n    setRangesFromPanoData() {\n        const panoData = this.viewer.state.textureData.panoData as PanoData;\n        if (panoData?.isEquirectangular) {\n            this.setVerticalRange(this.__getPanoVerticalRange(panoData));\n            this.setHorizontalRange(this.__getPanoHorizontalRange(panoData));\n        }\n    }\n\n    /**\n     * Gets the vertical range defined by the viewer's panoData\n     */\n    private __getPanoVerticalRange(p: PanoData): Range {\n        if (p.croppedHeight === p.fullHeight) {\n            return null;\n        } else {\n            const getAngle = (y: number) => Math.PI * (1 - y / p.fullHeight) - Math.PI / 2;\n            return [getAngle(p.croppedY + p.croppedHeight), getAngle(p.croppedY)];\n        }\n    }\n\n    /**\n     * Gets the horizontal range defined by the viewer's panoData\n     */\n    private __getPanoHorizontalRange(p: PanoData): Range {\n        if (p.croppedWidth === p.fullWidth) {\n            return null;\n        } else {\n            const getAngle = (x: number) => 2 * Math.PI * (x / p.fullWidth) - Math.PI;\n            return [getAngle(p.croppedX), getAngle(p.croppedX + p.croppedWidth)];\n        }\n    }\n\n    /**\n     * Immediately moves the viewer to respect the ranges\n     */\n    private __moveToRange() {\n        this.viewer.rotate(this.viewer.getPosition());\n    }\n\n    /**\n     * Apply \"horizontalRange\" and \"verticalRange\"\n     */\n    private __applyRanges(\n        position: Position = this.viewer.getPosition(),\n        zoomLevel: number = this.viewer.getZoomLevel(),\n    ): RangeResult {\n        const rangedPosition: Position = { yaw: position.yaw, pitch: position.pitch };\n        const sidesReached: Record<string, true> = {};\n\n        const vFov = this.viewer.dataHelper.zoomLevelToFov(zoomLevel);\n        const hFov = this.viewer.dataHelper.vFovToHFov(vFov);\n\n        if (this.config.horizontalRange) {\n            const range = utils.clone(this.config.horizontalRange) as [number, number];\n            const rangeFov = range[0] > range[1] ? range[1] + (2 * Math.PI - range[0]) : range[1] - range[0];\n\n            // for very narrow ranges, lock the horizontal angle to the center\n            if (rangeFov <= MathUtils.degToRad(hFov)) {\n                range[0] = utils.parseAngle(range[0] + rangeFov / 2);\n                range[1] = range[0];\n            } else {\n                const offset = MathUtils.degToRad(hFov) / 2;\n                range[0] = utils.parseAngle(range[0] + offset);\n                range[1] = utils.parseAngle(range[1] - offset);\n            }\n\n            if (range[0] > range[1]) {\n                // when the range cross horizontal origin\n                if (position.yaw > range[1] && position.yaw < range[0]) {\n                    if (position.yaw > range[0] / 2 + range[1] / 2) {\n                        // detect which side we are closer too\n                        rangedPosition.yaw = range[0];\n                        sidesReached.left = true;\n                    } else {\n                        rangedPosition.yaw = range[1];\n                        sidesReached.right = true;\n                    }\n                }\n            } else if (position.yaw < range[0]) {\n                rangedPosition.yaw = range[0];\n                sidesReached.left = true;\n            } else if (position.yaw > range[1]) {\n                rangedPosition.yaw = range[1];\n                sidesReached.right = true;\n            }\n        }\n\n        if (this.config.verticalRange) {\n            const range = utils.clone(this.config.verticalRange) as [number, number];\n            const rangeFov = range[1] - range[0];\n\n            // for very narrow ranges, lock the vertical angle to the center\n            if (rangeFov <= MathUtils.degToRad(vFov)) {\n                range[0] = utils.parseAngle(range[0] + rangeFov / 2, true);\n                range[1] = range[0];\n            } else {\n                const offset = MathUtils.degToRad(vFov) / 2;\n                range[0] = utils.parseAngle(range[0] + offset, true);\n                range[1] = utils.parseAngle(range[1] - offset, true);\n            }\n\n            if (position.pitch < range[0]) {\n                rangedPosition.pitch = range[0];\n                sidesReached.bottom = true;\n            } else if (position.pitch > range[1]) {\n                rangedPosition.pitch = range[1];\n                sidesReached.top = true;\n            }\n        }\n\n        return { rangedPosition, sidesReached };\n    }\n\n    /**\n     * Reverses autorotate direction with smooth transition\n     */\n    private __reverseAutorotate(left: boolean, right: boolean) {\n        // reverse already ongoing\n        if (\n            (left && this.autorotate.config.autorotateSpeed > 0)\n            || (right && this.autorotate.config.autorotateSpeed < 0)\n        ) {\n            return;\n        }\n\n        this.autorotate.reverse();\n    }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,kBAA0D;AAC1D,mBAA0B;AAQ1B,IAAM,MAAM;AAEZ,IAAM,YAAY,kBAAM,gBAA0C;AAAA,EAC9D,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,aAAa;AACjB,CAAC;AAKM,IAAM,sBAAN,MAAM,4BAA2B,uCAItC;AAAA,EAWE,OAAO,WAAW,QAA4D;AAC1E,WAAO,CAAC,qBAAoB,MAAM;AAAA,EACtC;AAAA,EAEA,YAAY,QAAgB,QAAkC;AAC1D,UAAM,QAAQ,MAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKS,OAAO;AACZ,UAAM,KAAK;AAEX,SAAK,aAAa,KAAK,OAAO,UAAU,YAAY;AAEpD,SAAK,OAAO,iBAAiB,mBAAO,oBAAoB,MAAM,IAAI;AAClE,SAAK,OAAO,iBAAiB,mBAAO,qBAAqB,MAAM,IAAI;AACnE,SAAK,OAAO,iBAAiB,mBAAO,iBAAiB,MAAM,IAAI;AAC/D,SAAK,OAAO,iBAAiB,mBAAO,mBAAmB,MAAM,IAAI;AACjE,SAAK,OAAO,iBAAiB,mBAAO,kBAAkB,MAAM,IAAI;AAEhE,SAAK,iBAAiB,KAAK,OAAO,aAAa;AAC/C,SAAK,mBAAmB,KAAK,OAAO,eAAe;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKS,UAAU;AACf,SAAK,OAAO,oBAAoB,mBAAO,oBAAoB,MAAM,IAAI;AACrE,SAAK,OAAO,oBAAoB,mBAAO,qBAAqB,MAAM,IAAI;AACtE,SAAK,OAAO,oBAAoB,mBAAO,iBAAiB,MAAM,IAAI;AAClE,SAAK,OAAO,oBAAoB,mBAAO,mBAAmB,MAAM,IAAI;AACpE,SAAK,OAAO,oBAAoB,mBAAO,kBAAkB,MAAM,IAAI;AAEnE,UAAM,QAAQ;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,GAAU;AAClB,YAAQ,EAAE,MAAM;AAAA,MACZ,KAAK,mBAAO,oBAAoB;AAC5B,YAAI,KAAK,OAAO,aAAa;AACzB,eAAK,sBAAsB;AAAA,QAC/B,OAAO;AACH,eAAK,cAAc;AAAA,QACvB;AACA;AAAA,MAEJ,KAAK,mBAAO,kBAAkB;AAAA,MAC9B,KAAK,mBAAO,mBAAmB,MAAM;AACjC,cAAM,KAAK;AACX,cAAM,EAAE,gBAAgB,aAAa,IAAI,KAAK,cAAc,GAAG,UAAU,GAAG,SAAS;AACrF,YAAI,GAAG,YAAY,OAAO,KAAK,YAAY,EAAE,QAAQ;AAEjD,aAAG,WAAW;AAAA,QAClB;AACA;AAAA,MACJ;AAAA,MAEA,KAAK,mBAAO,qBAAqB,MAAM;AACnC,cAAM,kBAAmB,EAAkC;AAC3D,cAAM,EAAE,cAAc,eAAe,IAAI,KAAK,cAAc,eAAe;AAE3E,aAAK,aAAa,QAAQ,aAAa,UAAU,KAAK,YAAY,UAAU,GAAG;AAC3E,eAAK,oBAAoB,aAAa,MAAM,aAAa,KAAK;AAAA,QAClE,WACI,KAAK,IAAI,gBAAgB,MAAM,eAAe,GAAG,IAAI,OAClD,KAAK,IAAI,gBAAgB,QAAQ,eAAe,KAAK,IAAI,KAC9D;AACE,eAAK,OAAO,SAAS,SAAS,SAAS,cAAc;AAAA,QACzD;AACA;AAAA,MACJ;AAAA,MAEA,KAAK,mBAAO,iBAAiB,MAAM;AAC/B,cAAM,kBAAkB,KAAK,OAAO,YAAY;AAChD,cAAM,EAAE,eAAe,IAAI,KAAK,cAAc,eAAe;AAE7D,YACI,KAAK,IAAI,gBAAgB,MAAM,eAAe,GAAG,IAAI,OAClD,KAAK,IAAI,gBAAgB,QAAQ,eAAe,KAAK,IAAI,KAC9D;AACE,eAAK,OAAO,SAAS,SAAS,SAAS,cAAc;AAAA,QACzD;AACA;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,OAAqB;AAElC,QAAI,SAAS,MAAM,WAAW,GAAG;AAC7B,wBAAM,QAAQ,+CAA+C;AAC7D,cAAQ;AAAA,IACZ;AAGA,QAAI,OAAO;AACP,WAAK,OAAO,gBAAgB,MAAM,IAAI,WAAS,kBAAM,WAAW,OAAO,IAAI,CAAC;AAE5E,UAAI,KAAK,OAAO,cAAc,CAAC,IAAI,KAAK,OAAO,cAAc,CAAC,GAAG;AAC7D,0BAAM,QAAQ,uCAAuC;AACrD,aAAK,OAAO,gBAAgB,CAAC,KAAK,OAAO,cAAc,CAAC,GAAG,KAAK,OAAO,cAAc,CAAC,CAAC;AAAA,MAC3F;AAEA,UAAI,KAAK,OAAO,MAAM,OAAO;AACzB,aAAK,cAAc;AAAA,MACvB;AAAA,IACJ,OAAO;AACH,WAAK,OAAO,gBAAgB;AAAA,IAChC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,OAAqB;AAEpC,QAAI,SAAS,MAAM,WAAW,GAAG;AAC7B,wBAAM,QAAQ,iDAAiD;AAC/D,cAAQ;AAAA,IACZ;AAGA,QAAI,OAAO;AACP,WAAK,OAAO,kBAAkB,MAAM,IAAI,WAAS,kBAAM,WAAW,KAAK,CAAC;AAExE,UAAI,KAAK,OAAO,MAAM,OAAO;AACzB,aAAK,cAAc;AAAA,MACvB;AAAA,IACJ,OAAO;AACH,WAAK,OAAO,kBAAkB;AAAA,IAClC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB;AACpB,UAAM,WAAW,KAAK,OAAO,MAAM,YAAY;AAC/C,QAAI,UAAU,mBAAmB;AAC7B,WAAK,iBAAiB,KAAK,uBAAuB,QAAQ,CAAC;AAC3D,WAAK,mBAAmB,KAAK,yBAAyB,QAAQ,CAAC;AAAA,IACnE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAuB,GAAoB;AAC/C,QAAI,EAAE,kBAAkB,EAAE,YAAY;AAClC,aAAO;AAAA,IACX,OAAO;AACH,YAAM,WAAW,CAAC,MAAc,KAAK,MAAM,IAAI,IAAI,EAAE,cAAc,KAAK,KAAK;AAC7E,aAAO,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,GAAG,SAAS,EAAE,QAAQ,CAAC;AAAA,IACxE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAyB,GAAoB;AACjD,QAAI,EAAE,iBAAiB,EAAE,WAAW;AAChC,aAAO;AAAA,IACX,OAAO;AACH,YAAM,WAAW,CAAC,MAAc,IAAI,KAAK,MAAM,IAAI,EAAE,aAAa,KAAK;AACvE,aAAO,CAAC,SAAS,EAAE,QAAQ,GAAG,SAAS,EAAE,WAAW,EAAE,YAAY,CAAC;AAAA,IACvE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB;AACpB,SAAK,OAAO,OAAO,KAAK,OAAO,YAAY,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKQ,cACJ,WAAqB,KAAK,OAAO,YAAY,GAC7C,YAAoB,KAAK,OAAO,aAAa,GAClC;AACX,UAAM,iBAA2B,EAAE,KAAK,SAAS,KAAK,OAAO,SAAS,MAAM;AAC5E,UAAM,eAAqC,CAAC;AAE5C,UAAM,OAAO,KAAK,OAAO,WAAW,eAAe,SAAS;AAC5D,UAAM,OAAO,KAAK,OAAO,WAAW,WAAW,IAAI;AAEnD,QAAI,KAAK,OAAO,iBAAiB;AAC7B,YAAM,QAAQ,kBAAM,MAAM,KAAK,OAAO,eAAe;AACrD,YAAM,WAAW,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC;AAG/F,UAAI,YAAY,uBAAU,SAAS,IAAI,GAAG;AACtC,cAAM,CAAC,IAAI,kBAAM,WAAW,MAAM,CAAC,IAAI,WAAW,CAAC;AACnD,cAAM,CAAC,IAAI,MAAM,CAAC;AAAA,MACtB,OAAO;AACH,cAAM,SAAS,uBAAU,SAAS,IAAI,IAAI;AAC1C,cAAM,CAAC,IAAI,kBAAM,WAAW,MAAM,CAAC,IAAI,MAAM;AAC7C,cAAM,CAAC,IAAI,kBAAM,WAAW,MAAM,CAAC,IAAI,MAAM;AAAA,MACjD;AAEA,UAAI,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG;AAErB,YAAI,SAAS,MAAM,MAAM,CAAC,KAAK,SAAS,MAAM,MAAM,CAAC,GAAG;AACpD,cAAI,SAAS,MAAM,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,GAAG;AAE5C,2BAAe,MAAM,MAAM,CAAC;AAC5B,yBAAa,OAAO;AAAA,UACxB,OAAO;AACH,2BAAe,MAAM,MAAM,CAAC;AAC5B,yBAAa,QAAQ;AAAA,UACzB;AAAA,QACJ;AAAA,MACJ,WAAW,SAAS,MAAM,MAAM,CAAC,GAAG;AAChC,uBAAe,MAAM,MAAM,CAAC;AAC5B,qBAAa,OAAO;AAAA,MACxB,WAAW,SAAS,MAAM,MAAM,CAAC,GAAG;AAChC,uBAAe,MAAM,MAAM,CAAC;AAC5B,qBAAa,QAAQ;AAAA,MACzB;AAAA,IACJ;AAEA,QAAI,KAAK,OAAO,eAAe;AAC3B,YAAM,QAAQ,kBAAM,MAAM,KAAK,OAAO,aAAa;AACnD,YAAM,WAAW,MAAM,CAAC,IAAI,MAAM,CAAC;AAGnC,UAAI,YAAY,uBAAU,SAAS,IAAI,GAAG;AACtC,cAAM,CAAC,IAAI,kBAAM,WAAW,MAAM,CAAC,IAAI,WAAW,GAAG,IAAI;AACzD,cAAM,CAAC,IAAI,MAAM,CAAC;AAAA,MACtB,OAAO;AACH,cAAM,SAAS,uBAAU,SAAS,IAAI,IAAI;AAC1C,cAAM,CAAC,IAAI,kBAAM,WAAW,MAAM,CAAC,IAAI,QAAQ,IAAI;AACnD,cAAM,CAAC,IAAI,kBAAM,WAAW,MAAM,CAAC,IAAI,QAAQ,IAAI;AAAA,MACvD;AAEA,UAAI,SAAS,QAAQ,MAAM,CAAC,GAAG;AAC3B,uBAAe,QAAQ,MAAM,CAAC;AAC9B,qBAAa,SAAS;AAAA,MAC1B,WAAW,SAAS,QAAQ,MAAM,CAAC,GAAG;AAClC,uBAAe,QAAQ,MAAM,CAAC;AAC9B,qBAAa,MAAM;AAAA,MACvB;AAAA,IACJ;AAEA,WAAO,EAAE,gBAAgB,aAAa;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,MAAe,OAAgB;AAEvD,QACK,QAAQ,KAAK,WAAW,OAAO,kBAAkB,KAC9C,SAAS,KAAK,WAAW,OAAO,kBAAkB,GACxD;AACE;AAAA,IACJ;AAEA,SAAK,WAAW,QAAQ;AAAA,EAC5B;AACJ;AA/Ra,oBAKgB,KAAK;AALrB,oBAMgB,UAAU;AAN1B,oBAOgB,eAAe;AAP/B,oBAQgB,kBAAyD;AAAA,EAC9E;AAAA,EACA;AACJ;AAXG,IAAM,qBAAN;","names":[]}