{"version":3,"file":"CanvasTextSystem.mjs","sources":["../../../../src/scene/text/canvas/CanvasTextSystem.ts"],"sourcesContent":["import { Color } from '../../../color/Color';\nimport { ExtensionType } from '../../../extensions/Extensions';\nimport { nextPow2 } from '../../../maths/misc/pow2';\nimport { CanvasPool } from '../../../rendering/renderers/shared/texture/CanvasPool';\nimport { TexturePool } from '../../../rendering/renderers/shared/texture/TexturePool';\nimport { getCanvasBoundingBox } from '../../../utils/canvas/getCanvasBoundingBox';\nimport { deprecation } from '../../../utils/logging/deprecation';\nimport { TextStyle } from '../TextStyle';\nimport { getPo2TextureFromSource } from '../utils/getPo2TextureFromSource';\nimport { CanvasTextMetrics } from './CanvasTextMetrics';\nimport { fontStringFromTextStyle } from './utils/fontStringFromTextStyle';\nimport { getCanvasFillStyle } from './utils/getCanvasFillStyle';\n\nimport type { ICanvas } from '../../../environment/canvas/ICanvas';\nimport type { ICanvasRenderingContext2D } from '../../../environment/canvas/ICanvasRenderingContext2D';\nimport type { System } from '../../../rendering/renderers/shared/system/System';\nimport type { Texture } from '../../../rendering/renderers/shared/texture/Texture';\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { TextOptions } from '../AbstractText';\nimport type { Text } from '../Text';\n\ninterface CanvasAndContext\n{\n    canvas: ICanvas;\n    context: ICanvasRenderingContext2D;\n}\n\n/**\n * System plugin to the renderer to manage canvas text.\n * @memberof rendering\n */\nexport class CanvasTextSystem implements System\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLSystem,\n            ExtensionType.WebGPUSystem,\n            ExtensionType.CanvasSystem,\n        ],\n        name: 'canvasText',\n    } as const;\n\n    private _activeTextures: Record<string, {\n        canvasAndContext: CanvasAndContext,\n        texture: Texture,\n        usageCount: number,\n    }> = {};\n\n    private readonly _renderer: Renderer;\n\n    constructor(_renderer: Renderer)\n    {\n        this._renderer = _renderer;\n    }\n\n    public getTextureSize(text: string, resolution: number, style: TextStyle): { width: number, height: number }\n    {\n        const measured = CanvasTextMetrics.measureText(text || ' ', style);\n\n        let width = Math.ceil(Math.ceil((Math.max(1, measured.width) + (style.padding * 2))) * resolution);\n        let height = Math.ceil(Math.ceil((Math.max(1, measured.height) + (style.padding * 2))) * resolution);\n\n        width = Math.ceil((width) - 1e-6);\n        height = Math.ceil((height) - 1e-6);\n        width = nextPow2(width);\n        height = nextPow2(height);\n\n        return { width, height };\n    }\n\n    /**\n     * This is a function that will create a texture from a text string, style and resolution.\n     * Useful if you want to make a texture of your text and use if for various other pixi things!\n     * @param options - The options of the text that will be used to generate the texture.\n     * @param options.text - the text to render\n     * @param options.style - the style of the text\n     * @param options.resolution - the resolution of the texture\n     * @returns the newly created texture\n     */\n    /** @deprecated since 8.0.0 */\n    public getTexture(text: string, resolution: number, style: TextStyle, textKey: string): Texture;\n    public getTexture(options: TextOptions): Texture;\n    public getTexture(options: TextOptions | string, resolution?: number, style?: TextStyle, _textKey?: string): Texture\n    {\n        if (typeof options === 'string')\n        {\n            deprecation('8.0.0', 'CanvasTextSystem.getTexture: Use object TextOptions instead of separate arguments');\n\n            options = {\n                text: options,\n                style,\n                resolution,\n            };\n        }\n\n        if (!(options.style instanceof TextStyle))\n        {\n            options.style = new TextStyle(options.style);\n        }\n\n        const { texture, canvasAndContext } = this.createTextureAndCanvas(\n            options as {text: string, style: TextStyle, resolution?: number}\n        );\n\n        this._renderer.texture.initSource(texture._source);\n\n        CanvasPool.returnCanvasAndContext(canvasAndContext);\n\n        return texture;\n    }\n\n    public createTextureAndCanvas(options: {text: string, style: TextStyle, resolution?: number})\n    {\n        const { text, style } = options;\n\n        const resolution = options.resolution ?? this._renderer.resolution;\n\n        // create a canvas with the word hello on it\n        const measured = CanvasTextMetrics.measureText(text || ' ', style);\n\n        const width = Math.ceil(Math.ceil((Math.max(1, measured.width) + (style.padding * 2))) * resolution);\n        const height = Math.ceil(Math.ceil((Math.max(1, measured.height) + (style.padding * 2))) * resolution);\n\n        const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(width, height);\n\n        // create a texture from the canvas\n        const { canvas } = canvasAndContext;\n\n        this.renderTextToCanvas(text, style, resolution, canvasAndContext);\n\n        const texture = getPo2TextureFromSource(canvas, width, height, resolution);\n\n        if (style.trim)\n        {\n            const trimmed = getCanvasBoundingBox(canvas, resolution);\n\n            texture.frame.copyFrom(trimmed);\n\n            texture.updateUvs();\n        }\n\n        return { texture, canvasAndContext };\n    }\n\n    public getManagedTexture(text: Text)\n    {\n        text._resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n        const textKey = text._getKey();\n\n        if (this._activeTextures[textKey])\n        {\n            this._increaseReferenceCount(textKey);\n\n            return this._activeTextures[textKey].texture;\n        }\n\n        const { texture, canvasAndContext } = this.createTextureAndCanvas(text);\n\n        this._activeTextures[textKey] = {\n            canvasAndContext,\n            texture,\n            usageCount: 1,\n        };\n\n        return texture;\n    }\n\n    private _increaseReferenceCount(textKey: string)\n    {\n        this._activeTextures[textKey].usageCount++;\n    }\n\n    public decreaseReferenceCount(textKey: string)\n    {\n        const activeTexture = this._activeTextures[textKey];\n\n        activeTexture.usageCount--;\n\n        if (activeTexture.usageCount === 0)\n        {\n            CanvasPool.returnCanvasAndContext(activeTexture.canvasAndContext);\n            TexturePool.returnTexture(activeTexture.texture);\n\n            const source = activeTexture.texture.source;\n\n            source.resource = null;\n            source.uploadMethodId = 'unknown';\n            source.alphaMode = 'no-premultiply-alpha';\n\n            this._activeTextures[textKey] = null;\n        }\n    }\n\n    public getReferenceCount(textKey: string)\n    {\n        return this._activeTextures[textKey].usageCount;\n    }\n\n    /**\n     * Renders text to its canvas, and updates its texture.\n     *\n     * By default this is used internally to ensure the texture is correct before rendering,\n     * but it can be used called externally, for example from this class to 'pre-generate' the texture from a piece of text,\n     * and then shared across multiple Sprites.\n     * @param text\n     * @param style\n     * @param resolution\n     * @param canvasAndContext\n     */\n    public renderTextToCanvas(text: string, style: TextStyle, resolution: number, canvasAndContext: CanvasAndContext): void\n    {\n        const { canvas, context } = canvasAndContext;\n\n        const font = fontStringFromTextStyle(style);\n\n        const measured = CanvasTextMetrics.measureText(text || ' ', style);// , canvas);\n        const lines = measured.lines;\n        const lineHeight = measured.lineHeight;\n        const lineWidths = measured.lineWidths;\n        const maxLineWidth = measured.maxLineWidth;\n        const fontProperties = measured.fontProperties;\n\n        const height = canvas.height;\n\n        context.resetTransform();\n\n        context.scale(resolution, resolution);\n\n        const padding = style.padding * 2;\n\n        context.clearRect(0, 0, measured.width + 4 + padding, measured.height + 4 + padding);\n\n        // set stroke styles..\n\n        if (style._stroke?.width)\n        {\n            const strokeStyle = style._stroke;\n\n            context.lineWidth = strokeStyle.width;\n\n            context.miterLimit = strokeStyle.miterLimit;\n            context.lineJoin = strokeStyle.join;\n            context.lineCap = strokeStyle.cap;\n        }\n\n        // return;\n        context.font = font;\n\n        let linePositionX: number;\n        let linePositionY: number;\n\n        // require 2 passes if a shadow; the first to draw the drop shadow, the second to draw the text\n        const passesCount = style.dropShadow ? 2 : 1;\n\n        // For v4, we drew text at the colours of the drop shadow underneath the normal text. This gave the correct zIndex,\n        // but features such as alpha and shadowblur did not look right at all, since we were using actual text as a shadow.\n        //\n        // For v5.0.0, we moved over to just use the canvas API for drop shadows, which made them look much nicer and more\n        // visually please, but now because the stroke is drawn and then the fill, drop shadows would appear on both the fill\n        // and the stroke; and fill drop shadows would appear over the top of the stroke.\n        //\n        // For v5.1.1, the new route is to revert to v4 style of drawing text first to get the drop shadows underneath normal\n        // text, but instead drawing text in the correct location, we'll draw it off screen (-paddingY), and then adjust the\n        // drop shadow so only that appears on screen (+paddingY). Now we'll have the correct draw order of the shadow\n        // beneath the text, whilst also having the proper text shadow styling.\n        for (let i = 0; i < passesCount; ++i)\n        {\n            const isShadowPass = style.dropShadow && i === 0;\n            // we only want the drop shadow, so put text way off-screen\n            const dsOffsetText = isShadowPass ? Math.ceil(Math.max(1, height) + (style.padding * 2)) : 0;\n            const dsOffsetShadow = dsOffsetText * resolution;\n\n            if (isShadowPass)\n            {\n                // On Safari, text with gradient and drop shadows together do not position correctly\n                // if the scale of the canvas is not 1: https://bugs.webkit.org/show_bug.cgi?id=197689\n                // Therefore we'll set the styles to be a plain black whilst generating this drop shadow\n                context.fillStyle = 'black';\n                context.strokeStyle = 'black';\n\n                const shadowOptions = style.dropShadow;\n\n                const dropShadowColor = shadowOptions.color;\n                const dropShadowAlpha = shadowOptions.alpha;\n\n                context.shadowColor = Color.shared\n                    .setValue(dropShadowColor)\n                    .setAlpha(dropShadowAlpha)\n                    .toRgbaString();\n\n                const dropShadowBlur = shadowOptions.blur * resolution;\n                const dropShadowDistance = shadowOptions.distance * resolution;\n\n                context.shadowBlur = dropShadowBlur;\n                context.shadowOffsetX = Math.cos(shadowOptions.angle) * dropShadowDistance;\n                context.shadowOffsetY = (Math.sin(shadowOptions.angle) * dropShadowDistance) + dsOffsetShadow;\n            }\n            else\n            {\n                context.globalAlpha = style._fill?.alpha ?? 1;\n                context.fillStyle = style._fill ? getCanvasFillStyle(style._fill, context) : null;\n\n                if (style._stroke?.width)\n                {\n                    context.strokeStyle = getCanvasFillStyle(style._stroke, context);\n                }\n\n                context.shadowColor = 'black';\n            }\n\n            let linePositionYShift = (lineHeight - fontProperties.fontSize) / 2;\n\n            if (lineHeight - fontProperties.fontSize < 0)\n            {\n                linePositionYShift = 0;\n            }\n\n            const strokeWidth = style._stroke?.width ?? 0;\n\n            // draw lines line by line\n            for (let i = 0; i < lines.length; i++)\n            {\n                linePositionX = strokeWidth / 2;\n                linePositionY = ((strokeWidth / 2) + (i * lineHeight)) + fontProperties.ascent + linePositionYShift;\n\n                if (style.align === 'right')\n                {\n                    linePositionX += maxLineWidth - lineWidths[i];\n                }\n                else if (style.align === 'center')\n                {\n                    linePositionX += (maxLineWidth - lineWidths[i]) / 2;\n                }\n\n                if (style._stroke?.width)\n                {\n                    this._drawLetterSpacing(\n                        lines[i],\n                        style,\n                        canvasAndContext,\n                        linePositionX + style.padding,\n                        linePositionY + style.padding - dsOffsetText,\n                        true\n                    );\n                }\n\n                if (style._fill !== undefined)\n                {\n                    this._drawLetterSpacing(\n                        lines[i],\n                        style,\n                        canvasAndContext,\n                        linePositionX + style.padding,\n                        linePositionY + style.padding - dsOffsetText\n                    );\n                }\n            }\n        }\n    }\n\n    /**\n     * Render the text with letter-spacing.\n     * @param text - The text to draw\n     * @param style\n     * @param canvasAndContext\n     * @param x - Horizontal position to draw the text\n     * @param y - Vertical position to draw the text\n     * @param isStroke - Is this drawing for the outside stroke of the\n     *  text? If not, it's for the inside fill\n     */\n    private _drawLetterSpacing(\n        text: string,\n        style: TextStyle,\n        canvasAndContext: CanvasAndContext,\n        x: number, y: number,\n        isStroke = false\n    ): void\n    {\n        const { context } = canvasAndContext;\n\n        // letterSpacing of 0 means normal\n        const letterSpacing = style.letterSpacing;\n\n        let useExperimentalLetterSpacing = false;\n\n        if (CanvasTextMetrics.experimentalLetterSpacingSupported)\n        {\n            if (CanvasTextMetrics.experimentalLetterSpacing)\n            {\n                context.letterSpacing = `${letterSpacing}px`;\n                context.textLetterSpacing = `${letterSpacing}px`;\n                useExperimentalLetterSpacing = true;\n            }\n            else\n            {\n                context.letterSpacing = '0px';\n                context.textLetterSpacing = '0px';\n            }\n        }\n\n        if (letterSpacing === 0 || useExperimentalLetterSpacing)\n        {\n            if (isStroke)\n            {\n                context.strokeText(text, x, y);\n            }\n            else\n            {\n                context.fillText(text, x, y);\n            }\n\n            return;\n        }\n\n        let currentPosition = x;\n\n        const stringArray = CanvasTextMetrics.graphemeSegmenter(text);\n        let previousWidth = context.measureText(text).width;\n        let currentWidth = 0;\n\n        for (let i = 0; i < stringArray.length; ++i)\n        {\n            const currentChar = stringArray[i];\n\n            if (isStroke)\n            {\n                context.strokeText(currentChar, currentPosition, y);\n            }\n            else\n            {\n                context.fillText(currentChar, currentPosition, y);\n            }\n            let textStr = '';\n\n            for (let j = i + 1; j < stringArray.length; ++j)\n            {\n                textStr += stringArray[j];\n            }\n            currentWidth = context.measureText(textStr).width;\n            currentPosition += previousWidth - currentWidth + letterSpacing;\n            previousWidth = currentWidth;\n        }\n    }\n\n    public destroy(): void\n    {\n        this._activeTextures = null;\n    }\n}\n"],"names":["i"],"mappings":";;;;;;;;;;;;;;AA+BO,MAAM,gBACb,CAAA;AAAA,EAmBI,YAAY,SACZ,EAAA;AATA,IAAA,IAAA,CAAQ,kBAIH,EAAC,CAAA;AAMF,IAAA,IAAA,CAAK,SAAY,GAAA,SAAA,CAAA;AAAA,GACrB;AAAA,EAEO,cAAA,CAAe,IAAc,EAAA,UAAA,EAAoB,KACxD,EAAA;AACI,IAAA,MAAM,QAAW,GAAA,iBAAA,CAAkB,WAAY,CAAA,IAAA,IAAQ,KAAK,KAAK,CAAA,CAAA;AAEjE,IAAA,IAAI,KAAQ,GAAA,IAAA,CAAK,IAAK,CAAA,IAAA,CAAK,KAAM,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,QAAA,CAAS,KAAK,CAAK,GAAA,KAAA,CAAM,OAAU,GAAA,CAAG,IAAI,UAAU,CAAA,CAAA;AACjG,IAAA,IAAI,MAAS,GAAA,IAAA,CAAK,IAAK,CAAA,IAAA,CAAK,KAAM,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,QAAA,CAAS,MAAM,CAAK,GAAA,KAAA,CAAM,OAAU,GAAA,CAAG,IAAI,UAAU,CAAA,CAAA;AAEnG,IAAQ,KAAA,GAAA,IAAA,CAAK,IAAM,CAAA,KAAA,GAAS,IAAI,CAAA,CAAA;AAChC,IAAS,MAAA,GAAA,IAAA,CAAK,IAAM,CAAA,MAAA,GAAU,IAAI,CAAA,CAAA;AAClC,IAAA,KAAA,GAAQ,SAAS,KAAK,CAAA,CAAA;AACtB,IAAA,MAAA,GAAS,SAAS,MAAM,CAAA,CAAA;AAExB,IAAO,OAAA,EAAE,OAAO,MAAO,EAAA,CAAA;AAAA,GAC3B;AAAA,EAcO,UAAW,CAAA,OAAA,EAA+B,UAAqB,EAAA,KAAA,EAAmB,QACzF,EAAA;AACI,IAAI,IAAA,OAAO,YAAY,QACvB,EAAA;AACI,MAAA,WAAA,CAAY,SAAS,mFAAmF,CAAA,CAAA;AAExG,MAAU,OAAA,GAAA;AAAA,QACN,IAAM,EAAA,OAAA;AAAA,QACN,KAAA;AAAA,QACA,UAAA;AAAA,OACJ,CAAA;AAAA,KACJ;AAEA,IAAI,IAAA,EAAE,OAAQ,CAAA,KAAA,YAAiB,SAC/B,CAAA,EAAA;AACI,MAAA,OAAA,CAAQ,KAAQ,GAAA,IAAI,SAAU,CAAA,OAAA,CAAQ,KAAK,CAAA,CAAA;AAAA,KAC/C;AAEA,IAAA,MAAM,EAAE,OAAA,EAAS,gBAAiB,EAAA,GAAI,IAAK,CAAA,sBAAA;AAAA,MACvC,OAAA;AAAA,KACJ,CAAA;AAEA,IAAA,IAAA,CAAK,SAAU,CAAA,OAAA,CAAQ,UAAW,CAAA,OAAA,CAAQ,OAAO,CAAA,CAAA;AAEjD,IAAA,UAAA,CAAW,uBAAuB,gBAAgB,CAAA,CAAA;AAElD,IAAO,OAAA,OAAA,CAAA;AAAA,GACX;AAAA,EAEO,uBAAuB,OAC9B,EAAA;AACI,IAAM,MAAA,EAAE,IAAM,EAAA,KAAA,EAAU,GAAA,OAAA,CAAA;AAExB,IAAA,MAAM,UAAa,GAAA,OAAA,CAAQ,UAAc,IAAA,IAAA,CAAK,SAAU,CAAA,UAAA,CAAA;AAGxD,IAAA,MAAM,QAAW,GAAA,iBAAA,CAAkB,WAAY,CAAA,IAAA,IAAQ,KAAK,KAAK,CAAA,CAAA;AAEjE,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,IAAK,CAAA,IAAA,CAAK,KAAM,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,QAAA,CAAS,KAAK,CAAK,GAAA,KAAA,CAAM,OAAU,GAAA,CAAG,IAAI,UAAU,CAAA,CAAA;AACnG,IAAA,MAAM,MAAS,GAAA,IAAA,CAAK,IAAK,CAAA,IAAA,CAAK,KAAM,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,QAAA,CAAS,MAAM,CAAK,GAAA,KAAA,CAAM,OAAU,GAAA,CAAG,IAAI,UAAU,CAAA,CAAA;AAErG,IAAA,MAAM,gBAAmB,GAAA,UAAA,CAAW,0BAA2B,CAAA,KAAA,EAAO,MAAM,CAAA,CAAA;AAG5E,IAAM,MAAA,EAAE,QAAW,GAAA,gBAAA,CAAA;AAEnB,IAAA,IAAA,CAAK,kBAAmB,CAAA,IAAA,EAAM,KAAO,EAAA,UAAA,EAAY,gBAAgB,CAAA,CAAA;AAEjE,IAAA,MAAM,OAAU,GAAA,uBAAA,CAAwB,MAAQ,EAAA,KAAA,EAAO,QAAQ,UAAU,CAAA,CAAA;AAEzE,IAAA,IAAI,MAAM,IACV,EAAA;AACI,MAAM,MAAA,OAAA,GAAU,oBAAqB,CAAA,MAAA,EAAQ,UAAU,CAAA,CAAA;AAEvD,MAAQ,OAAA,CAAA,KAAA,CAAM,SAAS,OAAO,CAAA,CAAA;AAE9B,MAAA,OAAA,CAAQ,SAAU,EAAA,CAAA;AAAA,KACtB;AAEA,IAAO,OAAA,EAAE,SAAS,gBAAiB,EAAA,CAAA;AAAA,GACvC;AAAA,EAEO,kBAAkB,IACzB,EAAA;AACI,IAAA,IAAA,CAAK,cAAc,IAAK,CAAA,eAAA,GAAkB,IAAK,CAAA,SAAA,CAAU,aAAa,IAAK,CAAA,UAAA,CAAA;AAC3E,IAAM,MAAA,OAAA,GAAU,KAAK,OAAQ,EAAA,CAAA;AAE7B,IAAI,IAAA,IAAA,CAAK,eAAgB,CAAA,OAAO,CAChC,EAAA;AACI,MAAA,IAAA,CAAK,wBAAwB,OAAO,CAAA,CAAA;AAEpC,MAAO,OAAA,IAAA,CAAK,eAAgB,CAAA,OAAO,CAAE,CAAA,OAAA,CAAA;AAAA,KACzC;AAEA,IAAA,MAAM,EAAE,OAAS,EAAA,gBAAA,EAAqB,GAAA,IAAA,CAAK,uBAAuB,IAAI,CAAA,CAAA;AAEtE,IAAK,IAAA,CAAA,eAAA,CAAgB,OAAO,CAAI,GAAA;AAAA,MAC5B,gBAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAY,EAAA,CAAA;AAAA,KAChB,CAAA;AAEA,IAAO,OAAA,OAAA,CAAA;AAAA,GACX;AAAA,EAEQ,wBAAwB,OAChC,EAAA;AACI,IAAK,IAAA,CAAA,eAAA,CAAgB,OAAO,CAAE,CAAA,UAAA,EAAA,CAAA;AAAA,GAClC;AAAA,EAEO,uBAAuB,OAC9B,EAAA;AACI,IAAM,MAAA,aAAA,GAAgB,IAAK,CAAA,eAAA,CAAgB,OAAO,CAAA,CAAA;AAElD,IAAc,aAAA,CAAA,UAAA,EAAA,CAAA;AAEd,IAAI,IAAA,aAAA,CAAc,eAAe,CACjC,EAAA;AACI,MAAW,UAAA,CAAA,sBAAA,CAAuB,cAAc,gBAAgB,CAAA,CAAA;AAChE,MAAY,WAAA,CAAA,aAAA,CAAc,cAAc,OAAO,CAAA,CAAA;AAE/C,MAAM,MAAA,MAAA,GAAS,cAAc,OAAQ,CAAA,MAAA,CAAA;AAErC,MAAA,MAAA,CAAO,QAAW,GAAA,IAAA,CAAA;AAClB,MAAA,MAAA,CAAO,cAAiB,GAAA,SAAA,CAAA;AACxB,MAAA,MAAA,CAAO,SAAY,GAAA,sBAAA,CAAA;AAEnB,MAAK,IAAA,CAAA,eAAA,CAAgB,OAAO,CAAI,GAAA,IAAA,CAAA;AAAA,KACpC;AAAA,GACJ;AAAA,EAEO,kBAAkB,OACzB,EAAA;AACI,IAAO,OAAA,IAAA,CAAK,eAAgB,CAAA,OAAO,CAAE,CAAA,UAAA,CAAA;AAAA,GACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,kBAAmB,CAAA,IAAA,EAAc,KAAkB,EAAA,UAAA,EAAoB,gBAC9E,EAAA;AACI,IAAM,MAAA,EAAE,MAAQ,EAAA,OAAA,EAAY,GAAA,gBAAA,CAAA;AAE5B,IAAM,MAAA,IAAA,GAAO,wBAAwB,KAAK,CAAA,CAAA;AAE1C,IAAA,MAAM,QAAW,GAAA,iBAAA,CAAkB,WAAY,CAAA,IAAA,IAAQ,KAAK,KAAK,CAAA,CAAA;AACjE,IAAA,MAAM,QAAQ,QAAS,CAAA,KAAA,CAAA;AACvB,IAAA,MAAM,aAAa,QAAS,CAAA,UAAA,CAAA;AAC5B,IAAA,MAAM,aAAa,QAAS,CAAA,UAAA,CAAA;AAC5B,IAAA,MAAM,eAAe,QAAS,CAAA,YAAA,CAAA;AAC9B,IAAA,MAAM,iBAAiB,QAAS,CAAA,cAAA,CAAA;AAEhC,IAAA,MAAM,SAAS,MAAO,CAAA,MAAA,CAAA;AAEtB,IAAA,OAAA,CAAQ,cAAe,EAAA,CAAA;AAEvB,IAAQ,OAAA,CAAA,KAAA,CAAM,YAAY,UAAU,CAAA,CAAA;AAEpC,IAAM,MAAA,OAAA,GAAU,MAAM,OAAU,GAAA,CAAA,CAAA;AAEhC,IAAQ,OAAA,CAAA,SAAA,CAAU,CAAG,EAAA,CAAA,EAAG,QAAS,CAAA,KAAA,GAAQ,IAAI,OAAS,EAAA,QAAA,CAAS,MAAS,GAAA,CAAA,GAAI,OAAO,CAAA,CAAA;AAInF,IAAI,IAAA,KAAA,CAAM,SAAS,KACnB,EAAA;AACI,MAAA,MAAM,cAAc,KAAM,CAAA,OAAA,CAAA;AAE1B,MAAA,OAAA,CAAQ,YAAY,WAAY,CAAA,KAAA,CAAA;AAEhC,MAAA,OAAA,CAAQ,aAAa,WAAY,CAAA,UAAA,CAAA;AACjC,MAAA,OAAA,CAAQ,WAAW,WAAY,CAAA,IAAA,CAAA;AAC/B,MAAA,OAAA,CAAQ,UAAU,WAAY,CAAA,GAAA,CAAA;AAAA,KAClC;AAGA,IAAA,OAAA,CAAQ,IAAO,GAAA,IAAA,CAAA;AAEf,IAAI,IAAA,aAAA,CAAA;AACJ,IAAI,IAAA,aAAA,CAAA;AAGJ,IAAM,MAAA,WAAA,GAAc,KAAM,CAAA,UAAA,GAAa,CAAI,GAAA,CAAA,CAAA;AAa3C,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,WAAA,EAAa,EAAE,CACnC,EAAA;AACI,MAAM,MAAA,YAAA,GAAe,KAAM,CAAA,UAAA,IAAc,CAAM,KAAA,CAAA,CAAA;AAE/C,MAAA,MAAM,YAAe,GAAA,YAAA,GAAe,IAAK,CAAA,IAAA,CAAK,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,MAAM,CAAK,GAAA,KAAA,CAAM,OAAU,GAAA,CAAE,CAAI,GAAA,CAAA,CAAA;AAC3F,MAAA,MAAM,iBAAiB,YAAe,GAAA,UAAA,CAAA;AAEtC,MAAA,IAAI,YACJ,EAAA;AAII,QAAA,OAAA,CAAQ,SAAY,GAAA,OAAA,CAAA;AACpB,QAAA,OAAA,CAAQ,WAAc,GAAA,OAAA,CAAA;AAEtB,QAAA,MAAM,gBAAgB,KAAM,CAAA,UAAA,CAAA;AAE5B,QAAA,MAAM,kBAAkB,aAAc,CAAA,KAAA,CAAA;AACtC,QAAA,MAAM,kBAAkB,aAAc,CAAA,KAAA,CAAA;AAEtC,QAAQ,OAAA,CAAA,WAAA,GAAc,MAAM,MACvB,CAAA,QAAA,CAAS,eAAe,CACxB,CAAA,QAAA,CAAS,eAAe,CAAA,CACxB,YAAa,EAAA,CAAA;AAElB,QAAM,MAAA,cAAA,GAAiB,cAAc,IAAO,GAAA,UAAA,CAAA;AAC5C,QAAM,MAAA,kBAAA,GAAqB,cAAc,QAAW,GAAA,UAAA,CAAA;AAEpD,QAAA,OAAA,CAAQ,UAAa,GAAA,cAAA,CAAA;AACrB,QAAA,OAAA,CAAQ,aAAgB,GAAA,IAAA,CAAK,GAAI,CAAA,aAAA,CAAc,KAAK,CAAI,GAAA,kBAAA,CAAA;AACxD,QAAA,OAAA,CAAQ,gBAAiB,IAAK,CAAA,GAAA,CAAI,aAAc,CAAA,KAAK,IAAI,kBAAsB,GAAA,cAAA,CAAA;AAAA,OAGnF,MAAA;AACI,QAAQ,OAAA,CAAA,WAAA,GAAc,KAAM,CAAA,KAAA,EAAO,KAAS,IAAA,CAAA,CAAA;AAC5C,QAAA,OAAA,CAAQ,YAAY,KAAM,CAAA,KAAA,GAAQ,mBAAmB,KAAM,CAAA,KAAA,EAAO,OAAO,CAAI,GAAA,IAAA,CAAA;AAE7E,QAAI,IAAA,KAAA,CAAM,SAAS,KACnB,EAAA;AACI,UAAA,OAAA,CAAQ,WAAc,GAAA,kBAAA,CAAmB,KAAM,CAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AAAA,SACnE;AAEA,QAAA,OAAA,CAAQ,WAAc,GAAA,OAAA,CAAA;AAAA,OAC1B;AAEA,MAAI,IAAA,kBAAA,GAAA,CAAsB,UAAa,GAAA,cAAA,CAAe,QAAY,IAAA,CAAA,CAAA;AAElE,MAAI,IAAA,UAAA,GAAa,cAAe,CAAA,QAAA,GAAW,CAC3C,EAAA;AACI,QAAqB,kBAAA,GAAA,CAAA,CAAA;AAAA,OACzB;AAEA,MAAM,MAAA,WAAA,GAAc,KAAM,CAAA,OAAA,EAAS,KAAS,IAAA,CAAA,CAAA;AAG5C,MAAA,KAAA,IAASA,EAAI,GAAA,CAAA,EAAGA,EAAI,GAAA,KAAA,CAAM,QAAQA,EAClC,EAAA,EAAA;AACI,QAAA,aAAA,GAAgB,WAAc,GAAA,CAAA,CAAA;AAC9B,QAAA,aAAA,GAAkB,WAAc,GAAA,CAAA,GAAMA,EAAI,GAAA,UAAA,GAAe,eAAe,MAAS,GAAA,kBAAA,CAAA;AAEjF,QAAI,IAAA,KAAA,CAAM,UAAU,OACpB,EAAA;AACI,UAAiB,aAAA,IAAA,YAAA,GAAe,WAAWA,EAAC,CAAA,CAAA;AAAA,SAChD,MAAA,IACS,KAAM,CAAA,KAAA,KAAU,QACzB,EAAA;AACI,UAAkB,aAAA,IAAA,CAAA,YAAA,GAAe,UAAWA,CAAAA,EAAC,CAAK,IAAA,CAAA,CAAA;AAAA,SACtD;AAEA,QAAI,IAAA,KAAA,CAAM,SAAS,KACnB,EAAA;AACI,UAAK,IAAA,CAAA,kBAAA;AAAA,YACD,MAAMA,EAAC,CAAA;AAAA,YACP,KAAA;AAAA,YACA,gBAAA;AAAA,YACA,gBAAgB,KAAM,CAAA,OAAA;AAAA,YACtB,aAAA,GAAgB,MAAM,OAAU,GAAA,YAAA;AAAA,YAChC,IAAA;AAAA,WACJ,CAAA;AAAA,SACJ;AAEA,QAAI,IAAA,KAAA,CAAM,UAAU,KACpB,CAAA,EAAA;AACI,UAAK,IAAA,CAAA,kBAAA;AAAA,YACD,MAAMA,EAAC,CAAA;AAAA,YACP,KAAA;AAAA,YACA,gBAAA;AAAA,YACA,gBAAgB,KAAM,CAAA,OAAA;AAAA,YACtB,aAAA,GAAgB,MAAM,OAAU,GAAA,YAAA;AAAA,WACpC,CAAA;AAAA,SACJ;AAAA,OACJ;AAAA,KACJ;AAAA,GACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,mBACJ,IACA,EAAA,KAAA,EACA,kBACA,CAAW,EAAA,CAAA,EACX,WAAW,KAEf,EAAA;AACI,IAAM,MAAA,EAAE,SAAY,GAAA,gBAAA,CAAA;AAGpB,IAAA,MAAM,gBAAgB,KAAM,CAAA,aAAA,CAAA;AAE5B,IAAA,IAAI,4BAA+B,GAAA,KAAA,CAAA;AAEnC,IAAA,IAAI,kBAAkB,kCACtB,EAAA;AACI,MAAA,IAAI,kBAAkB,yBACtB,EAAA;AACI,QAAQ,OAAA,CAAA,aAAA,GAAgB,GAAG,aAAa,CAAA,EAAA,CAAA,CAAA;AACxC,QAAQ,OAAA,CAAA,iBAAA,GAAoB,GAAG,aAAa,CAAA,EAAA,CAAA,CAAA;AAC5C,QAA+B,4BAAA,GAAA,IAAA,CAAA;AAAA,OAGnC,MAAA;AACI,QAAA,OAAA,CAAQ,aAAgB,GAAA,KAAA,CAAA;AACxB,QAAA,OAAA,CAAQ,iBAAoB,GAAA,KAAA,CAAA;AAAA,OAChC;AAAA,KACJ;AAEA,IAAI,IAAA,aAAA,KAAkB,KAAK,4BAC3B,EAAA;AACI,MAAA,IAAI,QACJ,EAAA;AACI,QAAQ,OAAA,CAAA,UAAA,CAAW,IAAM,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AAAA,OAGjC,MAAA;AACI,QAAQ,OAAA,CAAA,QAAA,CAAS,IAAM,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AAAA,OAC/B;AAEA,MAAA,OAAA;AAAA,KACJ;AAEA,IAAA,IAAI,eAAkB,GAAA,CAAA,CAAA;AAEtB,IAAM,MAAA,WAAA,GAAc,iBAAkB,CAAA,iBAAA,CAAkB,IAAI,CAAA,CAAA;AAC5D,IAAA,IAAI,aAAgB,GAAA,OAAA,CAAQ,WAAY,CAAA,IAAI,CAAE,CAAA,KAAA,CAAA;AAC9C,IAAA,IAAI,YAAe,GAAA,CAAA,CAAA;AAEnB,IAAA,KAAA,IAAS,IAAI,CAAG,EAAA,CAAA,GAAI,WAAY,CAAA,MAAA,EAAQ,EAAE,CAC1C,EAAA;AACI,MAAM,MAAA,WAAA,GAAc,YAAY,CAAC,CAAA,CAAA;AAEjC,MAAA,IAAI,QACJ,EAAA;AACI,QAAQ,OAAA,CAAA,UAAA,CAAW,WAAa,EAAA,eAAA,EAAiB,CAAC,CAAA,CAAA;AAAA,OAGtD,MAAA;AACI,QAAQ,OAAA,CAAA,QAAA,CAAS,WAAa,EAAA,eAAA,EAAiB,CAAC,CAAA,CAAA;AAAA,OACpD;AACA,MAAA,IAAI,OAAU,GAAA,EAAA,CAAA;AAEd,MAAA,KAAA,IAAS,IAAI,CAAI,GAAA,CAAA,EAAG,IAAI,WAAY,CAAA,MAAA,EAAQ,EAAE,CAC9C,EAAA;AACI,QAAA,OAAA,IAAW,YAAY,CAAC,CAAA,CAAA;AAAA,OAC5B;AACA,MAAe,YAAA,GAAA,OAAA,CAAQ,WAAY,CAAA,OAAO,CAAE,CAAA,KAAA,CAAA;AAC5C,MAAA,eAAA,IAAmB,gBAAgB,YAAe,GAAA,aAAA,CAAA;AAClD,MAAgB,aAAA,GAAA,YAAA,CAAA;AAAA,KACpB;AAAA,GACJ;AAAA,EAEO,OACP,GAAA;AACI,IAAA,IAAA,CAAK,eAAkB,GAAA,IAAA,CAAA;AAAA,GAC3B;AACJ,CAAA;AAAA;AAlaa,gBAAA,CAGK,SAAY,GAAA;AAAA,EACtB,IAAM,EAAA;AAAA,IACF,aAAc,CAAA,WAAA;AAAA,IACd,aAAc,CAAA,YAAA;AAAA,IACd,aAAc,CAAA,YAAA;AAAA,GAClB;AAAA,EACA,IAAM,EAAA,YAAA;AACV,CAAA;;;;"}