@omnimedia/omnitool 1.1.0-43 → 1.1.0-44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/package.json +17 -18
  2. package/s/demo/demo.bundle.ts +20 -40
  3. package/s/demo/routines/export-test.ts +8 -0
  4. package/s/demo/routines/playback-test.ts +21 -0
  5. package/s/demo/routines/timeline-setup.ts +24 -0
  6. package/s/demo/routines/transcode-test.ts +2 -0
  7. package/s/driver/driver-worker.ts +9 -0
  8. package/s/driver/driver.test.ts +1 -1
  9. package/s/driver/driver.ts +8 -22
  10. package/s/driver/fns/schematic.ts +6 -2
  11. package/s/driver/fns/work.ts +2 -133
  12. package/s/driver/parts/compositor.ts +178 -0
  13. package/s/driver/parts/machina.ts +19 -20
  14. package/s/index.ts +1 -0
  15. package/s/timeline/index.ts +1 -1
  16. package/s/timeline/parts/media.ts +11 -2
  17. package/s/timeline/parts/{compositor → renderers}/parts/html-tree.ts +2 -2
  18. package/s/timeline/parts/{compositor → renderers}/parts/tree-builder.ts +4 -2
  19. package/s/timeline/parts/{compositor → renderers}/playback.ts +4 -13
  20. package/s/timeline/parts/{compositor → renderers}/samplers/html.ts +19 -5
  21. package/s/timeline/parts/{compositor → renderers}/samplers/webcodecs.ts +1 -1
  22. package/s/timeline/parts/resource-pool.ts +8 -4
  23. package/s/timeline/parts/resource.ts +1 -0
  24. package/s/timeline/sugar/o.ts +8 -4
  25. package/s/timeline/sugar/omni-test.ts +14 -14
  26. package/s/timeline/sugar/omni.ts +2 -2
  27. package/s/timeline/utils/datafile.ts +14 -4
  28. package/s/timeline/utils/dummy-data.ts +3 -3
  29. package/x/demo/WebGLRenderer-Q3OV2JVE.js +2 -0
  30. package/x/demo/WebGLRenderer-Q3OV2JVE.js.map +7 -0
  31. package/x/demo/WebGPURenderer-FUFF62QA.js +2 -0
  32. package/x/demo/WebGPURenderer-FUFF62QA.js.map +7 -0
  33. package/x/demo/browserAll-PGQYU756.js +2 -0
  34. package/x/demo/browserAll-PGQYU756.js.map +7 -0
  35. package/x/demo/chunk-2RBLPWNG.js +393 -0
  36. package/x/demo/chunk-2RBLPWNG.js.map +7 -0
  37. package/x/demo/chunk-6DBMQOFE.js +42 -0
  38. package/x/demo/chunk-6DBMQOFE.js.map +7 -0
  39. package/x/demo/chunk-LAJHJD2S.js +2 -0
  40. package/x/demo/chunk-LAJHJD2S.js.map +7 -0
  41. package/x/demo/chunk-LQU5JKKZ.js +269 -0
  42. package/x/demo/chunk-LQU5JKKZ.js.map +7 -0
  43. package/x/demo/chunk-RFNLITDQ.js +327 -0
  44. package/x/demo/chunk-RFNLITDQ.js.map +7 -0
  45. package/x/demo/chunk-TBWCKYN2.js +2 -0
  46. package/x/demo/chunk-TBWCKYN2.js.map +7 -0
  47. package/x/demo/chunk-TLDBHU4V.js +15 -0
  48. package/x/demo/chunk-TLDBHU4V.js.map +7 -0
  49. package/x/demo/chunk-X2GHKWPJ.js +157 -0
  50. package/x/demo/chunk-X2GHKWPJ.js.map +7 -0
  51. package/x/demo/demo.bundle.js +18 -27
  52. package/x/demo/demo.bundle.js.map +1 -1
  53. package/x/demo/demo.bundle.min.js +2378 -534
  54. package/x/demo/demo.bundle.min.js.map +4 -4
  55. package/x/demo/routines/export-test.d.ts +2 -0
  56. package/x/demo/routines/export-test.js +7 -0
  57. package/x/demo/routines/export-test.js.map +1 -0
  58. package/x/demo/routines/playback-test.d.ts +3 -0
  59. package/x/demo/routines/playback-test.js +17 -0
  60. package/x/demo/routines/playback-test.js.map +1 -0
  61. package/x/demo/routines/timeline-setup.d.ts +6 -0
  62. package/x/demo/routines/timeline-setup.js +13 -0
  63. package/x/demo/routines/timeline-setup.js.map +1 -0
  64. package/x/demo/routines/transcode-test.js +2 -0
  65. package/x/demo/routines/transcode-test.js.map +1 -1
  66. package/x/demo/webworkerAll-3YNCLHCR.js +2 -0
  67. package/x/demo/webworkerAll-3YNCLHCR.js.map +7 -0
  68. package/x/driver/WebGLRenderer-OMRWYQIV.js +2 -0
  69. package/x/driver/WebGLRenderer-OMRWYQIV.js.map +7 -0
  70. package/x/driver/WebGPURenderer-KQJB2OJJ.js +2 -0
  71. package/x/driver/WebGPURenderer-KQJB2OJJ.js.map +7 -0
  72. package/x/driver/browserAll-YBZEJCN3.js +2 -0
  73. package/x/driver/browserAll-YBZEJCN3.js.map +7 -0
  74. package/x/driver/chunk-3L3MB5NY.js +393 -0
  75. package/x/driver/chunk-3L3MB5NY.js.map +7 -0
  76. package/x/driver/chunk-42BQ4XKE.js +269 -0
  77. package/x/driver/chunk-42BQ4XKE.js.map +7 -0
  78. package/x/driver/chunk-4HAYG3N5.js +327 -0
  79. package/x/driver/chunk-4HAYG3N5.js.map +7 -0
  80. package/x/driver/chunk-BFBY7VYB.js +42 -0
  81. package/x/driver/chunk-BFBY7VYB.js.map +7 -0
  82. package/x/driver/chunk-KM6O72WE.js +157 -0
  83. package/x/driver/chunk-KM6O72WE.js.map +7 -0
  84. package/x/driver/chunk-N6HD4WYJ.js +2 -0
  85. package/x/driver/chunk-N6HD4WYJ.js.map +7 -0
  86. package/x/driver/chunk-WCZ2O3UN.js +15 -0
  87. package/x/driver/chunk-WCZ2O3UN.js.map +7 -0
  88. package/x/driver/chunk-XWNSF3WJ.js +2 -0
  89. package/x/driver/chunk-XWNSF3WJ.js.map +7 -0
  90. package/x/driver/driver-worker.d.ts +1 -0
  91. package/x/driver/driver-worker.js +6 -0
  92. package/x/driver/driver-worker.js.map +1 -0
  93. package/x/driver/driver.d.ts +5 -4
  94. package/x/driver/driver.js +10 -20
  95. package/x/driver/driver.js.map +1 -1
  96. package/x/driver/driver.test.js +1 -1
  97. package/x/driver/driver.test.js.map +1 -1
  98. package/x/driver/driver.worker.bundle.min.js +119 -3504
  99. package/x/driver/driver.worker.bundle.min.js.map +4 -4
  100. package/x/driver/fns/host.d.ts +1 -2
  101. package/x/driver/fns/schematic.d.ts +6 -1
  102. package/x/driver/fns/work.d.ts +2 -4
  103. package/x/driver/fns/work.js +1 -100
  104. package/x/driver/fns/work.js.map +1 -1
  105. package/x/driver/parts/compositor.d.ts +15 -0
  106. package/x/driver/parts/compositor.js +152 -0
  107. package/x/driver/parts/compositor.js.map +1 -0
  108. package/x/driver/parts/machina.d.ts +0 -20
  109. package/x/driver/parts/machina.js +6 -10
  110. package/x/driver/parts/machina.js.map +1 -1
  111. package/x/driver/webworkerAll-BKJQW6P7.js +2 -0
  112. package/x/driver/webworkerAll-BKJQW6P7.js.map +7 -0
  113. package/x/features/speech/transcribe/parts/prep-audio.d.ts +1 -1
  114. package/x/features/speech/transcribe/worker.bundle.min.js +899 -899
  115. package/x/features/speech/transcribe/worker.bundle.min.js.map +4 -4
  116. package/x/index.d.ts +1 -0
  117. package/x/index.html +2 -2
  118. package/x/index.js +1 -0
  119. package/x/index.js.map +1 -1
  120. package/x/timeline/index.d.ts +1 -1
  121. package/x/timeline/index.js +1 -1
  122. package/x/timeline/index.js.map +1 -1
  123. package/x/timeline/parts/filmstrip.d.ts +1 -1
  124. package/x/timeline/parts/media.d.ts +2 -0
  125. package/x/timeline/parts/media.js +10 -2
  126. package/x/timeline/parts/media.js.map +1 -1
  127. package/x/timeline/parts/renderers/export.js.map +1 -0
  128. package/x/timeline/parts/{compositor → renderers}/parts/html-tree.js +2 -2
  129. package/x/timeline/parts/renderers/parts/html-tree.js.map +1 -0
  130. package/x/timeline/parts/renderers/parts/schedulers.js.map +1 -0
  131. package/x/timeline/parts/{compositor → renderers}/parts/tree-builder.js +4 -2
  132. package/x/timeline/parts/renderers/parts/tree-builder.js.map +1 -0
  133. package/x/timeline/parts/renderers/parts/webcodecs-tree.js.map +1 -0
  134. package/x/timeline/parts/{compositor → renderers}/playback.d.ts +2 -4
  135. package/x/timeline/parts/{compositor → renderers}/playback.js +5 -14
  136. package/x/timeline/parts/renderers/playback.js.map +1 -0
  137. package/x/timeline/parts/{compositor → renderers}/samplers/html.js +14 -5
  138. package/x/timeline/parts/renderers/samplers/html.js.map +1 -0
  139. package/x/timeline/parts/{compositor → renderers}/samplers/webcodecs.js +1 -1
  140. package/x/timeline/parts/renderers/samplers/webcodecs.js.map +1 -0
  141. package/x/timeline/parts/resource-pool.d.ts +2 -0
  142. package/x/timeline/parts/resource-pool.js +7 -4
  143. package/x/timeline/parts/resource-pool.js.map +1 -1
  144. package/x/timeline/parts/resource.d.ts +1 -0
  145. package/x/timeline/sugar/o.d.ts +4 -1
  146. package/x/timeline/sugar/o.js +4 -4
  147. package/x/timeline/sugar/o.js.map +1 -1
  148. package/x/timeline/sugar/omni-test.js +14 -7
  149. package/x/timeline/sugar/omni-test.js.map +1 -1
  150. package/x/timeline/sugar/omni.d.ts +1 -2
  151. package/x/timeline/sugar/omni.js +2 -2
  152. package/x/timeline/sugar/omni.js.map +1 -1
  153. package/x/timeline/utils/datafile.d.ts +4 -3
  154. package/x/timeline/utils/datafile.js +16 -5
  155. package/x/timeline/utils/datafile.js.map +1 -1
  156. package/x/timeline/utils/dummy-data.d.ts +1 -2
  157. package/x/timeline/utils/dummy-data.js +4 -2
  158. package/x/timeline/utils/dummy-data.js.map +1 -1
  159. package/x/timeline/parts/compositor/export.js.map +0 -1
  160. package/x/timeline/parts/compositor/parts/html-tree.js.map +0 -1
  161. package/x/timeline/parts/compositor/parts/schedulers.js.map +0 -1
  162. package/x/timeline/parts/compositor/parts/tree-builder.js.map +0 -1
  163. package/x/timeline/parts/compositor/parts/webcodecs-tree.js.map +0 -1
  164. package/x/timeline/parts/compositor/playback.js.map +0 -1
  165. package/x/timeline/parts/compositor/samplers/html.js.map +0 -1
  166. package/x/timeline/parts/compositor/samplers/webcodecs.js.map +0 -1
  167. /package/s/timeline/parts/{compositor → renderers}/export.ts +0 -0
  168. /package/s/timeline/parts/{compositor → renderers}/parts/schedulers.ts +0 -0
  169. /package/s/timeline/parts/{compositor → renderers}/parts/webcodecs-tree.ts +0 -0
  170. /package/x/timeline/parts/{compositor → renderers}/export.d.ts +0 -0
  171. /package/x/timeline/parts/{compositor → renderers}/export.js +0 -0
  172. /package/x/timeline/parts/{compositor → renderers}/parts/html-tree.d.ts +0 -0
  173. /package/x/timeline/parts/{compositor → renderers}/parts/schedulers.d.ts +0 -0
  174. /package/x/timeline/parts/{compositor → renderers}/parts/schedulers.js +0 -0
  175. /package/x/timeline/parts/{compositor → renderers}/parts/tree-builder.d.ts +0 -0
  176. /package/x/timeline/parts/{compositor → renderers}/parts/webcodecs-tree.d.ts +0 -0
  177. /package/x/timeline/parts/{compositor → renderers}/parts/webcodecs-tree.js +0 -0
  178. /package/x/timeline/parts/{compositor → renderers}/samplers/html.d.ts +0 -0
  179. /package/x/timeline/parts/{compositor → renderers}/samplers/webcodecs.d.ts +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../node_modules/parse-svg-path/index.js", "../../node_modules/pixi.js/src/assets/loader/parsers/LoaderParser.ts", "../../node_modules/pixi.js/src/utils/path.ts", "../../node_modules/pixi.js/src/assets/utils/convertToList.ts", "../../node_modules/pixi.js/src/assets/utils/createStringVariations.ts", "../../node_modules/pixi.js/src/assets/utils/isSingleItem.ts", "../../node_modules/pixi.js/src/assets/resolver/Resolver.ts", "../../node_modules/pixi.js/src/assets/utils/copySearchParams.ts", "../../node_modules/pixi.js/src/spritesheet/Spritesheet.ts", "../../node_modules/pixi.js/src/spritesheet/spritesheetAsset.ts", "../../node_modules/pixi.js/src/spritesheet/init.ts", "../../node_modules/pixi.js/src/rendering/mask/utils/addMaskBounds.ts", "../../node_modules/pixi.js/src/rendering/mask/utils/addMaskLocalBounds.ts", "../../node_modules/pixi.js/src/rendering/mask/alpha/AlphaMask.ts", "../../node_modules/pixi.js/src/rendering/mask/color/ColorMask.ts", "../../node_modules/pixi.js/src/rendering/mask/stencil/StencilMask.ts", "../../node_modules/pixi.js/src/rendering/renderers/shared/texture/sources/ImageSource.ts", "../../node_modules/pixi.js/src/utils/browser/detectVideoAlphaMode.ts", "../../node_modules/pixi.js/src/rendering/renderers/shared/texture/sources/VideoSource.ts", "../../node_modules/pixi.js/src/assets/cache/Cache.ts", "../../node_modules/pixi.js/src/rendering/renderers/shared/texture/utils/textureFrom.ts", "../../node_modules/pixi.js/src/rendering/init.ts", "../../node_modules/pixi.js/src/app/ResizePlugin.ts", "../../node_modules/pixi.js/src/app/TickerPlugin.ts", "../../node_modules/pixi.js/src/rendering/renderers/shared/geometry/utils/buildUvs.ts", "../../node_modules/pixi.js/src/rendering/renderers/shared/geometry/utils/transformVertices.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/BatchableGraphics.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildCircle.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/utils/getOrientationOfPoints.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildLine.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildPixelLine.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/utils/triangulateWithHoles.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildPolygon.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildRectangle.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildTriangle.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/fill/FillGradient.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/utils/generateTextureFillMatrix.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/utils/buildContextBatches.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/GraphicsContextSystem.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/GraphicsPipe.ts", "../../node_modules/pixi.js/src/scene/mesh/shared/BatchableMesh.ts", "../../node_modules/pixi.js/src/scene/mesh/shared/MeshPipe.ts", "../../node_modules/pixi.js/src/scene/particle-container/gl/GlParticleContainerAdaptor.ts", "../../node_modules/pixi.js/src/scene/particle-container/shared/utils/createIndicesForQuads.ts", "../../node_modules/pixi.js/src/scene/particle-container/shared/utils/generateParticleUpdateFunction.ts", "../../node_modules/pixi.js/src/scene/particle-container/shared/ParticleBuffer.ts", "../../node_modules/pixi.js/lib/scene/particle-container/shared/shader/particles.frag.mjs", "../../node_modules/pixi.js/lib/scene/particle-container/shared/shader/particles.vert.mjs", "../../node_modules/pixi.js/lib/scene/particle-container/shared/shader/particles.wgsl.mjs", "../../node_modules/pixi.js/src/scene/particle-container/shared/shader/ParticleShader.ts", "../../node_modules/pixi.js/src/scene/particle-container/shared/ParticleContainerPipe.ts", "../../node_modules/pixi.js/src/scene/particle-container/shared/GlParticleContainerPipe.ts", "../../node_modules/pixi.js/src/scene/particle-container/gpu/GpuParticleContainerAdaptor.ts", "../../node_modules/pixi.js/src/scene/particle-container/shared/GpuParticleContainerPipe.ts", "../../node_modules/pixi.js/src/scene/text/utils/updateTextBounds.ts", "../../node_modules/pixi.js/src/scene/text/canvas/BatchableText.ts", "../../node_modules/pixi.js/src/scene/text/canvas/CanvasTextPipe.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/fill/FillPattern.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/svg/parseSVGPath.ts", "../../node_modules/pixi.js/src/maths/shapes/Circle.ts", "../../node_modules/pixi.js/src/maths/shapes/Ellipse.ts", "../../node_modules/pixi.js/src/maths/misc/squaredDistanceToLineSegment.ts", "../../node_modules/pixi.js/src/maths/shapes/Polygon.ts", "../../node_modules/pixi.js/src/maths/shapes/RoundedRectangle.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildAdaptiveBezier.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildAdaptiveQuadratic.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildArc.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildArcTo.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/buildCommands/buildArcToSvg.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/path/roundShape.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/path/ShapePath.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/path/GraphicsPath.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/svg/parseSVGFloatAttribute.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/svg/parseSVGDefinitions.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/svg/utils/extractSvgUrlId.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/svg/parseSVGStyle.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/svg/utils/fillOperations.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/svg/utils/pathOperations.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/svg/SVGParser.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/utils/convertFillInputToFillStyle.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/GraphicsContext.ts", "../../node_modules/pixi.js/src/scene/text/TextStyle.ts", "../../node_modules/pixi.js/src/scene/text/utils/getPo2TextureFromSource.ts", "../../node_modules/pixi.js/src/utils/canvas/getCanvasBoundingBox.ts", "../../node_modules/tiny-lru/dist/tiny-lru.js", "../../node_modules/pixi.js/src/scene/text/canvas/utils/fontStringFromTextStyle.ts", "../../node_modules/pixi.js/src/scene/text/canvas/CanvasTextMetrics.ts", "../../node_modules/pixi.js/src/scene/text/canvas/utils/getCanvasFillStyle.ts", "../../node_modules/pixi.js/src/scene/text/canvas/CanvasTextGenerator.ts", "../../node_modules/pixi.js/src/scene/text/canvas/CanvasTextSystem.ts", "../../node_modules/pixi.js/src/scene/graphics/shared/Graphics.ts", "../../node_modules/pixi.js/src/scene/text/sdfShader/shader-bits/localUniformMSDFBit.ts", "../../node_modules/pixi.js/src/scene/text/sdfShader/shader-bits/mSDFBit.ts", "../../node_modules/pixi.js/src/scene/text/sdfShader/SdfShader.ts", "../../node_modules/pixi.js/src/scene/text-bitmap/AbstractBitmapFont.ts", "../../node_modules/pixi.js/src/scene/text-bitmap/DynamicBitmapFont.ts", "../../node_modules/pixi.js/src/scene/text-bitmap/utils/getBitmapTextLayout.ts", "../../node_modules/pixi.js/src/scene/text-bitmap/utils/resolveCharacters.ts", "../../node_modules/pixi.js/src/scene/text-bitmap/BitmapFontManager.ts", "../../node_modules/pixi.js/src/scene/text-bitmap/BitmapTextPipe.ts", "../../node_modules/pixi.js/src/scene/text-html/BatchableHTMLText.ts", "../../node_modules/pixi.js/src/scene/text-html/HTMLTextPipe.ts", "../../node_modules/pixi.js/src/utils/browser/isSafari.ts", "../../node_modules/pixi.js/src/scene/text-html/HTMLTextRenderData.ts", "../../node_modules/pixi.js/src/scene/text-html/utils/extractFontFamilies.ts", "../../node_modules/pixi.js/src/scene/text-html/utils/loadFontAsBase64.ts", "../../node_modules/pixi.js/src/scene/text-html/utils/loadFontCSS.ts", "../../node_modules/pixi.js/src/scene/text-html/utils/getFontCss.ts", "../../node_modules/pixi.js/src/scene/text-html/utils/getSVGUrl.ts", "../../node_modules/pixi.js/src/scene/text-html/utils/getTemporaryCanvasFromImage.ts", "../../node_modules/pixi.js/src/scene/text-html/utils/loadSVGImage.ts", "../../node_modules/pixi.js/src/scene/text-html/utils/measureHtmlText.ts", "../../node_modules/pixi.js/src/scene/text-html/HTMLTextSystem.ts", "../../node_modules/pixi.js/src/scene/mesh/shared/MeshGeometry.ts", "../../node_modules/pixi.js/src/scene/sprite-tiling/shader/tilingBit.ts", "../../node_modules/pixi.js/src/scene/sprite-tiling/shader/TilingSpriteShader.ts", "../../node_modules/pixi.js/src/scene/sprite-tiling/utils/QuadGeometry.ts", "../../node_modules/pixi.js/src/scene/sprite-tiling/utils/setPositions.ts", "../../node_modules/pixi.js/src/scene/sprite-tiling/utils/applyMatrix.ts", "../../node_modules/pixi.js/src/scene/sprite-tiling/utils/setUvs.ts", "../../node_modules/pixi.js/src/scene/sprite-tiling/TilingSpritePipe.ts", "../../node_modules/pixi.js/src/scene/mesh-plane/PlaneGeometry.ts", "../../node_modules/pixi.js/src/scene/sprite-nine-slice/NineSliceGeometry.ts", "../../node_modules/pixi.js/src/scene/sprite-nine-slice/NineSliceSpritePipe.ts", "../../node_modules/pixi.js/src/filters/FilterPipe.ts", "../../node_modules/pixi.js/lib/filters/defaults/defaultFilter.vert.mjs", "../../node_modules/pixi.js/lib/filters/defaults/passthrough/passthrough.frag.mjs", "../../node_modules/pixi.js/lib/filters/defaults/passthrough/passthrough.wgsl.mjs", "../../node_modules/pixi.js/src/filters/defaults/passthrough/PassthroughFilter.ts", "../../node_modules/pixi.js/src/scene/container/bounds/getRenderableBounds.ts", "../../node_modules/pixi.js/src/filters/FilterSystem.ts"],
4
+ "sourcesContent": ["\nmodule.exports = parse\n\n/**\n * expected argument lengths\n * @type {Object}\n */\n\nvar length = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0}\n\n/**\n * segment pattern\n * @type {RegExp}\n */\n\nvar segment = /([astvzqmhlc])([^astvzqmhlc]*)/ig\n\n/**\n * parse an svg path data string. Generates an Array\n * of commands where each command is an Array of the\n * form `[command, arg1, arg2, ...]`\n *\n * @param {String} path\n * @return {Array}\n */\n\nfunction parse(path) {\n\tvar data = []\n\tpath.replace(segment, function(_, command, args){\n\t\tvar type = command.toLowerCase()\n\t\targs = parseValues(args)\n\n\t\t// overloaded moveTo\n\t\tif (type == 'm' && args.length > 2) {\n\t\t\tdata.push([command].concat(args.splice(0, 2)))\n\t\t\ttype = 'l'\n\t\t\tcommand = command == 'm' ? 'l' : 'L'\n\t\t}\n\n\t\twhile (true) {\n\t\t\tif (args.length == length[type]) {\n\t\t\t\targs.unshift(command)\n\t\t\t\treturn data.push(args)\n\t\t\t}\n\t\t\tif (args.length < length[type]) throw new Error('malformed path data')\n\t\t\tdata.push([command].concat(args.splice(0, length[type])))\n\t\t}\n\t})\n\treturn data\n}\n\nvar number = /-?[0-9]*\\.?[0-9]+(?:e[-+]?\\d+)?/ig\n\nfunction parseValues(args) {\n\tvar numbers = args.match(number)\n\treturn numbers ? numbers.map(Number) : []\n}\n", "import type { ExtensionMetadata } from '../../../extensions/Extensions';\nimport type { ResolvedAsset } from '../../types';\nimport type { Loader } from '../Loader';\n\n/**\n * The extension priority for loader parsers.\n * Helpful when managing multiple parsers that share the same extension test.\n * The higher priority parsers will be checked first.\n * @category assets\n * @advanced\n */\nexport enum LoaderParserPriority\n{\n /** Generic parsers: txt, json, webfonts */\n Low = 0,\n /** PixiJS assets with generic extensions: spritesheets, bitmapfonts */\n Normal = 1,\n /** Specific texture types: svg, png, ktx, dds, basis */\n High = 2,\n}\n\n/**\n * A more verbose version of the LoaderParser, allowing you to set the loaded, parsed, and unloaded asset separately\n * @category assets\n * @advanced\n */\nexport interface LoaderParserAdvanced<\n ASSET = any,\n PARSED_ASSET = ASSET,\n UNLOAD_ASSET = ASSET,\n META_DATA = any,\n CONFIG = Record<string, any>\n>\n{\n /** Should be ExtensionType.LoaderParser */\n extension?: ExtensionMetadata;\n\n /** A config to adjust the parser */\n config?: CONFIG;\n\n /**\n * @deprecated Use `id` instead.\n */\n name?: string;\n /** The name of the parser (this can be used when specifying parser in a ResolvedAsset) */\n id: string;\n\n /**\n * Each URL to load will be tested here,\n * if the test is passed the assets are loaded using the load function below.\n * Good place to test for things like file extensions!\n * @param url - The URL to test\n * @param resolvedAsset - Any custom additional information relevant to the asset being loaded\n * @param loader - The loader instance\n */\n test?: (url: string, resolvedAsset?: ResolvedAsset<META_DATA>, loader?: Loader) => boolean;\n\n /**\n * This is the promise that loads the URL provided\n * resolves with a loaded asset if returned by the parser.\n * @param url - The URL to load\n * @param resolvedAsset - Any custom additional information relevant to the asset being loaded\n * @param loader - The loader instance\n */\n load?: <T>(url: string, resolvedAsset?: ResolvedAsset<META_DATA>, loader?: Loader) => Promise<ASSET | T>;\n\n /**\n * This function is used to test if the parse function should be run on the asset\n * If this returns true then parse is called with the asset\n * @param asset - The loaded asset data\n * @param resolvedAsset - Any custom additional information relevant to the asset being loaded\n * @param loader - The loader instance\n */\n testParse?: (asset: ASSET, resolvedAsset?: ResolvedAsset<META_DATA>, loader?: Loader) => Promise<boolean>;\n\n /**\n * Gets called on the asset it testParse passes. Useful to convert a raw asset into something more useful\n * @param asset - The loaded asset data\n * @param resolvedAsset - Any custom additional information relevant to the asset being loaded\n * @param loader - The loader instance\n */\n parse?: <T>(asset: ASSET, resolvedAsset?: ResolvedAsset<META_DATA>, loader?: Loader) => Promise<PARSED_ASSET | T>;\n\n /**\n * If an asset is parsed using this parser, the unload function will be called when the user requests an asset\n * to be unloaded. This is useful for things like sounds or textures that can be unloaded from memory\n * @param asset - The asset to unload/destroy\n * @param resolvedAsset - Any custom additional information relevant to the asset being loaded\n * @param loader - The loader instance\n */\n unload?: (asset: UNLOAD_ASSET, resolvedAsset?: ResolvedAsset<META_DATA>, loader?: Loader) => Promise<void> | void;\n}\n\n/**\n * The interface to define a loader parser *(all functions are optional)*.\n *\n * When you create a `parser` object, the flow for every asset loaded is:\n *\n * 1. `parser.test()` - Each URL to load will be tested here, if the test is passed the assets are\n * loaded using the load function below. Good place to test for things like file extensions!\n * 2. `parser.load()` - This is the promise that loads the URL provided resolves with a loaded asset\n * if returned by the parser.\n * 3. `parser.testParse()` - This function is used to test if the parse function should be run on the\n * asset If this returns true then parse is called with the asset\n * 4. `parse.parse()` - Gets called on the asset it testParse passes. Useful to convert a raw asset\n * into something more useful\n *\n * <br/>\n * Some loaders may only be used for parsing, some only for loading, and some for both!\n * @category assets\n * @advanced\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface LoaderParser<ASSET = any, META_DATA = any, CONFIG = Record<string, any>>\n extends LoaderParserAdvanced<ASSET, ASSET, ASSET, META_DATA, CONFIG> {}\n", "import { DOMAdapter } from '../environment/adapter';\n\nfunction assertPath(path: string)\n{\n if (typeof path !== 'string')\n {\n throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`);\n }\n}\n\nfunction removeUrlParams(url: string): string\n{\n const re = url.split('?')[0];\n\n return re.split('#')[0];\n}\n\nfunction escapeRegExp(string: string)\n{\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\nfunction replaceAll(str: string, find: string, replace: string)\n{\n return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);\n}\n\n// Resolves . and .. elements in a path with directory names\nfunction normalizeStringPosix(path: string, allowAboveRoot: boolean)\n{\n let res = '';\n let lastSegmentLength = 0;\n let lastSlash = -1;\n let dots = 0;\n let code = -1;\n\n for (let i = 0; i <= path.length; ++i)\n {\n if (i < path.length)\n {\n code = path.charCodeAt(i);\n }\n else if (code === 47)\n {\n break;\n }\n else\n {\n code = 47;\n }\n if (code === 47)\n {\n if (lastSlash === i - 1 || dots === 1)\n {\n // NOOP\n }\n else if (lastSlash !== i - 1 && dots === 2)\n {\n if (\n res.length < 2\n || lastSegmentLength !== 2\n || res.charCodeAt(res.length - 1) !== 46\n || res.charCodeAt(res.length - 2) !== 46\n )\n {\n if (res.length > 2)\n {\n const lastSlashIndex = res.lastIndexOf('/');\n\n if (lastSlashIndex !== res.length - 1)\n {\n if (lastSlashIndex === -1)\n {\n res = '';\n lastSegmentLength = 0;\n }\n else\n {\n res = res.slice(0, lastSlashIndex);\n lastSegmentLength = res.length - 1 - res.lastIndexOf('/');\n }\n lastSlash = i;\n dots = 0;\n continue;\n }\n }\n else if (res.length === 2 || res.length === 1)\n {\n res = '';\n lastSegmentLength = 0;\n lastSlash = i;\n dots = 0;\n continue;\n }\n }\n if (allowAboveRoot)\n {\n if (res.length > 0)\n { res += '/..'; }\n else\n { res = '..'; }\n lastSegmentLength = 2;\n }\n }\n else\n {\n if (res.length > 0)\n {\n res += `/${path.slice(lastSlash + 1, i)}`;\n }\n else\n {\n res = path.slice(lastSlash + 1, i);\n }\n lastSegmentLength = i - lastSlash - 1;\n }\n lastSlash = i;\n dots = 0;\n }\n else if (code === 46 && dots !== -1)\n {\n ++dots;\n }\n else\n {\n dots = -1;\n }\n }\n\n return res;\n}\n\n/**\n * Path utilities for working with URLs and file paths in a cross-platform way.\n * All paths that are passed in will become normalized to have posix separators.\n * ```js\n * import { path } from 'pixi.js';\n *\n * path.normalize('http://www.example.com/foo/bar/../baz'); // http://www.example.com/foo/baz\n * ```\n * @category utils\n * @advanced\n */\nexport interface Path\n{\n /**\n * Converts a path to posix format.\n * @param path - The path to convert to posix\n */\n toPosix: (path: string) => string;\n /**\n * Checks if the path is a URL e.g. http://, https://\n * @param path - The path to check\n */\n isUrl: (path: string) => boolean;\n /**\n * Checks if the path is a data URL\n * @param path - The path to check\n */\n isDataUrl: (path: string) => boolean;\n /**\n * Checks if the path is a blob URL\n * @param path - The path to check\n */\n isBlobUrl: (path: string) => boolean;\n /**\n * Checks if the path has a protocol e.g. http://, https://, file:///, data:, blob:, C:/\n * This will return true for windows file paths\n * @param path - The path to check\n */\n hasProtocol: (path: string) => boolean;\n /**\n * Returns the protocol of the path e.g. http://, https://, file:///, data:, blob:, C:/\n * @param path - The path to get the protocol from\n */\n getProtocol: (path: string) => string;\n /**\n * Converts URL to an absolute path.\n * When loading from a Web Worker, we must use absolute paths.\n * If the URL is already absolute we return it as is\n * If it's not, we convert it\n * @param url - The URL to test\n * @param baseUrl - The base URL to use\n * @param rootUrl - The root URL to use\n */\n toAbsolute: (url: string, baseUrl?: string, rootUrl?: string) => string;\n /**\n * Normalizes the given path, resolving '..' and '.' segments\n * @param path - The path to normalize\n */\n normalize: (path: string) => string;\n /**\n * Determines if path is an absolute path.\n * Absolute paths can be urls, data urls, or paths on disk\n * @param path - The path to test\n */\n isAbsolute: (path: string) => boolean;\n /**\n * Joins all given path segments together using the platform-specific separator as a delimiter,\n * then normalizes the resulting path\n * @param paths - The segments of the path to join\n */\n join: (...paths: string[]) => string;\n /**\n * Returns the directory name of a path\n * @param path - The path to parse\n */\n dirname: (path: string) => string;\n /**\n * Returns the root of the path e.g. /, C:/, file:///, http://domain.com/\n * @param path - The path to parse\n */\n rootname: (path: string) => string;\n /**\n * Returns the last portion of a path\n * @param path - The path to test\n * @param ext - Optional extension to remove\n */\n basename: (path: string, ext?: string) => string;\n /**\n * Returns the extension of the path, from the last occurrence of the . (period) character to end of string in the last\n * portion of the path. If there is no . in the last portion of the path, or if there are no . characters other than\n * the first character of the basename of path, an empty string is returned.\n * @param path - The path to parse\n */\n extname: (path: string) => string;\n /**\n * Parses a path into an object containing the 'root', `dir`, `base`, `ext`, and `name` properties.\n * @param path - The path to parse\n */\n parse: (path: string) => { root?: string, dir?: string, base?: string, ext?: string, name?: string };\n sep: string,\n delimiter: string,\n joinExtensions: string[],\n}\n\n/**\n * Path utilities for working with URLs and file paths in a cross-platform way.\n * All paths that are passed in will become normalized to have posix separators.\n * @example\n * ```ts\n * import { path } from 'pixi.js';\n *\n * // Basic path normalization\n * path.normalize('http://www.example.com/foo/bar/../baz');\n * // -> 'http://www.example.com/foo/baz'\n *\n * // Working with file paths\n * path.join('assets', 'images', 'sprite.png');\n * // -> 'assets/images/sprite.png'\n *\n * // URL handling\n * path.toAbsolute('images/texture.png', 'http://example.com/assets/');\n * // -> 'http://example.com/assets/images/texture.png'\n * ```\n * @remarks\n * - Normalizes to POSIX separators (forward slashes)\n * - Handles URLs, data URLs, and file paths\n * - Supports path composition and decomposition\n * - Common in asset loading and URL management\n * @category utils\n * @standard\n * @see {@link Path} For full API reference\n * @see {@link DOMAdapter} For platform-specific path handling\n */\nexport const path: Path = {\n /**\n * Converts a path to posix format.\n * @param path - The path to convert to posix\n * @example\n * ```ts\n * // Convert a Windows path to POSIX format\n * path.toPosix('C:\\\\Users\\\\User\\\\Documents\\\\file.txt');\n * // -> 'C:/Users/User/Documents/file.txt'\n * ```\n */\n toPosix(path: string) { return replaceAll(path, '\\\\', '/'); },\n /**\n * Checks if the path is a URL e.g. http://, https://\n * @param path - The path to check\n * @example\n * ```ts\n * // Check if a path is a URL\n * path.isUrl('http://www.example.com');\n * // -> true\n * path.isUrl('C:/Users/User/Documents/file.txt');\n * // -> false\n * ```\n */\n isUrl(path: string) { return (/^https?:/).test(this.toPosix(path)); },\n /**\n * Checks if the path is a data URL\n * @param path - The path to check\n * @example\n * ```ts\n * // Check if a path is a data URL\n * path.isDataUrl('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...');\n * // -> true\n * ```\n */\n isDataUrl(path: string)\n {\n // eslint-disable-next-line max-len\n return (/^data:([a-z]+\\/[a-z0-9-+.]+(;[a-z0-9-.!#$%*+.{}|~`]+=[a-z0-9-.!#$%*+.{}()_|~`]+)*)?(;base64)?,([a-z0-9!$&',()*+;=\\-._~:@\\/?%\\s<>]*?)$/i)\n .test(path);\n },\n /**\n * Checks if the path is a blob URL\n * @param path - The path to check\n * @example\n * ```ts\n * // Check if a path is a blob URL\n * path.isBlobUrl('blob:http://www.example.com/12345678-1234-1234-1234-123456789012');\n * // -> true\n * ```\n */\n isBlobUrl(path: string)\n {\n // Not necessary to have an exact regex to match the blob URLs\n return path.startsWith('blob:');\n },\n /**\n * Checks if the path has a protocol e.g. http://, https://, file:///, data:, blob:, C:/\n * This will return true for windows file paths\n * @param path - The path to check\n * @example\n * ```ts\n * // Check if a path has a protocol\n * path.hasProtocol('http://www.example.com');\n * // -> true\n * path.hasProtocol('C:/Users/User/Documents/file.txt');\n * // -> true\n * ```\n */\n hasProtocol(path: string) { return (/^[^/:]+:/).test(this.toPosix(path)); },\n /**\n * Returns the protocol of the path e.g. http://, https://, file:///, data:, blob:, C:/\n * @param path - The path to get the protocol from\n * @example\n * ```ts\n * // Get the protocol from a URL\n * path.getProtocol('http://www.example.com/path/to/resource');\n * // -> 'http://'\n * // Get the protocol from a file path\n * path.getProtocol('C:/Users/User/Documents/file.txt');\n * // -> 'C:/'\n * ```\n */\n getProtocol(path: string)\n {\n assertPath(path);\n path = this.toPosix(path);\n\n const matchFile = (/^file:\\/\\/\\//).exec(path);\n\n if (matchFile)\n {\n return matchFile[0];\n }\n\n const matchProtocol = (/^[^/:]+:\\/{0,2}/).exec(path);\n\n if (matchProtocol)\n {\n return matchProtocol[0];\n }\n\n return '';\n },\n\n /**\n * Converts URL to an absolute path.\n * When loading from a Web Worker, we must use absolute paths.\n * If the URL is already absolute we return it as is\n * If it's not, we convert it\n * @param url - The URL to test\n * @param customBaseUrl - The base URL to use\n * @param customRootUrl - The root URL to use\n * @example\n * ```ts\n * // Convert a relative URL to an absolute path\n * path.toAbsolute('images/texture.png', 'http://example.com/assets/');\n * // -> 'http://example.com/assets/images/texture.png'\n * ```\n */\n toAbsolute(url: string, customBaseUrl?: string, customRootUrl?: string)\n {\n assertPath(url);\n\n if (this.isDataUrl(url) || this.isBlobUrl(url)) return url;\n\n const baseUrl = removeUrlParams(this.toPosix(customBaseUrl ?? DOMAdapter.get().getBaseUrl()));\n const rootUrl = removeUrlParams(this.toPosix(customRootUrl ?? this.rootname(baseUrl)));\n\n url = this.toPosix(url);\n\n // root relative url\n if (url.startsWith('/'))\n {\n return path.join(rootUrl, url.slice(1));\n }\n\n const absolutePath = this.isAbsolute(url) ? url : this.join(baseUrl, url);\n\n return absolutePath;\n },\n\n /**\n * Normalizes the given path, resolving '..' and '.' segments\n * @param path - The path to normalize\n * @example\n * ```ts\n * // Normalize a path with relative segments\n * path.normalize('http://www.example.com/foo/bar/../baz');\n * // -> 'http://www.example.com/foo/baz'\n * // Normalize a file path with relative segments\n * path.normalize('C:\\\\Users\\\\User\\\\Documents\\\\..\\\\file.txt');\n * // -> 'C:/Users/User/file.txt'\n * ```\n */\n normalize(path: string)\n {\n assertPath(path);\n\n if (path.length === 0) return '.';\n if (this.isDataUrl(path) || this.isBlobUrl(path)) return path;\n\n path = this.toPosix(path);\n\n let protocol = '';\n const isAbsolute = path.startsWith('/');\n\n if (this.hasProtocol(path))\n {\n protocol = this.rootname(path);\n path = path.slice(protocol.length);\n }\n\n const trailingSeparator = path.endsWith('/');\n\n // Normalize the path\n path = normalizeStringPosix(path, false);\n\n if (path.length > 0 && trailingSeparator) path += '/';\n if (isAbsolute) return `/${path}`;\n\n return protocol + path;\n },\n\n /**\n * Determines if path is an absolute path.\n * Absolute paths can be urls, data urls, or paths on disk\n * @param path - The path to test\n * @example\n * ```ts\n * // Check if a path is absolute\n * path.isAbsolute('http://www.example.com/foo/bar');\n * // -> true\n * path.isAbsolute('C:/Users/User/Documents/file.txt');\n * // -> true\n * ```\n */\n isAbsolute(path: string)\n {\n assertPath(path);\n path = this.toPosix(path);\n\n if (this.hasProtocol(path)) return true;\n\n return path.startsWith('/');\n },\n\n /**\n * Joins all given path segments together using the platform-specific separator as a delimiter,\n * then normalizes the resulting path\n * @param segments - The segments of the path to join\n * @example\n * ```ts\n * // Join multiple path segments\n * path.join('assets', 'images', 'sprite.png');\n * // -> 'assets/images/sprite.png'\n * // Join with relative segments\n * path.join('assets', 'images', '../textures', 'sprite.png');\n * // -> 'assets/textures/sprite.png'\n * ```\n */\n join(...segments: string[])\n {\n if (segments.length === 0)\n { return '.'; }\n let joined;\n\n for (let i = 0; i < segments.length; ++i)\n {\n const arg = segments[i];\n\n assertPath(arg);\n if (arg.length > 0)\n {\n if (joined === undefined) joined = arg;\n else\n {\n const prevArg = segments[i - 1] ?? '';\n\n if (this.joinExtensions.includes(this.extname(prevArg).toLowerCase()))\n {\n joined += `/../${arg}`;\n }\n else\n {\n joined += `/${arg}`;\n }\n }\n }\n }\n if (joined === undefined) { return '.'; }\n\n return this.normalize(joined);\n },\n\n /**\n * Returns the directory name of a path\n * @param path - The path to parse\n * @example\n * ```ts\n * // Get the directory name of a path\n * path.dirname('http://www.example.com/foo/bar/baz.png');\n * // -> 'http://www.example.com/foo/bar'\n * // Get the directory name of a file path\n * path.dirname('C:/Users/User/Documents/file.txt');\n * // -> 'C:/Users/User/Documents'\n * ```\n */\n dirname(path: string)\n {\n assertPath(path);\n if (path.length === 0) return '.';\n path = this.toPosix(path);\n let code = path.charCodeAt(0);\n const hasRoot = code === 47;\n let end = -1;\n let matchedSlash = true;\n\n const proto = this.getProtocol(path);\n const origpath = path;\n\n path = path.slice(proto.length);\n\n for (let i = path.length - 1; i >= 1; --i)\n {\n code = path.charCodeAt(i);\n if (code === 47)\n {\n if (!matchedSlash)\n {\n end = i;\n break;\n }\n }\n else\n {\n // We saw the first non-path separator\n matchedSlash = false;\n }\n }\n\n // if end is -1 and its a url then we need to add the path back\n // eslint-disable-next-line no-nested-ternary\n if (end === -1) return hasRoot ? '/' : this.isUrl(origpath) ? proto + path : proto;\n if (hasRoot && end === 1) return '//';\n\n return proto + path.slice(0, end);\n },\n\n /**\n * Returns the root of the path e.g. /, C:/, file:///, http://domain.com/\n * @param path - The path to parse\n * @example\n * ```ts\n * // Get the root of a URL\n * path.rootname('http://www.example.com/foo/bar/baz.png');\n * // -> 'http://www.example.com/'\n * // Get the root of a file path\n * path.rootname('C:/Users/User/Documents/file.txt');\n * // -> 'C:/'\n * ```\n */\n rootname(path: string)\n {\n assertPath(path);\n path = this.toPosix(path);\n\n let root = '';\n\n if (path.startsWith('/')) root = '/';\n else\n {\n root = this.getProtocol(path);\n }\n\n if (this.isUrl(path))\n {\n // need to find the first path separator\n const index = path.indexOf('/', root.length);\n\n if (index !== -1)\n {\n root = path.slice(0, index);\n }\n else root = path;\n\n if (!root.endsWith('/')) root += '/';\n }\n\n return root;\n },\n\n /**\n * Returns the last portion of a path\n * @param path - The path to test\n * @param ext - Optional extension to remove\n * @example\n * ```ts\n * // Get the basename of a URL\n * path.basename('http://www.example.com/foo/bar/baz.png');\n * // -> 'baz.png'\n * // Get the basename of a file path\n * path.basename('C:/Users/User/Documents/file.txt');\n * // -> 'file.txt'\n * ```\n */\n basename(path: string, ext?: string)\n {\n assertPath(path);\n if (ext) assertPath(ext);\n\n path = removeUrlParams(this.toPosix(path));\n\n let start = 0;\n let end = -1;\n let matchedSlash = true;\n let i: number;\n\n if (ext !== undefined && ext.length > 0 && ext.length <= path.length)\n {\n if (ext.length === path.length && ext === path) return '';\n let extIdx = ext.length - 1;\n let firstNonSlashEnd = -1;\n\n for (i = path.length - 1; i >= 0; --i)\n {\n const code = path.charCodeAt(i);\n\n if (code === 47)\n {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash)\n {\n start = i + 1;\n break;\n }\n }\n else\n {\n if (firstNonSlashEnd === -1)\n {\n // We saw the first non-path separator, remember this index in case\n // we need it if the extension ends up not matching\n matchedSlash = false;\n firstNonSlashEnd = i + 1;\n }\n if (extIdx >= 0)\n {\n // Try to match the explicit extension\n if (code === ext.charCodeAt(extIdx))\n {\n if (--extIdx === -1)\n {\n // We matched the extension, so mark this as the end of our path\n // component\n end = i;\n }\n }\n else\n {\n // Extension does not match, so our result is the entire path\n // component\n extIdx = -1;\n end = firstNonSlashEnd;\n }\n }\n }\n }\n\n if (start === end) end = firstNonSlashEnd; else if (end === -1) end = path.length;\n\n return path.slice(start, end);\n }\n for (i = path.length - 1; i >= 0; --i)\n {\n if (path.charCodeAt(i) === 47)\n {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash)\n {\n start = i + 1;\n break;\n }\n }\n else if (end === -1)\n {\n // We saw the first non-path separator, mark this as the end of our\n // path component\n matchedSlash = false;\n end = i + 1;\n }\n }\n\n if (end === -1) return '';\n\n return path.slice(start, end);\n },\n\n /**\n * Returns the extension of the path, from the last occurrence of the . (period) character to end of string in the last\n * portion of the path. If there is no . in the last portion of the path, or if there are no . characters other than\n * the first character of the basename of path, an empty string is returned.\n * @param path - The path to parse\n * @example\n * ```ts\n * // Get the extension of a URL\n * path.extname('http://www.example.com/foo/bar/baz.png');\n * // -> '.png'\n * // Get the extension of a file path\n * path.extname('C:/Users/User/Documents/file.txt');\n * // -> '.txt'\n * ```\n */\n extname(path: string)\n {\n assertPath(path);\n path = removeUrlParams(this.toPosix(path));\n\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n\n for (let i = path.length - 1; i >= 0; --i)\n {\n const code = path.charCodeAt(i);\n\n if (code === 47)\n {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash)\n {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1)\n {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (code === 46)\n {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1) startDot = i;\n else if (preDotState !== 1) preDotState = 1;\n }\n else if (startDot !== -1)\n {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n\n if (\n startDot === -1 || end === -1\n // We saw a non-dot character immediately before the dot\n || preDotState === 0\n // The (right-most) trimmed path component is exactly '..'\n // eslint-disable-next-line no-mixed-operators/no-mixed-operators\n || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1\n )\n {\n return '';\n }\n\n return path.slice(startDot, end);\n },\n\n /**\n * Parses a path into an object containing the 'root', `dir`, `base`, `ext`, and `name` properties.\n * @param path - The path to parse\n * @example\n * ```ts\n * // Parse a URL\n * const parsed = path.parse('http://www.example.com/foo/bar/baz.png');\n * // -> {\n * // root: 'http://www.example.com/',\n * // dir: 'http://www.example.com/foo/bar',\n * // base: 'baz.png',\n * // ext: '.png',\n * // name: 'baz'\n * // }\n * // Parse a file path\n * const parsedFile = path.parse('C:/Users/User/Documents/file.txt');\n * // -> {\n * // root: 'C:/',\n * // dir: 'C:/Users/User/Documents',\n * // base: 'file.txt',\n * // ext: '.txt',\n * // name: 'file'\n * // }\n * ```\n */\n parse(path: string)\n {\n assertPath(path);\n\n const ret = { root: '', dir: '', base: '', ext: '', name: '' };\n\n if (path.length === 0) return ret;\n path = removeUrlParams(this.toPosix(path));\n\n let code = path.charCodeAt(0);\n const isAbsolute = this.isAbsolute(path);\n let start: number;\n const protocol = '';\n\n ret.root = this.rootname(path);\n\n if (isAbsolute || this.hasProtocol(path))\n {\n start = 1;\n }\n else\n {\n start = 0;\n }\n let startDot = -1;\n let startPart = 0;\n let end = -1;\n let matchedSlash = true;\n let i = path.length - 1;\n\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n let preDotState = 0;\n\n // Get non-dir info\n for (; i >= start; --i)\n {\n code = path.charCodeAt(i);\n if (code === 47)\n {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash)\n {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1)\n {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (code === 46)\n {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1) startDot = i;\n else if (preDotState !== 1) preDotState = 1;\n }\n else if (startDot !== -1)\n {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n\n if (\n startDot === -1 || end === -1\n // We saw a non-dot character immediately before the dot\n || preDotState === 0\n // The (right-most) trimmed path component is exactly '..'\n // eslint-disable-next-line no-mixed-operators/no-mixed-operators\n || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1\n )\n {\n if (end !== -1)\n {\n if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);\n else ret.base = ret.name = path.slice(startPart, end);\n }\n }\n else\n {\n if (startPart === 0 && isAbsolute)\n {\n ret.name = path.slice(1, startDot);\n ret.base = path.slice(1, end);\n }\n else\n {\n ret.name = path.slice(startPart, startDot);\n ret.base = path.slice(startPart, end);\n }\n ret.ext = path.slice(startDot, end);\n }\n\n ret.dir = this.dirname(path);\n if (protocol) ret.dir = protocol + ret.dir;\n\n return ret;\n },\n\n sep: '/',\n delimiter: ':',\n joinExtensions: ['.html'],\n} as Path;\n", "/**\n * @param input\n * @param transform\n * @param forceTransform\n * @internal\n */\nexport const convertToList = <T>(\n input: string | T | (string | T)[],\n transform?: (input: string) => T,\n forceTransform = false\n): T[] =>\n{\n if (!Array.isArray(input))\n {\n input = [input as T];\n }\n\n if (!transform)\n {\n return input as T[];\n }\n\n return (input as (string | T)[]).map((item): T =>\n {\n if (typeof item === 'string' || forceTransform)\n {\n return transform(item as string);\n }\n\n return item as T;\n });\n};\n", "function processX(base: string, ids: string[][], depth: number, result: string[], tags: string[])\n{\n const id = ids[depth];\n\n for (let i = 0; i < id.length; i++)\n {\n const value = id[i];\n\n if (depth < ids.length - 1)\n {\n processX(base.replace(result[depth], value), ids, depth + 1, result, tags);\n }\n else\n {\n tags.push(base.replace(result[depth], value));\n }\n }\n}\n\n/**\n * Creates a list of all possible combinations of the given strings.\n * @example\n * const out2 = createStringVariations('name is {chicken,wolf,sheep}');\n * console.log(out2); // [ 'name is chicken', 'name is wolf', 'name is sheep' ]\n * @param string - The string to process\n * @internal\n */\nexport function createStringVariations(string: string): string[]\n{\n const regex = /\\{(.*?)\\}/g;\n\n const result = string.match(regex);\n\n const tags: string[] = [];\n\n if (result)\n {\n const ids: string[][] = [];\n\n result.forEach((vars) =>\n {\n // first remove the brackets...\n const split = vars.substring(1, vars.length - 1).split(',');\n\n ids.push(split);\n });\n\n processX(string, ids, 0, result, tags);\n }\n else\n {\n tags.push(string);\n }\n\n return tags;\n}\n", "/**\n * Checks if the given value is an array.\n * @param item - The item to test\n * @internal\n */\nexport const isSingleItem = (item: unknown): boolean => (!Array.isArray(item));\n", "import { warn } from '../../utils/logging/warn';\nimport { path } from '../../utils/path';\nimport { convertToList } from '../utils/convertToList';\nimport { createStringVariations } from '../utils/createStringVariations';\nimport { isSingleItem } from '../utils/isSingleItem';\n\nimport type {\n ArrayOr,\n AssetsBundle,\n AssetsManifest,\n AssetSrc,\n ResolvedAsset,\n ResolvedSrc,\n UnresolvedAsset,\n} from '../types';\nimport type { PreferOrder, ResolveURLParser } from './types';\n\n/**\n * Options for how the resolver deals with generating bundle ids\n * @category assets\n * @advanced\n */\nexport interface BundleIdentifierOptions\n{\n /** The character that is used to connect the bundleId and the assetId when generating a bundle asset id key */\n connector?: string;\n /**\n * A function that generates a bundle asset id key from a bundleId and an assetId\n * @param bundleId - the bundleId\n * @param assetId - the assetId\n * @returns the bundle asset id key\n */\n createBundleAssetId?: (bundleId: string, assetId: string) => string;\n /**\n * A function that generates an assetId from a bundle asset id key. This is the reverse of generateBundleAssetId\n * @param bundleId - the bundleId\n * @param assetBundleId - the bundle asset id key\n * @returns the assetId\n */\n extractAssetIdFromBundle?: (bundleId: string, assetBundleId: string) => string;\n}\n\n/**\n * A class that is responsible for resolving mapping asset URLs to keys.\n * At its most basic it can be used for Aliases:\n *\n * ```js\n * resolver.add('foo', 'bar');\n * resolver.resolveUrl('foo') // => 'bar'\n * ```\n *\n * It can also be used to resolve the most appropriate asset for a given URL:\n *\n * ```js\n * resolver.prefer({\n * params: {\n * format: 'webp',\n * resolution: 2,\n * }\n * });\n *\n * resolver.add('foo', ['bar@2x.webp', 'bar@2x.png', 'bar.webp', 'bar.png']);\n *\n * resolver.resolveUrl('foo') // => 'bar@2x.webp'\n * ```\n * Other features include:\n * - Ability to process a manifest file to get the correct understanding of how to resolve all assets\n * - Ability to add custom parsers for specific file types\n * - Ability to add custom prefer rules\n *\n * This class only cares about the URL, not the loading of the asset itself.\n *\n * It is not intended that this class is created by developers - its part of the Asset class\n * This is the third major system of PixiJS' main Assets class\n * @category assets\n * @advanced\n */\nexport class Resolver\n{\n /**\n * The prefix that denotes a URL is for a retina asset.\n * @default /@([0-9\\.]+)x/\n * @example `@2x`\n */\n public static RETINA_PREFIX = /@([0-9\\.]+)x/;\n\n private readonly _defaultBundleIdentifierOptions: Required<BundleIdentifierOptions> = {\n connector: '-',\n createBundleAssetId: (bundleId, assetId) =>\n `${bundleId}${this._bundleIdConnector}${assetId}`,\n extractAssetIdFromBundle: (bundleId, assetBundleId) =>\n assetBundleId.replace(`${bundleId}${this._bundleIdConnector}`, ''),\n };\n\n /** The character that is used to connect the bundleId and the assetId when generating a bundle asset id key */\n private _bundleIdConnector = this._defaultBundleIdentifierOptions.connector;\n\n /**\n * A function that generates a bundle asset id key from a bundleId and an assetId\n * @param bundleId - the bundleId\n * @param assetId - the assetId\n * @returns the bundle asset id key\n */\n private _createBundleAssetId: (\n bundleId: string,\n assetId: string\n ) => string = this._defaultBundleIdentifierOptions.createBundleAssetId;\n\n /**\n * A function that generates an assetId from a bundle asset id key. This is the reverse of generateBundleAssetId\n * @param bundleId - the bundleId\n * @param assetBundleId - the bundle asset id key\n * @returns the assetId\n */\n private _extractAssetIdFromBundle: (\n bundleId: string,\n assetBundleId: string\n ) => string = this._defaultBundleIdentifierOptions.extractAssetIdFromBundle;\n\n private _assetMap: Record<string, ResolvedAsset[]> = {};\n private _preferredOrder: PreferOrder[] = [];\n private readonly _parsers: ResolveURLParser[] = [];\n\n private _resolverHash: Record<string, ResolvedAsset> = {};\n private _rootPath: string;\n private _basePath: string;\n private _manifest: AssetsManifest;\n private _bundles: Record<string, string[]> = {};\n private _defaultSearchParams: string;\n\n /**\n * Override how the resolver deals with generating bundle ids.\n * must be called before any bundles are added\n * @param bundleIdentifier - the bundle identifier options\n */\n public setBundleIdentifier(bundleIdentifier: BundleIdentifierOptions): void\n {\n this._bundleIdConnector = bundleIdentifier.connector ?? this._bundleIdConnector;\n this._createBundleAssetId = bundleIdentifier.createBundleAssetId ?? this._createBundleAssetId;\n this._extractAssetIdFromBundle = bundleIdentifier.extractAssetIdFromBundle ?? this._extractAssetIdFromBundle;\n\n if (this._extractAssetIdFromBundle('foo', this._createBundleAssetId('foo', 'bar')) !== 'bar')\n {\n throw new Error('[Resolver] GenerateBundleAssetId are not working correctly');\n }\n }\n\n /**\n * Let the resolver know which assets you prefer to use when resolving assets.\n * Multiple prefer user defined rules can be added.\n * @example\n * resolver.prefer({\n * // first look for something with the correct format, and then then correct resolution\n * priority: ['format', 'resolution'],\n * params:{\n * format:'webp', // prefer webp images\n * resolution: 2, // prefer a resolution of 2\n * }\n * })\n * resolver.add('foo', ['bar@2x.webp', 'bar@2x.png', 'bar.webp', 'bar.png']);\n * resolver.resolveUrl('foo') // => 'bar@2x.webp'\n * @param preferOrders - the prefer options\n */\n public prefer(...preferOrders: PreferOrder[]): void\n {\n preferOrders.forEach((prefer) =>\n {\n this._preferredOrder.push(prefer);\n\n if (!prefer.priority)\n {\n // generate the priority based on the order of the object\n prefer.priority = Object.keys(prefer.params);\n }\n });\n\n this._resolverHash = {};\n }\n\n /**\n * Set the base path to prepend to all urls when resolving\n * @example\n * resolver.basePath = 'https://home.com/';\n * resolver.add('foo', 'bar.ong');\n * resolver.resolveUrl('foo', 'bar.png'); // => 'https://home.com/bar.png'\n * @param basePath - the base path to use\n */\n public set basePath(basePath: string)\n {\n this._basePath = basePath;\n }\n\n public get basePath(): string\n {\n return this._basePath;\n }\n\n /**\n * Set the root path for root-relative URLs. By default the `basePath`'s root is used. If no `basePath` is set, then the\n * default value for browsers is `window.location.origin`\n * @example\n * // Application hosted on https://home.com/some-path/index.html\n * resolver.basePath = 'https://home.com/some-path/';\n * resolver.rootPath = 'https://home.com/';\n * resolver.add('foo', '/bar.png');\n * resolver.resolveUrl('foo', '/bar.png'); // => 'https://home.com/bar.png'\n * @param rootPath - the root path to use\n */\n public set rootPath(rootPath: string)\n {\n this._rootPath = rootPath;\n }\n\n public get rootPath(): string\n {\n return this._rootPath;\n }\n\n /**\n * All the active URL parsers that help the parser to extract information and create\n * an asset object-based on parsing the URL itself.\n *\n * Can be added using the extensions API\n * @example\n * resolver.add('foo', [\n * {\n * resolution: 2,\n * format: 'png',\n * src: 'image@2x.png',\n * },\n * {\n * resolution:1,\n * format:'png',\n * src: 'image.png',\n * },\n * ]);\n *\n * // With a url parser the information such as resolution and file format could extracted from the url itself:\n * extensions.add({\n * extension: ExtensionType.ResolveParser,\n * test: loadTextures.test, // test if url ends in an image\n * parse: (value: string) =>\n * ({\n * resolution: parseFloat(Resolver.RETINA_PREFIX.exec(value)?.[1] ?? '1'),\n * format: value.split('.').pop(),\n * src: value,\n * }),\n * });\n *\n * // Now resolution and format can be extracted from the url\n * resolver.add('foo', [\n * 'image@2x.png',\n * 'image.png',\n * ]);\n */\n public get parsers(): ResolveURLParser[]\n {\n return this._parsers;\n }\n\n /** Used for testing, this resets the resolver to its initial state */\n public reset(): void\n {\n this.setBundleIdentifier(this._defaultBundleIdentifierOptions);\n\n this._assetMap = {};\n this._preferredOrder = [];\n // Do not reset this._parsers\n\n this._resolverHash = {};\n this._rootPath = null;\n this._basePath = null;\n this._manifest = null;\n this._bundles = {};\n this._defaultSearchParams = null;\n }\n\n /**\n * Sets the default URL search parameters for the URL resolver. The urls can be specified as a string or an object.\n * @param searchParams - the default url parameters to append when resolving urls\n */\n public setDefaultSearchParams(searchParams: string | Record<string, unknown>): void\n {\n if (typeof searchParams === 'string')\n {\n this._defaultSearchParams = searchParams;\n }\n else\n {\n const queryValues = searchParams as Record<string, any>;\n\n this._defaultSearchParams = Object.keys(queryValues)\n .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryValues[key])}`)\n .join('&');\n }\n }\n\n /**\n * Returns the aliases for a given asset\n * @param asset - the asset to get the aliases for\n */\n public getAlias(asset: UnresolvedAsset): string[]\n {\n const { alias, src } = asset;\n const aliasesToUse = convertToList<ArrayOr<string | AssetSrc>>(\n alias || src, (value: string | AssetSrc) =>\n {\n if (typeof value === 'string') return value;\n\n if (Array.isArray(value)) return value.map((v) => (v as ResolvedSrc)?.src ?? v);\n\n if (value?.src) return value.src;\n\n return value;\n }, true) as string[];\n\n return aliasesToUse;\n }\n\n /**\n * Add a manifest to the asset resolver. This is a nice way to add all the asset information in one go.\n * generally a manifest would be built using a tool.\n * @param manifest - the manifest to add to the resolver\n */\n public addManifest(manifest: AssetsManifest): void\n {\n if (this._manifest)\n {\n // #if _DEBUG\n warn('[Resolver] Manifest already exists, this will be overwritten');\n // #endif\n }\n\n this._manifest = manifest;\n\n manifest.bundles.forEach((bundle) =>\n {\n this.addBundle(bundle.name, bundle.assets);\n });\n }\n\n /**\n * This adds a bundle of assets in one go so that you can resolve them as a group.\n * For example you could add a bundle for each screen in you pixi app\n * @example\n * resolver.addBundle('animals', [\n * { alias: 'bunny', src: 'bunny.png' },\n * { alias: 'chicken', src: 'chicken.png' },\n * { alias: 'thumper', src: 'thumper.png' },\n * ]);\n * // or\n * resolver.addBundle('animals', {\n * bunny: 'bunny.png',\n * chicken: 'chicken.png',\n * thumper: 'thumper.png',\n * });\n *\n * const resolvedAssets = await resolver.resolveBundle('animals');\n * @param bundleId - The id of the bundle to add\n * @param assets - A record of the asset or assets that will be chosen from when loading via the specified key\n */\n public addBundle(bundleId: string, assets: AssetsBundle['assets']): void\n {\n const assetNames: string[] = [];\n let convertedAssets: UnresolvedAsset[] = assets as UnresolvedAsset[];\n\n if (!Array.isArray(assets))\n {\n // convert to array...\n convertedAssets = Object.entries(assets).map(([alias, src]) =>\n {\n if (typeof src === 'string' || Array.isArray(src))\n {\n return { alias, src };\n }\n\n return { alias, ...src };\n });\n }\n\n // when storing keys against a bundle we prepend the bundleId to each asset key\n // and pass it through as an additional alias for the asset\n // this keeps clashing ids separate on a per-bundle basis\n // you can also resolve a file using the bundleId-assetId syntax\n\n convertedAssets.forEach((asset) =>\n {\n const srcs = asset.src;\n const aliases = asset.alias;\n let ids: string[];\n\n if (typeof aliases === 'string')\n {\n const bundleAssetId = this._createBundleAssetId(bundleId, aliases);\n\n assetNames.push(bundleAssetId);\n ids = [aliases, bundleAssetId];\n }\n else\n {\n const bundleIds = aliases.map((name) => this._createBundleAssetId(bundleId, name));\n\n assetNames.push(...bundleIds);\n ids = [...aliases, ...bundleIds];\n }\n\n this.add({\n ...asset,\n ...{\n alias: ids,\n src: srcs,\n }\n });\n });\n\n this._bundles[bundleId] = assetNames;\n }\n\n /**\n * Tells the resolver what keys are associated with witch asset.\n * The most important thing the resolver does\n * @example\n * // Single key, single asset:\n * resolver.add({alias: 'foo', src: 'bar.png');\n * resolver.resolveUrl('foo') // => 'bar.png'\n *\n * // Multiple keys, single asset:\n * resolver.add({alias: ['foo', 'boo'], src: 'bar.png'});\n * resolver.resolveUrl('foo') // => 'bar.png'\n * resolver.resolveUrl('boo') // => 'bar.png'\n *\n * // Multiple keys, multiple assets:\n * resolver.add({alias: ['foo', 'boo'], src: ['bar.png', 'bar.webp']});\n * resolver.resolveUrl('foo') // => 'bar.png'\n *\n * // Add custom data attached to the resolver\n * Resolver.add({\n * alias: 'bunnyBooBooSmooth',\n * src: 'bunny{png,webp}',\n * data: { scaleMode:SCALE_MODES.NEAREST }, // Base texture options\n * });\n *\n * resolver.resolve('bunnyBooBooSmooth') // => { src: 'bunny.png', data: { scaleMode: SCALE_MODES.NEAREST } }\n * @param aliases - the UnresolvedAsset or array of UnresolvedAssets to add to the resolver\n */\n public add(\n aliases: ArrayOr<UnresolvedAsset>,\n ): void\n {\n const assets: UnresolvedAsset[] = [];\n\n if (Array.isArray(aliases))\n {\n assets.push(...(aliases as UnresolvedAsset[]));\n }\n else\n {\n assets.push(aliases as UnresolvedAsset);\n }\n\n let keyCheck: (key: string) => void;\n\n // #if _DEBUG\n // eslint-disable-next-line prefer-const\n keyCheck = (key: string) =>\n {\n if (this.hasKey(key))\n {\n // #if _DEBUG\n warn(`[Resolver] already has key: ${key} overwriting`);\n // #endif\n }\n };\n // #endif\n\n const assetArray = convertToList(assets);\n\n // loop through all the assets and generate a resolve asset for each src\n assetArray.forEach((asset) =>\n {\n const { src } = asset;\n let {\n data,\n format,\n loadParser: userDefinedLoadParser,\n parser: userDefinedParser,\n } = asset;\n\n // src can contain an unresolved asset itself\n // so we need to merge that data with the current asset\n // we dont need to create string variations for the src if it is a ResolvedAsset\n const srcsToUse: (string | ResolvedSrc)[][] = convertToList<AssetSrc>(src).map((src) =>\n {\n if (typeof src === 'string')\n { return createStringVariations(src); }\n\n return Array.isArray(src) ? src : [src];\n });\n\n const aliasesToUse = this.getAlias(asset);\n\n // #if _DEBUG\n Array.isArray(aliasesToUse) ? aliasesToUse.forEach(keyCheck) : keyCheck(aliasesToUse);\n // #endif\n\n // loop through all the srcs and generate a resolve asset for each src\n const resolvedAssets: ResolvedAsset[] = [];\n\n // Helper function to parse a URL string using registered parsers\n const parseUrl = (url: string): ResolvedAsset =>\n {\n const parser = this._parsers.find((p) => p.test(url));\n\n return {\n ...parser?.parse(url),\n src: url,\n };\n };\n\n srcsToUse.forEach((srcs) =>\n {\n srcs.forEach((src) =>\n {\n let formattedAsset = {} as ResolvedAsset;\n\n if (typeof src !== 'object')\n {\n // first see if it contains any {} tags...\n formattedAsset = parseUrl(src);\n }\n else\n {\n data = src.data ?? data;\n format = src.format ?? format;\n if (src.loadParser || src.parser)\n {\n userDefinedLoadParser = src.loadParser ?? userDefinedLoadParser;\n userDefinedParser = src.parser ?? userDefinedParser;\n }\n\n formattedAsset = {\n ...parseUrl(src.src),\n ...src,\n };\n }\n\n // check if aliases is undefined\n if (!aliasesToUse)\n {\n throw new Error(`[Resolver] alias is undefined for this asset: ${formattedAsset.src}`);\n }\n\n formattedAsset = this._buildResolvedAsset(formattedAsset, {\n aliases: aliasesToUse,\n data,\n format,\n loadParser: userDefinedLoadParser,\n parser: userDefinedParser,\n progressSize: asset.progressSize,\n });\n\n resolvedAssets.push(formattedAsset);\n });\n });\n\n aliasesToUse.forEach((alias) =>\n {\n this._assetMap[alias] = resolvedAssets;\n });\n });\n }\n\n // TODO: this needs an overload like load did in Assets\n /**\n * If the resolver has had a manifest set via setManifest, this will return the assets urls for\n * a given bundleId or bundleIds.\n * @example\n * // Manifest Example\n * const manifest = {\n * bundles: [\n * {\n * name: 'load-screen',\n * assets: [\n * {\n * alias: 'background',\n * src: 'sunset.png',\n * },\n * {\n * alias: 'bar',\n * src: 'load-bar.{png,webp}',\n * },\n * ],\n * },\n * {\n * name: 'game-screen',\n * assets: [\n * {\n * alias: 'character',\n * src: 'robot.png',\n * },\n * {\n * alias: 'enemy',\n * src: 'bad-guy.png',\n * },\n * ],\n * },\n * ]\n * };\n *\n * resolver.setManifest(manifest);\n * const resolved = resolver.resolveBundle('load-screen');\n * @param bundleIds - The bundle ids to resolve\n * @returns All the bundles assets or a hash of assets for each bundle specified\n */\n public resolveBundle(bundleIds: ArrayOr<string>):\n Record<string, ResolvedAsset> | Record<string, Record<string, ResolvedAsset>>\n {\n const singleAsset = isSingleItem(bundleIds);\n\n bundleIds = convertToList<string>(bundleIds);\n\n const out: Record<string, Record<string, ResolvedAsset>> = {};\n\n bundleIds.forEach((bundleId) =>\n {\n const assetNames = this._bundles[bundleId];\n\n if (assetNames)\n {\n const results = this.resolve(assetNames) as Record<string, ResolvedAsset>;\n\n const assets: Record<string, ResolvedAsset> = {};\n\n for (const key in results)\n {\n const asset = results[key];\n\n assets[this._extractAssetIdFromBundle(bundleId, key)] = asset;\n }\n\n out[bundleId] = assets;\n }\n });\n\n return singleAsset ? out[bundleIds[0]] : out;\n }\n\n /**\n * Does exactly what resolve does, but returns just the URL rather than the whole asset object\n * @param key - The key or keys to resolve\n * @returns - The URLs associated with the key(s)\n */\n public resolveUrl(key: ArrayOr<string>): string | Record<string, string>\n {\n const result = this.resolve(key as string) as ResolvedAsset | Record<string, ResolvedAsset>;\n\n if (typeof key !== 'string')\n {\n const out: Record<string, string> = {};\n\n for (const i in result)\n {\n out[i] = (result as Record<string, ResolvedAsset>)[i].src;\n }\n\n return out;\n }\n\n return (result as ResolvedAsset).src;\n }\n\n /**\n * Resolves each key in the list to an asset object.\n * Another key function of the resolver! After adding all the various key/asset pairs. this will run the logic\n * of finding which asset to return based on any preferences set using the `prefer` function\n * by default the same key passed in will be returned if nothing is matched by the resolver.\n * @example\n * resolver.add('boo', 'bunny.png');\n *\n * resolver.resolve('boo') // => { src: 'bunny.png' }\n *\n * // Will return the same string as no key was added for this value..\n * resolver.resolve('another-thing.png') // => { src: 'another-thing.png' }\n * @param keys - key or keys to resolve\n * @returns - the resolve asset or a hash of resolve assets for each key specified\n */\n public resolve(keys: string): ResolvedAsset;\n public resolve(keys: string[]): Record<string, ResolvedAsset>;\n public resolve(keys: ArrayOr<string>): ResolvedAsset | Record<string, ResolvedAsset>\n {\n const singleAsset = isSingleItem(keys);\n\n keys = convertToList<string>(keys);\n\n const result: Record<string, ResolvedAsset> = {};\n\n keys.forEach((key) =>\n {\n if (!this._resolverHash[key])\n {\n if (this._assetMap[key])\n {\n let assets = this._assetMap[key];\n const preferredOrder = this._getPreferredOrder(assets);\n\n preferredOrder?.priority.forEach((priorityKey) =>\n {\n preferredOrder.params[priorityKey].forEach((value: unknown) =>\n {\n const filteredAssets = assets.filter((asset) =>\n {\n if (asset[priorityKey as keyof ResolvedAsset])\n {\n return asset[priorityKey as keyof ResolvedAsset] === value;\n }\n\n return false;\n });\n\n if (filteredAssets.length)\n {\n assets = filteredAssets;\n }\n });\n });\n\n this._resolverHash[key] = assets[0];\n }\n else\n {\n this._resolverHash[key] = this._buildResolvedAsset({\n alias: [key],\n src: key,\n }, {});\n }\n }\n\n result[key] = this._resolverHash[key];\n });\n\n return singleAsset ? result[keys[0]] : result;\n }\n\n /**\n * Checks if an asset with a given key exists in the resolver\n * @param key - The key of the asset\n */\n public hasKey(key: string): boolean\n {\n return !!this._assetMap[key];\n }\n\n /**\n * Checks if a bundle with the given key exists in the resolver\n * @param key - The key of the bundle\n */\n public hasBundle(key: string): boolean\n {\n return !!this._bundles[key];\n }\n\n /**\n * Internal function for figuring out what prefer criteria an asset should use.\n * @param assets\n */\n private _getPreferredOrder(assets: ResolvedAsset[]): PreferOrder\n {\n for (let i = 0; i < assets.length; i++)\n {\n const asset = assets[i];\n\n const preferred = this._preferredOrder.find((preference: PreferOrder) =>\n preference.params.format.includes(asset.format));\n\n if (preferred)\n {\n return preferred;\n }\n }\n\n return this._preferredOrder[0];\n }\n\n /**\n * Appends the default url parameters to the url\n * @param url - The url to append the default parameters to\n * @returns - The url with the default parameters appended\n */\n private _appendDefaultSearchParams(url: string): string\n {\n if (!this._defaultSearchParams) return url;\n\n const paramConnector = (/\\?/).test(url) ? '&' : '?';\n\n return `${url}${paramConnector}${this._defaultSearchParams}`;\n }\n\n private _buildResolvedAsset(formattedAsset: ResolvedAsset, data?: {\n aliases?: string[],\n data?: Record<string, unknown>\n loadParser?: string,\n parser?: string,\n format?: string,\n progressSize?: number,\n }): ResolvedAsset\n {\n const { aliases, data: assetData, loadParser, parser, format, progressSize } = data;\n\n if (this._basePath || this._rootPath)\n {\n formattedAsset.src = path.toAbsolute(formattedAsset.src, this._basePath, this._rootPath);\n }\n\n formattedAsset.alias = aliases ?? formattedAsset.alias ?? [formattedAsset.src];\n formattedAsset.src = this._appendDefaultSearchParams(formattedAsset.src);\n formattedAsset.data = { ...assetData || {}, ...formattedAsset.data };\n formattedAsset.loadParser = loadParser ?? formattedAsset.loadParser;\n formattedAsset.parser = parser ?? formattedAsset.parser;\n formattedAsset.format = format ?? formattedAsset.format ?? getUrlExtension(formattedAsset.src);\n if (progressSize !== undefined)\n {\n formattedAsset.progressSize = progressSize;\n }\n\n return formattedAsset;\n }\n}\n\n/**\n * @param url\n * @internal\n */\nexport function getUrlExtension(url: string)\n{\n return url.split('.').pop().split('?').shift()\n .split('#')\n .shift();\n}\n", "/**\n * Copies the search params from one url to another\n * @param targetUrl - the url to copy the search params to\n * @param sourceUrl - the url container the search params we want to copy\n * @returns the url with the search params copied\n * @internal\n */\nexport const copySearchParams = (targetUrl: string, sourceUrl: string) =>\n{\n const searchParams = sourceUrl.split('?')[1];\n\n if (searchParams)\n {\n targetUrl += `?${searchParams}`;\n }\n\n return targetUrl;\n};\n", "import { Rectangle } from '../maths/shapes/Rectangle';\nimport { TextureSource } from '../rendering/renderers/shared/texture/sources/TextureSource';\nimport { Texture } from '../rendering/renderers/shared/texture/Texture';\n\nimport type { PointData } from '../maths/point/PointData';\nimport type { BindableTexture, TextureBorders } from '../rendering/renderers/shared/texture/Texture';\nimport type { Dict } from '../utils/types';\n\n/**\n * Represents the JSON data for a spritesheet atlas.\n * @category assets\n * @advanced\n */\nexport interface SpritesheetFrameData\n{\n /** The frame rectangle of the texture. */\n frame: {\n x: number;\n y: number;\n w: number;\n h: number;\n };\n /** Whether the texture is trimmed. */\n trimmed?: boolean;\n /** Whether the texture is rotated. */\n rotated?: boolean;\n /** The source size of the texture. */\n sourceSize?: {\n w: number;\n h: number;\n };\n /** The sprite source size. */\n spriteSourceSize?: {\n h?: number;\n w?: number;\n x: number;\n y: number;\n };\n /** The anchor point of the texture. */\n anchor?: PointData;\n /** The 9-slice borders of the texture. */\n borders?: TextureBorders\n}\n\n/**\n * Atlas format.\n * @category assets\n * @advanced\n */\nexport interface SpritesheetData\n{\n /** The frames of the atlas. */\n frames: Dict<SpritesheetFrameData>;\n /** The animations of the atlas. */\n animations?: Dict<string[]>;\n /** The meta data of the atlas. */\n meta: {\n app?: string;\n format?: string;\n frameTags?: {\n from: number;\n name: string;\n to: number;\n direction: string;\n }[];\n image?: string;\n layers?: {\n blendMode: string;\n name: string;\n opacity: number;\n }[];\n scale: number | string;\n size?: {\n h: number;\n w: number;\n };\n slices?: {\n color: string;\n name: string;\n keys: {\n frame: number,\n bounds: {\n x: number;\n y: number;\n w: number;\n h: number;\n };\n }[];\n }[];\n related_multi_packs?: string[];\n version?: string;\n };\n}\n\n/**\n * Options for loading a spritesheet from an atlas.\n * @category assets\n * @advanced\n */\nexport interface SpritesheetOptions<S extends SpritesheetData = SpritesheetData>\n{\n /** Reference to Texture */\n texture: BindableTexture;\n /** JSON data for the atlas. */\n data: S;\n /** The filename to consider when determining the resolution of the spritesheet. */\n resolutionFilename?: string;\n /**\n * Prefix to add to texture names when adding to global TextureCache,\n * using this option can be helpful if you have multiple texture atlases\n * that share texture names and you need to disambiguate them.\n */\n cachePrefix?: string;\n}\n\n/**\n * Utility class for maintaining reference to a collection\n * of Textures on a single Spritesheet.\n *\n * To access a sprite sheet from your code you may pass its JSON data file to Pixi's loader:\n *\n * ```js\n * import { Assets } from 'pixi.js';\n *\n * const sheet = await Assets.load('images/spritesheet.json');\n * ```\n *\n * Alternately, you may circumvent the loader by instantiating the Spritesheet directly:\n *\n * ```js\n * import { Spritesheet } from 'pixi.js';\n *\n * const sheet = new Spritesheet(texture, spritesheetData);\n * await sheet.parse();\n * console.log('Spritesheet ready to use!');\n * ```\n *\n * With the `sheet.textures` you can create Sprite objects, and `sheet.animations` can be used to create an AnimatedSprite.\n *\n * Here's an example of a sprite sheet JSON data file:\n * ```json\n * {\n * \"frames\": {\n * \"enemy1.png\":\n * {\n * \"frame\": {\"x\":103,\"y\":1,\"w\":32,\"h\":32},\n * \"spriteSourceSize\": {\"x\":0,\"y\":0,\"w\":32,\"h\":32},\n * \"sourceSize\": {\"w\":32,\"h\":32},\n * \"anchor\": {\"x\":0.5,\"y\":0.5}\n * },\n * \"enemy2.png\":\n * {\n * \"frame\": {\"x\":103,\"y\":35,\"w\":32,\"h\":32},\n * \"spriteSourceSize\": {\"x\":0,\"y\":0,\"w\":32,\"h\":32},\n * \"sourceSize\": {\"w\":32,\"h\":32},\n * \"anchor\": {\"x\":0.5,\"y\":0.5}\n * },\n * \"button.png\":\n * {\n * \"frame\": {\"x\":1,\"y\":1,\"w\":100,\"h\":100},\n * \"spriteSourceSize\": {\"x\":0,\"y\":0,\"w\":100,\"h\":100},\n * \"sourceSize\": {\"w\":100,\"h\":100},\n * \"anchor\": {\"x\":0,\"y\":0},\n * \"borders\": {\"left\":35,\"top\":35,\"right\":35,\"bottom\":35}\n * }\n * },\n *\n * \"animations\": {\n * \"enemy\": [\"enemy1.png\",\"enemy2.png\"]\n * },\n *\n * \"meta\": {\n * \"image\": \"sheet.png\",\n * \"format\": \"RGBA8888\",\n * \"size\": {\"w\":136,\"h\":102},\n * \"scale\": \"1\"\n * }\n * }\n * ```\n * Sprite sheets can be packed using tools like {@link https://codeandweb.com/texturepacker|TexturePacker},\n * {@link https://renderhjs.net/shoebox/|Shoebox} or {@link https://github.com/krzysztof-o/spritesheet.js|Spritesheet.js}.\n * Default anchor points (see {@link Texture#defaultAnchor}), default 9-slice borders\n * (see {@link Texture#defaultBorders}) and grouping of animation sprites are currently only\n * supported by TexturePacker.\n *\n * Alternative ways for loading spritesheet image if you need more control:\n *\n * ```js\n * import { Assets } from 'pixi.js';\n *\n * const sheetTexture = await Assets.load('images/spritesheet.png');\n * Assets.add({\n * alias: 'atlas',\n * src: 'images/spritesheet.json',\n * data: {texture: sheetTexture} // using of preloaded texture\n * });\n * const sheet = await Assets.load('atlas')\n * ```\n *\n * or:\n *\n * ```js\n * import { Assets } from 'pixi.js';\n *\n * Assets.add({\n * alias: 'atlas',\n * src: 'images/spritesheet.json',\n * data: {imageFilename: 'my-spritesheet.2x.avif'} // using of custom filename located in \"images/my-spritesheet.2x.avif\"\n * });\n * const sheet = await Assets.load('atlas')\n * ```\n * @category assets\n * @standard\n */\nexport class Spritesheet<S extends SpritesheetData = SpritesheetData>\n{\n /**\n * The maximum number of Textures to build per process.\n * @advanced\n */\n public static readonly BATCH_SIZE = 1000;\n\n /** For multi-packed spritesheets, this contains a reference to all the other spritesheets it depends on. */\n public linkedSheets: Spritesheet<S>[] = [];\n\n /** Reference to the source texture. */\n public textureSource: TextureSource;\n\n /**\n * A map containing all textures of the sprite sheet.\n * Can be used to create a {@link Sprite}:\n * @example\n * import { Sprite } from 'pixi.js';\n *\n * new Sprite(sheet.textures['image.png']);\n */\n public textures: Record<keyof S['frames'], Texture>;\n\n /**\n * A map containing the textures for each animation.\n * Can be used to create an {@link AnimatedSprite}:\n * @example\n * import { AnimatedSprite } from 'pixi.js';\n *\n * new AnimatedSprite(sheet.animations['anim_name']);\n */\n public animations: Record<keyof NonNullable<S['animations']>, Texture[]>;\n\n /**\n * Reference to the original JSON data.\n * @type {object}\n */\n public data: S;\n\n /** The resolution of the spritesheet. */\n public resolution: number;\n\n /**\n * Reference to original source image from the Loader. This reference is retained so we\n * can destroy the Texture later on. It is never used internally.\n */\n private _texture: Texture;\n\n /**\n * Map of spritesheet frames.\n * @type {object}\n */\n private _frames: S['frames'];\n\n /** Collection of frame names. */\n private _frameKeys: (keyof S['frames'])[];\n\n /** Current batch index being processed. */\n private _batchIndex: number;\n\n /**\n * Callback when parse is completed.\n * @type {Function}\n */\n private _callback: (textures: Dict<Texture>) => void;\n\n /** Prefix string to add to global cache */\n public readonly cachePrefix: string;\n\n /**\n * @class\n * @param options - Options to use when constructing a new Spritesheet.\n */\n constructor(options: SpritesheetOptions<S>);\n\n /**\n * @param texture - Reference to the source BaseTexture object.\n * @param {object} data - Spritesheet image data.\n */\n constructor(texture: BindableTexture, data: S);\n\n constructor(optionsOrTexture: SpritesheetOptions<S> | BindableTexture, arg1?: S)\n {\n let options = optionsOrTexture as SpritesheetOptions<S>;\n\n if ((optionsOrTexture as BindableTexture)?.source instanceof TextureSource)\n {\n options = {\n texture: optionsOrTexture as BindableTexture,\n data: arg1,\n };\n }\n const { texture, data, cachePrefix = '' } = options;\n\n this.cachePrefix = cachePrefix;\n this._texture = texture instanceof Texture ? texture : null;\n this.textureSource = texture.source;\n this.textures = {} as Record<keyof S['frames'], Texture>;\n this.animations = {} as Record<keyof NonNullable<S['animations']>, Texture[]>;\n this.data = data;\n\n const metaResolution = parseFloat(data.meta.scale as string);\n\n if (metaResolution)\n {\n this.resolution = metaResolution;\n texture.source.resolution = this.resolution;\n }\n else\n {\n this.resolution = texture.source._resolution;\n }\n\n this._frames = this.data.frames;\n this._frameKeys = Object.keys(this._frames);\n this._batchIndex = 0;\n this._callback = null;\n }\n\n /**\n * Parser spritesheet from loaded data. This is done asynchronously\n * to prevent creating too many Texture within a single process.\n */\n public parse(): Promise<Record<string, Texture>>\n {\n return new Promise((resolve) =>\n {\n this._callback = resolve;\n this._batchIndex = 0;\n\n if (this._frameKeys.length <= Spritesheet.BATCH_SIZE)\n {\n this._processFrames(0);\n this._processAnimations();\n this._parseComplete();\n }\n else\n {\n this._nextBatch();\n }\n });\n }\n\n /**\n * Process a batch of frames\n * @param initialFrameIndex - The index of frame to start.\n */\n private _processFrames(initialFrameIndex: number): void\n {\n let frameIndex = initialFrameIndex;\n const maxFrames = Spritesheet.BATCH_SIZE;\n\n while (frameIndex - initialFrameIndex < maxFrames && frameIndex < this._frameKeys.length)\n {\n const i = this._frameKeys[frameIndex];\n const data = this._frames[i];\n const rect = data.frame;\n\n if (rect)\n {\n let frame = null;\n let trim = null;\n const sourceSize = data.trimmed !== false && data.sourceSize\n ? data.sourceSize : data.frame;\n\n const orig = new Rectangle(\n 0,\n 0,\n Math.floor(sourceSize.w) / this.resolution,\n Math.floor(sourceSize.h) / this.resolution\n );\n\n if (data.rotated)\n {\n frame = new Rectangle(\n Math.floor(rect.x) / this.resolution,\n Math.floor(rect.y) / this.resolution,\n Math.floor(rect.h) / this.resolution,\n Math.floor(rect.w) / this.resolution\n );\n }\n else\n {\n frame = new Rectangle(\n Math.floor(rect.x) / this.resolution,\n Math.floor(rect.y) / this.resolution,\n Math.floor(rect.w) / this.resolution,\n Math.floor(rect.h) / this.resolution\n );\n }\n\n // Check to see if the sprite is trimmed\n if (data.trimmed !== false && data.spriteSourceSize)\n {\n trim = new Rectangle(\n Math.floor(data.spriteSourceSize.x) / this.resolution,\n Math.floor(data.spriteSourceSize.y) / this.resolution,\n Math.floor(rect.w) / this.resolution,\n Math.floor(rect.h) / this.resolution\n );\n }\n\n this.textures[i] = new Texture({\n source: this.textureSource,\n\n frame,\n orig,\n trim,\n rotate: data.rotated ? 2 : 0,\n defaultAnchor: data.anchor,\n defaultBorders: data.borders,\n\n label: i.toString(),\n });\n }\n\n frameIndex++;\n }\n }\n\n /** Parse animations config. */\n private _processAnimations(): void\n {\n const animations = this.data.animations || {};\n\n for (const animName in animations)\n {\n this.animations[animName as keyof S['animations']] = [];\n for (let i = 0; i < animations[animName].length; i++)\n {\n const frameName = animations[animName][i];\n\n this.animations[animName].push(this.textures[frameName]);\n }\n }\n }\n\n /** The parse has completed. */\n private _parseComplete(): void\n {\n const callback = this._callback;\n\n this._callback = null;\n this._batchIndex = 0;\n callback.call(this, this.textures);\n }\n\n /** Begin the next batch of textures. */\n private _nextBatch(): void\n {\n this._processFrames(this._batchIndex * Spritesheet.BATCH_SIZE);\n this._batchIndex++;\n setTimeout(() =>\n {\n if (this._batchIndex * Spritesheet.BATCH_SIZE < this._frameKeys.length)\n {\n this._nextBatch();\n }\n else\n {\n this._processAnimations();\n this._parseComplete();\n }\n }, 0);\n }\n\n /**\n * Destroy Spritesheet and don't use after this.\n * @param {boolean} [destroyBase=false] - Whether to destroy the base texture as well\n */\n public destroy(destroyBase = false): void\n {\n for (const i in this.textures)\n {\n this.textures[i].destroy();\n }\n this._frames = null;\n this._frameKeys = null;\n this.data = null;\n this.textures = null;\n if (destroyBase)\n {\n this._texture?.destroy();\n this.textureSource.destroy();\n }\n this._texture = null;\n this.textureSource = null;\n this.linkedSheets = [];\n }\n}\n", "import { LoaderParserPriority } from '../assets/loader/parsers/LoaderParser';\nimport { Resolver } from '../assets/resolver/Resolver';\nimport { copySearchParams } from '../assets/utils/copySearchParams';\nimport { ExtensionType } from '../extensions/Extensions';\nimport { Texture } from '../rendering/renderers/shared/texture/Texture';\nimport { path } from '../utils/path';\nimport { Spritesheet } from './Spritesheet';\n\nimport type { AssetExtensionAdvanced } from '../assets/AssetExtension';\nimport type { Loader } from '../assets/loader/Loader';\nimport type { ResolvedAsset } from '../assets/types';\nimport type { TextureSourceOptions } from '../rendering/renderers/shared/texture/sources/TextureSource';\nimport type { SpritesheetData } from './Spritesheet';\n\n/**\n * Interface for the JSON data structure of a spritesheet.\n * This is used to define the structure of the JSON file that describes a spritesheet.\n * It includes metadata about the spritesheet and the frames it contains.\n * @see {@link Spritesheet}\n * @see {@link SpritesheetData}\n * @category assets\n * @advanced\n */\nexport interface SpriteSheetJson extends SpritesheetData\n{\n meta: {\n image: string;\n scale: string;\n related_multi_packs?: string[];\n };\n}\n\nconst validImages = ['jpg', 'png', 'jpeg', 'avif', 'webp',\n 'basis', 'etc2', 'bc7', 'bc6h', 'bc5', 'bc4', 'bc3', 'bc2', 'bc1', 'eac', 'astc'];\n\nfunction getCacheableAssets(keys: string[], asset: Spritesheet, ignoreMultiPack: boolean)\n{\n const out: Record<string, any> = {};\n\n keys.forEach((key: string) =>\n {\n out[key] = asset;\n });\n\n Object.keys(asset.textures).forEach((key) =>\n {\n out[`${asset.cachePrefix}${key}`] = asset.textures[key];\n });\n\n if (!ignoreMultiPack)\n {\n const basePath = path.dirname(keys[0]);\n\n asset.linkedSheets.forEach((item: Spritesheet, i) =>\n {\n const out2 = getCacheableAssets([`${basePath}/${asset.data.meta.related_multi_packs[i]}`], item, true);\n\n Object.assign(out, out2);\n });\n }\n\n return out;\n}\n\n/**\n * Asset extension for loading spritesheets\n * @example\n * import { Assets } from 'pixi.js';\n *\n * Assets.load({\n * alias: 'spritesheet',\n * src: 'path/to/spritesheet.json',\n * data: {\n * ignoreMultiPack: true,\n * textureOptions: {\n * scaleMode: \"nearest\"\n * }\n * }\n * })\n * @type {AssetExtension}\n * @category assets\n * @advanced\n */\nexport const spritesheetAsset = {\n extension: ExtensionType.Asset,\n /** Handle the caching of the related Spritesheet Textures */\n cache: {\n test: (asset: Spritesheet) => asset instanceof Spritesheet,\n getCacheableAssets: (keys: string[], asset: Spritesheet) => getCacheableAssets(keys, asset, false),\n },\n /** Resolve the resolution of the asset. */\n resolver: {\n extension: {\n type: ExtensionType.ResolveParser,\n name: 'resolveSpritesheet',\n },\n test: (value: string): boolean =>\n {\n const tempURL = value.split('?')[0];\n const split = tempURL.split('.');\n const extension = split.pop();\n const format = split.pop();\n\n return extension === 'json' && validImages.includes(format);\n },\n parse: (value: string) =>\n {\n const split = value.split('.');\n\n return {\n resolution: parseFloat(Resolver.RETINA_PREFIX.exec(value)?.[1] ?? '1'),\n format: split[split.length - 2],\n src: value,\n };\n },\n },\n /**\n * Loader plugin that parses sprite sheets!\n * once the JSON has been loaded this checks to see if the JSON is spritesheet data.\n * If it is, we load the spritesheets image and parse the data into Spritesheet\n * All textures in the sprite sheet are then added to the cache\n */\n loader: {\n /** used for deprecation purposes */\n name: 'spritesheetLoader',\n id: 'spritesheet',\n\n extension: {\n type: ExtensionType.LoadParser,\n priority: LoaderParserPriority.Normal,\n name: 'spritesheetLoader',\n },\n\n async testParse(asset: SpriteSheetJson, options: ResolvedAsset): Promise<boolean>\n {\n return (path.extname(options.src).toLowerCase() === '.json' && !!asset.frames);\n },\n\n async parse(\n asset: SpriteSheetJson,\n options: ResolvedAsset<{\n texture?: Texture,\n imageFilename?: string,\n ignoreMultiPack?: boolean,\n textureOptions?: TextureSourceOptions,\n cachePrefix?: string,\n }>,\n loader?: Loader\n ): Promise<Spritesheet>\n {\n const {\n texture: imageTexture, // if user need to use preloaded texture\n imageFilename, // if user need to use custom filename (not from jsonFile.meta.image)\n textureOptions, // if user need to set texture options on texture\n cachePrefix, // if user need to use custom cache prefix\n } = options?.data ?? {};\n\n let basePath = path.dirname(options.src);\n\n if (basePath && basePath.lastIndexOf('/') !== (basePath.length - 1))\n {\n basePath += '/';\n }\n\n let texture: Texture;\n\n if (imageTexture instanceof Texture)\n {\n texture = imageTexture;\n }\n else\n {\n const imagePath = copySearchParams(basePath + (imageFilename ?? asset.meta.image), options.src);\n\n const assets = await loader.load<Texture>([{ src: imagePath, data: textureOptions }]);\n\n texture = assets[imagePath];\n }\n\n const spritesheet = new Spritesheet({\n texture: texture.source,\n data: asset,\n cachePrefix\n });\n\n await spritesheet.parse();\n\n // Check and add the multi atlas\n // Heavily influenced and based on https://github.com/rocket-ua/pixi-tps-loader/blob/master/src/ResourceLoader.js\n const multiPacks = asset?.meta?.related_multi_packs;\n\n if (Array.isArray(multiPacks))\n {\n const promises: Promise<Spritesheet<SpriteSheetJson>>[] = [];\n\n for (const item of multiPacks)\n {\n if (typeof item !== 'string')\n {\n continue;\n }\n\n let itemUrl = basePath + item;\n\n // Check if the file wasn't already added as multipack\n if (options.data?.ignoreMultiPack)\n {\n continue;\n }\n\n itemUrl = copySearchParams(itemUrl, options.src);\n\n promises.push(loader.load<Spritesheet<SpriteSheetJson>>({\n src: itemUrl,\n data: {\n textureOptions,\n ignoreMultiPack: true,\n }\n }));\n }\n\n const res = await Promise.all(promises);\n\n spritesheet.linkedSheets = res;\n res.forEach((item) =>\n {\n item.linkedSheets = [spritesheet].concat(spritesheet.linkedSheets.filter((sp) => (sp !== item)));\n });\n }\n\n return spritesheet;\n },\n\n async unload(spritesheet: Spritesheet, _resolvedAsset, loader)\n {\n await loader.unload(spritesheet.textureSource._sourceOrigin);\n\n spritesheet.destroy(false);\n },\n }\n} satisfies AssetExtensionAdvanced<SpriteSheetJson, Spritesheet, Spritesheet, Spritesheet>;\n", "import { extensions } from '../extensions/Extensions';\nimport { spritesheetAsset } from './spritesheetAsset';\n\nextensions.add(spritesheetAsset);\n", "import { Bounds } from '../../../scene/container/bounds/Bounds';\nimport { getGlobalBounds } from '../../../scene/container/bounds/getGlobalBounds';\n\nimport type { Container } from '../../../scene/container/Container';\n\nconst tempBounds = new Bounds();\n\n/**\n * @param mask\n * @param bounds\n * @param skipUpdateTransform\n * @internal\n */\nexport function addMaskBounds(mask: Container, bounds: Bounds, skipUpdateTransform: boolean): void\n{\n const boundsToMask = tempBounds;\n\n mask.measurable = true;\n\n getGlobalBounds(mask, skipUpdateTransform, boundsToMask);\n\n bounds.addBoundsMask(boundsToMask);\n\n mask.measurable = false;\n}\n\n", "import { getLocalBounds } from '../../../scene/container/bounds/getLocalBounds';\nimport { boundsPool, matrixPool } from '../../../scene/container/bounds/utils/matrixAndBoundsPool';\nimport { warn } from '../../../utils/logging/warn';\n\nimport type { Matrix } from '../../../maths/matrix/Matrix';\nimport type { Bounds } from '../../../scene/container/bounds/Bounds';\nimport type { Container } from '../../../scene/container/Container';\n\n/**\n * @param mask\n * @param bounds\n * @param localRoot\n * @internal\n */\nexport function addMaskLocalBounds(mask: Container, bounds: Bounds, localRoot: Container): void\n{\n const boundsToMask = boundsPool.get();\n\n mask.measurable = true;\n\n const tempMatrix = matrixPool.get().identity();\n\n const relativeMask = getMatrixRelativeToParent(mask, localRoot, tempMatrix);\n\n getLocalBounds(mask, boundsToMask, relativeMask);\n\n mask.measurable = false;\n\n bounds.addBoundsMask(boundsToMask);\n\n matrixPool.return(tempMatrix);\n boundsPool.return(boundsToMask);\n}\n\nfunction getMatrixRelativeToParent(target: Container, root: Container, matrix: Matrix): Matrix\n{\n if (!target)\n {\n // we have reach the top of the tree!\n // #if _DEBUG\n warn('Mask bounds, renderable is not inside the root container');\n // #endif\n\n return matrix;\n }\n\n if (target !== root)\n {\n getMatrixRelativeToParent(target.parent, root, matrix);\n\n target.updateLocalTransform();\n\n matrix.append(target.localTransform);\n }\n\n return matrix;\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { Sprite } from '../../../scene/sprite/Sprite';\nimport { addMaskBounds } from '../utils/addMaskBounds';\nimport { addMaskLocalBounds } from '../utils/addMaskLocalBounds';\n\nimport type { ExtensionMetadata } from '../../../extensions/Extensions';\nimport type { Point } from '../../../maths/point/Point';\nimport type { Bounds } from '../../../scene/container/bounds/Bounds';\nimport type { Container } from '../../../scene/container/Container';\nimport type { Effect } from '../../../scene/container/Effect';\nimport type { PoolItem } from '../../../utils/pool/Pool';\n\n/**\n * AlphaMask is an effect that applies a mask to a container using the alpha channel of a sprite.\n * It can be used to create complex masking effects by using a sprite as the mask.\n * The mask can be inverted, and it can render the mask to a texture if the mask is not a sprite.\n * @category rendering\n * @advanced\n */\nexport class AlphaMask implements Effect, PoolItem\n{\n public static extension: ExtensionMetadata = ExtensionType.MaskEffect;\n\n public priority = 0;\n public mask: Container;\n public inverse: boolean = false;\n public pipe = 'alphaMask';\n public renderMaskToTexture: boolean;\n\n constructor(options?: {mask: Container})\n {\n if (options?.mask)\n {\n this.init(options.mask);\n }\n }\n\n public init(mask: Container): void\n {\n this.mask = mask;\n\n // TODO - might want to change this to adjust on the fly\n // user may add children to the sprite..\n this.renderMaskToTexture = !(mask instanceof Sprite);\n\n this.mask.renderable = this.renderMaskToTexture;\n this.mask.includeInBuild = !this.renderMaskToTexture;\n\n this.mask.measurable = false;\n }\n\n public reset()\n {\n if (this.mask === null) return;\n this.mask.measurable = true;\n this.mask = null;\n }\n\n public addBounds(bounds: Bounds, skipUpdateTransform?: boolean): void\n {\n if (!this.inverse)\n {\n addMaskBounds(this.mask, bounds, skipUpdateTransform);\n }\n }\n\n public addLocalBounds(bounds: Bounds, localRoot: Container): void\n {\n addMaskLocalBounds(this.mask, bounds, localRoot);\n }\n\n public containsPoint(point: Point, hitTestFn: (container: Container, point: Point) => boolean): boolean\n {\n const mask = this.mask as any;\n\n // if the point is in the mask, yay!\n return hitTestFn(mask, point);\n }\n\n public destroy(): void\n {\n this.reset();\n }\n\n public static test(mask: any): boolean\n {\n return mask instanceof Sprite;\n }\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\n\nimport type { ExtensionMetadata } from '../../../extensions/Extensions';\nimport type { Effect } from '../../../scene/container/Effect';\nimport type { PoolItem } from '../../../utils/pool/Pool';\n\n/**\n * The ColorMask effect allows you to apply a color mask to the rendering process.\n * This can be useful for selectively rendering certain colors or for creating\n * effects based on color values.\n * @category rendering\n * @advanced\n */\nexport class ColorMask implements Effect, PoolItem\n{\n public static extension: ExtensionMetadata = ExtensionType.MaskEffect;\n\n public priority = 0;\n public mask: number;\n public pipe = 'colorMask';\n\n constructor(options: {mask: number})\n {\n if (options?.mask)\n {\n this.init(options.mask);\n }\n }\n\n public init(mask: number): void\n {\n this.mask = mask;\n }\n\n public destroy(): void\n {\n // nothing to destroy\n }\n\n public static test(mask: any): boolean\n {\n return typeof mask === 'number';\n }\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { Container } from '../../../scene/container/Container';\nimport { addMaskBounds } from '../utils/addMaskBounds';\nimport { addMaskLocalBounds } from '../utils/addMaskLocalBounds';\n\nimport type { ExtensionMetadata } from '../../../extensions/Extensions';\nimport type { Point } from '../../../maths/point/Point';\nimport type { Bounds } from '../../../scene/container/bounds/Bounds';\nimport type { Effect } from '../../../scene/container/Effect';\nimport type { PoolItem } from '../../../utils/pool/Pool';\n\n/**\n * A mask that uses the stencil buffer to clip the rendering of a container.\n * This is useful for complex masks that cannot be achieved with simple shapes.\n * It is more performant than using a `Graphics` mask, but requires WebGL support.\n * It is also useful for masking with `Container` objects that have complex shapes.\n * @category rendering\n * @advanced\n */\nexport class StencilMask implements Effect, PoolItem\n{\n public static extension: ExtensionMetadata = ExtensionType.MaskEffect;\n\n public priority = 0;\n public mask: Container;\n public pipe = 'stencilMask';\n\n constructor(options: {mask: Container})\n {\n if (options?.mask)\n {\n this.init(options.mask);\n }\n }\n\n public init(mask: Container): void\n {\n this.mask = mask;\n this.mask.includeInBuild = false;\n this.mask.measurable = false;\n }\n\n public reset()\n {\n if (this.mask === null) return;\n this.mask.measurable = true;\n this.mask.includeInBuild = true;\n this.mask = null;\n }\n\n public addBounds(bounds: Bounds, skipUpdateTransform: boolean): void\n {\n addMaskBounds(this.mask, bounds, skipUpdateTransform);\n }\n\n public addLocalBounds(bounds: Bounds, localRoot: Container): void\n {\n addMaskLocalBounds(this.mask, bounds, localRoot);\n }\n\n public containsPoint(point: Point, hitTestFn: (container: Container, point: Point) => boolean): boolean\n {\n const mask = this.mask as any;\n\n // if the point is in the mask, yay!\n return hitTestFn(mask, point);\n }\n\n public destroy(): void\n {\n this.reset();\n }\n\n public static test(mask: any): boolean\n {\n return mask instanceof Container;\n }\n}\n", "import { ExtensionType } from '../../../../../extensions/Extensions';\nimport { TextureSource } from './TextureSource';\n\nimport type { ICanvas } from '../../../../../environment/canvas/ICanvas';\nimport type { ExtensionMetadata } from '../../../../../extensions/Extensions';\nimport type { TextureSourceOptions } from './TextureSource';\n\n/**\n * The type of image-like resource that can be used as a texture source.\n *\n * - `ImageBitmap` is used for bitmap images.\n * - `HTMLCanvasElement` and `OffscreenCanvas` are used for canvas elements.\n * - `ICanvas` is an interface for canvas-like objects.\n * - `VideoFrame` is used for video frames.\n * - `HTMLImageElement` is used for HTML image elements.\n * - `HTMLVideoElement` is used for HTML video elements.\n * @category rendering\n * @advanced\n */\nexport type ImageResource =\nImageBitmap\n| HTMLCanvasElement\n| OffscreenCanvas\n| ICanvas\n| VideoFrame\n| HTMLImageElement\n| HTMLVideoElement;\n\n/**\n * A texture source that uses an image-like resource as its resource.\n * It can handle HTMLImageElement, ImageBitmap, VideoFrame, and HTMLVideoElement.\n * It is used for textures that can be uploaded to the GPU.\n * @category rendering\n * @advanced\n */\nexport class ImageSource extends TextureSource<ImageResource>\n{\n public static extension: ExtensionMetadata = ExtensionType.TextureSource;\n public uploadMethodId = 'image';\n\n constructor(options: TextureSourceOptions<ImageResource>)\n {\n super(options);\n\n this.autoGarbageCollect = true;\n }\n\n public static test(resource: any): resource is ImageResource\n {\n return (globalThis.HTMLImageElement && resource instanceof HTMLImageElement)\n || (typeof ImageBitmap !== 'undefined' && resource instanceof ImageBitmap)\n || (globalThis.VideoFrame && resource instanceof VideoFrame);\n }\n}\n", "/* eslint-disable no-restricted-globals */\nimport { DOMAdapter } from '../../environment/adapter';\n\nimport type { ALPHA_MODES } from '../../rendering/renderers/shared/texture/const';\n\nlet promise: Promise<ALPHA_MODES> | undefined;\n\n/**\n * Helper for detecting the correct alpha mode for video textures.\n * For some reason, some browsers/devices/WebGL implementations premultiply the alpha\n * of a video before and then a second time if `UNPACK_PREMULTIPLY_ALPHA_WEBGL`\n * is true. So the video is premultiplied twice if the alpha mode is `UNPACK`.\n * In this case we need the alpha mode to be `PMA`. This function detects\n * the upload behavior by uploading a white 2x2 webm with 50% alpha\n * without `UNPACK_PREMULTIPLY_ALPHA_WEBGL` and then checking whether\n * the uploaded pixels are premultiplied.\n * @category utils\n * @internal\n * @returns {Promise<ALPHA_MODES>} The correct alpha mode for video textures.\n */\nexport async function detectVideoAlphaMode(): Promise<ALPHA_MODES>\n{\n promise ??= (async () =>\n {\n const canvas = DOMAdapter.get().createCanvas(1, 1);\n const gl = canvas.getContext('webgl');\n\n if (!gl)\n {\n return 'premultiply-alpha-on-upload';\n }\n\n const video = await new Promise<HTMLVideoElement | null>((resolve) =>\n {\n const video = document.createElement('video');\n\n video.onloadeddata = () => resolve(video);\n video.onerror = () => resolve(null);\n video.autoplay = false;\n video.crossOrigin = 'anonymous';\n video.preload = 'auto';\n // eslint-disable-next-line max-len\n video.src = 'data:video/webm;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEAAAAAAAHTEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHGTbuMU6uEElTDZ1OsggEXTbuMU6uEHFO7a1OsggG97AEAAAAAAABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmoCrXsYMPQkBNgIRMYXZmV0GETGF2ZkSJiEBEAAAAAAAAFlSua8yuAQAAAAAAAEPXgQFzxYgAAAAAAAAAAZyBACK1nIN1bmSIgQCGhVZfVlA5g4EBI+ODhAJiWgDglLCBArqBApqBAlPAgQFVsIRVuYEBElTDZ9Vzc9JjwItjxYgAAAAAAAAAAWfInEWjh0VOQ09ERVJEh49MYXZjIGxpYnZweC12cDlnyKJFo4hEVVJBVElPTkSHlDAwOjAwOjAwLjA0MDAwMDAwMAAAH0O2dcfngQCgwqGggQAAAIJJg0IAABAAFgA4JBwYSgAAICAAEb///4r+AAB1oZ2mm+6BAaWWgkmDQgAAEAAWADgkHBhKAAAgIABIQBxTu2uRu4+zgQC3iveBAfGCAXHwgQM=';\n video.load();\n });\n\n if (!video)\n {\n return 'premultiply-alpha-on-upload';\n }\n\n const texture = gl.createTexture();\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n const framebuffer = gl.createFramebuffer();\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0\n );\n\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);\n\n const pixel = new Uint8Array(4);\n\n gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);\n\n gl.deleteFramebuffer(framebuffer);\n gl.deleteTexture(texture);\n gl.getExtension('WEBGL_lose_context')?.loseContext();\n\n return pixel[0] <= pixel[3] ? 'premultiplied-alpha' : 'premultiply-alpha-on-upload';\n })();\n\n return promise;\n}\n", "// VideoSource.ts\n\nimport { ExtensionType } from '../../../../../extensions/Extensions';\nimport { Ticker } from '../../../../../ticker/Ticker';\nimport { detectVideoAlphaMode } from '../../../../../utils/browser/detectVideoAlphaMode';\nimport { TextureSource } from './TextureSource';\n\nimport type { ExtensionMetadata } from '../../../../../extensions/Extensions';\nimport type { Dict } from '../../../../../utils/types';\nimport type { ALPHA_MODES } from '../const';\nimport type { TextureSourceOptions } from './TextureSource';\n\n/**\n * The type of resource used for video textures.\n * This is typically an HTMLVideoElement.\n * @category rendering\n * @advanced\n */\nexport type VideoResource = HTMLVideoElement;\n\n/**\n * Options for video sources.\n * @category rendering\n * @advanced\n */\nexport interface VideoSourceOptions extends TextureSourceOptions<VideoResource>\n{\n /** If true, the video will start loading immediately. */\n autoLoad?: boolean;\n /** If true, the video will start playing as soon as it is loaded. */\n autoPlay?: boolean;\n /** The number of times a second to update the texture from the video. Leave at 0 to update at every render. */\n updateFPS?: number;\n /** If true, the video will be loaded with the `crossorigin` attribute. */\n crossorigin?: boolean | string;\n /** If true, the video will loop when it ends. */\n loop?: boolean;\n /** If true, the video will be muted. */\n muted?: boolean;\n /** If true, the video will play inline. */\n playsinline?: boolean;\n /** If true, the video will be preloaded. */\n preload?: boolean;\n /** The time in milliseconds to wait for the video to preload before timing out. */\n preloadTimeoutMs?: number;\n /** The alpha mode of the video. */\n alphaMode?: ALPHA_MODES;\n}\n\n/**\n * A texture source that uses a video as its resource.\n * It automatically resizes the texture based on the video dimensions.\n * It also provides methods to control playback and handle video events.\n * This class supports automatic loading, playback, and frame updates.\n * It can also handle cross-origin videos and provides options for looping, muting, and inline playback.\n * @category rendering\n * @advanced\n */\nexport class VideoSource extends TextureSource<VideoResource>\n{\n public static extension: ExtensionMetadata = ExtensionType.TextureSource;\n\n /** The default options for video sources. */\n public static defaultOptions: VideoSourceOptions = {\n ...TextureSource.defaultOptions,\n /** If true, the video will start loading immediately. */\n autoLoad: true,\n /** If true, the video will start playing as soon as it is loaded. */\n autoPlay: true,\n /** The number of times a second to update the texture from the video. Leave at 0 to update at every render. */\n updateFPS: 0,\n /** If true, the video will be loaded with the `crossorigin` attribute. */\n crossorigin: true,\n /** If true, the video will loop when it ends. */\n loop: false,\n /** If true, the video will be muted. */\n muted: true,\n /** If true, the video will play inline. */\n playsinline: true,\n /** If true, the video will be preloaded. */\n preload: false,\n };\n\n // Public\n /** Whether or not the video is ready to play. */\n public isReady = false;\n /** The upload method for this texture. */\n public uploadMethodId = 'video';\n\n // Protected\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 // Private\n /**\n * `true` to use Ticker.shared to auto update the base texture.\n * @default true\n */\n private _autoUpdate: boolean;\n\n /**\n * `true` if the instance is currently connected to Ticker.shared to auto update the base texture.\n * @default false\n */\n private _isConnectedToTicker: boolean;\n\n /**\n * Promise when loading.\n * @default null\n */\n private _load: Promise<this>;\n\n private _msToNextUpdate: number;\n private _preloadTimeout: number;\n\n /** Callback when completed with load. */\n private _resolve: (value?: this | PromiseLike<this>) => void;\n private _reject: (error: ErrorEvent) => void;\n\n private _updateFPS: number;\n private _videoFrameRequestCallbackHandle: number | null;\n\n constructor(\n options: VideoSourceOptions\n )\n {\n super(options);\n\n // Merge provided options with default ones\n options = {\n ...VideoSource.defaultOptions,\n ...options\n };\n\n this._autoUpdate = true;\n this._isConnectedToTicker = false;\n this._updateFPS = options.updateFPS || 0;\n this._msToNextUpdate = 0;\n this.autoPlay = options.autoPlay !== false;\n this.alphaMode = options.alphaMode ?? 'premultiply-alpha-on-upload';\n\n // Binding for frame updates\n this._videoFrameRequestCallback = this._videoFrameRequestCallback.bind(this);\n this._videoFrameRequestCallbackHandle = null;\n\n this._load = null;\n this._resolve = null;\n this._reject = null;\n\n // Bind for listeners\n this._onCanPlay = this._onCanPlay.bind(this);\n this._onCanPlayThrough = this._onCanPlayThrough.bind(this);\n this._onError = this._onError.bind(this);\n this._onPlayStart = this._onPlayStart.bind(this);\n this._onPlayStop = this._onPlayStop.bind(this);\n this._onSeeked = this._onSeeked.bind(this);\n\n if (options.autoLoad !== false)\n {\n void this.load();\n }\n }\n\n /** Update the video frame if the source is not destroyed and meets certain conditions. */\n protected updateFrame(): void\n {\n if (this.destroyed)\n {\n return;\n }\n\n if (this._updateFPS)\n {\n // Account for if video has had its playbackRate changed\n const elapsedMS = Ticker.shared.elapsedMS * this.resource.playbackRate;\n\n this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS);\n }\n\n if (!this._updateFPS || this._msToNextUpdate <= 0)\n {\n this._msToNextUpdate = this._updateFPS ? Math.floor(1000 / this._updateFPS) : 0;\n }\n\n if (this.isValid)\n {\n this.update();\n }\n }\n\n /** Callback to update the video frame and potentially request the next frame update. */\n private _videoFrameRequestCallback(): void\n {\n this.updateFrame();\n\n if (this.destroyed)\n {\n this._videoFrameRequestCallbackHandle = null;\n }\n else\n {\n this._videoFrameRequestCallbackHandle = this.resource.requestVideoFrameCallback(\n this._videoFrameRequestCallback\n );\n }\n }\n\n /**\n * Checks if the resource has valid dimensions.\n * @returns {boolean} True if width and height are set, otherwise false.\n */\n public get isValid(): boolean\n {\n return !!this.resource.videoWidth && !!this.resource.videoHeight;\n }\n\n /**\n * Start preloading the video resource.\n * @returns {Promise<this>} Handle the validate event\n */\n public async load(): Promise<this>\n {\n if (this._load)\n {\n return this._load;\n }\n\n const source = this.resource;\n const options = this.options as VideoSourceOptions;\n\n // Check if source data is enough and set it to complete if needed\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 // Add event listeners related to playback and seeking\n source.addEventListener('play', this._onPlayStart);\n source.addEventListener('pause', this._onPlayStop);\n source.addEventListener('seeked', this._onSeeked);\n\n // Add or handle source readiness event listeners\n if (!this._isSourceReady())\n {\n if (!options.preload)\n {\n // since this event fires early, only bind if not waiting for a preload event\n source.addEventListener('canplay', this._onCanPlay);\n }\n source.addEventListener('canplaythrough', this._onCanPlayThrough);\n source.addEventListener('error', this._onError, true);\n }\n else\n {\n // Source is already ready, so handle it immediately\n this._mediaReady();\n }\n\n this.alphaMode = await detectVideoAlphaMode();\n\n // Create and return the loading promise\n this._load = new Promise((resolve, reject): void =>\n {\n if (this.isValid)\n {\n resolve(this);\n }\n else\n {\n this._resolve = resolve;\n this._reject = reject;\n\n if (options.preloadTimeoutMs !== undefined)\n {\n this._preloadTimeout = setTimeout(() =>\n {\n this._onError(new ErrorEvent(`Preload exceeded timeout of ${options.preloadTimeoutMs}ms`));\n }) as unknown as number;\n }\n source.load();\n }\n });\n\n return this._load;\n }\n\n /**\n * Handle video error events.\n * @param event - The error event\n */\n private _onError(event: ErrorEvent): void\n {\n this.resource.removeEventListener('error', this._onError, true);\n this.emit('error', event);\n\n if (this._reject)\n {\n this._reject(event);\n this._reject = null;\n this._resolve = null;\n }\n }\n\n /**\n * Checks if the underlying source is playing.\n * @returns True if playing.\n */\n private _isSourcePlaying(): boolean\n {\n const source = this.resource;\n\n return (!source.paused && !source.ended);\n }\n\n /**\n * Checks if the underlying source is ready for playing.\n * @returns True if ready.\n */\n private _isSourceReady(): boolean\n {\n const source = this.resource;\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 // Handle edge case where video might not have received its \"can play\" event yet\n if (!this.isValid)\n {\n this._mediaReady();\n }\n\n this._configureAutoUpdate();\n }\n\n /** Stops the update loop when a pause event is triggered. */\n private _onPlayStop(): void\n {\n this._configureAutoUpdate();\n }\n\n /** Handles behavior when the video completes seeking to the current playback position. */\n private _onSeeked(): void\n {\n if (this._autoUpdate && !this._isSourcePlaying())\n {\n this._msToNextUpdate = 0;\n this.updateFrame();\n this._msToNextUpdate = 0;\n }\n }\n\n private _onCanPlay(): void\n {\n const source = this.resource;\n\n // Remove event listeners\n source.removeEventListener('canplay', this._onCanPlay);\n\n this._mediaReady();\n }\n\n private _onCanPlayThrough(): void\n {\n const source = this.resource;\n\n // Remove event listeners\n source.removeEventListener('canplaythrough', this._onCanPlay);\n\n if (this._preloadTimeout)\n {\n clearTimeout(this._preloadTimeout);\n this._preloadTimeout = undefined;\n }\n\n this._mediaReady();\n }\n\n /** Fired when the video is loaded and ready to play. */\n private _mediaReady(): void\n {\n const source = this.resource;\n\n if (this.isValid)\n {\n this.isReady = true;\n this.resize(source.videoWidth, source.videoHeight);\n }\n\n // Reset update timers and perform a frame update\n this._msToNextUpdate = 0;\n this.updateFrame();\n this._msToNextUpdate = 0;\n\n // Resolve the loading promise if it exists\n if (this._resolve)\n {\n this._resolve(this);\n this._resolve = null;\n this._reject = null;\n }\n\n // Handle play behavior based on current source status\n if (this._isSourcePlaying())\n {\n this._onPlayStart();\n }\n else if (this.autoPlay)\n {\n void this.resource.play();\n }\n }\n\n /** Cleans up resources and event listeners associated with this texture. */\n public destroy()\n {\n this._configureAutoUpdate();\n\n const source = this.resource;\n\n if (source)\n {\n // Remove event listeners\n source.removeEventListener('play', this._onPlayStart);\n source.removeEventListener('pause', this._onPlayStop);\n source.removeEventListener('seeked', this._onSeeked);\n source.removeEventListener('canplay', this._onCanPlay);\n source.removeEventListener('canplaythrough', this._onCanPlayThrough);\n source.removeEventListener('error', this._onError, true);\n\n // Clear the video source and pause\n source.pause();\n source.src = '';\n source.load();\n }\n\n super.destroy();\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 this._configureAutoUpdate();\n }\n }\n\n /**\n * How many times a second to update the texture from the video.\n * 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 this._configureAutoUpdate();\n }\n }\n\n /**\n * Configures the updating mechanism based on the current state and settings.\n *\n * This method decides between using the browser's native video frame callback or a custom ticker\n * for updating the video frame. It ensures optimal performance and responsiveness\n * based on the video's state, playback status, and the desired frames-per-second setting.\n *\n * - If `_autoUpdate` is enabled and the video source is playing:\n * - It will prefer the native video frame callback if available and no specific FPS is set.\n * - Otherwise, it will use a custom ticker for manual updates.\n * - If `_autoUpdate` is disabled or the video isn't playing, any active update mechanisms are halted.\n */\n private _configureAutoUpdate(): void\n {\n // Check if automatic updating is enabled and if the source is currently playing\n if (this._autoUpdate && this._isSourcePlaying())\n {\n // Determine if we should use the browser's native video frame callback (generally for better performance)\n if (!this._updateFPS && this.resource.requestVideoFrameCallback)\n {\n // If connected to a custom ticker, remove the update frame function from it\n if (this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.updateFrame, this);\n this._isConnectedToTicker = false;\n // Reset the time until the next update\n this._msToNextUpdate = 0;\n }\n\n // Check if we haven't already requested a video frame callback, and if not, request one\n if (this._videoFrameRequestCallbackHandle === null)\n {\n this._videoFrameRequestCallbackHandle = this.resource.requestVideoFrameCallback(\n this._videoFrameRequestCallback\n );\n }\n }\n else\n {\n // If a video frame request callback exists, cancel it, as we are switching to manual ticker-based updates\n if (this._videoFrameRequestCallbackHandle !== null)\n {\n this.resource.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle);\n this._videoFrameRequestCallbackHandle = null;\n }\n\n // If not connected to the custom ticker, add the update frame function to it\n if (!this._isConnectedToTicker)\n {\n Ticker.shared.add(this.updateFrame, this);\n this._isConnectedToTicker = true;\n // Reset the time until the next update\n this._msToNextUpdate = 0;\n }\n }\n }\n else\n {\n // If automatic updating is disabled or the source isn't playing, perform cleanup\n\n // Cancel any existing video frame callback request\n if (this._videoFrameRequestCallbackHandle !== null)\n {\n this.resource.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle);\n this._videoFrameRequestCallbackHandle = null;\n }\n\n // Remove the update frame function from the custom ticker\n if (this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.updateFrame, this);\n this._isConnectedToTicker = false;\n // Reset the time until the next update\n this._msToNextUpdate = 0;\n }\n }\n }\n\n /**\n * Map of video MIME types that can't be directly derived from file extensions.\n * @readonly\n */\n public static MIME_TYPES: Dict<string>\n = {\n ogv: 'video/ogg',\n mov: 'video/quicktime',\n m4v: 'video/mp4',\n };\n\n public static test(resource: any): resource is VideoResource\n {\n return (globalThis.HTMLVideoElement && resource instanceof HTMLVideoElement);\n }\n}\n", "import { warn } from '../../utils/logging/warn';\nimport { convertToList } from '../utils/convertToList';\n\nimport type { CacheParser } from './CacheParser';\n\n/** @internal */\nclass CacheClass\n{\n private readonly _parsers: CacheParser[] = [];\n\n private readonly _cache: Map<any, any> = new Map();\n private readonly _cacheMap: Map<string, {\n keys: string[],\n cacheKeys: string[],\n }> = new Map();\n\n /** Clear all entries. */\n public reset(): void\n {\n this._cacheMap.clear();\n this._cache.clear();\n }\n\n /**\n * Check if the key exists\n * @param key - The key to check\n */\n public has(key: any): boolean\n {\n return this._cache.has(key);\n }\n\n /**\n * Fetch entry by key\n * @param key - The key of the entry to get\n */\n public get<T = any>(key: any): T\n {\n const result = this._cache.get(key);\n\n if (!result)\n {\n // #if _DEBUG\n warn(`[Assets] Asset id ${key} was not found in the Cache`);\n // #endif\n }\n\n return result as T;\n }\n\n /**\n * Set a value by key or keys name\n * @param key - The key or keys to set\n * @param value - The value to store in the cache or from which cacheable assets will be derived.\n */\n public set<T = any>(key: any | any[], value: T): void\n {\n const keys = convertToList<string>(key);\n\n let cacheableAssets: Record<string, any>;\n\n for (let i = 0; i < this.parsers.length; i++)\n {\n const parser = this.parsers[i];\n\n if (parser.test(value))\n {\n cacheableAssets = parser.getCacheableAssets(keys, value);\n\n break;\n }\n }\n\n // convert cacheable assets to a map of key-value pairs\n const cacheableMap = new Map(Object.entries(cacheableAssets || {}));\n\n if (!cacheableAssets)\n {\n keys.forEach((key) =>\n {\n cacheableMap.set(key, value);\n });\n }\n\n const cacheKeys = [...cacheableMap.keys()];\n\n const cachedAssets = {\n cacheKeys,\n keys\n };\n\n // this is so we can remove them later..\n keys.forEach((key) =>\n {\n this._cacheMap.set(key, cachedAssets as any);\n });\n\n cacheKeys.forEach((key) =>\n {\n const val = cacheableAssets ? cacheableAssets[key] : value;\n\n if (this._cache.has(key) && this._cache.get(key) !== val)\n {\n // #if _DEBUG\n warn('[Cache] already has key:', key);\n // #endif\n }\n\n this._cache.set(key, cacheableMap.get(key));\n });\n }\n\n /**\n * Remove entry by key\n *\n * This function will also remove any associated alias from the cache also.\n * @param key - The key of the entry to remove\n */\n public remove(key: any): void\n {\n if (!this._cacheMap.has(key))\n {\n // #if _DEBUG\n warn(`[Assets] Asset id ${key} was not found in the Cache`);\n // #endif\n\n return;\n }\n\n const cacheMap = this._cacheMap.get(key);\n\n const cacheKeys = cacheMap.cacheKeys;\n\n cacheKeys.forEach((key) =>\n {\n this._cache.delete(key);\n });\n\n cacheMap.keys.forEach((key: string) =>\n {\n this._cacheMap.delete(key);\n });\n }\n\n /**\n * All loader parsers registered\n * @advanced\n */\n public get parsers(): CacheParser[]\n {\n return this._parsers;\n }\n}\n\n/**\n * A global cache for all assets in your PixiJS application. The cache system provides fast\n * access to loaded assets and prevents duplicate loading.\n *\n * Key Features:\n * - Automatic caching of loaded assets\n * - Support for custom cache parsers\n * - Automatic parsing of complex assets (e.g., spritesheets)\n * - Memory management utilities\n * > [!IMPORTANT] You typically do not need to use this class directly.\n * > Use the main {@link Assets} class for high-level asset management.\n * > `Assets.get(key)` will automatically use the cache.\n * @example\n * ```ts\n * import { Cache } from 'pixi.js';\n *\n * // Store an asset in the cache\n * Cache.set('myTexture', texture);\n *\n * // Retrieve an asset\n * const texture = Cache.get('myTexture');\n *\n * // Check if an asset exists\n * if (Cache.has('myTexture')) {\n * // Use the cached asset\n * const sprite = new Sprite(Cache.get('myTexture'));\n * }\n *\n * // Remove an asset from cache\n * Cache.remove('myTexture');\n *\n * // Clear all cached assets\n * Cache.reset();\n * ```\n * @remarks\n * The Cache is a core component of PixiJS' asset management system:\n * - Used internally by the {@link Assets} class\n * - Supports automatic parsing via {@link CacheParser}\n * - Handles complex asset types like spritesheets\n * - Manages memory through asset removal\n *\n * > [!IMPORTANT]\n * > This is a singleton class and should not be instantiated directly.\n * > Use the exported `Cache` instance instead.\n * @see {@link Assets} For high-level asset management\n * @see {@link CacheParser} For custom cache parsing\n * @category assets\n * @class\n * @advanced\n */\nexport const Cache = new CacheClass();\n", "import { Cache } from '../../../../../assets/cache/Cache';\nimport { extensions, ExtensionType } from '../../../../../extensions/Extensions';\nimport { TextureSource } from '../sources/TextureSource';\nimport { Texture } from '../Texture';\n\nimport type { ICanvas } from '../../../../../environment/canvas/ICanvas';\nimport type { TypedArray } from '../../buffer/Buffer';\nimport type { BufferSourceOptions } from '../sources/BufferImageSource';\nimport type { CanvasSourceOptions } from '../sources/CanvasSource';\nimport type { ImageResource } from '../sources/ImageSource';\nimport type { TextureSourceOptions } from '../sources/TextureSource';\nimport type { TextureSourceLike } from '../Texture';\n\ninterface TextureSourceConstructor<T extends TextureSource = TextureSource>\n{\n new (options: TextureSourceOptions): T;\n test(options: ImageResource | TypedArray | ArrayBuffer | ICanvas): boolean;\n}\n\nconst sources: TextureSourceConstructor[] = [];\n\nextensions.handleByList(ExtensionType.TextureSource, sources);\n\n/**\n * The type of resource or options that can be used to create a texture source.\n * This includes ImageResource, TextureSourceOptions, BufferSourceOptions, and CanvasSourceOptions.\n * @category rendering\n * @advanced\n */\nexport type TextureResourceOrOptions =\n ImageResource\n | TextureSourceOptions<ImageResource>\n | BufferSourceOptions\n | CanvasSourceOptions;\n\n/**\n * @param options\n * @deprecated since v8.2.0\n * @see TextureSource.from\n * @category rendering\n * @internal\n */\nexport function autoDetectSource(options: TextureResourceOrOptions = {}): TextureSource\n{\n return textureSourceFrom(options);\n}\n\n/**\n * Creates a texture source from the options provided\n * @param options - The options to create the texture source from. This can be\n */\nfunction textureSourceFrom(options: TextureResourceOrOptions = {}): TextureSource\n{\n const hasResource = options && (options as TextureSourceOptions).resource;\n const res = hasResource ? (options as TextureSourceOptions).resource : options;\n const opts = hasResource ? options as TextureSourceOptions : { resource: options } as TextureSourceOptions;\n\n for (let i = 0; i < sources.length; i++)\n {\n const Source = sources[i];\n\n if (Source.test(res))\n {\n return new Source(opts);\n }\n }\n\n throw new Error(`Could not find a source type for resource: ${opts.resource}`);\n}\n\n/**\n * @param options\n * @param skipCache\n * @internal\n */\nexport function resourceToTexture(\n options: TextureResourceOrOptions = {},\n skipCache = false\n): Texture\n{\n const hasResource = options && (options as TextureSourceOptions).resource;\n const resource = hasResource ? (options as TextureSourceOptions).resource : options;\n const opts = hasResource ? options as TextureSourceOptions : { resource: options } as TextureSourceOptions;\n\n if (!skipCache && Cache.has(resource))\n {\n return Cache.get(resource);\n }\n\n const texture = new Texture({ source: textureSourceFrom(opts) });\n\n texture.on('destroy', () =>\n {\n if (Cache.has(resource))\n {\n Cache.remove(resource);\n }\n });\n\n if (!skipCache)\n {\n Cache.set(resource, texture);\n }\n\n return texture;\n}\n\n/**\n * Helper function that creates a returns Texture based on the source you provide.\n * The source should be loaded and ready to go. If not its best to grab the asset using Assets.\n * @param id - String or Source to create texture from\n * @param skipCache - Skip adding the texture to the cache\n * @returns The texture based on the Id provided\n * @category utils\n * @internal\n */\nexport function textureFrom(id: TextureSourceLike, skipCache = false): Texture\n{\n if (typeof id === 'string')\n {\n return Cache.get(id);\n }\n else if (id instanceof TextureSource)\n {\n return new Texture({ source: id });\n }\n\n // return a auto generated texture from resource\n return resourceToTexture(id, skipCache);\n}\n\nTexture.from = textureFrom;\nTextureSource.from = textureSourceFrom;\n", "import { extensions } from '../extensions/Extensions';\nimport { AlphaMask } from './mask/alpha/AlphaMask';\nimport { ColorMask } from './mask/color/ColorMask';\nimport { StencilMask } from './mask/stencil/StencilMask';\nimport { BufferImageSource } from './renderers/shared/texture/sources/BufferImageSource';\nimport { CanvasSource } from './renderers/shared/texture/sources/CanvasSource';\nimport { ImageSource } from './renderers/shared/texture/sources/ImageSource';\nimport { VideoSource } from './renderers/shared/texture/sources/VideoSource';\nimport './renderers/shared/texture/utils/textureFrom';\nimport './mask/MaskEffectManager';\n\nextensions.add(AlphaMask, ColorMask, StencilMask, VideoSource, ImageSource, CanvasSource, BufferImageSource);\n\n", "import { ExtensionType } from '../extensions/Extensions';\n\nimport type { ExtensionMetadata } from '../extensions/Extensions';\nimport type { Renderer } from '../rendering/renderers/types';\n\ntype ResizeableRenderer = Pick<Renderer, 'resize'>;\n\n/**\n * Application options for the {@link ResizePlugin}.\n * These options control how your application handles window and element resizing.\n * @example\n * ```ts\n * // Auto-resize to window\n * await app.init({ resizeTo: window });\n *\n * // Auto-resize to container element\n * await app.init({ resizeTo: document.querySelector('#game') });\n * ```\n * @category app\n * @standard\n */\nexport interface ResizePluginOptions\n{\n /**\n * Element to automatically resize the renderer to.\n * @example\n * ```ts\n * const app = new Application();\n * await app.init({\n * resizeTo: window, // Resize to the entire window\n * // or\n * resizeTo: document.querySelector('#game-container'), // Resize to a specific element\n * // or\n * resizeTo: null, // Disable auto-resize\n * });\n * ```\n * @default null\n */\n resizeTo?: Window | HTMLElement;\n}\n\n/**\n * Middleware for Application's resize functionality. This plugin handles automatic\n * and manual resizing of your PixiJS application.\n *\n * Adds the following features to {@link Application}:\n * - `resizeTo`: Set an element to automatically resize to\n * - `resize`: Manually trigger a resize\n * - `queueResize`: Queue a resize for the next animation frame\n * - `cancelResize`: Cancel a queued resize\n * @example\n * ```ts\n * import { Application, ResizePlugin } from 'pixi.js';\n *\n * // Create application\n * const app = new Application();\n *\n * // Example 1: Auto-resize to window\n * await app.init({ resizeTo: window });\n *\n * // Example 2: Auto-resize to specific element\n * const container = document.querySelector('#game-container');\n * await app.init({ resizeTo: container });\n *\n * // Example 3: Change resize target at runtime\n * app.resizeTo = window; // Enable auto-resize to window\n * app.resizeTo = null; // Disable auto-resize\n * ```\n * @category app\n * @standard\n */\nexport class ResizePlugin\n{\n /** @ignore */\n public static extension: ExtensionMetadata = ExtensionType.Application;\n /** @internal */\n public static resizeTo: Window | HTMLElement;\n /** @internal */\n public static resize: () => void;\n /** @internal */\n public static renderer: ResizeableRenderer;\n /** @internal */\n public static queueResize: () => void;\n /** @internal */\n public static render: () => void;\n /** @internal */\n private static _resizeId: number;\n /** @internal */\n private static _resizeTo: Window | HTMLElement;\n /** @internal */\n private static _cancelResize: () => void;\n\n /**\n * Initialize the plugin with scope of application instance\n * @private\n * @param {object} [options] - See application options\n */\n public static init(options: ResizePluginOptions): void\n {\n Object.defineProperty(this, 'resizeTo',\n {\n configurable: true,\n set(dom: Window | HTMLElement)\n {\n globalThis.removeEventListener('resize', this.queueResize);\n this._resizeTo = dom;\n if (dom)\n {\n globalThis.addEventListener('resize', this.queueResize);\n this.resize();\n }\n },\n get()\n {\n return this._resizeTo;\n },\n });\n\n this.queueResize = (): void =>\n {\n if (!this._resizeTo)\n {\n return;\n }\n\n this._cancelResize();\n\n // // Throttle resize events per raf\n this._resizeId = requestAnimationFrame(() => this.resize());\n };\n\n this._cancelResize = (): void =>\n {\n if (this._resizeId)\n {\n cancelAnimationFrame(this._resizeId);\n this._resizeId = null;\n }\n };\n\n this.resize = (): void =>\n {\n if (!this._resizeTo)\n {\n return;\n }\n\n // clear queue resize\n this._cancelResize();\n\n let width: number;\n let height: number;\n\n // Resize to the window\n if (this._resizeTo === globalThis.window)\n {\n width = globalThis.innerWidth;\n height = globalThis.innerHeight;\n }\n // Resize to other HTML entities\n else\n {\n const { clientWidth, clientHeight } = this._resizeTo as HTMLElement;\n\n width = clientWidth;\n height = clientHeight;\n }\n\n this.renderer.resize(width, height);\n this.render();\n };\n\n // On resize\n this._resizeId = null;\n this._resizeTo = null;\n this.resizeTo = options.resizeTo || null;\n }\n\n /**\n * Clean up the ticker, scoped to application\n * @private\n */\n public static destroy(): void\n {\n globalThis.removeEventListener('resize', this.queueResize);\n this._cancelResize();\n this._cancelResize = null;\n this.queueResize = null;\n this.resizeTo = null;\n this.resize = null;\n }\n}\n", "import { ExtensionType } from '../extensions/Extensions';\nimport { UPDATE_PRIORITY } from '../ticker/const';\nimport { Ticker } from '../ticker/Ticker';\n\nimport type { ExtensionMetadata } from '../extensions/Extensions';\n\n/**\n * Application options for the {@link TickerPlugin}.\n * These options control the animation loop and update cycle of your PixiJS application.\n * @example\n * ```ts\n * import { Application } from 'pixi.js';\n *\n * // Basic setup with default options\n * const app = new Application();\n * await app.init({\n * autoStart: true, // Start animation loop automatically\n * sharedTicker: false // Use dedicated ticker instance\n * });\n *\n * // Advanced setup with shared ticker\n * const app2 = new Application();\n * await app2.init({\n * autoStart: false, // Don't start automatically\n * sharedTicker: true // Use global shared ticker\n * });\n *\n * // Start animation when ready\n * app2.start();\n * ```\n * @remarks\n * The ticker is the heart of your application's animation system. It:\n * - Manages the render loop\n * - Provides accurate timing information\n * - Handles frame-based updates\n * - Supports priority-based execution order\n * @see {@link Ticker} For detailed ticker functionality\n * @see {@link UPDATE_PRIORITY} For update priority constants\n * @category app\n * @standard\n */\nexport interface TickerPluginOptions\n{\n /**\n * Controls whether the animation loop starts automatically after initialization.\n * > [!IMPORTANT]\n * > Setting this to `false` does NOT stop the shared ticker even if `sharedTicker` is `true`.\n * > You must stop the shared ticker manually if needed.\n * @example\n * ```ts\n * // Auto-start (default behavior)\n * await app.init({ autoStart: true });\n *\n * // Manual start\n * await app.init({ autoStart: false });\n * app.start(); // Start when ready\n * ```\n * @default true\n */\n autoStart?: boolean;\n\n /**\n * Controls whether to use the shared global ticker or create a new instance.\n *\n * The shared ticker is useful when you have multiple instances that should sync their updates.\n * However, it has some limitations regarding update order control.\n *\n * Update Order:\n * 1. System ticker (always runs first)\n * 2. Shared ticker (if enabled)\n * 3. App ticker (if using own ticker)\n * @example\n * ```ts\n * // Use shared ticker (global instance)\n * await app.init({ sharedTicker: true });\n *\n * // Use dedicated ticker (default)\n * await app.init({ sharedTicker: false });\n *\n * // Access ticker properties\n * console.log(app.ticker.FPS); // Current FPS\n * console.log(app.ticker.deltaMS); // MS since last update\n * ```\n * @default false\n */\n sharedTicker?: boolean;\n}\n\n/**\n * Middleware for Application's {@link Ticker} functionality. This plugin manages the\n * animation loop and update cycle of your PixiJS application.\n *\n * Adds the following features to {@link Application}:\n * - `ticker`: Access to the application's ticker\n * - `start`: Start the animation loop\n * - `stop`: Stop the animation loop\n * @example\n * ```ts\n * import { Application, TickerPlugin, extensions } from 'pixi.js';\n *\n * // Create application\n * const app = new Application();\n *\n * // Example 1: Basic ticker usage (default autoStart)\n * await app.init({ autoStart: true }); // Starts ticker automatically\n *\n * // Example 2: Manual ticker control\n * await app.init({ autoStart: false }); // Don't start automatically\n * app.start(); // Start manually\n * app.stop(); // Stop manually\n *\n * // Example 3: Add custom update logic\n * app.ticker.add((ticker) => {\n * // Run every frame, delta is the time since last update\n * sprite.rotation += 0.1 * ticker.deltaTime;\n * });\n *\n * // Example 4: Control update priority\n * import { UPDATE_PRIORITY } from 'pixi.js';\n *\n * app.ticker.add(\n * (ticker) => {\n * // Run before normal priority updates\n * },\n * null,\n * UPDATE_PRIORITY.HIGH\n * );\n *\n * // Example 5: One-time update\n * app.ticker.addOnce(() => {\n * console.log('Runs next frame only');\n * });\n * ```\n * @see {@link Ticker} For detailed ticker functionality\n * @see {@link UPDATE_PRIORITY} For priority constants\n * @category app\n * @standard\n */\nexport class TickerPlugin\n{\n /** @ignore */\n public static extension: ExtensionMetadata = ExtensionType.Application;\n\n /** @internal */\n public static start: () => void;\n /** @internal */\n public static stop: () => void;\n /** @internal */\n private static _ticker: Ticker;\n /** @internal */\n public static ticker: Ticker;\n\n /**\n * Initialize the plugin with scope of application instance\n * @private\n * @param {object} [options] - See application options\n */\n public static init(options?: PixiMixins.ApplicationOptions): void\n {\n // Set default\n options = Object.assign({\n autoStart: true,\n sharedTicker: false,\n }, options);\n\n // Create ticker setter\n Object.defineProperty(this, 'ticker',\n {\n configurable: true,\n set(ticker)\n {\n if (this._ticker)\n {\n this._ticker.remove(this.render, this);\n }\n this._ticker = ticker;\n if (ticker)\n {\n ticker.add(this.render, this, UPDATE_PRIORITY.LOW);\n }\n },\n get()\n {\n return this._ticker;\n },\n });\n\n this.stop = (): void =>\n {\n this._ticker.stop();\n };\n\n this.start = (): void =>\n {\n this._ticker.start();\n };\n\n this._ticker = null;\n this.ticker = options.sharedTicker ? Ticker.shared : new Ticker();\n\n // Start the rendering\n if (options.autoStart)\n {\n this.start();\n }\n }\n\n /**\n * Clean up the ticker, scoped to application.\n * @private\n */\n public static destroy(): void\n {\n if (this._ticker)\n {\n const oldTicker = this._ticker;\n\n this.ticker = null;\n oldTicker.destroy();\n }\n }\n}\n", "import type { Matrix } from '../../../../../maths/matrix/Matrix';\n\n/**\n * Takes a vertices array and a matrix and transforms the vertices based on the matrix.\n * this out put is written to the uvs array\n * @param vertices - the vertices to calculate uvs from\n * @param verticesStride - the stride of the vertice\n * @param verticesOffset - the offset of the vertices\n * @param uvs - the uvs to fill\n * @param uvsOffset - the offset of the uvs\n * @param uvsStride - the stride of the uvs\n * @param size - the size of the vertices\n * @param matrix - the matrix to apply to the uvs\n * @internal\n */\nexport function buildUvs(\n vertices: number[],\n verticesStride: number,\n verticesOffset: number,\n\n uvs: number[],\n uvsOffset: number,\n uvsStride: number,\n\n size: number,\n matrix: Matrix = null\n): void\n{\n let index = 0;\n\n verticesOffset *= verticesStride;\n uvsOffset *= uvsStride;\n\n const a = matrix.a;\n const b = matrix.b;\n const c = matrix.c;\n const d = matrix.d;\n const tx = matrix.tx;\n const ty = matrix.ty;\n\n while (index < size)\n {\n const x = vertices[verticesOffset];\n const y = vertices[verticesOffset + 1];\n\n uvs[uvsOffset] = (a * x) + (c * y) + tx;\n uvs[uvsOffset + 1] = (b * x) + (d * y) + ty;\n\n uvsOffset += uvsStride;\n\n verticesOffset += verticesStride;\n\n index++;\n }\n}\n/**\n * @param uvs\n * @param uvsOffset\n * @param uvsStride\n * @param size\n * @internal\n */\nexport function buildSimpleUvs(\n uvs: number[],\n uvsOffset: number,\n uvsStride: number,\n size: number,\n)\n{\n let index = 0;\n\n uvsOffset *= uvsStride;\n\n while (index < size)\n {\n uvs[uvsOffset] = 0;\n uvs[uvsOffset + 1] = 0;\n\n uvsOffset += uvsStride;\n\n index++;\n }\n}\n", "import type { Matrix } from '../../../../../maths/matrix/Matrix';\n\n/**\n * Transforms the vertices in an array with the given matrix.\n * @param vertices - the vertices to transform\n * @param m - the matrix to apply to the vertices\n * @param offset - the offset of the vertices (defaults to 0)\n * @param stride - the stride of the vertices (defaults to 2)\n * @param size - the size of the vertices (defaults to vertices.length / stride - offset)\n * @category rendering\n * @internal\n */\nexport function transformVertices(vertices: number[], m: Matrix, offset?: number, stride?: number, size?: number)\n{\n const a = m.a;\n const b = m.b;\n const c = m.c;\n const d = m.d;\n const tx = m.tx;\n const ty = m.ty;\n\n offset ||= 0;\n stride ||= 2;\n size ||= (vertices.length / stride) - offset;\n\n let index = offset * stride;\n\n for (let i = 0; i < size; i++)\n {\n const x = vertices[index];\n const y = vertices[index + 1];\n\n vertices[index] = (a * x) + (c * y) + tx;\n vertices[index + 1] = (b * x) + (d * y) + ty;\n\n index += stride;\n }\n}\n", "import { Matrix } from '../../../maths/matrix/Matrix';\nimport { multiplyHexColors } from '../../container/utils/multiplyHexColors';\n\nimport type { Batch, Batcher } from '../../../rendering/batcher/shared/Batcher';\nimport type { DefaultBatchableMeshElement } from '../../../rendering/batcher/shared/DefaultBatcher';\nimport type { Topology } from '../../../rendering/renderers/shared/geometry/const';\nimport type { Texture } from '../../../rendering/renderers/shared/texture/Texture';\nimport type { Graphics } from './Graphics';\n\nconst identityMatrix = new Matrix();\n\n/**\n * A batchable graphics object.\n * @ignore\n */\nexport class BatchableGraphics implements DefaultBatchableMeshElement\n{\n public readonly packAsQuad = false;\n public batcherName = 'default';\n\n public texture: Texture;\n\n public topology: Topology = 'triangle-list';\n public renderable: Graphics;\n public indexOffset: number;\n public indexSize: number;\n public attributeOffset: number;\n public attributeSize: number;\n public baseColor: number;\n public alpha: number;\n public applyTransform = true;\n public roundPixels: 0 | 1 = 0;\n\n public _indexStart: number;\n public _textureId: number;\n public _attributeStart: number;\n public _batcher: Batcher = null;\n public _batch: Batch = null;\n\n public geometryData: { vertices: number[]; uvs: number[]; indices: number[]; };\n\n get uvs()\n {\n return this.geometryData.uvs;\n }\n\n get positions()\n {\n return this.geometryData.vertices;\n }\n\n get indices()\n {\n return this.geometryData.indices;\n }\n\n get blendMode()\n {\n if (this.renderable && this.applyTransform)\n {\n return this.renderable.groupBlendMode;\n }\n\n return 'normal';\n }\n\n get color()\n {\n const rgb = this.baseColor;\n const bgr = (rgb >> 16) | (rgb & 0xff00) | ((rgb & 0xff) << 16);\n const renderable = this.renderable;\n\n if (renderable)\n {\n return multiplyHexColors(bgr, renderable.groupColor)\n + ((this.alpha * renderable.groupAlpha * 255) << 24);\n }\n\n return bgr + ((this.alpha * 255) << 24);\n }\n\n get transform()\n {\n return this.renderable?.groupTransform || identityMatrix;\n }\n\n public copyTo(gpuBuffer: BatchableGraphics)\n {\n gpuBuffer.indexOffset = this.indexOffset;\n gpuBuffer.indexSize = this.indexSize;\n\n gpuBuffer.attributeOffset = this.attributeOffset;\n gpuBuffer.attributeSize = this.attributeSize;\n\n gpuBuffer.baseColor = this.baseColor;\n gpuBuffer.alpha = this.alpha;\n\n gpuBuffer.texture = this.texture;\n gpuBuffer.geometryData = this.geometryData;\n\n gpuBuffer.topology = this.topology;\n }\n\n public reset()\n {\n this.applyTransform = true;\n this.renderable = null;\n this.topology = 'triangle-list';\n }\n\n public destroy()\n {\n this.renderable = null;\n this.texture = null;\n this.geometryData = null;\n this._batcher = null;\n this._batch = null;\n }\n}\n", "import { ExtensionType } from '../../../../extensions/Extensions';\n\nimport type { Circle } from '../../../../maths/shapes/Circle';\nimport type { Ellipse } from '../../../../maths/shapes/Ellipse';\nimport type { RoundedRectangle } from '../../../../maths/shapes/RoundedRectangle';\nimport type { ShapeBuildCommand } from './ShapeBuildCommand';\n\n/** @internal */\ntype RoundedShape = Circle | Ellipse | RoundedRectangle;\n\n/**\n * Builds a rectangle to draw\n *\n * Ignored from docs since it is not directly exposed.\n * @internal\n */\nexport const buildCircle: ShapeBuildCommand<RoundedShape> = {\n extension: {\n type: ExtensionType.ShapeBuilder,\n name: 'circle',\n },\n\n build(shape: RoundedShape, points: number[]): boolean\n {\n let x;\n let y;\n let dx;\n let dy;\n\n let rx;\n let ry;\n\n if (shape.type === 'circle')\n {\n const circle = shape as Circle;\n\n rx = ry = circle.radius;\n if (rx <= 0)\n {\n return false;\n }\n x = circle.x;\n y = circle.y;\n dx = dy = 0;\n }\n\n else if (shape.type === 'ellipse')\n {\n const ellipse = shape as Ellipse;\n\n rx = ellipse.halfWidth;\n ry = ellipse.halfHeight;\n if (rx <= 0 || ry <= 0)\n { // skip zero ellipse\n return false;\n }\n x = ellipse.x;\n y = ellipse.y;\n dx = dy = 0;\n }\n else\n {\n const roundedRect = shape as RoundedRectangle;\n const halfWidth = roundedRect.width / 2;\n const halfHeight = roundedRect.height / 2;\n\n x = roundedRect.x + halfWidth;\n y = roundedRect.y + halfHeight;\n rx = ry = Math.max(0, Math.min(roundedRect.radius, Math.min(halfWidth, halfHeight)));\n dx = halfWidth - rx;\n dy = halfHeight - ry;\n }\n\n if (dx < 0 || dy < 0)\n {\n return false;\n }\n\n // Choose a number of segments such that the maximum absolute deviation from the circle is approximately 0.029\n const n = Math.ceil(2.3 * Math.sqrt(rx + ry));\n const m = (n * 8) + (dx ? 4 : 0) + (dy ? 4 : 0);\n\n if (m === 0)\n {\n return false;\n }\n\n if (n === 0)\n {\n points[0] = points[6] = x + dx;\n points[1] = points[3] = y + dy;\n points[2] = points[4] = x - dx;\n points[5] = points[7] = y - dy;\n\n return true;\n }\n\n let j1 = 0;\n let j2 = (n * 4) + (dx ? 2 : 0) + 2;\n let j3 = j2;\n let j4 = m;\n\n let x0 = dx + rx;\n let y0 = dy;\n let x1 = x + x0;\n let x2 = x - x0;\n let y1 = y + y0;\n\n points[j1++] = x1;\n points[j1++] = y1;\n points[--j2] = y1;\n points[--j2] = x2;\n\n if (dy)\n {\n const y2 = y - y0;\n\n points[j3++] = x2;\n points[j3++] = y2;\n points[--j4] = y2;\n points[--j4] = x1;\n }\n\n for (let i = 1; i < n; i++)\n {\n const a = Math.PI / 2 * (i / n);\n const x0 = dx + (Math.cos(a) * rx);\n const y0 = dy + (Math.sin(a) * ry);\n const x1 = x + x0;\n const x2 = x - x0;\n const y1 = y + y0;\n const y2 = y - y0;\n\n points[j1++] = x1;\n points[j1++] = y1;\n points[--j2] = y1;\n points[--j2] = x2;\n points[j3++] = x2;\n points[j3++] = y2;\n points[--j4] = y2;\n points[--j4] = x1;\n }\n\n x0 = dx;\n y0 = dy + ry;\n x1 = x + x0;\n x2 = x - x0;\n y1 = y + y0;\n const y2 = y - y0;\n\n points[j1++] = x1;\n points[j1++] = y1;\n points[--j4] = y2;\n points[--j4] = x1;\n\n if (dx)\n {\n points[j1++] = x2;\n points[j1++] = y1;\n points[--j4] = y2;\n points[--j4] = x2;\n }\n\n return true;\n },\n\n triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset)\n {\n if (points.length === 0)\n {\n return;\n }\n\n // Compute center (average of all points)\n let centerX = 0; let\n centerY = 0;\n\n for (let i = 0; i < points.length; i += 2)\n {\n centerX += points[i];\n centerY += points[i + 1];\n }\n centerX /= (points.length / 2);\n centerY /= (points.length / 2);\n\n // Set center vertex\n let count = verticesOffset;\n\n vertices[count * verticesStride] = centerX;\n vertices[(count * verticesStride) + 1] = centerY;\n const centerIndex = count++;\n\n // Set edge vertices and indices\n for (let i = 0; i < points.length; i += 2)\n {\n vertices[count * verticesStride] = points[i];\n vertices[(count * verticesStride) + 1] = points[i + 1];\n\n if (i > 0)\n { // Skip first point for indices\n indices[indicesOffset++] = count;\n indices[indicesOffset++] = centerIndex;\n indices[indicesOffset++] = count - 1;\n }\n count++;\n }\n\n // Connect last point to the first edge point\n indices[indicesOffset++] = centerIndex + 1;\n indices[indicesOffset++] = centerIndex;\n indices[indicesOffset++] = count - 1;\n }\n\n};\n\n/** @internal */\nexport const buildEllipse = { ...buildCircle, extension: { ...buildCircle.extension, name: 'ellipse' } };\n/** @internal */\nexport const buildRoundedRectangle = { ...buildCircle, extension: { ...buildCircle.extension, name: 'roundedRectangle' } };\n", "/**\n * @param points\n * @internal\n */\nexport function getOrientationOfPoints(points: number[]): number\n{\n const m = points.length;\n\n if (m < 6)\n {\n return 1;\n }\n\n let area = 0;\n\n for (let i = 0, x1 = points[m - 2], y1 = points[m - 1]; i < m; i += 2)\n {\n const x2 = points[i];\n const y2 = points[i + 1];\n\n area += (x2 - x1) * (y2 + y1);\n\n x1 = x2;\n y1 = y2;\n }\n\n if (area < 0)\n {\n return -1;\n }\n\n return 1;\n}\n", "import { Point } from '../../../../maths/point/Point';\nimport { closePointEps, curveEps } from '../const';\nimport { getOrientationOfPoints } from '../utils/getOrientationOfPoints';\n\nimport type { StrokeAttributes } from '../FillTypes';\n\n/**\n * Buffers vertices to draw a square cap.\n *\n * Ignored from docs since it is not directly exposed.\n * @ignore\n * @private\n * @param {number} x - X-coord of end point\n * @param {number} y - Y-coord of end point\n * @param {number} nx - X-coord of line normal pointing inside\n * @param {number} ny - Y-coord of line normal pointing inside\n * @param {number} innerWeight - Weight of inner points\n * @param {number} outerWeight - Weight of outer points\n * @param {boolean} clockwise - Whether the cap is drawn clockwise\n * @param {Array<number>} verts - vertex buffer\n * @returns {number} - no. of vertices pushed\n */\nfunction square(\n x: number,\n y: number,\n nx: number,\n ny: number,\n innerWeight: number,\n outerWeight: number,\n clockwise: boolean, /* rotation for square (true at left end, false at right end) */\n verts: Array<number>\n): number\n{\n const ix = x - (nx * innerWeight);\n const iy = y - (ny * innerWeight);\n const ox = x + (nx * outerWeight);\n const oy = y + (ny * outerWeight);\n\n /* Rotate nx,ny for extension vector */\n let exx; let\n eyy;\n\n if (clockwise)\n {\n exx = ny;\n eyy = -nx;\n }\n else\n {\n exx = -ny;\n eyy = nx;\n }\n\n /* [i|0]x,y extended at cap */\n const eix = ix + exx;\n const eiy = iy + eyy;\n const eox = ox + exx;\n const eoy = oy + eyy;\n\n /* Square itself must be inserted clockwise*/\n verts.push(eix, eiy);\n verts.push(eox, eoy);\n\n return 2;\n}\n\n/**\n * Buffers vertices to draw an arc at the line joint or cap.\n *\n * Ignored from docs since it is not directly exposed.\n * @ignore\n * @private\n * @param {number} cx - X-coord of center\n * @param {number} cy - Y-coord of center\n * @param {number} sx - X-coord of arc start\n * @param {number} sy - Y-coord of arc start\n * @param {number} ex - X-coord of arc end\n * @param {number} ey - Y-coord of arc end\n * @param {Array[]} verts - buffer of vertices\n * @param {boolean} clockwise - orientation of vertices\n * @returns {number} - no. of vertices pushed\n */\nfunction round(\n cx: number,\n cy: number,\n sx: number,\n sy: number,\n ex: number,\n ey: number,\n verts: number[],\n clockwise: boolean, /* if not cap, then clockwise is turn of joint, otherwise rotation from angle0 to angle1 */\n): number\n{\n const cx2p0x = sx - cx;\n const cy2p0y = sy - cy;\n\n let angle0 = Math.atan2(cx2p0x, cy2p0y);\n let angle1 = Math.atan2(ex - cx, ey - cy);\n\n if (clockwise && angle0 < angle1)\n {\n angle0 += Math.PI * 2;\n }\n else if (!clockwise && angle0 > angle1)\n {\n angle1 += Math.PI * 2;\n }\n\n let startAngle = angle0;\n const angleDiff = angle1 - angle0;\n const absAngleDiff = Math.abs(angleDiff);\n\n const radius = Math.sqrt((cx2p0x * cx2p0x) + (cy2p0y * cy2p0y));\n const segCount = ((15 * absAngleDiff * Math.sqrt(radius) / Math.PI) >> 0) + 1;\n const angleInc = angleDiff / segCount;\n\n startAngle += angleInc;\n\n if (clockwise)\n {\n verts.push(cx, cy);\n verts.push(sx, sy);\n\n for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc)\n {\n verts.push(cx, cy);\n verts.push(cx + ((Math.sin(angle) * radius)),\n cy + ((Math.cos(angle) * radius)));\n }\n\n verts.push(cx, cy);\n verts.push(ex, ey);\n }\n else\n {\n verts.push(sx, sy);\n verts.push(cx, cy);\n\n for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc)\n {\n verts.push(cx + ((Math.sin(angle) * radius)),\n cy + ((Math.cos(angle) * radius)));\n verts.push(cx, cy);\n }\n\n verts.push(ex, ey);\n verts.push(cx, cy);\n }\n\n return segCount * 2;\n}\n\n/**\n * Builds a line to draw using the polygon method.\n * @param points\n * @param lineStyle\n * @param flipAlignment\n * @param closed\n * @param vertices\n * @param indices\n * @internal\n */\nexport function buildLine(\n points: number[],\n lineStyle: StrokeAttributes,\n flipAlignment: boolean,\n closed: boolean,\n vertices: number[],\n indices: number[],\n): void\n{\n // const shape = graphicsData.shape as Polygon;\n // let points = graphicsData.points || shape.points.slice();\n const eps = closePointEps;\n\n if (points.length === 0)\n {\n return;\n }\n\n const style = lineStyle;\n\n let alignment = style.alignment;\n\n if (lineStyle.alignment !== 0.5)\n {\n // rotate the points!\n let orientation = getOrientationOfPoints(points);\n\n if (flipAlignment)orientation *= -1;\n\n alignment = ((alignment - 0.5) * orientation) + 0.5;\n }\n\n // get first and last point.. figure out the middle!\n const firstPoint = new Point(points[0], points[1]);\n const lastPoint = new Point(points[points.length - 2], points[points.length - 1]);\n const closedShape = closed;\n const closedPath = Math.abs(firstPoint.x - lastPoint.x) < eps\n && Math.abs(firstPoint.y - lastPoint.y) < eps;\n\n // if the first point is the last point - gonna have issues :)\n if (closedShape)\n {\n // need to clone as we are going to slightly modify the shape..\n points = points.slice();\n\n if (closedPath)\n {\n points.pop();\n points.pop();\n lastPoint.set(points[points.length - 2], points[points.length - 1]);\n }\n\n const midPointX = (firstPoint.x + lastPoint.x) * 0.5;\n const midPointY = (lastPoint.y + firstPoint.y) * 0.5;\n\n points.unshift(midPointX, midPointY);\n points.push(midPointX, midPointY);\n }\n\n const verts = vertices;\n\n const length = points.length / 2;\n let indexCount = points.length;\n const indexStart = verts.length / 2;\n\n // Max. inner and outer width\n const width = style.width / 2;\n const widthSquared = width * width;\n const miterLimitSquared = style.miterLimit * style.miterLimit;\n\n /* Line segments of interest where (x1,y1) forms the corner. */\n let x0 = points[0];\n let y0 = points[1];\n let x1 = points[2];\n let y1 = points[3];\n let x2 = 0;\n let y2 = 0;\n\n /* perp[?](x|y) = the line normal with magnitude lineWidth. */\n let perpX = -(y0 - y1);\n let perpY = x0 - x1;\n let perp1x = 0;\n let perp1y = 0;\n\n let dist = Math.sqrt((perpX * perpX) + (perpY * perpY));\n\n perpX /= dist;\n perpY /= dist;\n perpX *= width;\n perpY *= width;\n\n const ratio = alignment;// 0.5;\n const innerWeight = (1 - ratio) * 2;\n const outerWeight = ratio * 2;\n\n if (!closedShape)\n {\n if (style.cap === 'round')\n {\n indexCount += round(\n x0 - (perpX * (innerWeight - outerWeight) * 0.5),\n y0 - (perpY * (innerWeight - outerWeight) * 0.5),\n x0 - (perpX * innerWeight),\n y0 - (perpY * innerWeight),\n x0 + (perpX * outerWeight),\n y0 + (perpY * outerWeight),\n verts,\n true,\n ) + 2;\n }\n else if (style.cap === 'square')\n {\n indexCount += square(x0, y0, perpX, perpY, innerWeight, outerWeight, true, verts);\n }\n }\n\n // Push first point (below & above vertices)\n verts.push(\n x0 - (perpX * innerWeight),\n y0 - (perpY * innerWeight));\n verts.push(\n x0 + (perpX * outerWeight),\n y0 + (perpY * outerWeight));\n\n for (let i = 1; i < length - 1; ++i)\n {\n x0 = points[(i - 1) * 2];\n y0 = points[((i - 1) * 2) + 1];\n\n x1 = points[i * 2];\n y1 = points[(i * 2) + 1];\n\n x2 = points[(i + 1) * 2];\n y2 = points[((i + 1) * 2) + 1];\n\n perpX = -(y0 - y1);\n perpY = x0 - x1;\n\n dist = Math.sqrt((perpX * perpX) + (perpY * perpY));\n perpX /= dist;\n perpY /= dist;\n perpX *= width;\n perpY *= width;\n\n perp1x = -(y1 - y2);\n perp1y = x1 - x2;\n\n dist = Math.sqrt((perp1x * perp1x) + (perp1y * perp1y));\n perp1x /= dist;\n perp1y /= dist;\n perp1x *= width;\n perp1y *= width;\n\n /* d[x|y](0|1) = the component displacement between points p(0,1|1,2) */\n const dx0 = x1 - x0;\n const dy0 = y0 - y1;\n const dx1 = x1 - x2;\n const dy1 = y2 - y1;\n\n /* +ve if internal angle < 90 degree, -ve if internal angle > 90 degree. */\n const dot = (dx0 * dx1) + (dy0 * dy1);\n /* +ve if internal angle counterclockwise, -ve if internal angle clockwise. */\n const cross = (dy0 * dx1) - (dy1 * dx0);\n const clockwise = (cross < 0);\n\n /* Going nearly parallel? */\n /* atan(0.001) ~= 0.001 rad ~= 0.057 degree */\n if (Math.abs(cross) < 0.001 * Math.abs(dot))\n {\n verts.push(\n x1 - (perpX * innerWeight),\n y1 - (perpY * innerWeight));\n verts.push(\n x1 + (perpX * outerWeight),\n y1 + (perpY * outerWeight));\n\n /* 180 degree corner? */\n if (dot >= 0)\n {\n if (style.join === 'round')\n {\n indexCount += round(\n x1, y1,\n x1 - (perpX * innerWeight), y1 - (perpY * innerWeight),\n x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight),\n verts, false) + 4;\n }\n else\n {\n indexCount += 2;\n }\n\n verts.push(\n x1 - (perp1x * outerWeight),\n y1 - (perp1y * outerWeight));\n verts.push(\n x1 + (perp1x * innerWeight),\n y1 + (perp1y * innerWeight));\n }\n\n continue;\n }\n\n /* p[x|y] is the miter point. pDist is the distance between miter point and p1. */\n const c1 = ((-perpX + x0) * (-perpY + y1)) - ((-perpX + x1) * (-perpY + y0));\n const c2 = ((-perp1x + x2) * (-perp1y + y1)) - ((-perp1x + x1) * (-perp1y + y2));\n const px = ((dx0 * c2) - (dx1 * c1)) / cross;\n const py = ((dy1 * c1) - (dy0 * c2)) / cross;\n const pDist = ((px - x1) * (px - x1)) + ((py - y1) * (py - y1));\n\n /* Inner miter point */\n const imx = x1 + ((px - x1) * innerWeight);\n const imy = y1 + ((py - y1) * innerWeight);\n /* Outer miter point */\n const omx = x1 - ((px - x1) * outerWeight);\n const omy = y1 - ((py - y1) * outerWeight);\n\n /* Is the inside miter point too far away, creating a spike? */\n const smallerInsideSegmentSq = Math.min((dx0 * dx0) + (dy0 * dy0), (dx1 * dx1) + (dy1 * dy1));\n const insideWeight = clockwise ? innerWeight : outerWeight;\n const smallerInsideDiagonalSq = smallerInsideSegmentSq + (insideWeight * insideWeight * widthSquared);\n const insideMiterOk = pDist <= smallerInsideDiagonalSq;\n\n if (insideMiterOk)\n {\n if (style.join === 'bevel' || pDist / widthSquared > miterLimitSquared)\n {\n if (clockwise) /* rotating at inner angle */\n {\n verts.push(imx, imy); // inner miter point\n verts.push(x1 + (perpX * outerWeight), y1 + (perpY * outerWeight)); // first segment's outer vertex\n verts.push(imx, imy); // inner miter point\n verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight)); // second segment's outer vertex\n }\n else /* rotating at outer angle */\n {\n verts.push(x1 - (perpX * innerWeight), y1 - (perpY * innerWeight)); // first segment's inner vertex\n verts.push(omx, omy); // outer miter point\n verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight)); // second segment's outer vertex\n verts.push(omx, omy); // outer miter point\n }\n\n indexCount += 2;\n }\n else if (style.join === 'round')\n {\n if (clockwise) /* arc is outside */\n {\n verts.push(imx, imy);\n verts.push(x1 + (perpX * outerWeight), y1 + (perpY * outerWeight));\n\n indexCount += round(\n x1, y1,\n x1 + (perpX * outerWeight), y1 + (perpY * outerWeight),\n x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight),\n verts, true\n ) + 4;\n\n verts.push(imx, imy);\n verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight));\n }\n else /* arc is inside */\n {\n verts.push(x1 - (perpX * innerWeight), y1 - (perpY * innerWeight));\n verts.push(omx, omy);\n\n indexCount += round(\n x1, y1,\n x1 - (perpX * innerWeight), y1 - (perpY * innerWeight),\n x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight),\n verts, false\n ) + 4;\n\n verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight));\n verts.push(omx, omy);\n }\n }\n else\n {\n verts.push(imx, imy);\n verts.push(omx, omy);\n }\n }\n else // inside miter is NOT ok\n {\n verts.push(x1 - (perpX * innerWeight), y1 - (perpY * innerWeight)); // first segment's inner vertex\n verts.push(x1 + (perpX * outerWeight), y1 + (perpY * outerWeight)); // first segment's outer vertex\n if (style.join === 'round')\n {\n if (clockwise) /* arc is outside */\n {\n indexCount += round(\n x1, y1,\n x1 + (perpX * outerWeight), y1 + (perpY * outerWeight),\n x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight),\n verts, true\n ) + 2;\n }\n else /* arc is inside */\n {\n indexCount += round(\n x1, y1,\n x1 - (perpX * innerWeight), y1 - (perpY * innerWeight),\n x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight),\n verts, false\n ) + 2;\n }\n }\n else if (style.join === 'miter' && pDist / widthSquared <= miterLimitSquared)\n {\n if (clockwise)\n {\n verts.push(omx, omy); // inner miter point\n verts.push(omx, omy); // inner miter point\n }\n else\n {\n verts.push(imx, imy); // outer miter point\n verts.push(imx, imy); // outer miter point\n }\n indexCount += 2;\n }\n verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight)); // second segment's inner vertex\n verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight)); // second segment's outer vertex\n indexCount += 2;\n }\n }\n\n x0 = points[(length - 2) * 2];\n y0 = points[((length - 2) * 2) + 1];\n\n x1 = points[(length - 1) * 2];\n y1 = points[((length - 1) * 2) + 1];\n\n perpX = -(y0 - y1);\n perpY = x0 - x1;\n\n dist = Math.sqrt((perpX * perpX) + (perpY * perpY));\n perpX /= dist;\n perpY /= dist;\n perpX *= width;\n perpY *= width;\n\n verts.push(x1 - (perpX * innerWeight), y1 - (perpY * innerWeight));\n verts.push(x1 + (perpX * outerWeight), y1 + (perpY * outerWeight));\n\n if (!closedShape)\n {\n if (style.cap === 'round')\n {\n indexCount += round(\n x1 - (perpX * (innerWeight - outerWeight) * 0.5),\n y1 - (perpY * (innerWeight - outerWeight) * 0.5),\n x1 - (perpX * innerWeight),\n y1 - (perpY * innerWeight),\n x1 + (perpX * outerWeight),\n y1 + (perpY * outerWeight),\n verts,\n false\n ) + 2;\n }\n else if (style.cap === 'square')\n {\n indexCount += square(x1, y1, perpX, perpY, innerWeight, outerWeight, false, verts);\n }\n }\n\n // const indices = graphicsGeometry.indices;\n const eps2 = curveEps * curveEps;\n\n // indices.push(indexStart);\n for (let i = indexStart; i < indexCount + indexStart - 2; ++i)\n {\n x0 = verts[(i * 2)];\n y0 = verts[(i * 2) + 1];\n\n x1 = verts[(i + 1) * 2];\n y1 = verts[((i + 1) * 2) + 1];\n\n x2 = verts[(i + 2) * 2];\n y2 = verts[((i + 2) * 2) + 1];\n\n /* Skip zero area triangles */\n if (Math.abs((x0 * (y1 - y2)) + (x1 * (y2 - y0)) + (x2 * (y0 - y1))) < eps2)\n {\n continue;\n }\n\n indices.push(i, i + 1, i + 2);\n }\n}\n\n", "import { closePointEps } from '../const';\n\n/**\n * Builds a line to draw using the polygon method.\n * @param points\n * @param closed\n * @param vertices\n * @param indices\n * @internal\n */\nexport function buildPixelLine(\n points: number[],\n closed: boolean,\n vertices: number[],\n indices: number[],\n): void\n{\n const eps = closePointEps;\n\n if (points.length === 0)\n {\n return;\n }\n\n // get first and last point.. figure out the middle!\n\n const fx = points[0];\n const fy = points[1];\n\n const lx = points[points.length - 2];\n\n const ly = points[points.length - 1];\n\n const closePath = closed || (Math.abs(fx - lx) < eps && Math.abs(fy - ly) < eps);\n\n const verts = vertices;\n\n const length = points.length / 2;\n const indexStart = verts.length / 2;\n\n for (let i = 0; i < length; i++)\n {\n verts.push(points[(i * 2)]);\n verts.push(points[(i * 2) + 1]);\n }\n\n for (let i = 0; i < length - 1; i++)\n {\n indices.push(indexStart + i, indexStart + i + 1);\n }\n\n if (closePath)\n {\n indices.push(indexStart + length - 1, indexStart);\n }\n}\n\n", "import { earcut } from '../../../../utils/utils';\n\n/**\n * @param points\n * @param holes\n * @param vertices\n * @param verticesStride\n * @param verticesOffset\n * @param indices\n * @param indicesOffset\n * @internal\n */\nexport function triangulateWithHoles(\n points: number[],\n holes: number[],\n vertices: number[],\n verticesStride: number,\n verticesOffset: number,\n\n indices: number[],\n indicesOffset: number\n)\n{\n const triangles = earcut(points, holes, 2);\n\n if (!triangles)\n {\n return;\n }\n\n for (let i = 0; i < triangles.length; i += 3)\n {\n indices[indicesOffset++] = (triangles[i] + verticesOffset);\n indices[indicesOffset++] = (triangles[i + 1] + verticesOffset);\n indices[indicesOffset++] = (triangles[i + 2] + verticesOffset);\n }\n\n let index = verticesOffset * verticesStride;\n\n for (let i = 0; i < points.length; i += 2)\n {\n vertices[index] = points[i];\n vertices[index + 1] = points[i + 1];\n\n index += verticesStride;\n }\n}\n\n", "import { ExtensionType } from '../../../../extensions/Extensions';\nimport { triangulateWithHoles } from '../utils/triangulateWithHoles';\n\nimport type { Polygon } from '../../../../maths/shapes/Polygon';\nimport type { ShapeBuildCommand } from './ShapeBuildCommand';\n\nconst emptyArray: number[] = [];\n\n/**\n * Builds a rectangle to draw\n *\n * Ignored from docs since it is not directly exposed.\n * @ignore\n * @private\n */\nexport const buildPolygon: ShapeBuildCommand<Polygon> = {\n extension: {\n type: ExtensionType.ShapeBuilder,\n name: 'polygon',\n },\n\n build(shape: Polygon, points: number[]): boolean\n {\n for (let i = 0; i < shape.points.length; i++)\n {\n points[i] = shape.points[i];\n }\n\n return true;\n },\n\n triangulate(\n points: number[],\n // holes: number[],\n vertices: number[],\n verticesStride: number,\n verticesOffset: number,\n\n indices: number[],\n indicesOffset: number\n )\n {\n triangulateWithHoles(points, emptyArray, vertices, verticesStride, verticesOffset, indices, indicesOffset);\n },\n\n};\n", "import { ExtensionType } from '../../../../extensions/Extensions';\n\nimport type { Rectangle } from '../../../../maths/shapes/Rectangle';\nimport type { ShapeBuildCommand } from './ShapeBuildCommand';\n\n/**\n * Builds a rectangle to draw\n *\n * Ignored from docs since it is not directly exposed.\n * @ignore\n * @private\n */\nexport const buildRectangle: ShapeBuildCommand<Rectangle> = {\n extension: {\n type: ExtensionType.ShapeBuilder,\n name: 'rectangle',\n },\n\n build(shape: Rectangle, points: number[]): boolean\n {\n const rectData = shape;\n const x = rectData.x;\n const y = rectData.y;\n const width = rectData.width;\n const height = rectData.height;\n\n if (!(width > 0 && height > 0))\n {\n return false;\n }\n\n points[0] = x;\n points[1] = y;\n points[2] = x + width;\n points[3] = y;\n points[4] = x + width;\n points[5] = y + height;\n points[6] = x;\n points[7] = y + height;\n\n return true;\n },\n\n triangulate(\n points: number[],\n\n vertices: number[],\n verticesStride: number,\n verticesOffset: number,\n\n indices: number[],\n indicesOffset: number\n )\n {\n let count = 0;\n\n verticesOffset *= verticesStride;\n\n vertices[verticesOffset + count] = points[0];\n vertices[verticesOffset + count + 1] = points[1];\n\n count += verticesStride;\n\n vertices[verticesOffset + count] = points[2];\n vertices[verticesOffset + count + 1] = points[3];\n\n count += verticesStride;\n\n vertices[verticesOffset + count] = points[6];\n vertices[verticesOffset + count + 1] = points[7];\n\n count += verticesStride;\n\n vertices[verticesOffset + count] = points[4];\n vertices[verticesOffset + count + 1] = points[5];\n\n count += verticesStride;\n\n const verticesIndex = verticesOffset / verticesStride;\n\n // triangle 1\n indices[indicesOffset++] = verticesIndex;\n indices[indicesOffset++] = verticesIndex + 1;\n indices[indicesOffset++] = verticesIndex + 2;\n\n // triangle 2\n indices[indicesOffset++] = verticesIndex + 1;\n indices[indicesOffset++] = verticesIndex + 3;\n indices[indicesOffset++] = verticesIndex + 2;\n },\n};\n", "import { ExtensionType } from '../../../../extensions/Extensions';\n\nimport type { Triangle } from '../../../../maths/shapes/Triangle';\nimport type { ShapeBuildCommand } from './ShapeBuildCommand';\n\n/**\n * Builds a triangle to draw\n *\n * Ignored from docs since it is not directly exposed.\n * @ignore\n * @private\n */\nexport const buildTriangle: ShapeBuildCommand<Triangle> = {\n extension: {\n type: ExtensionType.ShapeBuilder,\n name: 'triangle',\n },\n\n build(shape: Triangle, points: number[]): boolean\n {\n points[0] = shape.x;\n points[1] = shape.y;\n points[2] = shape.x2;\n points[3] = shape.y2;\n points[4] = shape.x3;\n points[5] = shape.y3;\n\n return true;\n },\n\n triangulate(\n points: number[],\n\n vertices: number[],\n verticesStride: number,\n verticesOffset: number,\n\n indices: number[],\n indicesOffset: number\n )\n {\n let count = 0;\n\n verticesOffset *= verticesStride;\n\n vertices[verticesOffset + count] = points[0];\n vertices[verticesOffset + count + 1] = points[1];\n\n count += verticesStride;\n\n vertices[verticesOffset + count] = points[2];\n vertices[verticesOffset + count + 1] = points[3];\n\n count += verticesStride;\n\n vertices[verticesOffset + count] = points[4];\n vertices[verticesOffset + count + 1] = points[5];\n\n const verticesIndex = verticesOffset / verticesStride;\n\n // triangle 1\n indices[indicesOffset++] = verticesIndex;\n indices[indicesOffset++] = verticesIndex + 1;\n indices[indicesOffset++] = verticesIndex + 2;\n },\n};\n", "import { Color } from '../../../../color/Color';\nimport { DOMAdapter } from '../../../../environment/adapter';\nimport { Matrix } from '../../../../maths/matrix/Matrix';\nimport { type WRAP_MODE } from '../../../../rendering/renderers/shared/texture/const';\nimport { ImageSource } from '../../../../rendering/renderers/shared/texture/sources/ImageSource';\nimport { Texture } from '../../../../rendering/renderers/shared/texture/Texture';\nimport { uid } from '../../../../utils/data/uid';\nimport { deprecation } from '../../../../utils/logging/deprecation';\nimport { definedProps } from '../../../container/utils/definedProps';\n\nimport type { ColorSource } from '../../../../color/Color';\nimport type { PointData } from '../../../../maths/point/PointData';\nimport type { CanvasAndContext } from '../../../../rendering/renderers/shared/texture/CanvasPool';\nimport type { TextureSpace } from '../FillTypes';\n\n/**\n * Defines the type of gradient to create.\n *\n * It can be:\n * - 'linear': A linear gradient that transitions colors along a straight line.\n * - 'radial': A radial gradient that transitions colors in a circular pattern from an inner circle to an outer circle.\n * @category scene\n * @standard\n */\nexport type GradientType = 'linear' | 'radial';\n\n/**\n * Represents the style options for a linear gradient fill.\n * @category scene\n * @standard\n */\nexport interface BaseGradientOptions\n{\n /** The type of gradient */\n type?: GradientType;\n /** Array of colors stops to use in the gradient */\n colorStops?: { offset: number, color: ColorSource }[];\n /** Whether coordinates are 'global' or 'local' */\n textureSpace?: TextureSpace;\n /**\n * The size of the texture to use for the gradient - this is for advanced usage.\n * The texture size does not need to match the size of the object being drawn.\n * Due to GPU interpolation, gradient textures can be relatively small!\n * Consider using a larger texture size if your gradient has a lot of very tight color steps\n */\n textureSize?: number;\n /**\n * The wrap mode of the gradient.\n * This can be 'clamp-to-edge' or 'repeat'.\n * @default 'clamp-to-edge'\n */\n wrapMode?: WRAP_MODE\n}\n\n/**\n * Options specific to linear gradients.\n * A linear gradient creates a smooth transition between colors along a straight line defined by start and end points.\n * @category scene\n * @standard\n */\nexport interface LinearGradientOptions extends BaseGradientOptions\n{\n /** The type of gradient. Must be 'linear' for linear gradients. */\n type?: 'linear';\n\n /**\n * The start point of the gradient.\n * This point defines where the gradient begins.\n * It is represented as a PointData object containing x and y coordinates.\n * The coordinates are in local space by default (0-1), but can be in global space if specified.\n */\n start?: PointData;\n\n /**\n * The end point of the gradient.\n * This point defines where the gradient ends.\n * It is represented as a PointData object containing x and y coordinates.\n * The coordinates are in local space by default (0-1), but can be in global space if specified.\n */\n end?: PointData;\n}\n\n/**\n * Options specific to radial gradients.\n * A radial gradient creates a smooth transition between colors that radiates outward in a circular pattern.\n * The gradient is defined by inner and outer circles, each with their own radius.\n * @category scene\n * @standard\n */\nexport interface RadialGradientOptions extends BaseGradientOptions\n{\n /** The type of gradient. Must be 'radial' for radial gradients. */\n type?: 'radial';\n /** The center point of the inner circle where the gradient begins. In local coordinates by default (0-1). */\n center?: PointData;\n /** The radius of the inner circle where the gradient begins. */\n innerRadius?: number;\n /** The center point of the outer circle where the gradient ends. In local coordinates by default (0-1). */\n outerCenter?: PointData;\n /** The radius of the outer circle where the gradient ends. */\n outerRadius?: number;\n /**\n * The y scale of the gradient, use this to make the gradient elliptical.\n * NOTE: Only applied to radial gradients used with Graphics.\n */\n scale?: number;\n /**\n * The rotation of the gradient in radians, useful for making the gradient elliptical.\n * NOTE: Only applied to radial gradients used with Graphics.\n */\n rotation?: number;\n}\n\n/**\n * Options for creating a gradient fill.\n * @category scene\n * @standard\n */\nexport type GradientOptions = LinearGradientOptions | RadialGradientOptions;\n\n/**\n * If no color stops are provided, we use a default gradient of white to black - this is to avoid a blank gradient if a dev\n * forgets to set them.\n */\nconst emptyColorStops: { offset: number, color: string }[] = [{ offset: 0, color: 'white' }, { offset: 1, color: 'black' }];\n\n/**\n * Class representing a gradient fill that can be used to fill shapes and text.\n * Supports both linear and radial gradients with multiple color stops.\n *\n * For linear gradients, color stops define colors and positions (0 to 1) along a line from start point (x0,y0)\n * to end point (x1,y1).\n *\n * For radial gradients, color stops define colors between two circles - an inner circle centered at (x0,y0) with radius r0,\n * and an outer circle centered at (x1,y1) with radius r1.\n * @example\n * ```ts\n * // Create a vertical linear gradient from red to blue\n * const linearGradient = new FillGradient({\n * type: 'linear',\n * start: { x: 0, y: 0 }, // Start at top\n * end: { x: 0, y: 1 }, // End at bottom\n * colorStops: [\n * { offset: 0, color: 'red' }, // Red at start\n * { offset: 1, color: 'blue' } // Blue at end\n * ],\n * // Use normalized coordinate system where (0,0) is the top-left and (1,1) is the bottom-right of the shape\n * textureSpace: 'local'\n * });\n *\n * // Create a radial gradient from yellow center to green edge\n * const radialGradient = new FillGradient({\n * type: 'radial',\n * center: { x: 0.5, y: 0.5 },\n * innerRadius: 0,\n * outerCenter: { x: 0.5, y: 0.5 },\n * outerRadius: 0.5,\n * colorStops: [\n * { offset: 0, color: 'yellow' }, // Center color\n * { offset: 1, color: 'green' } // Edge color\n * ],\n * // Use normalized coordinate system where (0,0) is the top-left and (1,1) is the bottom-right of the shape\n * textureSpace: 'local'\n * });\n *\n * // Create a rainbow linear gradient in global coordinates\n * const globalGradient = new FillGradient({\n * type: 'linear',\n * start: { x: 0, y: 0 },\n * end: { x: 100, y: 0 },\n * colorStops: [\n * { offset: 0, color: 0xff0000 }, // Red\n * { offset: 0.33, color: 0x00ff00 }, // Green\n * { offset: 0.66, color: 0x0000ff }, // Blue\n * { offset: 1, color: 0xff00ff } // Purple\n * ],\n * textureSpace: 'global' // Use world coordinates\n * });\n *\n * // Create an offset radial gradient\n * const offsetRadial = new FillGradient({\n * type: 'radial',\n * center: { x: 0.3, y: 0.3 },\n * innerRadius: 0.1,\n * outerCenter: { x: 0.5, y: 0.5 },\n * outerRadius: 0.5,\n * colorStops: [\n * { offset: 0, color: 'white' },\n * { offset: 1, color: 'black' }\n * ],\n * // Use normalized coordinate system where (0,0) is the top-left and (1,1) is the bottom-right of the shape\n * textureSpace: 'local'\n * });\n * ```\n *\n * Internally this creates a texture of the gradient then applies a\n * transform to it to give it the correct size and angle.\n *\n * This means that it's important to destroy a gradient when it is no longer needed\n * to avoid memory leaks.\n *\n * If you want to animate a gradient then it's best to modify and update an existing one\n * rather than creating a whole new one each time. That or use a custom shader.\n * @category scene\n * @standard\n */\nexport class FillGradient implements CanvasGradient\n{\n /** Default options for creating a gradient fill */\n public static readonly defaultLinearOptions: LinearGradientOptions = {\n start: { x: 0, y: 0 },\n end: { x: 0, y: 1 },\n colorStops: [],\n textureSpace: 'local',\n type: 'linear',\n textureSize: 256,\n wrapMode: 'clamp-to-edge'\n };\n\n /** Default options for creating a radial gradient fill */\n public static readonly defaultRadialOptions: RadialGradientOptions = {\n center: { x: 0.5, y: 0.5 },\n innerRadius: 0,\n outerRadius: 0.5,\n colorStops: [],\n scale: 1,\n textureSpace: 'local',\n type: 'radial',\n textureSize: 256,\n wrapMode: 'clamp-to-edge'\n };\n\n /**\n * Unique identifier for this gradient instance\n * @internal\n */\n public readonly uid: number = uid('fillGradient');\n /**\n * Internal tick counter to track changes in the gradient.\n * This is used to invalidate the gradient when the texture changes.\n * @internal\n */\n public _tick: number = 0;\n /** Type of gradient - currently only supports 'linear' */\n public readonly type: GradientType = 'linear';\n\n /** Internal texture used to render the gradient */\n public texture: Texture;\n /** Transform matrix for positioning the gradient */\n public transform: Matrix;\n /** Array of color stops defining the gradient */\n public colorStops: Array<{ offset: number, color: string }> = [];\n\n /** Whether gradient coordinates are in local or global space */\n public textureSpace: TextureSpace;\n private readonly _textureSize: number;\n\n /** The start point of the linear gradient */\n public start: PointData;\n /** The end point of the linear gradient */\n public end: PointData;\n /** The wrap mode of the gradient texture */\n private readonly _wrapMode: WRAP_MODE;\n\n /** The center point of the inner circle of the radial gradient */\n public center: PointData;\n /** The center point of the outer circle of the radial gradient */\n public outerCenter: PointData;\n /** The radius of the inner circle of the radial gradient */\n public innerRadius: number;\n /** The radius of the outer circle of the radial gradient */\n public outerRadius: number;\n /** The scale of the radial gradient */\n public scale: number;\n /** The rotation of the radial gradient */\n public rotation: number;\n\n /**\n * Creates a new gradient fill. The constructor behavior changes based on the gradient type.\n * @param {GradientOptions} options - The options for the gradient\n * @see {@link LinearGradientOptions}\n * @see {@link RadialGradientOptions}\n */\n constructor(options: GradientOptions);\n /**\n * Deprecated: Use the options object instead.\n * @deprecated since 8.5.2\n * @ignore\n */\n constructor(\n x0?: number,\n y0?: number,\n x1?: number,\n y1?: number,\n textureSpace?: TextureSpace,\n textureSize?: number\n );\n constructor(...args: [GradientOptions] | [number?, number?, number?, number?, TextureSpace?, number?])\n {\n let options = ensureGradientOptions(args);\n\n const defaults = options.type === 'radial' ? FillGradient.defaultRadialOptions : FillGradient.defaultLinearOptions;\n\n options = { ...defaults, ...definedProps(options) };\n\n this._textureSize = options.textureSize;\n this._wrapMode = options.wrapMode;\n\n if (options.type === 'radial')\n {\n this.center = options.center;\n this.outerCenter = options.outerCenter ?? this.center;\n this.innerRadius = options.innerRadius;\n this.outerRadius = options.outerRadius;\n this.scale = options.scale;\n this.rotation = options.rotation;\n }\n else\n {\n this.start = options.start;\n this.end = options.end;\n }\n\n this.textureSpace = options.textureSpace;\n\n this.type = options.type;\n options.colorStops.forEach((stop) =>\n {\n this.addColorStop(stop.offset, stop.color);\n });\n }\n\n /**\n * Adds a color stop to the gradient\n * @param offset - Position of the stop (0-1)\n * @param color - Color of the stop\n * @returns This gradient instance for chaining\n */\n public addColorStop(offset: number, color: ColorSource): this\n {\n this.colorStops.push({ offset, color: Color.shared.setValue(color).toHexa() });\n\n return this;\n }\n\n /**\n * Builds the internal texture and transform for the gradient.\n * Called automatically when the gradient is first used.\n * @internal\n */\n public buildLinearGradient(): void\n {\n if (this.texture) return;\n\n let { x: x0, y: y0 } = this.start;\n let { x: x1, y: y1 } = this.end;\n\n let dx = x1 - x0;\n let dy = y1 - y0;\n\n // Determine flip based on original dx/dy and swap coordinates if necessary\n const flip = dx < 0 || dy < 0;\n\n if (this._wrapMode === 'clamp-to-edge')\n {\n if (dx < 0)\n {\n const temp = x0;\n\n x0 = x1;\n x1 = temp;\n dx *= -1;\n }\n if (dy < 0)\n {\n const temp = y0;\n\n y0 = y1;\n y1 = temp;\n dy *= -1;\n }\n }\n\n const colorStops = this.colorStops.length ? this.colorStops : emptyColorStops;\n\n const defaultSize = this._textureSize;\n\n const { canvas, context } = getCanvas(defaultSize, 1);\n\n const gradient = !flip\n ? context.createLinearGradient(0, 0, this._textureSize, 0)\n : context.createLinearGradient(this._textureSize, 0, 0, 0);\n\n addColorStops(gradient, colorStops);\n\n context.fillStyle = gradient;\n context.fillRect(0, 0, defaultSize, 1);\n\n this.texture = new Texture({\n source: new ImageSource({\n resource: canvas,\n addressMode: this._wrapMode,\n }),\n });\n\n // generate some UVS based on the gradient direction sent\n\n const dist = Math.sqrt((dx * dx) + (dy * dy));\n const angle = Math.atan2(dy, dx);\n\n // little offset to stop the uvs from flowing over the edge..\n // this matrix is inverted when used in the graphics\n // add a tiny off set to prevent uv bleeding..\n const m = new Matrix();\n\n m.scale((dist / defaultSize), 1);\n m.rotate(angle);\n m.translate(x0, y0);\n\n if (this.textureSpace === 'local')\n {\n m.scale(defaultSize, defaultSize);\n }\n this.transform = m;\n }\n\n /**\n * Builds the internal texture and transform for the gradient.\n * Called automatically when the gradient is first used.\n * @internal\n */\n public buildGradient(): void\n {\n if (!this.texture) this._tick++;\n if (this.type === 'linear')\n {\n this.buildLinearGradient();\n }\n else\n {\n this.buildRadialGradient();\n }\n }\n\n /**\n * Builds the internal texture and transform for the radial gradient.\n * Called automatically when the gradient is first used.\n * @internal\n */\n public buildRadialGradient(): void\n {\n if (this.texture) return;\n\n const colorStops = this.colorStops.length ? this.colorStops : emptyColorStops;\n\n const defaultSize = this._textureSize;\n const { canvas, context } = getCanvas(defaultSize, defaultSize);\n\n const { x: x0, y: y0 } = this.center;\n const { x: x1, y: y1 } = this.outerCenter;\n\n const r0 = this.innerRadius;\n const r1 = this.outerRadius;\n\n const ox = x1 - r1;\n const oy = y1 - r1;\n\n const scale = defaultSize / (r1 * 2);\n\n const cx = (x0 - ox) * scale;\n const cy = (y0 - oy) * scale;\n\n const gradient = context.createRadialGradient(\n cx,\n cy,\n r0 * scale,\n (x1 - ox) * scale,\n (y1 - oy) * scale,\n r1 * scale\n );\n\n addColorStops(gradient, colorStops);\n\n context.fillStyle = colorStops[colorStops.length - 1].color;\n context.fillRect(0, 0, defaultSize, defaultSize);\n\n context.fillStyle = gradient;\n\n // First translate to center\n context.translate(cx, cy);\n\n // Then apply rotation\n context.rotate(this.rotation);\n\n // Then scale2\n context.scale(1, this.scale);\n\n // Finally translate back, taking scale into account\n context.translate(-cx, -cy);\n\n context.fillRect(0, 0, defaultSize, defaultSize);\n\n this.texture = new Texture({\n source: new ImageSource({\n resource: canvas,\n addressMode: this._wrapMode,\n }),\n });\n\n const m = new Matrix();\n\n // this matrix is inverted when used in the graphics\n m.scale(1 / scale, 1 / scale);\n m.translate(ox, oy);\n\n if (this.textureSpace === 'local')\n {\n m.scale(defaultSize, defaultSize);\n }\n\n this.transform = m;\n }\n\n /** Destroys the gradient, releasing resources. This will also destroy the internal texture. */\n public destroy(): void\n {\n this.texture?.destroy(true);\n this.texture = null;\n this.transform = null;\n this.colorStops = [];\n this.start = null;\n this.end = null;\n this.center = null;\n this.outerCenter = null;\n }\n\n /**\n * Returns a unique key for this gradient instance.\n * This key is used for caching and texture management.\n * @returns {string} Unique key for the gradient\n */\n public get styleKey(): string\n {\n return `fill-gradient-${this.uid}-${this._tick}`;\n }\n}\n\nfunction addColorStops(gradient: CanvasGradient, colorStops: { offset: number, color: string }[]): void\n{\n for (let i = 0; i < colorStops.length; i++)\n {\n const stop = colorStops[i];\n\n gradient.addColorStop(stop.offset, stop.color);\n }\n}\n\nfunction getCanvas(width: number, height: number): CanvasAndContext\n{\n const canvas = DOMAdapter.get().createCanvas(width, height);\n const context = canvas.getContext('2d');\n\n return { canvas, context };\n}\n\n/**\n * Helper function to ensure consistent handling of gradient options.\n * This function handles both the new options object format and the deprecated parameter format.\n * @example\n * // New recommended way:\n * const options = ensureGradientOptions({\n * start: { x: 0, y: 0 },\n * end: { x: 100, y: 100 },\n * textureSpace: 'local'\n * });\n *\n * // Deprecated way (will show warning in debug):\n * const options = ensureGradientOptions([0, 0, 100, 100, 'local']);\n * @param args - Arguments passed to gradient constructor\n * @returns Normalized gradient options object\n * @internal\n */\nfunction ensureGradientOptions(\n args: any[],\n): GradientOptions\n{\n let options = (args[0] ?? {}) as GradientOptions;\n\n // @deprecated\n if (typeof options === 'number' || args[1])\n {\n // #if _DEBUG\n deprecation('8.5.2', `use options object instead`);\n // #endif\n\n options = {\n type: 'linear',\n start: { x: args[0], y: args[1] },\n end: { x: args[2], y: args[3] },\n textureSpace: args[4] as 'global' | 'local',\n textureSize: args[5] ?? FillGradient.defaultLinearOptions.textureSize\n };\n }\n\n return options;\n}\n", "import { Matrix } from '../../../../maths/matrix/Matrix';\nimport { Rectangle } from '../../../../maths/shapes/Rectangle';\nimport { FillGradient } from '../fill/FillGradient';\n\nimport type { ShapePrimitive } from '../../../../maths/shapes/ShapePrimitive';\nimport type { FillStyle, StrokeStyle } from '../FillTypes';\n\n/**\n * Temporary matrix used for matrix calculations\n * @internal\n */\nconst tempTextureMatrix = new Matrix();\n\n/**\n * Temporary rectangle used for bounds calculations\n * @internal\n */\nconst tempRect = new Rectangle();\n\n/**\n * Generates a texture matrix for mapping textures onto shapes.\n * This function handles both local and global texture space mapping.\n *\n * In local space, the texture is mapped to fit exactly within the bounds of the shape.\n * In global space, the texture is mapped using its own dimensions and position.\n * @param out - The matrix to store the result in\n * @param style - The fill style containing texture and mapping properties\n * @param shape - The shape to map the texture onto\n * @param matrix - Optional transform matrix to apply\n * @returns The generated texture matrix for UV mapping\n * @example\n * ```ts\n * const matrix = new Matrix();\n * const textureMatrix = generateTextureMatrix(matrix, fillStyle, shape);\n * // textureMatrix now contains the proper UV mapping for the texture\n * ```\n * @internal\n */\nexport function generateTextureMatrix(out: Matrix, style: FillStyle | StrokeStyle, shape: ShapePrimitive, matrix?: Matrix)\n{\n // Start with either the style's matrix inverted, or identity matrix\n const textureMatrix = style.matrix\n ? out.copyFrom(style.matrix).invert()\n : out.identity();\n\n if (style.textureSpace === 'local')\n {\n // For local space, map texture to shape's bounds\n const bounds = shape.getBounds(tempRect);\n\n if ((style as StrokeStyle).width)\n {\n bounds.pad((style as StrokeStyle).width);\n }\n\n const { x: tx, y: ty } = bounds;\n const sx = 1 / bounds.width;\n const sy = 1 / bounds.height;\n\n const mTx = -tx * sx;\n const mTy = -ty * sy;\n\n const a1 = textureMatrix.a;\n const b1 = textureMatrix.b;\n const c1 = textureMatrix.c;\n const d1 = textureMatrix.d;\n\n textureMatrix.a *= sx;\n textureMatrix.b *= sx;\n textureMatrix.c *= sy;\n textureMatrix.d *= sy;\n\n textureMatrix.tx = (mTx * a1) + (mTy * c1) + textureMatrix.tx;\n textureMatrix.ty = (mTx * b1) + (mTy * d1) + textureMatrix.ty;\n }\n else\n {\n // For global space, use texture's own dimensions\n textureMatrix.translate(style.texture.frame.x, style.texture.frame.y);\n textureMatrix.scale(1 / (style.texture.source.width), 1 / (style.texture.source.height));\n }\n\n const sourceStyle = style.texture.source.style;\n\n // we don't want to set the address mode if the fill is a gradient as this handles its own address mode\n if (!(style.fill instanceof FillGradient) && sourceStyle.addressMode === 'clamp-to-edge')\n {\n sourceStyle.addressMode = 'repeat';\n sourceStyle.update();\n }\n\n // Apply any additional transform matrix\n if (matrix)\n {\n textureMatrix.append(tempTextureMatrix.copyFrom(matrix).invert());\n }\n\n return textureMatrix;\n}\n", "import { extensions, ExtensionType } from '../../../../extensions/Extensions';\nimport { Matrix } from '../../../../maths/matrix/Matrix';\nimport { Rectangle } from '../../../../maths/shapes/Rectangle';\nimport { buildSimpleUvs, buildUvs } from '../../../../rendering/renderers/shared/geometry/utils/buildUvs';\nimport { transformVertices } from '../../../../rendering/renderers/shared/geometry/utils/transformVertices';\nimport { Texture } from '../../../../rendering/renderers/shared/texture/Texture';\nimport { BigPool } from '../../../../utils/pool/PoolGroup';\nimport { BatchableGraphics } from '../BatchableGraphics';\nimport { buildCircle, buildEllipse, buildRoundedRectangle } from '../buildCommands/buildCircle';\nimport { buildLine } from '../buildCommands/buildLine';\nimport { buildPixelLine } from '../buildCommands/buildPixelLine';\nimport { buildPolygon } from '../buildCommands/buildPolygon';\nimport { buildRectangle } from '../buildCommands/buildRectangle';\nimport { buildTriangle } from '../buildCommands/buildTriangle';\nimport { generateTextureMatrix as generateTextureFillMatrix } from './generateTextureFillMatrix';\nimport { triangulateWithHoles } from './triangulateWithHoles';\n\nimport type { Polygon } from '../../../../maths/shapes/Polygon';\nimport type { Topology } from '../../../../rendering/renderers/shared/geometry/const';\nimport type { ShapeBuildCommand } from '../buildCommands/ShapeBuildCommand';\nimport type { ConvertedFillStyle, ConvertedStrokeStyle } from '../FillTypes';\nimport type { GraphicsContext, TextureInstruction } from '../GraphicsContext';\nimport type { GpuGraphicsContext } from '../GraphicsContextSystem';\nimport type { ShapePath, ShapePrimitiveWithHoles } from '../path/ShapePath';\n\n/**\n * A record of shape builders, keyed by shape type.\n * @category scene\n * @advanced\n */\nexport const shapeBuilders: Record<string, ShapeBuildCommand> = {};\n\nextensions.handleByMap(ExtensionType.ShapeBuilder, shapeBuilders);\nextensions.add(buildRectangle, buildPolygon, buildTriangle, buildCircle, buildEllipse, buildRoundedRectangle);\n\nconst tempRect = new Rectangle();\nconst tempTextureMatrix = new Matrix();\n\n/**\n * @param context\n * @param gpuContext\n * @internal\n */\nexport function buildContextBatches(context: GraphicsContext, gpuContext: GpuGraphicsContext)\n{\n const { geometryData, batches } = gpuContext;\n\n // reset them..\n batches.length = 0;\n geometryData.indices.length = 0;\n geometryData.vertices.length = 0;\n geometryData.uvs.length = 0;\n\n for (let i = 0; i < context.instructions.length; i++)\n {\n const instruction = context.instructions[i];\n\n if (instruction.action === 'texture')\n {\n // add a quad!\n addTextureToGeometryData(instruction.data, batches, geometryData);\n }\n else if (instruction.action === 'fill' || instruction.action === 'stroke')\n {\n const isStroke = instruction.action === 'stroke';\n\n // build path collection of polys and shapes points..\n const shapePath = instruction.data.path.shapePath;\n\n const style = instruction.data.style;\n\n const hole = instruction.data.hole;\n\n if (isStroke && hole)\n {\n addShapePathToGeometryData(hole.shapePath, style, true, batches, geometryData);\n }\n\n if (hole)\n {\n // add the holes to the last shape primitive\n shapePath.shapePrimitives[shapePath.shapePrimitives.length - 1].holes = hole.shapePath.shapePrimitives;\n }\n\n addShapePathToGeometryData(shapePath, style, isStroke, batches, geometryData);\n }\n }\n}\n\nfunction addTextureToGeometryData(\n data: TextureInstruction['data'],\n batches: BatchableGraphics[],\n geometryData: {\n vertices: number[];\n uvs: number[];\n indices: number[];\n }\n)\n{\n const points: number[] = [];\n\n const build = shapeBuilders.rectangle;\n\n const rect = tempRect;\n\n rect.x = data.dx;\n rect.y = data.dy;\n rect.width = data.dw;\n rect.height = data.dh;\n\n const matrix = data.transform;\n\n // TODO - this can be cached...\n if (!build.build(rect, points))\n {\n return;\n }\n\n const { vertices, uvs, indices } = geometryData;\n\n const indexOffset = indices.length;\n const vertOffset = vertices.length / 2;\n\n if (matrix)\n {\n transformVertices(points, matrix);\n }\n\n build.triangulate(points, vertices, 2, vertOffset, indices, indexOffset);\n\n const texture = data.image;\n const textureUvs = texture.uvs;\n\n uvs.push(\n textureUvs.x0, textureUvs.y0,\n textureUvs.x1, textureUvs.y1,\n textureUvs.x3, textureUvs.y3,\n textureUvs.x2, textureUvs.y2,\n );\n\n const graphicsBatch = BigPool.get(BatchableGraphics);\n\n graphicsBatch.indexOffset = indexOffset;\n graphicsBatch.indexSize = indices.length - indexOffset;\n\n graphicsBatch.attributeOffset = vertOffset;\n graphicsBatch.attributeSize = (vertices.length / 2) - vertOffset;\n\n graphicsBatch.baseColor = data.style;\n graphicsBatch.alpha = data.alpha;\n\n graphicsBatch.texture = texture;\n graphicsBatch.geometryData = geometryData;\n\n batches.push(graphicsBatch);\n}\n\nfunction addShapePathToGeometryData(\n shapePath: ShapePath,\n style: ConvertedFillStyle | ConvertedStrokeStyle,\n isStroke: boolean,\n batches: BatchableGraphics[],\n geometryData: {\n vertices: number[];\n uvs: number[];\n indices: number[];\n }\n)\n{\n const { vertices, uvs, indices } = geometryData;\n\n shapePath.shapePrimitives.forEach(({ shape, transform: matrix, holes }) =>\n {\n const points: number[] = [];\n const build = shapeBuilders[shape.type];\n // TODO - this can be cached...\n // TODO - THIS IS DONE TWICE!!!!!!\n // ONCE FOR STROKE AND ONCE FOR FILL\n // move to the ShapePath2D class itself?\n\n if (!build.build(shape, points))\n {\n return;\n }\n\n const indexOffset = indices.length;\n const vertOffset = vertices.length / 2;\n let topology: Topology = 'triangle-list';\n\n if (matrix)\n {\n transformVertices(points, matrix);\n }\n\n if (!isStroke)\n {\n if (holes)\n {\n const holeIndices: number[] = [];\n\n const otherPoints = points.slice();\n\n const holeArrays = getHoleArrays(holes);\n\n holeArrays.forEach((holePoints) =>\n {\n holeIndices.push(otherPoints.length / 2);\n otherPoints.push(...holePoints);\n });\n\n triangulateWithHoles(otherPoints, holeIndices, vertices, 2, vertOffset, indices, indexOffset);\n }\n else\n {\n build.triangulate(points, vertices, 2, vertOffset, indices, indexOffset);\n }\n }\n else\n {\n const close = (shape as Polygon).closePath ?? true;\n const lineStyle = style as ConvertedStrokeStyle;\n\n if (!lineStyle.pixelLine)\n {\n buildLine(points, lineStyle, false, close, vertices, indices);\n }\n else\n {\n buildPixelLine(points, close, vertices, indices);\n topology = 'line-list';\n }\n }\n\n const uvsOffset = uvs.length / 2;\n\n const texture = style.texture;\n\n if (texture !== Texture.WHITE)\n {\n const textureMatrix = generateTextureFillMatrix(tempTextureMatrix, style, shape, matrix);\n\n buildUvs(vertices, 2, vertOffset, uvs, uvsOffset, 2, (vertices.length / 2) - vertOffset, textureMatrix);\n }\n else\n {\n buildSimpleUvs(uvs, uvsOffset, 2, (vertices.length / 2) - vertOffset);\n }\n\n const graphicsBatch = BigPool.get(BatchableGraphics);\n\n graphicsBatch.indexOffset = indexOffset;\n graphicsBatch.indexSize = indices.length - indexOffset;\n\n graphicsBatch.attributeOffset = vertOffset;\n graphicsBatch.attributeSize = (vertices.length / 2) - vertOffset;\n\n graphicsBatch.baseColor = style.color;\n graphicsBatch.alpha = style.alpha;\n\n graphicsBatch.texture = texture;\n graphicsBatch.geometryData = geometryData;\n graphicsBatch.topology = topology;\n\n batches.push(graphicsBatch);\n });\n}\n\nfunction getHoleArrays(holePrimitives: ShapePrimitiveWithHoles[])\n{\n const holeArrays = [];\n\n for (let k = 0; k < holePrimitives.length; k++)\n {\n const holePrimitive = holePrimitives[k].shape;\n\n // TODO - need to transform the points via there transform here..\n const holePoints: number[] = [];\n\n const holeBuilder = shapeBuilders[holePrimitive.type] as ShapeBuildCommand;\n\n if (holeBuilder.build(holePrimitive, holePoints))\n {\n holeArrays.push(holePoints);\n }\n }\n\n return holeArrays;\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { getTextureBatchBindGroup } from '../../../rendering/batcher/gpu/getTextureBatchBindGroup';\nimport { type BatcherOptions } from '../../../rendering/batcher/shared/Batcher';\nimport { DefaultBatcher } from '../../../rendering/batcher/shared/DefaultBatcher';\nimport { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport { deprecation, v8_3_4 } from '../../../utils/logging/deprecation';\nimport { BigPool } from '../../../utils/pool/PoolGroup';\nimport { buildContextBatches } from './utils/buildContextBatches';\n\nimport type { System } from '../../../rendering/renderers/shared/system/System';\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { PoolItem } from '../../../utils/pool/Pool';\nimport type { BatchableGraphics } from './BatchableGraphics';\nimport type { GraphicsContext } from './GraphicsContext';\n\ninterface GeometryData\n{\n vertices: number[];\n uvs: number[];\n indices: number[];\n}\n\n/**\n * A class that holds batchable graphics data for a GraphicsContext.\n * @category rendering\n * @ignore\n */\nexport class GpuGraphicsContext\n{\n public isBatchable: boolean;\n public context: GraphicsContext;\n\n public batches: BatchableGraphics[] = [];\n public geometryData: GeometryData = {\n vertices: [],\n uvs: [],\n indices: [],\n };\n public graphicsData: GraphicsContextRenderData;\n}\n\n/**\n * A class that holds the render data for a GraphicsContext.\n * @category rendering\n * @ignore\n */\nexport class GraphicsContextRenderData\n{\n public batcher: DefaultBatcher;\n public instructions = new InstructionSet();\n\n public init(options: BatcherOptions)\n {\n const maxTextures = options.maxTextures;\n\n this.batcher ? this.batcher._updateMaxTextures(maxTextures) : this.batcher = new DefaultBatcher({ maxTextures });\n this.instructions.reset();\n }\n\n /**\n * @deprecated since version 8.0.0\n * Use `batcher.geometry` instead.\n * @see {Batcher#geometry}\n */\n get geometry()\n {\n // #if _DEBUG\n deprecation(v8_3_4, 'GraphicsContextRenderData#geometry is deprecated, please use batcher.geometry instead.');\n // #endif\n\n return this.batcher.geometry;\n }\n\n public destroy()\n {\n this.batcher.destroy();\n this.instructions.destroy();\n\n this.batcher = null;\n this.instructions = null;\n }\n}\n\n/**\n * Options for the GraphicsContextSystem.\n * @category rendering\n * @advanced\n */\nexport interface GraphicsContextSystemOptions\n{\n /** A value from 0 to 1 that controls the smoothness of bezier curves (the higher the smoother) */\n bezierSmoothness?: number;\n}\n\n/**\n * A system that manages the rendering of GraphicsContexts.\n * @category rendering\n * @advanced\n */\nexport class GraphicsContextSystem implements System<GraphicsContextSystemOptions>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLSystem,\n ExtensionType.WebGPUSystem,\n ExtensionType.CanvasSystem,\n ],\n name: 'graphicsContext'\n } as const;\n\n /** The default options for the GraphicsContextSystem. */\n public static readonly defaultOptions: GraphicsContextSystemOptions = {\n /**\n * A value from 0 to 1 that controls the smoothness of bezier curves (the higher the smoother)\n * @default 0.5\n */\n bezierSmoothness: 0.5,\n };\n\n // the root context batches, used to either make a batch or geometry\n // all graphics use this as a base\n private _gpuContextHash: Record<number, GpuGraphicsContext> = {};\n // used for non-batchable graphics\n private _graphicsDataContextHash: Record<number, GraphicsContextRenderData> = Object.create(null);\n private readonly _renderer: Renderer;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n renderer.renderableGC.addManagedHash(this, '_gpuContextHash');\n renderer.renderableGC.addManagedHash(this, '_graphicsDataContextHash');\n }\n\n /**\n * Runner init called, update the default options\n * @ignore\n */\n public init(options?: GraphicsContextSystemOptions)\n {\n GraphicsContextSystem.defaultOptions.bezierSmoothness = options?.bezierSmoothness\n ?? GraphicsContextSystem.defaultOptions.bezierSmoothness;\n }\n\n /**\n * Returns the render data for a given GraphicsContext.\n * @param context - The GraphicsContext to get the render data for.\n * @internal\n */\n public getContextRenderData(context: GraphicsContext): GraphicsContextRenderData\n {\n return this._graphicsDataContextHash[context.uid] || this._initContextRenderData(context);\n }\n\n /**\n * Updates the GPU context for a given GraphicsContext.\n * If the context is dirty, it will rebuild the batches and geometry data.\n * @param context - The GraphicsContext to update.\n * @returns The updated GpuGraphicsContext.\n * @internal\n */\n public updateGpuContext(context: GraphicsContext)\n {\n let gpuContext: GpuGraphicsContext = this._gpuContextHash[context.uid]\n\n || this._initContext(context);\n\n if (context.dirty)\n {\n if (gpuContext)\n {\n this._cleanGraphicsContextData(context);\n }\n else\n {\n gpuContext = this._initContext(context);\n }\n\n buildContextBatches(context, gpuContext);\n\n const batchMode = context.batchMode;\n\n if (context.customShader || batchMode === 'no-batch')\n {\n gpuContext.isBatchable = false;\n }\n else if (batchMode === 'auto')\n {\n gpuContext.isBatchable = (gpuContext.geometryData.vertices.length < 400);\n }\n else\n {\n gpuContext.isBatchable = true;\n }\n\n context.dirty = false;\n }\n\n return gpuContext;\n }\n\n /**\n * Returns the GpuGraphicsContext for a given GraphicsContext.\n * If it does not exist, it will initialize a new one.\n * @param context - The GraphicsContext to get the GpuGraphicsContext for.\n * @returns The GpuGraphicsContext for the given GraphicsContext.\n * @internal\n */\n public getGpuContext(context: GraphicsContext): GpuGraphicsContext\n {\n return this._gpuContextHash[context.uid] || this._initContext(context);\n }\n\n private _initContextRenderData(context: GraphicsContext): GraphicsContextRenderData\n {\n const graphicsData: GraphicsContextRenderData = BigPool.get(GraphicsContextRenderData, {\n maxTextures: this._renderer.limits.maxBatchableTextures,\n });\n\n const { batches, geometryData } = this._gpuContextHash[context.uid];\n\n const vertexSize = geometryData.vertices.length;\n const indexSize = geometryData.indices.length;\n\n for (let i = 0; i < batches.length; i++)\n {\n batches[i].applyTransform = false;\n }\n\n const batcher = graphicsData.batcher;\n\n // TODO we can pool buffers here eventually..\n batcher.ensureAttributeBuffer(vertexSize);\n batcher.ensureIndexBuffer(indexSize);\n\n batcher.begin();\n\n for (let i = 0; i < batches.length; i++)\n {\n const batch = batches[i];\n\n batcher.add(batch);\n }\n\n batcher.finish(graphicsData.instructions);\n\n const geometry = batcher.geometry;\n\n // not to self - this works as we are assigning the batchers array buffer\n // once its up loaded - this buffer is then put back in the pool to be reused.\n // this mean we don't have to creating new Batchers for each graphics items\n geometry.indexBuffer.setDataWithSize(batcher.indexBuffer, batcher.indexSize, true);\n geometry.buffers[0].setDataWithSize(batcher.attributeBuffer.float32View, batcher.attributeSize, true);\n\n const drawBatches = batcher.batches;\n\n for (let i = 0; i < drawBatches.length; i++)\n {\n const batch = drawBatches[i];\n\n batch.bindGroup = getTextureBatchBindGroup(\n batch.textures.textures,\n batch.textures.count,\n this._renderer.limits.maxBatchableTextures\n );\n }\n\n this._graphicsDataContextHash[context.uid] = graphicsData;\n\n return graphicsData;\n }\n\n private _initContext(context: GraphicsContext): GpuGraphicsContext\n {\n const gpuContext = new GpuGraphicsContext();\n\n gpuContext.context = context;\n\n this._gpuContextHash[context.uid] = gpuContext;\n\n context.on('destroy', this.onGraphicsContextDestroy, this);\n\n return this._gpuContextHash[context.uid];\n }\n\n protected onGraphicsContextDestroy(context: GraphicsContext)\n {\n this._cleanGraphicsContextData(context);\n\n context.off('destroy', this.onGraphicsContextDestroy, this);\n\n this._gpuContextHash[context.uid] = null;\n }\n\n private _cleanGraphicsContextData(context: GraphicsContext)\n {\n const gpuContext: GpuGraphicsContext = this._gpuContextHash[context.uid];\n\n if (!gpuContext.isBatchable)\n {\n if (this._graphicsDataContextHash[context.uid])\n {\n BigPool.return(this.getContextRenderData(context) as PoolItem);\n\n // we will rebuild this...\n this._graphicsDataContextHash[context.uid] = null;\n }\n }\n\n if (gpuContext.batches)\n {\n gpuContext.batches.forEach((batch) =>\n {\n BigPool.return(batch as PoolItem);\n });\n }\n }\n\n public destroy()\n {\n // Clean up all graphics contexts\n for (const i in this._gpuContextHash)\n {\n if (this._gpuContextHash[i])\n {\n this.onGraphicsContextDestroy(this._gpuContextHash[i].context);\n }\n }\n\n this._gpuContextHash = {};\n this._graphicsDataContextHash = {};\n (this._renderer as null) = null;\n }\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { State } from '../../../rendering/renderers/shared/state/State';\nimport { type Renderer } from '../../../rendering/renderers/types';\nimport { BigPool } from '../../../utils/pool/PoolGroup';\nimport { color32BitToUniform } from '../gpu/colorToUniform';\nimport { BatchableGraphics } from './BatchableGraphics';\n\nimport type { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Shader } from '../../../rendering/renderers/shared/shader/Shader';\nimport type { PoolItem } from '../../../utils/pool/Pool';\nimport type { Graphics } from './Graphics';\nimport type { GpuGraphicsContext } from './GraphicsContextSystem';\n\n/** @internal */\nexport interface GraphicsAdaptor\n{\n shader: Shader;\n contextChange(renderer: Renderer): void;\n execute(graphicsPipe: GraphicsPipe, renderable: Graphics): void;\n destroy(): void;\n}\n\n/** @internal */\nexport class GraphicsGpuData\n{\n public batches: BatchableGraphics[] = [];\n public batched = false;\n public destroy()\n {\n this.batches.forEach((batch) =>\n {\n BigPool.return(batch as PoolItem);\n });\n\n this.batches.length = 0;\n }\n}\n\n/** @internal */\nexport class GraphicsPipe implements RenderPipe<Graphics>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'graphics',\n } as const;\n\n public renderer: Renderer;\n public state: State = State.for2d();\n\n private _adaptor: GraphicsAdaptor;\n\n constructor(renderer: Renderer, adaptor: GraphicsAdaptor)\n {\n this.renderer = renderer;\n\n this._adaptor = adaptor;\n\n this.renderer.runners.contextChange.add(this);\n }\n\n public contextChange(): void\n {\n this._adaptor.contextChange(this.renderer);\n }\n\n public validateRenderable(graphics: Graphics): boolean\n {\n // assume context is dirty..\n const context = graphics.context;\n\n const wasBatched = !!graphics._gpuData;\n\n const gpuContext = this.renderer.graphicsContext.updateGpuContext(context);\n\n if (gpuContext.isBatchable || wasBatched !== gpuContext.isBatchable)\n {\n // TODO what if they are the same size??\n return true;\n }\n\n return false;\n }\n\n public addRenderable(graphics: Graphics, instructionSet: InstructionSet)\n {\n const gpuContext = this.renderer.graphicsContext.updateGpuContext(graphics.context);\n\n // need to get batches here.. as we need to know if we can batch or not..\n // this also overrides the current batches..\n if (graphics.didViewUpdate)\n {\n this._rebuild(graphics);\n }\n\n if (gpuContext.isBatchable)\n {\n this._addToBatcher(graphics, instructionSet);\n }\n else\n {\n this.renderer.renderPipes.batch.break(instructionSet);\n instructionSet.add(graphics);\n }\n }\n\n public updateRenderable(graphics: Graphics)\n {\n const gpuData = this._getGpuDataForRenderable(graphics);\n\n const batches = gpuData.batches;\n\n for (let i = 0; i < batches.length; i++)\n {\n const batch = batches[i];\n\n batch._batcher.updateElement(batch);\n }\n }\n\n public execute(graphics: Graphics)\n {\n if (!graphics.isRenderable) return;\n\n const renderer = this.renderer;\n const context = graphics.context;\n const contextSystem = renderer.graphicsContext;\n\n // early out if there is no actual visual stuff...\n if (!contextSystem.getGpuContext(context).batches.length)\n { return; }\n\n const shader = context.customShader || this._adaptor.shader;\n\n this.state.blendMode = graphics.groupBlendMode;\n\n const localUniforms = shader.resources.localUniforms.uniforms;\n\n localUniforms.uTransformMatrix = graphics.groupTransform;\n localUniforms.uRound = renderer._roundPixels | graphics._roundPixels;\n\n color32BitToUniform(\n graphics.groupColorAlpha,\n localUniforms.uColor,\n 0,\n );\n\n this._adaptor.execute(this, graphics);\n }\n\n private _rebuild(graphics: Graphics)\n {\n const gpuData = this._getGpuDataForRenderable(graphics);\n\n const gpuContext = this.renderer.graphicsContext.updateGpuContext(graphics.context);\n\n // free up the batches..\n gpuData.destroy();\n\n if (gpuContext.isBatchable)\n {\n this._updateBatchesForRenderable(graphics, gpuData);\n }\n }\n\n private _addToBatcher(graphics: Graphics, instructionSet: InstructionSet)\n {\n const batchPipe = this.renderer.renderPipes.batch;\n\n const batches = this._getGpuDataForRenderable(graphics).batches;\n\n for (let i = 0; i < batches.length; i++)\n {\n const batch = batches[i];\n\n batchPipe.addToBatch(batch, instructionSet);\n }\n }\n\n private _getGpuDataForRenderable(graphics: Graphics): GraphicsGpuData\n {\n return graphics._gpuData[this.renderer.uid] || this._initGpuDataForRenderable(graphics);\n }\n\n private _initGpuDataForRenderable(graphics: Graphics): GraphicsGpuData\n {\n const gpuData = new GraphicsGpuData();\n\n graphics._gpuData[this.renderer.uid] = gpuData;\n\n return gpuData;\n }\n\n private _updateBatchesForRenderable(graphics: Graphics, gpuData: GraphicsGpuData)\n {\n const context = graphics.context;\n\n const gpuContext: GpuGraphicsContext = this.renderer.graphicsContext.getGpuContext(context);\n\n const roundPixels = (this.renderer._roundPixels | graphics._roundPixels) as 0 | 1;\n\n gpuData.batches = gpuContext.batches.map((batch) =>\n {\n const batchClone = BigPool.get(BatchableGraphics);\n\n batch.copyTo(batchClone);\n\n batchClone.renderable = graphics;\n\n batchClone.roundPixels = roundPixels;\n\n return batchClone;\n });\n }\n\n public destroy()\n {\n this.renderer = null;\n\n this._adaptor.destroy();\n this._adaptor = null;\n this.state = null;\n }\n}\n", "import type { Matrix } from '../../../maths/matrix/Matrix';\nimport type { Batch, Batcher } from '../../../rendering/batcher/shared/Batcher';\nimport type { DefaultBatchableMeshElement } from '../../../rendering/batcher/shared/DefaultBatcher';\nimport type { Topology } from '../../../rendering/renderers/shared/geometry/const';\nimport type { Texture } from '../../../rendering/renderers/shared/texture/Texture';\nimport type { ViewContainer } from '../../view/ViewContainer';\nimport type { MeshGeometry } from './MeshGeometry';\n\n/**\n * A batchable mesh object.\n * @ignore\n */\nexport class BatchableMesh implements DefaultBatchableMeshElement\n{\n public batcherName = 'default';\n\n public _topology: Topology;\n\n public readonly packAsQuad = false;\n public location: number;\n\n public renderable: ViewContainer;\n\n public indexOffset = 0;\n public attributeOffset = 0;\n\n public texture: Texture;\n public geometry: MeshGeometry;\n public transform: Matrix;\n public roundPixels: 0 | 1 = 0;\n\n public _attributeStart: number;\n public _batcher: Batcher = null;\n public _batch: Batch = null;\n public _indexStart: number;\n public _textureId: number;\n public _textureMatrixUpdateId: number = -1;\n\n private _transformedUvs: Float32Array;\n private _uvUpdateId: number = -1;\n\n get blendMode() { return this.renderable.groupBlendMode; }\n\n get topology() { return this._topology || this.geometry.topology; }\n set topology(value: Topology) { this._topology = value; }\n\n public reset()\n {\n this.renderable = null;\n this.texture = null;\n this._batcher = null;\n this._batch = null;\n this.geometry = null;\n this._uvUpdateId = -1;\n this._textureMatrixUpdateId = -1;\n }\n\n /**\n * Sets the texture for the batchable mesh.\n * As it does so, it resets the texture matrix update ID.\n * this is to ensure that the texture matrix is recalculated when the uvs are referenced\n * @param value - The texture to set.\n */\n public setTexture(value: Texture)\n {\n if (this.texture === value) return;\n\n this.texture = value;\n this._textureMatrixUpdateId = -1;\n }\n\n get uvs()\n {\n const geometry = this.geometry;\n\n const uvBuffer = geometry.getBuffer('aUV');\n\n const uvs = uvBuffer.data;\n\n let transformedUvs = uvs;\n const textureMatrix = this.texture.textureMatrix;\n\n if (!textureMatrix.isSimple)\n {\n transformedUvs = this._transformedUvs;\n\n if (this._textureMatrixUpdateId !== textureMatrix._updateID || this._uvUpdateId !== uvBuffer._updateID)\n {\n if (!transformedUvs || transformedUvs.length < uvs.length)\n {\n transformedUvs = this._transformedUvs = new Float32Array(uvs.length);\n }\n\n this._textureMatrixUpdateId = textureMatrix._updateID;\n this._uvUpdateId = uvBuffer._updateID;\n\n textureMatrix.multiplyUvs(uvs as Float32Array, transformedUvs);\n }\n }\n\n return transformedUvs as Float32Array;\n }\n\n get positions()\n {\n return this.geometry.positions;\n }\n\n get indices()\n {\n return this.geometry.indices;\n }\n\n get color()\n {\n return this.renderable.groupColorAlpha;\n }\n\n get groupTransform()\n {\n return this.renderable.groupTransform;\n }\n\n get attributeSize()\n {\n return this.geometry.positions.length / 2;\n }\n\n get indexSize()\n {\n return this.geometry.indices.length;\n }\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { Matrix } from '../../../maths/matrix/Matrix';\nimport { BindGroup } from '../../../rendering/renderers/gpu/shader/BindGroup';\nimport { UniformGroup } from '../../../rendering/renderers/shared/shader/UniformGroup';\nimport { getAdjustedBlendModeBlend } from '../../../rendering/renderers/shared/state/getAdjustedBlendModeBlend';\nimport { color32BitToUniform } from '../../graphics/gpu/colorToUniform';\nimport { type GPUData } from '../../view/ViewContainer';\nimport { BatchableMesh } from './BatchableMesh';\n\nimport type { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport type {\n InstructionPipe,\n RenderPipe\n} from '../../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { Mesh } from './Mesh';\n\n// TODO Record mode is a P2, will get back to this as it's not a priority\n// const recordMode = true;\n\n/**\n * GPUData for Mesh\n * @internal\n */\nexport class MeshGpuData implements GPUData\n{\n public meshData?: MeshData;\n public batchableMesh?: BatchableMesh;\n\n public destroy()\n {\n // BOOM!\n }\n}\n\n/**\n * The data for the mesh\n * @internal\n */\ninterface MeshData\n{\n /** if the mesh is batched or not */\n batched: boolean;\n /** the size of the index buffer */\n indexSize: number;\n /** the size of the vertex buffer */\n vertexSize: number;\n}\n\n/** @internal */\nexport interface MeshAdaptor\n{\n init(): void;\n execute(meshPipe: MeshPipe, mesh: Mesh): void;\n destroy(): void;\n}\n\n/**\n * The MeshPipe is responsible for handling the rendering of Mesh objects.\n * It manages the batching of meshes, updates their GPU data, and executes the rendering instructions.\n * It also handles the local uniforms for each mesh, such as transformation matrices and colors.\n * @category scene\n * @internal\n */\nexport class MeshPipe implements RenderPipe<Mesh>, InstructionPipe<Mesh>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'mesh',\n } as const;\n\n public localUniforms = new UniformGroup({\n uTransformMatrix: { value: new Matrix(), type: 'mat3x3<f32>' },\n uColor: { value: new Float32Array([1, 1, 1, 1]), type: 'vec4<f32>' },\n uRound: { value: 0, type: 'f32' },\n });\n\n public localUniformsBindGroup = new BindGroup({\n 0: this.localUniforms,\n });\n\n public renderer: Renderer;\n\n private _adaptor: MeshAdaptor;\n\n constructor(renderer: Renderer, adaptor: MeshAdaptor)\n {\n this.renderer = renderer;\n this._adaptor = adaptor;\n\n this._adaptor.init();\n }\n\n public validateRenderable(mesh: Mesh): boolean\n {\n const meshData = this._getMeshData(mesh);\n\n const wasBatched = meshData.batched;\n\n const isBatched = mesh.batched;\n\n meshData.batched = isBatched;\n\n if (wasBatched !== isBatched)\n {\n return true;\n }\n else if (isBatched)\n {\n const geometry = mesh._geometry;\n\n // no need to break the batch if it's the same size\n if (geometry.indices.length !== meshData.indexSize\n || geometry.positions.length !== meshData.vertexSize)\n {\n meshData.indexSize = geometry.indices.length;\n meshData.vertexSize = geometry.positions.length;\n\n return true;\n }\n\n const batchableMesh = this._getBatchableMesh(mesh);\n\n if (batchableMesh.texture.uid !== mesh._texture.uid)\n {\n batchableMesh._textureMatrixUpdateId = -1;\n }\n\n return !batchableMesh._batcher.checkAndUpdateTexture(\n batchableMesh,\n mesh._texture\n );\n }\n\n return false;\n }\n\n public addRenderable(mesh: Mesh, instructionSet: InstructionSet)\n {\n const batcher = this.renderer.renderPipes.batch;\n\n const meshData = this._getMeshData(mesh);\n\n if (mesh.didViewUpdate)\n {\n meshData.indexSize = mesh._geometry.indices?.length;\n meshData.vertexSize = mesh._geometry.positions?.length;\n }\n\n if (meshData.batched)\n {\n const gpuBatchableMesh = this._getBatchableMesh(mesh);\n\n gpuBatchableMesh.setTexture(mesh._texture);\n gpuBatchableMesh.geometry = mesh._geometry;\n\n batcher.addToBatch(gpuBatchableMesh, instructionSet);\n }\n else\n {\n batcher.break(instructionSet);\n\n instructionSet.add(mesh);\n }\n }\n\n public updateRenderable(mesh: Mesh)\n {\n if (mesh.batched)\n {\n const gpuBatchableMesh = this._getBatchableMesh(mesh);\n\n gpuBatchableMesh.setTexture(mesh._texture);\n\n gpuBatchableMesh.geometry = mesh._geometry;\n\n gpuBatchableMesh._batcher.updateElement(gpuBatchableMesh);\n }\n }\n\n public execute(mesh: Mesh)\n {\n if (!mesh.isRenderable) return;\n\n mesh.state.blendMode = getAdjustedBlendModeBlend(mesh.groupBlendMode, mesh.texture._source);\n\n const localUniforms = this.localUniforms;\n\n localUniforms.uniforms.uTransformMatrix = mesh.groupTransform;\n localUniforms.uniforms.uRound = this.renderer._roundPixels | mesh._roundPixels;\n localUniforms.update();\n\n color32BitToUniform(\n mesh.groupColorAlpha,\n localUniforms.uniforms.uColor,\n 0\n );\n\n this._adaptor.execute(this, mesh);\n }\n\n private _getMeshData(mesh: Mesh): MeshData\n {\n mesh._gpuData[this.renderer.uid] ||= new MeshGpuData();\n\n return mesh._gpuData[this.renderer.uid].meshData || this._initMeshData(mesh);\n }\n\n private _initMeshData(mesh: Mesh): MeshData\n {\n mesh._gpuData[this.renderer.uid].meshData = {\n batched: mesh.batched,\n indexSize: 0,\n vertexSize: 0,\n };\n\n return mesh._gpuData[this.renderer.uid].meshData;\n }\n\n private _getBatchableMesh(mesh: Mesh): BatchableMesh\n {\n mesh._gpuData[this.renderer.uid] ||= new MeshGpuData();\n\n return mesh._gpuData[this.renderer.uid].batchableMesh || this._initBatchableMesh(mesh);\n }\n\n private _initBatchableMesh(mesh: Mesh): BatchableMesh\n {\n // TODO - make this batchable graphics??\n const gpuMesh: BatchableMesh = new BatchableMesh();\n\n gpuMesh.renderable = mesh;\n gpuMesh.setTexture(mesh._texture);\n gpuMesh.transform = mesh.groupTransform;\n gpuMesh.roundPixels = (this.renderer._roundPixels | mesh._roundPixels) as 0 | 1;\n\n mesh._gpuData[this.renderer.uid].batchableMesh = gpuMesh;\n\n return gpuMesh;\n }\n\n public destroy()\n {\n this.localUniforms = null;\n this.localUniformsBindGroup = null;\n\n this._adaptor.destroy();\n this._adaptor = null;\n\n this.renderer = null;\n }\n}\n", "import type { WebGLRenderer } from '../../../rendering/renderers/gl/WebGLRenderer';\nimport type { ParticleContainer } from '../shared/ParticleContainer';\nimport type { ParticleContainerAdaptor, ParticleContainerPipe } from '../shared/ParticleContainerPipe';\n\n/** @internal */\nexport class GlParticleContainerAdaptor implements ParticleContainerAdaptor\n{\n public execute(particleContainerPipe: ParticleContainerPipe, container: ParticleContainer)\n {\n const state = particleContainerPipe.state;\n const renderer = particleContainerPipe.renderer as WebGLRenderer;\n const shader = container.shader || particleContainerPipe.defaultShader;\n\n shader.resources.uTexture = container.texture._source;\n shader.resources.uniforms = particleContainerPipe.localUniforms;\n\n const gl = renderer.gl;\n\n const buffer = particleContainerPipe.getBuffers(container);\n\n // now lets upload and render the buffers..\n renderer.shader.bind(shader);\n renderer.state.set(state);\n renderer.geometry.bind(buffer.geometry, shader.glProgram);\n\n const byteSize = buffer.geometry.indexBuffer.data.BYTES_PER_ELEMENT;\n const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT;\n\n gl.drawElements(gl.TRIANGLES, container.particleChildren.length * 6, glType, 0);\n }\n}\n", "/**\n * Generic Mask Stack data structure\n * @function createIndicesForQuads\n * @param {number} size - Number of quads\n * @param {Uint16Array|Uint32Array} [outBuffer] - Buffer for output, length has to be `6 * size`\n * @returns {Uint16Array|Uint32Array} - Resulting index buffer\n * @internal\n */\nexport function createIndicesForQuads(\n size: number,\n outBuffer: Uint16Array | Uint32Array | null = null\n): Uint16Array | Uint32Array\n{\n // the total number of indices in our array, there are 6 points per quad.\n const totalIndices = size * 6;\n\n // Check if we need to use Uint32Array\n if (totalIndices > 65535)\n {\n outBuffer ||= new Uint32Array(totalIndices); // Use Uint32Array if needed\n }\n else\n {\n outBuffer ||= new Uint16Array(totalIndices);\n }\n\n if (outBuffer.length !== totalIndices)\n {\n throw new Error(`Out buffer length is incorrect, got ${outBuffer.length} and expected ${totalIndices}`);\n }\n\n // fill the indices with the quads to draw\n for (let i = 0, j = 0; i < totalIndices; i += 6, j += 4)\n {\n outBuffer[i + 0] = j + 0;\n outBuffer[i + 1] = j + 1;\n outBuffer[i + 2] = j + 2;\n outBuffer[i + 3] = j + 0;\n outBuffer[i + 4] = j + 2;\n outBuffer[i + 5] = j + 3;\n }\n\n return outBuffer;\n}\n", "import {\n getAttributeInfoFromFormat\n} from '../../../../rendering/renderers/shared/geometry/utils/getAttributeInfoFromFormat';\n\nimport type { IParticle } from '../Particle';\nimport type { ParticleRendererProperty } from '../particleData';\n\n// TODO rename to update function\n/** @internal */\nexport type ParticleUpdateFunction = (ps: IParticle[], f32v: Float32Array, u32v: Uint32Array) => void;\n\n/**\n * @param properties\n * @internal\n */\nexport function generateParticleUpdateFunction(properties: Record<string, ParticleRendererProperty>)\n{\n return {\n dynamicUpdate: generateUpdateFunction(properties, true),\n staticUpdate: generateUpdateFunction(properties, false),\n };\n}\n\nfunction generateUpdateFunction(\n properties: Record<string, ParticleRendererProperty>,\n dynamic: boolean\n): ParticleUpdateFunction\n{\n const funcFragments: string[] = [];\n\n funcFragments.push(`\n\n var index = 0;\n\n for (let i = 0; i < ps.length; ++i)\n {\n const p = ps[i];\n\n `);\n\n let offset = 0;\n\n for (const i in properties)\n {\n const property = properties[i];\n\n if (dynamic !== property.dynamic) continue;\n\n funcFragments.push(`offset = index + ${offset}`);\n\n funcFragments.push(property.code);\n\n const attributeInfo = getAttributeInfoFromFormat(property.format);\n\n offset += attributeInfo.stride / 4;\n }\n\n funcFragments.push(`\n index += stride * 4;\n }\n `);\n\n // add to the front..\n funcFragments.unshift(`\n var stride = ${offset};\n `);\n\n const functionSource = funcFragments.join('\\n');\n\n // eslint-disable-next-line no-new-func\n return new Function('ps', 'f32v', 'u32v', functionSource) as ParticleUpdateFunction;\n}\n", "import { Buffer } from '../../../rendering/renderers/shared/buffer/Buffer';\nimport { BufferUsage } from '../../../rendering/renderers/shared/buffer/const';\nimport { Geometry } from '../../../rendering/renderers/shared/geometry/Geometry';\nimport { getAttributeInfoFromFormat } from '../../../rendering/renderers/shared/geometry/utils/getAttributeInfoFromFormat';\nimport { ViewableBuffer } from '../../../utils/data/ViewableBuffer';\nimport { createIndicesForQuads } from './utils/createIndicesForQuads';\nimport { generateParticleUpdateFunction } from './utils/generateParticleUpdateFunction';\n\nimport type { IndexBufferArray } from '../../../rendering/renderers/shared/geometry/Geometry';\nimport type { IParticle } from './Particle';\nimport type { ParticleRendererProperty } from './particleData';\nimport type { ParticleUpdateFunction } from './utils/generateParticleUpdateFunction';\n\n/**\n * Options for creating a ParticleBuffer.\n * @internal\n */\nexport interface ParticleBufferOptions\n{\n /** The size of the particle buffer, defaults to 1000. */\n size: number;\n /** A record of attributes that the particle container uses. */\n properties: Record<string, ParticleRendererProperty>;\n}\n\n/**\n * The ParticleBuffer holds the buffers and geometry for a particle container.\n * It also contains the upload functions for the static and dynamic properties.\n * @internal\n */\nexport class ParticleBuffer\n{\n /** The buffer containing static attribute data for all elements in the batch. */\n public staticAttributeBuffer: ViewableBuffer;\n /** The buffer containing dynamic attribute data for all elements in the batch. */\n public dynamicAttributeBuffer: ViewableBuffer;\n\n private readonly _staticBuffer: Buffer;\n private readonly _dynamicBuffer: Buffer;\n\n /** The buffer containing index data for all elements in the batch. */\n public indexBuffer: IndexBufferArray;\n\n private readonly _dynamicStride: number;\n private readonly _staticStride: number;\n\n /** The geometry of the particle buffer. */\n public readonly geometry: Geometry;\n\n private _size = 0;\n private readonly _dynamicUpload: ParticleUpdateFunction;\n private readonly _staticUpload: ParticleUpdateFunction;\n private readonly _generateParticleUpdateCache: Record<string, {\n dynamicUpdate: ParticleUpdateFunction;\n staticUpdate: ParticleUpdateFunction;\n }> = {};\n\n constructor(options: ParticleBufferOptions)\n {\n // size in sprites!\n const size = this._size = options.size ?? 1000;\n\n // TODO add the option to specify what is dynamic!\n const properties = options.properties;\n\n // in bytes!\n let staticVertexSize = 0;\n let dynamicVertexSize = 0;\n\n for (const i in properties)\n {\n const property = properties[i];\n const attributeInfo = getAttributeInfoFromFormat(property.format);\n\n if (property.dynamic)\n {\n // dynamic.\n dynamicVertexSize += attributeInfo.stride;\n }\n else\n {\n // static.\n staticVertexSize += attributeInfo.stride;\n }\n }\n\n this._dynamicStride = dynamicVertexSize / 4;\n this._staticStride = staticVertexSize / 4;\n\n this.staticAttributeBuffer = new ViewableBuffer(size * 4 * staticVertexSize);\n this.dynamicAttributeBuffer = new ViewableBuffer(size * 4 * dynamicVertexSize);\n\n this.indexBuffer = createIndicesForQuads(size);\n\n // build geometry..\n\n const geometry = new Geometry();\n\n let dynamicOffset = 0;\n let staticOffset = 0;\n\n this._staticBuffer = new Buffer({\n data: new Float32Array(1),\n label: 'static-particle-buffer',\n shrinkToFit: false,\n usage: BufferUsage.VERTEX | BufferUsage.COPY_DST\n });\n\n this._dynamicBuffer = new Buffer({\n data: new Float32Array(1),\n label: 'dynamic-particle-buffer',\n shrinkToFit: false,\n usage: BufferUsage.VERTEX | BufferUsage.COPY_DST\n });\n\n for (const i in properties)\n {\n const property = properties[i];\n const attributeInfo = getAttributeInfoFromFormat(property.format);\n\n if (property.dynamic)\n {\n geometry.addAttribute(property.attributeName, {\n buffer: this._dynamicBuffer,\n stride: this._dynamicStride * 4,\n offset: dynamicOffset * 4,\n format: property.format,\n });\n dynamicOffset += attributeInfo.size;\n }\n else\n {\n geometry.addAttribute(property.attributeName, {\n buffer: this._staticBuffer,\n stride: this._staticStride * 4,\n offset: staticOffset * 4,\n format: property.format,\n });\n staticOffset += attributeInfo.size;\n }\n }\n\n geometry.addIndex(this.indexBuffer);\n\n const uploadFunction = this.getParticleUpdate(properties);\n\n this._dynamicUpload = uploadFunction.dynamicUpdate;\n this._staticUpload = uploadFunction.staticUpdate;\n\n this.geometry = geometry;\n }\n\n public getParticleUpdate(properties: Record<string, ParticleRendererProperty>)\n {\n const key = getParticleSyncKey(properties);\n\n if (this._generateParticleUpdateCache[key])\n {\n return this._generateParticleUpdateCache[key];\n }\n\n this._generateParticleUpdateCache[key] = this.generateParticleUpdate(properties);\n\n return this._generateParticleUpdateCache[key];\n }\n\n public generateParticleUpdate(properties: Record<string, ParticleRendererProperty>)\n {\n return generateParticleUpdateFunction(properties);\n }\n\n public update(particles: IParticle[], uploadStatic: boolean)\n {\n // first resize the buffers if needed!\n // TODO resize!\n if (particles.length > this._size)\n {\n uploadStatic = true;\n\n this._size = Math.max(particles.length, (this._size * 1.5) | 0);\n\n this.staticAttributeBuffer = new ViewableBuffer(this._size * this._staticStride * 4 * 4);\n this.dynamicAttributeBuffer = new ViewableBuffer(this._size * this._dynamicStride * 4 * 4);\n this.indexBuffer = createIndicesForQuads(this._size);\n\n this.geometry.indexBuffer.setDataWithSize(\n this.indexBuffer, this.indexBuffer.byteLength, true);\n }\n\n const dynamicAttributeBuffer = this.dynamicAttributeBuffer;\n\n this._dynamicUpload(particles, dynamicAttributeBuffer.float32View, dynamicAttributeBuffer.uint32View);\n\n this._dynamicBuffer.setDataWithSize(\n this.dynamicAttributeBuffer.float32View, particles.length * this._dynamicStride * 4, true);\n\n if (uploadStatic)\n {\n const staticAttributeBuffer = this.staticAttributeBuffer;\n\n this._staticUpload(particles, staticAttributeBuffer.float32View, staticAttributeBuffer.uint32View);\n\n this._staticBuffer.setDataWithSize(\n staticAttributeBuffer.float32View, particles.length * this._staticStride * 4, true);\n }\n }\n\n public destroy()\n {\n this._staticBuffer.destroy();\n this._dynamicBuffer.destroy();\n this.geometry.destroy();\n }\n}\n\nfunction getParticleSyncKey(properties: Record<string, ParticleRendererProperty>)\n{\n const keyGen: string[] = [];\n\n for (const key in properties)\n {\n const property = properties[key];\n\n keyGen.push(key, property.code, property.dynamic ? 'd' : 's');\n }\n\n return keyGen.join('_');\n}\n\n", "var fragment = \"varying vec2 vUV;\\nvarying vec4 vColor;\\n\\nuniform sampler2D uTexture;\\n\\nvoid main(void){\\n vec4 color = texture2D(uTexture, vUV) * vColor;\\n gl_FragColor = color;\\n}\";\n\nexport { fragment as default };\n//# sourceMappingURL=particles.frag.mjs.map\n", "var vertex = \"attribute vec2 aVertex;\\nattribute vec2 aUV;\\nattribute vec4 aColor;\\n\\nattribute vec2 aPosition;\\nattribute float aRotation;\\n\\nuniform mat3 uTranslationMatrix;\\nuniform float uRound;\\nuniform vec2 uResolution;\\nuniform vec4 uColor;\\n\\nvarying vec2 vUV;\\nvarying vec4 vColor;\\n\\nvec2 roundPixels(vec2 position, vec2 targetSize)\\n{ \\n return (floor(((position * 0.5 + 0.5) * targetSize) + 0.5) / targetSize) * 2.0 - 1.0;\\n}\\n\\nvoid main(void){\\n float cosRotation = cos(aRotation);\\n float sinRotation = sin(aRotation);\\n float x = aVertex.x * cosRotation - aVertex.y * sinRotation;\\n float y = aVertex.x * sinRotation + aVertex.y * cosRotation;\\n\\n vec2 v = vec2(x, y);\\n v = v + aPosition;\\n\\n gl_Position = vec4((uTranslationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);\\n\\n if(uRound == 1.0)\\n {\\n gl_Position.xy = roundPixels(gl_Position.xy, uResolution);\\n }\\n\\n vUV = aUV;\\n vColor = vec4(aColor.rgb * aColor.a, aColor.a) * uColor;\\n}\\n\";\n\nexport { vertex as default };\n//# sourceMappingURL=particles.vert.mjs.map\n", "var wgsl = \"\\nstruct ParticleUniforms {\\n uTranslationMatrix:mat3x3<f32>,\\n uColor:vec4<f32>,\\n uRound:f32,\\n uResolution:vec2<f32>,\\n};\\n\\nfn roundPixels(position: vec2<f32>, targetSize: vec2<f32>) -> vec2<f32>\\n{\\n return (floor(((position * 0.5 + 0.5) * targetSize) + 0.5) / targetSize) * 2.0 - 1.0;\\n}\\n\\n@group(0) @binding(0) var<uniform> uniforms: ParticleUniforms;\\n\\n@group(1) @binding(0) var uTexture: texture_2d<f32>;\\n@group(1) @binding(1) var uSampler : sampler;\\n\\nstruct VSOutput {\\n @builtin(position) position: vec4<f32>,\\n @location(0) uv : vec2<f32>,\\n @location(1) color : vec4<f32>,\\n };\\n@vertex\\nfn mainVertex(\\n @location(0) aVertex: vec2<f32>,\\n @location(1) aPosition: vec2<f32>,\\n @location(2) aUV: vec2<f32>,\\n @location(3) aColor: vec4<f32>,\\n @location(4) aRotation: f32,\\n) -> VSOutput {\\n \\n let v = vec2(\\n aVertex.x * cos(aRotation) - aVertex.y * sin(aRotation),\\n aVertex.x * sin(aRotation) + aVertex.y * cos(aRotation)\\n ) + aPosition;\\n\\n var position = vec4((uniforms.uTranslationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);\\n\\n if(uniforms.uRound == 1.0) {\\n position = vec4(roundPixels(position.xy, uniforms.uResolution), position.zw);\\n }\\n\\n let vColor = vec4(aColor.rgb * aColor.a, aColor.a) * uniforms.uColor;\\n\\n return VSOutput(\\n position,\\n aUV,\\n vColor,\\n );\\n}\\n\\n@fragment\\nfn mainFragment(\\n @location(0) uv: vec2<f32>,\\n @location(1) color: vec4<f32>,\\n @builtin(position) position: vec4<f32>,\\n) -> @location(0) vec4<f32> {\\n\\n var sample = textureSample(uTexture, uSampler, uv) * color;\\n \\n return sample;\\n}\";\n\nexport { wgsl as default };\n//# sourceMappingURL=particles.wgsl.mjs.map\n", "import { Color } from '../../../../color/Color';\nimport { Matrix } from '../../../../maths/matrix/Matrix';\nimport { GlProgram } from '../../../../rendering/renderers/gl/shader/GlProgram';\nimport { GpuProgram } from '../../../../rendering/renderers/gpu/shader/GpuProgram';\nimport { Shader } from '../../../../rendering/renderers/shared/shader/Shader';\nimport { Texture } from '../../../../rendering/renderers/shared/texture/Texture';\nimport { TextureStyle } from '../../../../rendering/renderers/shared/texture/TextureStyle';\nimport fragment from './particles.frag';\nimport vertex from './particles.vert';\nimport wgsl from './particles.wgsl';\n\n/** @internal */\nexport class ParticleShader extends Shader\n{\n constructor()\n {\n const glProgram = GlProgram.from({\n vertex,\n fragment\n });\n\n const gpuProgram = GpuProgram.from({\n fragment: {\n source: wgsl,\n entryPoint: 'mainFragment'\n },\n vertex: {\n source: wgsl,\n entryPoint: 'mainVertex'\n }\n });\n\n super({\n glProgram,\n gpuProgram,\n resources: {\n // this will be replaced with the texture from the particle container\n uTexture: Texture.WHITE.source,\n // this will be replaced with the texture style from the particle container\n uSampler: new TextureStyle({}),\n // this will be replaced with the local uniforms from the particle container\n uniforms: {\n uTranslationMatrix: { value: new Matrix(), type: 'mat3x3<f32>' },\n uColor: { value: new Color(0xFFFFFF), type: 'vec4<f32>' },\n uRound: { value: 1, type: 'f32' },\n uResolution: { value: [0, 0], type: 'vec2<f32>' },\n }\n }\n });\n }\n}\n", "import { Matrix } from '../../../maths/matrix/Matrix';\nimport { UniformGroup } from '../../../rendering/renderers/shared/shader/UniformGroup';\nimport { getAdjustedBlendModeBlend } from '../../../rendering/renderers/shared/state/getAdjustedBlendModeBlend';\nimport { State } from '../../../rendering/renderers/shared/state/State';\nimport { color32BitToUniform } from '../../graphics/gpu/colorToUniform';\nimport { ParticleBuffer } from './ParticleBuffer';\nimport { ParticleShader } from './shader/ParticleShader';\n\nimport type { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Shader } from '../../../rendering/renderers/shared/shader/Shader';\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { ParticleContainer } from './ParticleContainer';\n\n/** @internal */\nexport interface ParticleContainerAdaptor\n{\n execute(particleContainerPop: ParticleContainerPipe, container: ParticleContainer): void;\n}\n\n/**\n * Renderer for Particles that is designer for speed over feature set.\n * @category scene\n * @internal\n */\nexport class ParticleContainerPipe implements RenderPipe<ParticleContainer>\n{\n /** The default shader that is used if a sprite doesn't have a more specific one. */\n public defaultShader: Shader;\n\n /** @internal */\n public adaptor: ParticleContainerAdaptor;\n /** @internal */\n public readonly state = State.for2d();\n /** @internal */\n public readonly renderer: Renderer;\n\n /** Local uniforms that are used for rendering particles. */\n public readonly localUniforms = new UniformGroup({\n uTranslationMatrix: { value: new Matrix(), type: 'mat3x3<f32>' },\n uColor: { value: new Float32Array(4), type: 'vec4<f32>' },\n uRound: { value: 1, type: 'f32' },\n uResolution: { value: [0, 0], type: 'vec2<f32>' },\n });\n\n /**\n * @param renderer - The renderer this sprite batch works for.\n * @param adaptor\n */\n constructor(renderer: Renderer, adaptor: ParticleContainerAdaptor)\n {\n this.renderer = renderer;\n\n this.adaptor = adaptor;\n\n this.defaultShader = new ParticleShader();\n\n this.state = State.for2d();\n }\n\n public validateRenderable(_renderable: ParticleContainer): boolean\n {\n // always fine :D\n return false;\n }\n\n public addRenderable(renderable: ParticleContainer, instructionSet: InstructionSet)\n {\n this.renderer.renderPipes.batch.break(instructionSet);\n instructionSet.add(renderable);\n }\n\n public getBuffers(renderable: ParticleContainer): ParticleBuffer\n {\n return renderable._gpuData[this.renderer.uid] || this._initBuffer(renderable);\n }\n\n private _initBuffer(renderable: ParticleContainer): ParticleBuffer\n {\n renderable._gpuData[this.renderer.uid] = new ParticleBuffer({\n size: renderable.particleChildren.length,\n properties: renderable._properties,\n });\n\n return renderable._gpuData[this.renderer.uid];\n }\n\n public updateRenderable(_renderable: ParticleContainer)\n {\n // nothing to be done here!\n\n }\n\n public execute(container: ParticleContainer): void\n {\n const children = container.particleChildren;\n\n if (children.length === 0)\n {\n return;\n }\n\n const renderer = this.renderer;\n const buffer = this.getBuffers(container);\n\n container.texture ||= children[0].texture;\n\n const state = this.state;\n\n buffer.update(children, container._childrenDirty);\n container._childrenDirty = false;\n\n state.blendMode = getAdjustedBlendModeBlend(container.blendMode, container.texture._source);\n\n const uniforms = this.localUniforms.uniforms;\n\n const transformationMatrix = uniforms.uTranslationMatrix;\n\n container.worldTransform.copyTo(transformationMatrix);\n\n transformationMatrix.prepend(renderer.globalUniforms.globalUniformData.projectionMatrix);\n\n uniforms.uResolution = renderer.globalUniforms.globalUniformData.resolution;\n uniforms.uRound = renderer._roundPixels | container._roundPixels;\n\n color32BitToUniform(\n container.groupColorAlpha,\n uniforms.uColor,\n 0\n );\n\n this.adaptor.execute(this, container);\n }\n\n /** Destroys the ParticleRenderer. */\n public destroy(): void\n {\n (this.renderer as null) = null;\n if (this.defaultShader)\n {\n this.defaultShader.destroy();\n this.defaultShader = null;\n }\n }\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { GlParticleContainerAdaptor } from '../gl/GlParticleContainerAdaptor';\nimport { ParticleContainerPipe } from './ParticleContainerPipe';\n\nimport type { WebGLRenderer } from '../../../rendering/renderers/gl/WebGLRenderer';\n\n/**\n * WebGL renderer for Particles that is designed for speed over feature set.\n * @category scene\n * @internal\n */\nexport class GlParticleContainerPipe extends ParticleContainerPipe\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ],\n name: 'particle',\n } as const;\n\n constructor(renderer: WebGLRenderer)\n {\n super(renderer, new GlParticleContainerAdaptor());\n }\n}\n", "import type { WebGPURenderer } from '../../../rendering/renderers/gpu/WebGPURenderer';\nimport type { ParticleContainer } from '../shared/ParticleContainer';\nimport type { ParticleContainerAdaptor, ParticleContainerPipe } from '../shared/ParticleContainerPipe';\n\n/** @internal */\nexport class GpuParticleContainerAdaptor implements ParticleContainerAdaptor\n{\n public execute(particleContainerPipe: ParticleContainerPipe, container: ParticleContainer)\n {\n const renderer = particleContainerPipe.renderer as WebGPURenderer;\n\n const shader = container.shader || particleContainerPipe.defaultShader;\n\n shader.groups[0] = renderer.renderPipes.uniformBatch.getUniformBindGroup(particleContainerPipe.localUniforms, true);\n\n shader.groups[1] = renderer.texture.getTextureBindGroup(container.texture);\n\n const state = particleContainerPipe.state;\n\n const buffer = particleContainerPipe.getBuffers(container);\n\n renderer.encoder.draw({\n geometry: buffer.geometry,\n shader: container.shader || particleContainerPipe.defaultShader,\n state,\n size: container.particleChildren.length * 6,\n });\n }\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { GpuParticleContainerAdaptor } from '../gpu/GpuParticleContainerAdaptor';\nimport { ParticleContainerPipe } from './ParticleContainerPipe';\n\nimport type { WebGPURenderer } from '../../../rendering/renderers/gpu/WebGPURenderer';\n\n/**\n * WebGPU renderer for Particles that is designed for speed over feature set.\n * @category scene\n * @internal\n */\nexport class GpuParticleContainerPipe extends ParticleContainerPipe\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGPUPipes,\n ],\n name: 'particle',\n } as const;\n\n constructor(renderer: WebGPURenderer)\n {\n super(renderer, new GpuParticleContainerAdaptor());\n }\n}\n", "import { updateQuadBounds } from '../../../utils/data/updateQuadBounds';\nimport { type BatchableSprite } from '../../sprite/BatchableSprite';\nimport { type AbstractText } from '../AbstractText';\nimport { type TextStyle, type TextStyleOptions } from '../TextStyle';\n\n/**\n * Updates the bounds of the given batchable sprite based on the provided text object.\n *\n * This function adjusts the bounds of the batchable sprite to match the dimensions\n * and anchor point of the text's texture. Additionally, it compensates for any padding\n * specified in the text's style to ensure the text is rendered correctly on screen.\n * @param {BatchableSprite} batchableSprite - The sprite whose bounds need to be updated.\n * @param {AbstractText} text - The text object containing the texture and style information.\n * @internal\n */\nexport function updateTextBounds(batchableSprite: BatchableSprite, text: AbstractText<TextStyle, TextStyleOptions>)\n{\n const { texture, bounds } = batchableSprite;\n const padding = text._style._getFinalPadding();\n\n // When HTML text textures are created, they include the padding around the text content\n // to prevent text clipping and provide a buffer zone. This padding is built into\n // the texture itself. However, we don't want this padding to affect the text's\n // actual position on screen.\n\n // First, calculate bounds using the full padded texture\n updateQuadBounds(bounds, text._anchor, texture);\n\n // Then adjust by the padding amount to compensate for the buffer zone\n // This shifts the render position back by the padding amount, ensuring the text\n // appears exactly where intended while maintaining the buffer zone around it.\n const paddingOffset = text._anchor._x * padding * 2;\n const paddingOffsetY = text._anchor._y * padding * 2;\n\n bounds.minX -= padding - paddingOffset;\n bounds.minY -= padding - paddingOffsetY;\n bounds.maxX -= padding - paddingOffset;\n bounds.maxY -= padding - paddingOffsetY;\n}\n", "import { BatchableSprite } from '../../sprite/BatchableSprite';\n\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { Text } from '../Text';\n\n/** @internal */\nexport class BatchableText extends BatchableSprite\n{\n private readonly _renderer: Renderer;\n public currentKey: string;\n\n constructor(renderer: Renderer)\n {\n super();\n\n // Next step is to make canvasTextSystem a GLOBAL object.\n // so this is ok for now..\n this._renderer = renderer;\n\n renderer.runners.resolutionChange.add(this);\n }\n\n public resolutionChange()\n {\n const text = this.renderable as Text;\n\n if (text._autoResolution)\n {\n text.onViewUpdate();\n }\n }\n\n public destroy()\n {\n const { canvasText } = this._renderer;\n const refCount = canvasText.getReferenceCount(this.currentKey);\n\n if (refCount > 0)\n {\n canvasText.decreaseReferenceCount(this.currentKey);\n }\n else if (this.texture)\n {\n canvasText.returnTexture(this.texture);\n }\n\n this._renderer.runners.resolutionChange.remove(this);\n (this._renderer as null) = null;\n }\n}\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { updateTextBounds } from '../utils/updateTextBounds';\nimport { BatchableText } from './BatchableText';\n\nimport type { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { Text } from '../Text';\n\n/** @internal */\nexport class CanvasTextPipe implements RenderPipe<Text>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'text',\n } as const;\n\n private _renderer: Renderer;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n }\n\n public validateRenderable(text: Text): boolean\n {\n const gpuText = this._getGpuText(text);\n\n const newKey = text.styleKey;\n\n if (gpuText.currentKey !== newKey) return true;\n\n return text._didTextUpdate;\n }\n\n public addRenderable(text: Text, instructionSet: InstructionSet)\n {\n const batchableText = this._getGpuText(text);\n\n if (text._didTextUpdate)\n {\n const resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n\n if (batchableText.currentKey !== text.styleKey || text.resolution !== resolution)\n {\n // If the text has changed, we need to update the GPU text\n this._updateGpuText(text);\n }\n\n text._didTextUpdate = false;\n\n updateTextBounds(batchableText, text);\n }\n\n this._renderer.renderPipes.batch.addToBatch(batchableText, instructionSet);\n }\n\n public updateRenderable(text: Text)\n {\n const batchableText = this._getGpuText(text);\n\n batchableText._batcher.updateElement(batchableText);\n }\n\n private _updateGpuText(text: Text)\n {\n const batchableText = this._getGpuText(text);\n\n if (batchableText.texture)\n {\n this._renderer.canvasText.decreaseReferenceCount(batchableText.currentKey);\n }\n\n text._resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n\n batchableText.texture = this._renderer.canvasText.getManagedTexture(text);\n batchableText.currentKey = text.styleKey;\n }\n\n private _getGpuText(text: Text)\n {\n return text._gpuData[this._renderer.uid] || this.initGpuText(text);\n }\n\n public initGpuText(text: Text)\n {\n const batchableText = new BatchableText(this._renderer);\n\n batchableText.currentKey = '--';\n batchableText.renderable = text;\n batchableText.transform = text.groupTransform;\n batchableText.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 };\n batchableText.roundPixels = (this._renderer._roundPixels | text._roundPixels) as 0 | 1;\n\n text._gpuData[this._renderer.uid] = batchableText;\n\n return batchableText;\n }\n\n public destroy()\n {\n this._renderer = null;\n }\n}\n", "import { Matrix } from '../../../../maths/matrix/Matrix';\nimport { uid } from '../../../../utils/data/uid';\n\nimport type { WRAP_MODE } from '../../../../rendering/renderers/shared/texture/const';\nimport type { Texture } from '../../../../rendering/renderers/shared/texture/Texture';\n\n/**\n * Defines the repetition modes for fill patterns.\n *\n * - `repeat`: The pattern repeats in both directions.\n * - `repeat-x`: The pattern repeats horizontally only.\n * - `repeat-y`: The pattern repeats vertically only.\n * - `no-repeat`: The pattern does not repeat.\n * @category scene\n * @standard\n */\nexport type PatternRepetition = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';\n\nconst repetitionMap = {\n repeat: {\n addressModeU: 'repeat',\n addressModeV: 'repeat',\n },\n 'repeat-x': {\n addressModeU: 'repeat',\n addressModeV: 'clamp-to-edge',\n },\n 'repeat-y': {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'repeat',\n },\n 'no-repeat': {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n },\n};\n\n/**\n * A class that represents a fill pattern for use in Text and Graphics fills.\n * It allows for textures to be used as patterns, with optional repetition modes.\n * @category scene\n * @standard\n * @example\n * const txt = await Assets.load('https://pixijs.com/assets/bg_scene_rotate.jpg');\n * const pat = new FillPattern(txt, 'repeat');\n *\n * const textPattern = new Text({\n * text: 'PixiJS',\n * style: {\n * fontSize: 36,\n * fill: 0xffffff,\n * stroke: { fill: pat, width: 10 },\n * },\n * });\n *\n * textPattern.y = (textGradient.height);\n */\nexport class FillPattern implements CanvasPattern\n{\n /**\n * unique id for this fill pattern\n * @internal\n */\n public readonly uid: number = uid('fillPattern');\n /**\n * Internal tick counter to track changes in the pattern.\n * This is used to invalidate the pattern when the texture or transform changes.\n * @internal\n */\n public _tick: number = 0;\n /** @internal */\n public _texture: Texture;\n /** The transform matrix applied to the pattern */\n public transform = new Matrix();\n\n constructor(texture: Texture, repetition?: PatternRepetition)\n {\n this.texture = texture;\n\n this.transform.scale(\n 1 / texture.frame.width,\n 1 / texture.frame.height\n );\n\n if (repetition)\n {\n texture.source.style.addressModeU = repetitionMap[repetition].addressModeU as WRAP_MODE;\n texture.source.style.addressModeV = repetitionMap[repetition].addressModeV as WRAP_MODE;\n }\n }\n\n /**\n * Sets the transform for the pattern\n * @param transform - The transform matrix to apply to the pattern.\n * If not provided, the pattern will use the default transform.\n */\n public setTransform(transform?: Matrix): void\n {\n const texture = this.texture;\n\n this.transform.copyFrom(transform);\n this.transform.invert();\n // transform.scale\n this.transform.scale(\n 1 / texture.frame.width,\n 1 / texture.frame.height\n );\n\n this._tick++;\n }\n\n /** Internal texture used to render the gradient */\n public get texture()\n {\n return this._texture;\n }\n public set texture(value: Texture)\n {\n if (this._texture === value) return;\n\n this._texture = value;\n this._tick++;\n }\n\n /**\n * Returns a unique key for this instance.\n * This key is used for caching.\n * @returns {string} Unique key for the instance\n */\n public get styleKey(): string\n {\n return `fill-pattern-${this.uid}-${this._tick}`;\n }\n\n /** Destroys the fill pattern, releasing resources. This will also destroy the internal texture. */\n public destroy(): void\n {\n this.texture.destroy(true);\n this.texture = null;\n }\n}\n", "import parse from 'parse-svg-path';\nimport { warn } from '../../../../utils/logging/warn';\n\nimport type { GraphicsPath } from '../path/GraphicsPath';\n\ninterface SubPath\n{\n startX: number;\n startY: number;\n}\n\n/**\n * Parses an SVG path data string and builds a GraphicsPath object from the commands.\n * This function handles all standard SVG path commands including moves, lines, curves and arcs.\n * It maintains state for the current position and subpaths to properly handle relative commands\n * and path closures.\n *\n * Supported SVG commands:\n * - M/m: Move to absolute/relative\n * - L/l: Line to absolute/relative\n * - H/h: Horizontal line absolute/relative\n * - V/v: Vertical line absolute/relative\n * - C/c: Cubic bezier curve absolute/relative\n * - S/s: Smooth cubic bezier curve absolute/relative\n * - Q/q: Quadratic bezier curve absolute/relative\n * - T/t: Smooth quadratic bezier curve absolute/relative\n * - A/a: Arc absolute/relative\n * - Z/z: Close path\n * @param svgPath - The SVG path data string to parse (e.g. \"M0,0 L100,100\")\n * @param path - The GraphicsPath object to build the path into\n * @returns The input path object with the SVG commands applied\n * @internal\n */\nexport function parseSVGPath(svgPath: string, path: GraphicsPath): GraphicsPath\n{\n // Parse the SVG path string into an array of commands\n const commands = parse(svgPath);\n\n // Track subpaths for proper path closure handling\n const subpaths: SubPath[] = [];\n let currentSubPath: SubPath | null = null;\n\n // Track current position for relative commands\n let lastX = 0;\n let lastY = 0;\n\n // Process each command in sequence\n for (let i = 0; i < commands.length; i++)\n {\n const command = commands[i];\n const type = command[0]; // The command letter\n const data = command; // The command parameters, 1-based indexed\n\n switch (type)\n {\n case 'M': // Move To (absolute)\n lastX = data[1];\n lastY = data[2];\n\n path.moveTo(lastX, lastY);\n break;\n case 'm': // Move To (relative)\n lastX += data[1];\n lastY += data[2];\n\n path.moveTo(lastX, lastY);\n break;\n case 'H': // Horizontal Line To (absolute)\n lastX = data[1];\n\n path.lineTo(lastX, lastY);\n break;\n case 'h': // Horizontal Line To (relative)\n lastX += data[1];\n\n path.lineTo(lastX, lastY);\n break;\n case 'V': // Vertical Line To (absolute)\n lastY = data[1];\n\n path.lineTo(lastX, lastY);\n break;\n case 'v': // Vertical Line To (relative)\n lastY += data[1];\n\n path.lineTo(lastX, lastY);\n break;\n case 'L': // Line To (absolute)\n lastX = data[1];\n lastY = data[2];\n\n path.lineTo(lastX, lastY);\n break;\n case 'l': // Line To (relative)\n lastX += data[1];\n lastY += data[2];\n\n path.lineTo(lastX, lastY);\n break;\n case 'C': // Cubic Bezier Curve (absolute)\n lastX = data[5];\n lastY = data[6];\n\n path.bezierCurveTo(\n data[1], data[2], // First control point\n data[3], data[4], // Second control point\n lastX, lastY // End point\n );\n break;\n case 'c': // Cubic Bezier Curve (relative)\n path.bezierCurveTo(\n lastX + data[1], lastY + data[2], // First control point\n lastX + data[3], lastY + data[4], // Second control point\n lastX + data[5], lastY + data[6] // End point\n );\n\n lastX += data[5];\n lastY += data[6];\n break;\n case 'S': // Smooth Cubic Bezier Curve (absolute)\n lastX = data[3];\n lastY = data[4];\n\n path.bezierCurveToShort(\n data[1], data[2], // Control point\n lastX, lastY // End point\n );\n break;\n case 's': // Smooth Cubic Bezier Curve (relative)\n path.bezierCurveToShort(\n lastX + data[1], lastY + data[2], // Control point\n lastX + data[3], lastY + data[4], // End point\n );\n\n lastX += data[3];\n lastY += data[4];\n break;\n case 'Q': // Quadratic Bezier Curve (absolute)\n lastX = data[3];\n lastY = data[4];\n\n path.quadraticCurveTo(\n data[1], data[2], // Control point\n lastX, lastY // End point\n );\n break;\n case 'q': // Quadratic Bezier Curve (relative)\n path.quadraticCurveTo(\n lastX + data[1], lastY + data[2], // Control point\n lastX + data[3], lastY + data[4] // End point\n );\n\n lastX += data[3];\n lastY += data[4];\n break;\n case 'T': // Smooth Quadratic Bezier Curve (absolute)\n lastX = data[1];\n lastY = data[2];\n\n path.quadraticCurveToShort(\n lastX, lastY // End point\n );\n break;\n case 't': // Smooth Quadratic Bezier Curve (relative)\n lastX += data[1];\n lastY += data[2];\n\n path.quadraticCurveToShort(\n lastX, lastY // End point\n );\n break;\n case 'A': // Arc (absolute)\n lastX = data[6];\n lastY = data[7];\n\n path.arcToSvg(\n data[1], // rx\n data[2], // ry\n data[3], // x-axis-rotation\n data[4], // large-arc-flag\n data[5], // sweep-flag\n lastX, lastY // End point\n );\n break;\n case 'a': // Arc (relative)\n lastX += data[6];\n lastY += data[7];\n\n path.arcToSvg(\n data[1], // rx\n data[2], // ry\n data[3], // x-axis-rotation\n data[4], // large-arc-flag\n data[5], // sweep-flag\n lastX, lastY // End point\n );\n break;\n case 'Z': // Close Path\n case 'z':\n path.closePath();\n if (subpaths.length > 0)\n {\n // Return to the start of the current subpath\n currentSubPath = subpaths.pop();\n if (currentSubPath)\n {\n lastX = currentSubPath.startX;\n lastY = currentSubPath.startY;\n }\n else\n {\n lastX = 0;\n lastY = 0;\n }\n }\n currentSubPath = null;\n break;\n default:\n // #if _DEBUG\n warn(`Unknown SVG path command: ${type}`);\n // #endif\n }\n\n // Track subpath starts for path closure\n if (type !== 'Z' && type !== 'z')\n {\n if (currentSubPath === null)\n {\n currentSubPath = { startX: lastX, startY: lastY };\n subpaths.push(currentSubPath);\n }\n }\n }\n\n return path;\n}\n", "import { Rectangle } from './Rectangle';\n\nimport type { SHAPE_PRIMITIVE } from '../misc/const';\nimport type { ShapePrimitive } from './ShapePrimitive';\n\n/**\n * The Circle object represents a circle shape in a two-dimensional coordinate system.\n * Used for drawing graphics and specifying hit areas for containers.\n * @example\n * ```ts\n * // Basic circle creation\n * const circle = new Circle(100, 100, 50);\n *\n * // Use as hit area\n * container.hitArea = new Circle(0, 0, 100);\n *\n * // Check point containment\n * const isInside = circle.contains(mouseX, mouseY);\n *\n * // Get bounding box\n * const bounds = circle.getBounds();\n * ```\n * @remarks\n * - Defined by center (x,y) and radius\n * - Supports point containment tests\n * - Can check stroke intersections\n * @see {@link Rectangle} For rectangular shapes\n * @category maths\n * @standard\n */\nexport class Circle implements ShapePrimitive\n{\n /**\n * The X coordinate of the center of this circle\n * @example\n * ```ts\n * // Basic x position\n * const circle = new Circle();\n * circle.x = 100;\n *\n * // Center circle on point\n * circle.x = point.x;\n * ```\n * @default 0\n */\n public x: number;\n\n /**\n * The Y coordinate of the center of this circle\n * @example\n * ```ts\n * // Basic y position\n * const circle = new Circle();\n * circle.y = 200;\n *\n * // Center circle on point\n * circle.y = point.y;\n * ```\n * @default 0\n */\n public y: number;\n\n /**\n * The radius of the circle\n * @example\n * ```ts\n * // Basic radius setting\n * const circle = new Circle(100, 100);\n * circle.radius = 50;\n *\n * // Calculate area\n * const area = Math.PI * circle.radius * circle.radius;\n * ```\n * @default 0\n */\n public radius: number;\n\n /**\n * The type of the object, mainly used to avoid `instanceof` checks.\n * @example\n * ```ts\n * // Check shape type\n * const shape = new Circle(0, 0, 50);\n * console.log(shape.type); // 'circle'\n *\n * // Use in type guards\n * if (shape.type === 'circle') {\n * console.log(shape.radius);\n * }\n * ```\n * @remarks\n * - Used for shape type checking\n * - More efficient than instanceof\n * - Read-only property\n * @readonly\n * @default 'circle'\n * @see {@link SHAPE_PRIMITIVE} For all shape types\n * @see {@link ShapePrimitive} For shape interface\n */\n public readonly type: SHAPE_PRIMITIVE = 'circle';\n\n /**\n * @param x - The X coordinate of the center of this circle\n * @param y - The Y coordinate of the center of this circle\n * @param radius - The radius of the circle\n */\n constructor(x = 0, y = 0, radius = 0)\n {\n this.x = x;\n this.y = y;\n this.radius = radius;\n }\n\n /**\n * Creates a clone of this Circle instance.\n * @example\n * ```ts\n * // Basic circle cloning\n * const original = new Circle(100, 100, 50);\n * const copy = original.clone();\n *\n * // Clone and modify\n * const modified = original.clone();\n * modified.radius = 75;\n *\n * // Verify independence\n * console.log(original.radius); // 50\n * console.log(modified.radius); // 75\n * ```\n * @returns A copy of the Circle\n * @see {@link Circle.copyFrom} For copying into existing circle\n * @see {@link Circle.copyTo} For copying to another circle\n */\n public clone(): Circle\n {\n return new Circle(this.x, this.y, this.radius);\n }\n\n /**\n * Checks whether the x and y coordinates given are contained within this circle.\n *\n * Uses the distance formula to determine if a point is inside the circle's radius.\n *\n * Commonly used for hit testing in PixiJS events and graphics.\n * @example\n * ```ts\n * // Basic containment check\n * const circle = new Circle(100, 100, 50);\n * const isInside = circle.contains(120, 120);\n *\n * // Check mouse position\n * const circle = new Circle(0, 0, 100);\n * container.hitArea = circle;\n * container.on('pointermove', (e) => {\n * // only called if pointer is within circle\n * });\n * ```\n * @param x - The X coordinate of the point to test\n * @param y - The Y coordinate of the point to test\n * @returns Whether the x/y coordinates are within this Circle\n * @see {@link Circle.strokeContains} For checking stroke intersection\n * @see {@link Circle.getBounds} For getting bounding box\n */\n public contains(x: number, y: number): boolean\n {\n if (this.radius <= 0) return false;\n\n const r2 = this.radius * this.radius;\n let dx = (this.x - x);\n let dy = (this.y - y);\n\n dx *= dx;\n dy *= dy;\n\n return (dx + dy <= r2);\n }\n\n /**\n * Checks whether the x and y coordinates given are contained within this circle including the stroke.\n * @example\n * ```ts\n * // Basic stroke check\n * const circle = new Circle(100, 100, 50);\n * const isOnStroke = circle.strokeContains(150, 100, 4); // 4px line width\n *\n * // Check with different alignments\n * const innerStroke = circle.strokeContains(150, 100, 4, 1); // Inside\n * const centerStroke = circle.strokeContains(150, 100, 4, 0.5); // Centered\n * const outerStroke = circle.strokeContains(150, 100, 4, 0); // Outside\n * ```\n * @param x - The X coordinate of the point to test\n * @param y - The Y coordinate of the point to test\n * @param width - The width of the line to check\n * @param alignment - The alignment of the stroke, 0.5 by default\n * @returns Whether the x/y coordinates are within this Circle's stroke\n * @see {@link Circle.contains} For checking fill containment\n * @see {@link Circle.getBounds} For getting stroke bounds\n */\n public strokeContains(x: number, y: number, width: number, alignment: number = 0.5): boolean\n {\n if (this.radius === 0) return false;\n\n const dx = (this.x - x);\n const dy = (this.y - y);\n const radius = this.radius;\n const outerWidth = (1 - alignment) * width;\n const distance = Math.sqrt((dx * dx) + (dy * dy));\n\n return (distance <= radius + outerWidth && distance > radius - (width - outerWidth));\n }\n\n /**\n * Returns the framing rectangle of the circle as a Rectangle object.\n * @example\n * ```ts\n * // Basic bounds calculation\n * const circle = new Circle(100, 100, 50);\n * const bounds = circle.getBounds();\n * // bounds: x=50, y=50, width=100, height=100\n *\n * // Reuse existing rectangle\n * const rect = new Rectangle();\n * circle.getBounds(rect);\n * ```\n * @param out - Optional Rectangle object to store the result\n * @returns The framing rectangle\n * @see {@link Rectangle} For rectangle properties\n * @see {@link Circle.contains} For point containment\n */\n public getBounds(out?: Rectangle): Rectangle\n {\n out ||= new Rectangle();\n\n out.x = this.x - this.radius;\n out.y = this.y - this.radius;\n out.width = this.radius * 2;\n out.height = this.radius * 2;\n\n return out;\n }\n\n /**\n * Copies another circle to this one.\n * @example\n * ```ts\n * // Basic copying\n * const source = new Circle(100, 100, 50);\n * const target = new Circle();\n * target.copyFrom(source);\n * ```\n * @param circle - The circle to copy from\n * @returns Returns itself\n * @see {@link Circle.copyTo} For copying to another circle\n * @see {@link Circle.clone} For creating new circle copy\n */\n public copyFrom(circle: Circle): this\n {\n this.x = circle.x;\n this.y = circle.y;\n this.radius = circle.radius;\n\n return this;\n }\n\n /**\n * Copies this circle to another one.\n * @example\n * ```ts\n * // Basic copying\n * const source = new Circle(100, 100, 50);\n * const target = new Circle();\n * source.copyTo(target);\n * ```\n * @param circle - The circle to copy to\n * @returns Returns given parameter\n * @see {@link Circle.copyFrom} For copying from another circle\n * @see {@link Circle.clone} For creating new circle copy\n */\n public copyTo(circle: Circle): Circle\n {\n circle.copyFrom(this);\n\n return circle;\n }\n\n // #if _DEBUG\n public toString(): string\n {\n return `[pixi.js/math:Circle x=${this.x} y=${this.y} radius=${this.radius}]`;\n }\n // #endif\n}\n", "import { Rectangle } from './Rectangle';\n\nimport type { ShapePrimitive } from './ShapePrimitive';\n\n/**\n * The Ellipse object is used to help draw graphics and can also be used to specify a hit area for containers.\n * @example\n * ```ts\n * // Basic ellipse creation\n * const ellipse = new Ellipse(100, 100, 20, 10);\n *\n * // Use as a hit area\n * container.hitArea = new Ellipse(0, 0, 50, 25);\n *\n * // Check point containment\n * const isInside = ellipse.contains(mouseX, mouseY);\n *\n * // Get bounding box\n * const bounds = ellipse.getBounds();\n * ```\n * @remarks\n * - Defined by center (x,y) and half dimensions\n * - Total width = halfWidth * 2\n * - Total height = halfHeight * 2\n * @see {@link Rectangle} For rectangular shapes\n * @see {@link Circle} For circular shapes\n * @category maths\n * @standard\n */\nexport class Ellipse implements ShapePrimitive\n{\n /**\n * The X coordinate of the center of this ellipse\n * @example\n * ```ts\n * // Basic x position\n * const ellipse = new Ellipse();\n * ellipse.x = 100;\n * ```\n * @default 0\n */\n public x: number;\n\n /**\n * The Y coordinate of the center of this ellipse\n * @example\n * ```ts\n * // Basic y position\n * const ellipse = new Ellipse();\n * ellipse.y = 200;\n * ```\n * @default 0\n */\n public y: number;\n\n /**\n * The half width of this ellipse\n * @example\n * ```ts\n * // Set half width\n * const ellipse = new Ellipse(100, 100);\n * ellipse.halfWidth = 50; // Total width will be 100\n * ```\n * @default 0\n */\n public halfWidth: number;\n\n /**\n * The half height of this ellipse\n * @example\n * ```ts\n * // Set half height\n * const ellipse = new Ellipse(100, 100);\n * ellipse.halfHeight = 25; // Total height will be 50\n * ```\n * @default 0\n */\n public halfHeight: number;\n\n /**\n * The type of the object, mainly used to avoid `instanceof` checks\n * @example\n * ```ts\n * // Check shape type\n * const shape = new Ellipse(0, 0, 50, 25);\n * console.log(shape.type); // 'ellipse'\n *\n * // Use in type guards\n * if (shape.type === 'ellipse') {\n * console.log(shape.halfWidth, shape.halfHeight);\n * }\n * ```\n * @readonly\n * @default 'ellipse'\n * @see {@link SHAPE_PRIMITIVE} For all shape types\n */\n public readonly type = 'ellipse';\n\n /**\n * @param x - The X coordinate of the center of this ellipse\n * @param y - The Y coordinate of the center of this ellipse\n * @param halfWidth - The half width of this ellipse\n * @param halfHeight - The half height of this ellipse\n */\n constructor(x = 0, y = 0, halfWidth = 0, halfHeight = 0)\n {\n this.x = x;\n this.y = y;\n this.halfWidth = halfWidth;\n this.halfHeight = halfHeight;\n }\n\n /**\n * Creates a clone of this Ellipse instance.\n * @example\n * ```ts\n * // Basic cloning\n * const original = new Ellipse(100, 100, 50, 25);\n * const copy = original.clone();\n *\n * // Clone and modify\n * const modified = original.clone();\n * modified.halfWidth *= 2;\n * modified.halfHeight *= 2;\n *\n * // Verify independence\n * console.log(original.halfWidth); // 50\n * console.log(modified.halfWidth); // 100\n * ```\n * @returns A copy of the ellipse\n * @see {@link Ellipse.copyFrom} For copying into existing ellipse\n * @see {@link Ellipse.copyTo} For copying to another ellipse\n */\n public clone(): Ellipse\n {\n return new Ellipse(this.x, this.y, this.halfWidth, this.halfHeight);\n }\n\n /**\n * Checks whether the x and y coordinates given are contained within this ellipse.\n * Uses normalized coordinates and the ellipse equation to determine containment.\n * @example\n * ```ts\n * // Basic containment check\n * const ellipse = new Ellipse(100, 100, 50, 25);\n * const isInside = ellipse.contains(120, 110);\n * ```\n * @remarks\n * - Uses ellipse equation (x²/a² + y²/b² ≤ 1)\n * - Returns false if dimensions are 0 or negative\n * - Normalized to center (0,0) for calculation\n * @param x - The X coordinate of the point to test\n * @param y - The Y coordinate of the point to test\n * @returns Whether the x/y coords are within this ellipse\n * @see {@link Ellipse.strokeContains} For checking stroke intersection\n * @see {@link Ellipse.getBounds} For getting containing rectangle\n */\n public contains(x: number, y: number): boolean\n {\n if (this.halfWidth <= 0 || this.halfHeight <= 0)\n {\n return false;\n }\n\n // normalize the coords to an ellipse with center 0,0\n let normx = ((x - this.x) / this.halfWidth);\n let normy = ((y - this.y) / this.halfHeight);\n\n normx *= normx;\n normy *= normy;\n\n return (normx + normy <= 1);\n }\n\n /**\n * Checks whether the x and y coordinates given are contained within this ellipse including stroke.\n * @example\n * ```ts\n * // Basic stroke check\n * const ellipse = new Ellipse(100, 100, 50, 25);\n * const isOnStroke = ellipse.strokeContains(150, 100, 4); // 4px line width\n *\n * // Check with different alignments\n * const innerStroke = ellipse.strokeContains(150, 100, 4, 1); // Inside\n * const centerStroke = ellipse.strokeContains(150, 100, 4, 0.5); // Centered\n * const outerStroke = ellipse.strokeContains(150, 100, 4, 0); // Outside\n * ```\n * @remarks\n * - Uses normalized ellipse equations\n * - Considers stroke alignment\n * - Returns false if dimensions are 0\n * @param x - The X coordinate of the point to test\n * @param y - The Y coordinate of the point to test\n * @param strokeWidth - The width of the line to check\n * @param alignment - The alignment of the stroke (1 = inner, 0.5 = centered, 0 = outer)\n * @returns Whether the x/y coords are within this ellipse's stroke\n * @see {@link Ellipse.contains} For checking fill containment\n * @see {@link Ellipse.getBounds} For getting stroke bounds\n */\n public strokeContains(x: number, y: number, strokeWidth: number, alignment: number = 0.5): boolean\n {\n const { halfWidth, halfHeight } = this;\n\n if (halfWidth <= 0 || halfHeight <= 0)\n {\n return false;\n }\n\n const strokeOuterWidth = strokeWidth * (1 - alignment);\n const strokeInnerWidth = strokeWidth - strokeOuterWidth;\n\n const innerHorizontal = halfWidth - strokeInnerWidth;\n const innerVertical = halfHeight - strokeInnerWidth;\n\n const outerHorizontal = halfWidth + strokeOuterWidth;\n const outerVertical = halfHeight + strokeOuterWidth;\n\n const normalizedX = x - this.x;\n const normalizedY = y - this.y;\n\n const innerEllipse = ((normalizedX * normalizedX) / (innerHorizontal * innerHorizontal))\n + ((normalizedY * normalizedY) / (innerVertical * innerVertical));\n\n const outerEllipse = ((normalizedX * normalizedX) / (outerHorizontal * outerHorizontal))\n + ((normalizedY * normalizedY) / (outerVertical * outerVertical));\n\n return innerEllipse > 1 && outerEllipse <= 1;\n }\n\n /**\n * Returns the framing rectangle of the ellipse as a Rectangle object.\n * @example\n * ```ts\n * // Basic bounds calculation\n * const ellipse = new Ellipse(100, 100, 50, 25);\n * const bounds = ellipse.getBounds();\n * // bounds: x=50, y=75, width=100, height=50\n *\n * // Reuse existing rectangle\n * const rect = new Rectangle();\n * ellipse.getBounds(rect);\n * ```\n * @remarks\n * - Creates Rectangle if none provided\n * - Top-left is (x-halfWidth, y-halfHeight)\n * - Width is halfWidth * 2\n * - Height is halfHeight * 2\n * @param out - Optional Rectangle object to store the result\n * @returns The framing rectangle\n * @see {@link Rectangle} For rectangle properties\n * @see {@link Ellipse.contains} For checking if a point is inside\n */\n public getBounds(out?: Rectangle): Rectangle\n {\n out ||= new Rectangle();\n\n out.x = this.x - this.halfWidth;\n out.y = this.y - this.halfHeight;\n out.width = this.halfWidth * 2;\n out.height = this.halfHeight * 2;\n\n return out;\n }\n\n /**\n * Copies another ellipse to this one.\n * @example\n * ```ts\n * // Basic copying\n * const source = new Ellipse(100, 100, 50, 25);\n * const target = new Ellipse();\n * target.copyFrom(source);\n * ```\n * @param ellipse - The ellipse to copy from\n * @returns Returns itself\n * @see {@link Ellipse.copyTo} For copying to another ellipse\n * @see {@link Ellipse.clone} For creating new ellipse copy\n */\n public copyFrom(ellipse: Ellipse): this\n {\n this.x = ellipse.x;\n this.y = ellipse.y;\n this.halfWidth = ellipse.halfWidth;\n this.halfHeight = ellipse.halfHeight;\n\n return this;\n }\n\n /**\n * Copies this ellipse to another one.\n * @example\n * ```ts\n * // Basic copying\n * const source = new Ellipse(100, 100, 50, 25);\n * const target = new Ellipse();\n * source.copyTo(target);\n * ```\n * @param ellipse - The ellipse to copy to\n * @returns Returns given parameter\n * @see {@link Ellipse.copyFrom} For copying from another ellipse\n * @see {@link Ellipse.clone} For creating new ellipse copy\n */\n public copyTo(ellipse: Ellipse): Ellipse\n {\n ellipse.copyFrom(this);\n\n return ellipse;\n }\n\n // #if _DEBUG\n public toString(): string\n {\n return `[pixi.js/math:Ellipse x=${this.x} y=${this.y} halfWidth=${this.halfWidth} halfHeight=${this.halfHeight}]`;\n }\n // #endif\n}\n", "/**\n * Calculates the squared distance from a point to a line segment defined by two endpoints.\n * @param x - x coordinate of the point\n * @param y - y coordinate of the point\n * @param x1 - x coordinate of the first endpoint of the line segment\n * @param y1 - y coordinate of the first endpoint of the line segment\n * @param x2 - x coordinate of the second endpoint of the line segment\n * @param y2 - y coordinate of the second endpoint of the line segment\n * @returns The squared distance from the point to the line segment\n * @category maths\n * @internal\n */\nexport function squaredDistanceToLineSegment(\n x: number, y: number,\n x1: number, y1: number,\n x2: number, y2: number\n): number\n{\n const a = x - x1;\n const b = y - y1;\n const c = x2 - x1;\n const d = y2 - y1;\n\n const dot = (a * c) + (b * d);\n const lenSq = (c * c) + (d * d);\n let param = -1;\n\n if (lenSq !== 0)\n {\n param = dot / lenSq;\n }\n\n let xx; let\n yy;\n\n if (param < 0)\n {\n xx = x1;\n yy = y1;\n }\n else if (param > 1)\n {\n xx = x2;\n yy = y2;\n }\n\n else\n {\n xx = x1 + (param * c);\n yy = y1 + (param * d);\n }\n\n const dx = x - xx;\n const dy = y - yy;\n\n return (dx * dx) + (dy * dy);\n}\n", "import { deprecation } from '../../utils/logging/deprecation';\nimport { squaredDistanceToLineSegment } from '../misc/squaredDistanceToLineSegment';\nimport { Rectangle } from './Rectangle';\n\nimport type { SHAPE_PRIMITIVE } from '../misc/const';\nimport type { PointData } from '../point/PointData';\nimport type { ShapePrimitive } from './ShapePrimitive';\n\nlet tempRect: Rectangle;\nlet tempRect2: Rectangle;\n\n/**\n * A class to define a shape via user defined coordinates.\n * Used for creating complex shapes and hit areas with custom points.\n * @example\n * ```ts\n * // Create polygon from array of points\n * const polygon1 = new Polygon([\n * new Point(0, 0),\n * new Point(0, 100),\n * new Point(100, 100)\n * ]);\n *\n * // Create from array of coordinates\n * const polygon2 = new Polygon([0, 0, 0, 100, 100, 100]);\n *\n * // Create from sequence of points\n * const polygon3 = new Polygon(\n * new Point(0, 0),\n * new Point(0, 100),\n * new Point(100, 100)\n * );\n *\n * // Create from sequence of coordinates\n * const polygon4 = new Polygon(0, 0, 0, 100, 100, 100);\n *\n * // Use as container hit area\n * container.hitArea = new Polygon([0, 0, 100, 0, 50, 100]);\n * ```\n * @see {@link Point} For point objects used in construction\n * @category maths\n * @standard\n */\nexport class Polygon implements ShapePrimitive\n{\n /**\n * An array of the points of this polygon stored as a flat array of numbers.\n * @example\n * ```ts\n * // Access points directly\n * const polygon = new Polygon([0, 0, 100, 0, 50, 100]);\n * console.log(polygon.points); // [0, 0, 100, 0, 50, 100]\n *\n * // Modify points\n * polygon.points[0] = 10; // Move first x coordinate\n * polygon.points[1] = 10; // Move first y coordinate\n * ```\n * @remarks\n * - Stored as [x1, y1, x2, y2, ...]\n * - Each pair represents a vertex\n * - Length is always even\n * - Can be modified directly\n */\n public points: number[];\n\n /**\n * Indicates if the polygon path is closed.\n * @example\n * ```ts\n * // Create open polygon\n * const polygon = new Polygon([0, 0, 100, 0, 50, 100]);\n * polygon.closePath = false;\n *\n * // Check path state\n * if (polygon.closePath) {\n * // Last point connects to first\n * }\n * ```\n * @remarks\n * - True by default\n * - False after moveTo\n * - True after closePath\n * @default true\n */\n public closePath: boolean;\n\n /**\n * The type of the object, mainly used to avoid `instanceof` checks\n * @example\n * ```ts\n * // Check shape type\n * const shape = new Polygon([0, 0, 100, 0, 50, 100]);\n * console.log(shape.type); // 'polygon'\n *\n * // Use in type guards\n * if (shape.type === 'polygon') {\n * // TypeScript knows this is a Polygon\n * console.log(shape.points.length);\n * }\n * ```\n * @readonly\n * @default 'polygon'\n * @see {@link SHAPE_PRIMITIVE} For all shape types\n */\n public readonly type: SHAPE_PRIMITIVE = 'polygon';\n\n constructor(points: PointData[] | number[]);\n constructor(...points: PointData[] | number[]);\n /**\n * @param points - This can be an array of Points\n * that form the polygon, a flat array of numbers that will be interpreted as [x,y, x,y, ...], or\n * the arguments passed can be all the points of the polygon e.g.\n * `new Polygon(new Point(), new Point(), ...)`, or the arguments passed can be flat\n * x,y values e.g. `new Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers.\n */\n constructor(...points: (PointData[] | number[])[] | PointData[] | number[])\n {\n let flat = Array.isArray(points[0]) ? points[0] : points;\n\n // if this is an array of points, convert it to a flat array of numbers\n if (typeof flat[0] !== 'number')\n {\n const p: number[] = [];\n\n for (let i = 0, il = flat.length; i < il; i++)\n {\n p.push((flat[i] as PointData).x, (flat[i] as PointData).y);\n }\n\n flat = p;\n }\n\n this.points = flat as number[];\n\n this.closePath = true;\n }\n\n /**\n * Determines whether the polygon's points are arranged in a clockwise direction.\n * Uses the shoelace formula (surveyor's formula) to calculate the signed area.\n *\n * A positive area indicates clockwise winding, while negative indicates counter-clockwise.\n *\n * The formula sums up the cross products of adjacent vertices:\n * For each pair of adjacent points (x1,y1) and (x2,y2), we calculate (x1*y2 - x2*y1)\n * The final sum divided by 2 gives the signed area - positive for clockwise.\n * @example\n * ```ts\n * // Check polygon winding\n * const polygon = new Polygon([0, 0, 100, 0, 50, 100]);\n * console.log(polygon.isClockwise()); // Check direction\n *\n * // Use in path construction\n * const hole = new Polygon([25, 25, 75, 25, 75, 75, 25, 75]);\n * if (hole.isClockwise() === shape.isClockwise()) {\n * hole.points.reverse(); // Reverse for proper hole winding\n * }\n * ```\n * @returns `true` if the polygon's points are arranged clockwise, `false` if counter-clockwise\n */\n public isClockwise(): boolean\n {\n let area = 0;\n const points = this.points;\n const length = points.length;\n\n for (let i = 0; i < length; i += 2)\n {\n const x1 = points[i];\n const y1 = points[i + 1];\n const x2 = points[(i + 2) % length];\n const y2 = points[(i + 3) % length];\n\n area += (x2 - x1) * (y2 + y1);\n }\n\n return area < 0;\n }\n\n /**\n * Checks if this polygon completely contains another polygon.\n * Used for detecting holes in shapes, like when parsing SVG paths.\n * @example\n * ```ts\n * // Basic containment check\n * const outerSquare = new Polygon([0,0, 100,0, 100,100, 0,100]); // A square\n * const innerSquare = new Polygon([25,25, 75,25, 75,75, 25,75]); // A smaller square inside\n *\n * outerSquare.containsPolygon(innerSquare); // Returns true\n * innerSquare.containsPolygon(outerSquare); // Returns false\n * ```\n * @remarks\n * - Uses bounds check for quick rejection\n * - Tests all points for containment\n * @param polygon - The polygon to test for containment\n * @returns True if this polygon completely contains the other polygon\n * @see {@link Polygon.contains} For single point testing\n * @see {@link Polygon.getBounds} For bounds calculation\n */\n public containsPolygon(polygon: Polygon): boolean\n {\n // Quick early-out: bounds check\n const thisBounds = this.getBounds(tempRect);\n const otherBounds = polygon.getBounds(tempRect2);\n\n if (!thisBounds.containsRect(otherBounds))\n {\n return false; // If bounds aren't contained, the polygon cannot be a hole\n }\n\n // Full point containment check\n const points = polygon.points;\n\n for (let i = 0; i < points.length; i += 2)\n {\n const x = points[i];\n const y = points[i + 1];\n\n // Combine bounds and polygon checks for efficiency\n if (!this.contains(x, y))\n {\n return false;\n }\n }\n\n return true; // All points are contained within bounds and polygon\n }\n\n /**\n * Creates a clone of this polygon.\n * @example\n * ```ts\n * // Basic cloning\n * const original = new Polygon([0, 0, 100, 0, 50, 100]);\n * const copy = original.clone();\n *\n * // Clone and modify\n * const modified = original.clone();\n * modified.points[0] = 10; // Modify first x coordinate\n * ```\n * @returns A copy of the polygon\n * @see {@link Polygon.copyFrom} For copying into existing polygon\n * @see {@link Polygon.copyTo} For copying to another polygon\n */\n public clone(): Polygon\n {\n const points = this.points.slice();\n const polygon = new Polygon(points);\n\n polygon.closePath = this.closePath;\n\n return polygon;\n }\n\n /**\n * Checks whether the x and y coordinates passed to this function are contained within this polygon.\n * Uses raycasting algorithm for point-in-polygon testing.\n * @example\n * ```ts\n * // Basic containment check\n * const polygon = new Polygon([0, 0, 100, 0, 50, 100]);\n * const isInside = polygon.contains(25, 25); // true\n * ```\n * @param x - The X coordinate of the point to test\n * @param y - The Y coordinate of the point to test\n * @returns Whether the x/y coordinates are within this polygon\n * @see {@link Polygon.strokeContains} For checking stroke intersection\n * @see {@link Polygon.containsPolygon} For polygon-in-polygon testing\n */\n public contains(x: number, y: number): boolean\n {\n let inside = false;\n\n // use some raycasting to test hits\n // https://github.com/substack/point-in-polygon/blob/master/index.js\n const length = this.points.length / 2;\n\n for (let i = 0, j = length - 1; i < length; j = i++)\n {\n const xi = this.points[i * 2];\n const yi = this.points[(i * 2) + 1];\n const xj = this.points[j * 2];\n const yj = this.points[(j * 2) + 1];\n const intersect = ((yi > y) !== (yj > y)) && (x < ((xj - xi) * ((y - yi) / (yj - yi))) + xi);\n\n if (intersect)\n {\n inside = !inside;\n }\n }\n\n return inside;\n }\n\n /**\n * Checks whether the x and y coordinates given are contained within this polygon including the stroke.\n * @example\n * ```ts\n * // Basic stroke check\n * const polygon = new Polygon([0, 0, 100, 0, 50, 100]);\n * const isOnStroke = polygon.strokeContains(25, 25, 4); // 4px line width\n *\n * // Check with different alignments\n * const innerStroke = polygon.strokeContains(25, 25, 4, 1); // Inside\n * const centerStroke = polygon.strokeContains(25, 25, 4, 0.5); // Centered\n * const outerStroke = polygon.strokeContains(25, 25, 4, 0); // Outside\n * ```\n * @param x - The X coordinate of the point to test\n * @param y - The Y coordinate of the point to test\n * @param strokeWidth - The width of the line to check\n * @param alignment - The alignment of the stroke (1 = inner, 0.5 = centered, 0 = outer)\n * @returns Whether the x/y coordinates are within this polygon's stroke\n * @see {@link Polygon.contains} For checking fill containment\n * @see {@link Polygon.getBounds} For getting stroke bounds\n */\n public strokeContains(x: number, y: number, strokeWidth: number, alignment = 0.5): boolean\n {\n const strokeWidthSquared = strokeWidth * strokeWidth;\n const rightWidthSquared = strokeWidthSquared * (1 - alignment);\n const leftWidthSquared = strokeWidthSquared - rightWidthSquared;\n\n const { points } = this;\n const iterationLength = points.length - (this.closePath ? 0 : 2);\n\n for (let i = 0; i < iterationLength; i += 2)\n {\n const x1 = points[i];\n const y1 = points[i + 1];\n const x2 = points[(i + 2) % points.length];\n const y2 = points[(i + 3) % points.length];\n\n const distanceSquared = squaredDistanceToLineSegment(x, y, x1, y1, x2, y2);\n\n const sign = Math.sign(((x2 - x1) * (y - y1)) - ((y2 - y1) * (x - x1)));\n\n if (distanceSquared <= (sign < 0 ? leftWidthSquared : rightWidthSquared))\n {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Returns the framing rectangle of the polygon as a Rectangle object.\n * @example\n * ```ts\n * // Basic bounds calculation\n * const polygon = new Polygon([0, 0, 100, 0, 50, 100]);\n * const bounds = polygon.getBounds();\n * // bounds: x=0, y=0, width=100, height=100\n *\n * // Reuse existing rectangle\n * const rect = new Rectangle();\n * polygon.getBounds(rect);\n * ```\n * @param out - Optional rectangle to store the result\n * @returns The framing rectangle\n * @see {@link Rectangle} For rectangle properties\n * @see {@link Polygon.contains} For checking if a point is inside\n */\n public getBounds(out?: Rectangle): Rectangle\n {\n out ||= new Rectangle();\n\n const points = this.points;\n\n let minX = Infinity;\n let maxX = -Infinity;\n\n let minY = Infinity;\n let maxY = -Infinity;\n\n for (let i = 0, n = points.length; i < n; i += 2)\n {\n const x = points[i];\n const y = points[i + 1];\n\n minX = x < minX ? x : minX;\n maxX = x > maxX ? x : maxX;\n\n minY = y < minY ? y : minY;\n maxY = y > maxY ? y : maxY;\n }\n\n out.x = minX;\n out.width = maxX - minX;\n\n out.y = minY;\n out.height = maxY - minY;\n\n return out;\n }\n\n /**\n * Copies another polygon to this one.\n * @example\n * ```ts\n * // Basic copying\n * const source = new Polygon([0, 0, 100, 0, 50, 100]);\n * const target = new Polygon();\n * target.copyFrom(source);\n * ```\n * @param polygon - The polygon to copy from\n * @returns Returns itself\n * @see {@link Polygon.copyTo} For copying to another polygon\n * @see {@link Polygon.clone} For creating new polygon copy\n */\n public copyFrom(polygon: Polygon): this\n {\n this.points = polygon.points.slice();\n this.closePath = polygon.closePath;\n\n return this;\n }\n\n /**\n * Copies this polygon to another one.\n * @example\n * ```ts\n * // Basic copying\n * const source = new Polygon([0, 0, 100, 0, 50, 100]);\n * const target = new Polygon();\n * source.copyTo(target);\n * ```\n * @param polygon - The polygon to copy to\n * @returns Returns given parameter\n * @see {@link Polygon.copyFrom} For copying from another polygon\n * @see {@link Polygon.clone} For creating new polygon copy\n */\n public copyTo(polygon: Polygon): Polygon\n {\n polygon.copyFrom(this);\n\n return polygon;\n }\n\n // #if _DEBUG\n public toString(): string\n {\n return `[pixi.js/math:Polygon`\n + `closeStroke=${this.closePath}`\n + `points=${this.points.reduce((pointsDesc, currentPoint) => `${pointsDesc}, ${currentPoint}`, '')}]`;\n }\n // #endif\n\n /**\n * Get the last X coordinate of the polygon.\n * @example\n * ```ts\n * // Basic coordinate access\n * const polygon = new Polygon([0, 0, 100, 200, 300, 400]);\n * console.log(polygon.lastX); // 300\n * ```\n * @readonly\n * @returns The x-coordinate of the last vertex\n * @see {@link Polygon.lastY} For last Y coordinate\n * @see {@link Polygon.points} For raw points array\n */\n get lastX(): number\n {\n return this.points[this.points.length - 2];\n }\n\n /**\n * Get the last Y coordinate of the polygon.\n * @example\n * ```ts\n * // Basic coordinate access\n * const polygon = new Polygon([0, 0, 100, 200, 300, 400]);\n * console.log(polygon.lastY); // 400\n * ```\n * @readonly\n * @returns The y-coordinate of the last vertex\n * @see {@link Polygon.lastX} For last X coordinate\n * @see {@link Polygon.points} For raw points array\n */\n get lastY(): number\n {\n return this.points[this.points.length - 1];\n }\n\n /**\n * Get the last X coordinate of the polygon.\n * @readonly\n * @deprecated since 8.11.0, use {@link Polygon.lastX} instead.\n */\n get x(): number\n {\n // #if _DEBUG\n deprecation('8.11.0', 'Polygon.lastX is deprecated, please use Polygon.lastX instead.');\n // #endif\n\n return this.points[this.points.length - 2];\n }\n\n /**\n * Get the last Y coordinate of the polygon.\n * @readonly\n * @deprecated since 8.11.0, use {@link Polygon.lastY} instead.\n */\n get y(): number\n {\n // #if _DEBUG\n deprecation('8.11.0', 'Polygon.y is deprecated, please use Polygon.lastY instead.');\n // #endif\n\n return this.points[this.points.length - 1];\n }\n /**\n * Get the first X coordinate of the polygon.\n * @example\n * ```ts\n * // Basic coordinate access\n * const polygon = new Polygon([0, 0, 100, 200, 300, 400]);\n * console.log(polygon.x); // 0\n * ```\n * @readonly\n * @returns The x-coordinate of the first vertex\n * @see {@link Polygon.startY} For first Y coordinate\n * @see {@link Polygon.points} For raw points array\n */\n get startX(): number\n {\n return this.points[0];\n }\n\n /**\n * Get the first Y coordinate of the polygon.\n * @example\n * ```ts\n * // Basic coordinate access\n * const polygon = new Polygon([0, 0, 100, 200, 300, 400]);\n * console.log(polygon.y); // 0\n * ```\n * @readonly\n * @returns The y-coordinate of the first vertex\n * @see {@link Polygon.startX} For first X coordinate\n * @see {@link Polygon.points} For raw points array\n */\n get startY(): number\n {\n return this.points[1];\n }\n}\n\n", "import { type SHAPE_PRIMITIVE } from '../misc/const';\nimport { Rectangle } from './Rectangle';\n\nimport type { ShapePrimitive } from './ShapePrimitive';\n\nconst isCornerWithinStroke = (\n pX: number,\n pY: number,\n cornerX: number,\n cornerY: number,\n radius: number,\n strokeWidthInner: number,\n strokeWidthOuter: number\n) =>\n{\n const dx = pX - cornerX;\n const dy = pY - cornerY;\n const distance = Math.sqrt((dx * dx) + (dy * dy));\n\n return distance >= radius - strokeWidthInner && distance <= radius + strokeWidthOuter;\n};\n\n/**\n * The `RoundedRectangle` object represents a rectangle with rounded corners.\n * Defined by position, dimensions and corner radius.\n * @example\n * ```ts\n * // Basic rectangle creation\n * const rect = new RoundedRectangle(100, 100, 200, 150, 20);\n * // Use as container hit area\n * container.hitArea = new RoundedRectangle(0, 0, 100, 100, 10);\n * // Check point containment\n * const isInside = rect.contains(mouseX, mouseY);\n * // Get bounds\n * const bounds = rect.getBounds();\n * ```\n * @remarks\n * - Position defined by top-left corner\n * - Radius clamped to half smallest dimension\n * - Common in UI elements\n * @see {@link Rectangle} For non-rounded rectangles\n * @category maths\n * @standard\n */\nexport class RoundedRectangle implements ShapePrimitive\n{\n /**\n * The X coordinate of the upper-left corner of the rounded rectangle\n * @example\n * ```ts\n * // Basic x position\n * const rect = new RoundedRectangle();\n * rect.x = 100;\n * ```\n * @default 0\n */\n public x: number;\n\n /**\n * The Y coordinate of the upper-left corner of the rounded rectangle\n * @example\n * ```ts\n * // Basic y position\n * const rect = new RoundedRectangle();\n * rect.y = 100;\n * ```\n * @default 0\n */\n public y: number;\n\n /**\n * The overall width of this rounded rectangle\n * @example\n * ```ts\n * // Basic width setting\n * const rect = new RoundedRectangle();\n * rect.width = 200; // Total width will be 200\n * ```\n * @default 0\n */\n public width: number;\n\n /**\n * The overall height of this rounded rectangle\n * @example\n * ```ts\n * // Basic height setting\n * const rect = new RoundedRectangle();\n * rect.height = 150; // Total height will be 150\n * ```\n * @default 0\n */\n public height: number;\n\n /**\n * Controls the radius of the rounded corners\n * @example\n * ```ts\n * // Basic radius setting\n * const rect = new RoundedRectangle(0, 0, 200, 150);\n * rect.radius = 20;\n *\n * // Clamp to maximum safe radius\n * rect.radius = Math.min(rect.width, rect.height) / 2;\n *\n * // Create pill shape\n * rect.radius = rect.height / 2;\n * ```\n * @remarks\n * - Automatically clamped to half of smallest dimension\n * - Common values: 0-20 for UI elements\n * - Higher values create more rounded corners\n * @default 20\n */\n public radius: number;\n\n /**\n * The type of the object, mainly used to avoid `instanceof` checks\n * @example\n * ```ts\n * // Check shape type\n * const shape = new RoundedRectangle(0, 0, 100, 100, 20);\n * console.log(shape.type); // 'roundedRectangle'\n *\n * // Use in type guards\n * if (shape.type === 'roundedRectangle') {\n * console.log(shape.radius);\n * }\n * ```\n * @readonly\n * @default 'roundedRectangle'\n * @see {@link SHAPE_PRIMITIVE} For all shape types\n */\n public readonly type: SHAPE_PRIMITIVE = 'roundedRectangle';\n\n /**\n * @param x - The X coordinate of the upper-left corner of the rounded rectangle\n * @param y - The Y coordinate of the upper-left corner of the rounded rectangle\n * @param width - The overall width of this rounded rectangle\n * @param height - The overall height of this rounded rectangle\n * @param radius - Controls the radius of the rounded corners\n */\n constructor(x = 0, y = 0, width = 0, height = 0, radius = 20)\n {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n this.radius = radius;\n }\n\n /**\n * Returns the framing rectangle of the rounded rectangle as a Rectangle object\n * @example\n * ```ts\n * // Basic bounds calculation\n * const rect = new RoundedRectangle(100, 100, 200, 150, 20);\n * const bounds = rect.getBounds();\n * // bounds: x=100, y=100, width=200, height=150\n *\n * // Reuse existing rectangle\n * const out = new Rectangle();\n * rect.getBounds(out);\n * ```\n * @remarks\n * - Rectangle matches outer dimensions\n * - Ignores corner radius\n * @param out - Optional rectangle to store the result\n * @returns The framing rectangle\n * @see {@link Rectangle} For rectangle properties\n * @see {@link RoundedRectangle.contains} For checking if a point is inside\n */\n public getBounds(out?: Rectangle): Rectangle\n {\n out ||= new Rectangle();\n\n out.x = this.x;\n out.y = this.y;\n out.width = this.width;\n out.height = this.height;\n\n return out;\n }\n\n /**\n * Creates a clone of this Rounded Rectangle.\n * @example\n * ```ts\n * // Basic cloning\n * const original = new RoundedRectangle(100, 100, 200, 150, 20);\n * const copy = original.clone();\n *\n * // Clone and modify\n * const modified = original.clone();\n * modified.radius = 30;\n * modified.width *= 2;\n *\n * // Verify independence\n * console.log(original.radius); // 20\n * console.log(modified.radius); // 30\n * ```\n * @returns A copy of the rounded rectangle\n * @see {@link RoundedRectangle.copyFrom} For copying into existing rectangle\n * @see {@link RoundedRectangle.copyTo} For copying to another rectangle\n */\n public clone(): RoundedRectangle\n {\n return new RoundedRectangle(this.x, this.y, this.width, this.height, this.radius);\n }\n\n /**\n * Copies another rectangle to this one.\n * @example\n * ```ts\n * // Basic copying\n * const source = new RoundedRectangle(100, 100, 200, 150, 20);\n * const target = new RoundedRectangle();\n * target.copyFrom(source);\n *\n * // Chain with other operations\n * const rect = new RoundedRectangle()\n * .copyFrom(source)\n * .getBounds(rect);\n * ```\n * @param rectangle - The rectangle to copy from\n * @returns Returns itself\n * @see {@link RoundedRectangle.copyTo} For copying to another rectangle\n * @see {@link RoundedRectangle.clone} For creating new rectangle copy\n */\n public copyFrom(rectangle: RoundedRectangle): this\n {\n this.x = rectangle.x;\n this.y = rectangle.y;\n this.width = rectangle.width;\n this.height = rectangle.height;\n\n return this;\n }\n\n /**\n * Copies this rectangle to another one.\n * @example\n * ```ts\n * // Basic copying\n * const source = new RoundedRectangle(100, 100, 200, 150, 20);\n * const target = new RoundedRectangle();\n * source.copyTo(target);\n *\n * // Chain with other operations\n * const result = source\n * .copyTo(new RoundedRectangle())\n * .getBounds();\n * ```\n * @param rectangle - The rectangle to copy to\n * @returns Returns given parameter\n * @see {@link RoundedRectangle.copyFrom} For copying from another rectangle\n * @see {@link RoundedRectangle.clone} For creating new rectangle copy\n */\n public copyTo(rectangle: RoundedRectangle): RoundedRectangle\n {\n rectangle.copyFrom(this);\n\n return rectangle;\n }\n\n /**\n * Checks whether the x and y coordinates given are contained within this Rounded Rectangle\n * @example\n * ```ts\n * // Basic containment check\n * const rect = new RoundedRectangle(100, 100, 200, 150, 20);\n * const isInside = rect.contains(150, 125); // true\n * // Check corner radius\n * const corner = rect.contains(100, 100); // false if within corner curve\n * ```\n * @remarks\n * - Returns false if width/height is 0 or negative\n * - Handles rounded corners with radius check\n * @param x - The X coordinate of the point to test\n * @param y - The Y coordinate of the point to test\n * @returns Whether the x/y coordinates are within this Rounded Rectangle\n * @see {@link RoundedRectangle.strokeContains} For checking stroke intersection\n * @see {@link RoundedRectangle.getBounds} For getting containing rectangle\n */\n public contains(x: number, y: number): boolean\n {\n if (this.width <= 0 || this.height <= 0)\n {\n return false;\n }\n if (x >= this.x && x <= this.x + this.width)\n {\n if (y >= this.y && y <= this.y + this.height)\n {\n const radius = Math.max(0, Math.min(this.radius, Math.min(this.width, this.height) / 2));\n\n if ((y >= this.y + radius && y <= this.y + this.height - radius)\n || (x >= this.x + radius && x <= this.x + this.width - radius))\n {\n return true;\n }\n let dx = x - (this.x + radius);\n let dy = y - (this.y + radius);\n const radius2 = radius * radius;\n\n if ((dx * dx) + (dy * dy) <= radius2)\n {\n return true;\n }\n dx = x - (this.x + this.width - radius);\n if ((dx * dx) + (dy * dy) <= radius2)\n {\n return true;\n }\n dy = y - (this.y + this.height - radius);\n if ((dx * dx) + (dy * dy) <= radius2)\n {\n return true;\n }\n dx = x - (this.x + radius);\n if ((dx * dx) + (dy * dy) <= radius2)\n {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Checks whether the x and y coordinates given are contained within this rectangle including the stroke.\n * @example\n * ```ts\n * // Basic stroke check\n * const rect = new RoundedRectangle(100, 100, 200, 150, 20);\n * const isOnStroke = rect.strokeContains(150, 100, 4); // 4px line width\n *\n * // Check with different alignments\n * const innerStroke = rect.strokeContains(150, 100, 4, 1); // Inside\n * const centerStroke = rect.strokeContains(150, 100, 4, 0.5); // Centered\n * const outerStroke = rect.strokeContains(150, 100, 4, 0); // Outside\n * ```\n * @param pX - The X coordinate of the point to test\n * @param pY - The Y coordinate of the point to test\n * @param strokeWidth - The width of the line to check\n * @param alignment - The alignment of the stroke (1 = inner, 0.5 = centered, 0 = outer)\n * @returns Whether the x/y coordinates are within this rectangle's stroke\n * @see {@link RoundedRectangle.contains} For checking fill containment\n * @see {@link RoundedRectangle.getBounds} For getting stroke bounds\n */\n public strokeContains(pX: number, pY: number, strokeWidth: number, alignment: number = 0.5): boolean\n {\n const { x, y, width, height, radius } = this;\n\n const strokeWidthOuter = strokeWidth * (1 - alignment);\n const strokeWidthInner = strokeWidth - strokeWidthOuter;\n\n const innerX = x + radius;\n const innerY = y + radius;\n const innerWidth = width - (radius * 2);\n const innerHeight = height - (radius * 2);\n const rightBound = x + width;\n const bottomBound = y + height;\n\n // Check if point is within the vertical edges (excluding corners)\n if (((pX >= x - strokeWidthOuter && pX <= x + strokeWidthInner)\n || (pX >= rightBound - strokeWidthInner && pX <= rightBound + strokeWidthOuter))\n && pY >= innerY && pY <= innerY + innerHeight)\n {\n return true;\n }\n\n // Check if point is within the horizontal edges (excluding corners)\n if (((pY >= y - strokeWidthOuter && pY <= y + strokeWidthInner)\n || (pY >= bottomBound - strokeWidthInner && pY <= bottomBound + strokeWidthOuter))\n && pX >= innerX && pX <= innerX + innerWidth)\n {\n return true;\n }\n\n // Top-left, top-right, bottom-right, bottom-left corners\n return (\n // Top-left\n (pX < innerX && pY < innerY\n && isCornerWithinStroke(pX, pY, innerX, innerY,\n radius, strokeWidthInner, strokeWidthOuter))\n // top-right\n || (pX > rightBound - radius && pY < innerY\n && isCornerWithinStroke(pX, pY, rightBound - radius, innerY,\n radius, strokeWidthInner, strokeWidthOuter))\n // bottom-right\n || (pX > rightBound - radius && pY > bottomBound - radius\n && isCornerWithinStroke(pX, pY, rightBound - radius, bottomBound - radius,\n radius, strokeWidthInner, strokeWidthOuter))\n // bottom-left\n || (pX < innerX && pY > bottomBound - radius\n && isCornerWithinStroke(pX, pY, innerX, bottomBound - radius,\n radius, strokeWidthInner, strokeWidthOuter)));\n }\n\n // #if _DEBUG\n public toString(): string\n {\n return `[pixi.js/math:RoundedRectangle x=${this.x} y=${this.y}`\n + `width=${this.width} height=${this.height} radius=${this.radius}]`;\n }\n // #endif\n}\n", "// thanks to https://github.com/mattdesl/adaptive-bezier-curve\n// for the original code!\n\nimport { GraphicsContextSystem } from '../GraphicsContextSystem';\n\nconst RECURSION_LIMIT = 8;\nconst FLT_EPSILON = 1.19209290e-7;\nconst PATH_DISTANCE_EPSILON = 1.0;\n\nconst curveAngleToleranceEpsilon = 0.01;\nconst mAngleTolerance = 0;\nconst mCuspLimit = 0;\n\n/**\n * @param points\n * @param sX\n * @param sY\n * @param cp1x\n * @param cp1y\n * @param cp2x\n * @param cp2y\n * @param eX\n * @param eY\n * @param smoothness\n * @internal\n */\nexport function buildAdaptiveBezier(\n points: number[],\n sX: number, sY: number,\n cp1x: number, cp1y: number,\n cp2x: number, cp2y: number,\n eX: number, eY: number,\n smoothness?: number,\n)\n{\n // TODO expose as a parameter\n const scale = 1;\n const smoothing = Math.min(\n 0.99, // a value of 1.0 actually inverts smoothing, so we cap it at 0.99\n Math.max(0, smoothness ?? GraphicsContextSystem.defaultOptions.bezierSmoothness)\n );\n let distanceTolerance = (PATH_DISTANCE_EPSILON - smoothing) / scale;\n\n distanceTolerance *= distanceTolerance;\n begin(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance);\n\n return points;\n}\n\n// //// Based on:\n// //// https://github.com/pelson/antigrain/blob/master/agg-2.4/src/agg_curves.cpp\n\nfunction begin(\n sX: number, sY: number,\n cp1x: number, cp1y: number,\n cp2x: number, cp2y: number,\n eX: number, eY: number,\n points: number[],\n distanceTolerance: number\n)\n{\n // dont need to actually ad this!\n // points.push(sX, sY);\n recursive(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance, 0);\n points.push(eX, eY);\n}\n\n// eslint-disable-next-line max-params\nfunction recursive(\n x1: number, y1: number,\n x2: number, y2: number,\n x3: number, y3: number,\n x4: number, y4: number,\n points: number[],\n distanceTolerance: number,\n level: number)\n{\n if (level > RECURSION_LIMIT)\n { return; }\n\n const pi = Math.PI;\n\n // Calculate all the mid-points of the line segments\n // ----------------------\n const x12 = (x1 + x2) / 2;\n const y12 = (y1 + y2) / 2;\n const x23 = (x2 + x3) / 2;\n const y23 = (y2 + y3) / 2;\n const x34 = (x3 + x4) / 2;\n const y34 = (y3 + y4) / 2;\n const x123 = (x12 + x23) / 2;\n const y123 = (y12 + y23) / 2;\n const x234 = (x23 + x34) / 2;\n const y234 = (y23 + y34) / 2;\n const x1234 = (x123 + x234) / 2;\n const y1234 = (y123 + y234) / 2;\n\n if (level > 0)\n { // Enforce subdivision first time\n // Try to approximate the full cubic curve by a single straight line\n // ------------------\n let dx = x4 - x1;\n let dy = y4 - y1;\n\n const d2 = Math.abs(((x2 - x4) * dy) - ((y2 - y4) * dx));\n const d3 = Math.abs(((x3 - x4) * dy) - ((y3 - y4) * dx));\n\n let da1; let da2;\n\n if (d2 > FLT_EPSILON && d3 > FLT_EPSILON)\n {\n // Regular care\n // -----------------\n if ((d2 + d3) * (d2 + d3) <= distanceTolerance * ((dx * dx) + (dy * dy)))\n {\n // If the curvature doesn't exceed the distanceTolerance value\n // we tend to finish subdivisions.\n // ----------------------\n if (mAngleTolerance < curveAngleToleranceEpsilon)\n {\n points.push(x1234, y1234);\n\n return;\n }\n\n // Angle & Cusp Condition\n // ----------------------\n const a23 = Math.atan2(y3 - y2, x3 - x2);\n\n da1 = Math.abs(a23 - Math.atan2(y2 - y1, x2 - x1));\n da2 = Math.abs(Math.atan2(y4 - y3, x4 - x3) - a23);\n if (da1 >= pi) da1 = (2 * pi) - da1;\n if (da2 >= pi) da2 = (2 * pi) - da2;\n\n if (da1 + da2 < mAngleTolerance)\n {\n // Finally we can stop the recursion\n // ----------------------\n points.push(x1234, y1234);\n\n return;\n }\n\n if (mCuspLimit !== 0.0)\n {\n if (da1 > mCuspLimit)\n {\n points.push(x2, y2);\n\n return;\n }\n\n if (da2 > mCuspLimit)\n {\n points.push(x3, y3);\n\n return;\n }\n }\n }\n }\n else if (d2 > FLT_EPSILON)\n {\n // p1,p3,p4 are collinear, p2 is considerable\n // ----------------------\n if (d2 * d2 <= distanceTolerance * ((dx * dx) + (dy * dy)))\n {\n if (mAngleTolerance < curveAngleToleranceEpsilon)\n {\n points.push(x1234, y1234);\n\n return;\n }\n\n // Angle Condition\n // ----------------------\n da1 = Math.abs(Math.atan2(y3 - y2, x3 - x2) - Math.atan2(y2 - y1, x2 - x1));\n if (da1 >= pi) da1 = (2 * pi) - da1;\n\n if (da1 < mAngleTolerance)\n {\n points.push(x2, y2);\n points.push(x3, y3);\n\n return;\n }\n\n if (mCuspLimit !== 0.0)\n {\n if (da1 > mCuspLimit)\n {\n points.push(x2, y2);\n\n return;\n }\n }\n }\n }\n else if (d3 > FLT_EPSILON)\n {\n // p1,p2,p4 are collinear, p3 is considerable\n // ----------------------\n if (d3 * d3 <= distanceTolerance * ((dx * dx) + (dy * dy)))\n {\n if (mAngleTolerance < curveAngleToleranceEpsilon)\n {\n points.push(x1234, y1234);\n\n return;\n }\n\n // Angle Condition\n // ----------------------\n da1 = Math.abs(Math.atan2(y4 - y3, x4 - x3) - Math.atan2(y3 - y2, x3 - x2));\n if (da1 >= pi) da1 = (2 * pi) - da1;\n\n if (da1 < mAngleTolerance)\n {\n points.push(x2, y2);\n points.push(x3, y3);\n\n return;\n }\n\n if (mCuspLimit !== 0.0)\n {\n if (da1 > mCuspLimit)\n {\n points.push(x3, y3);\n\n return;\n }\n }\n }\n }\n else\n {\n // Collinear case\n // -----------------\n dx = x1234 - ((x1 + x4) / 2);\n dy = y1234 - ((y1 + y4) / 2);\n if ((dx * dx) + (dy * dy) <= distanceTolerance)\n {\n points.push(x1234, y1234);\n\n return;\n }\n }\n }\n\n // Continue subdivision\n // ----------------------\n recursive(x1, y1, x12, y12, x123, y123, x1234, y1234, points, distanceTolerance, level + 1);\n recursive(x1234, y1234, x234, y234, x34, y34, x4, y4, points, distanceTolerance, level + 1);\n}\n\n", "// thanks to https://github.com/mattdesl/adaptive-quadratic-curve\n// for the original code!\n\nimport { GraphicsContextSystem } from '../GraphicsContextSystem';\n\nconst RECURSION_LIMIT = 8;\nconst FLT_EPSILON = 1.19209290e-7;\nconst PATH_DISTANCE_EPSILON = 1.0;\n\nconst curveAngleToleranceEpsilon = 0.01;\nconst mAngleTolerance = 0;\n\n/**\n * @param points\n * @param sX\n * @param sY\n * @param cp1x\n * @param cp1y\n * @param eX\n * @param eY\n * @param smoothness\n * @internal\n */\nexport function buildAdaptiveQuadratic(\n points: number[],\n sX: number, sY: number,\n cp1x: number, cp1y: number,\n eX: number, eY: number,\n smoothness?: number,\n)\n{\n const scale = 1.0;\n const smoothing = Math.min(\n 0.99, // a value of 1.0 actually inverts smoothing, so we cap it at 0.99\n Math.max(0, smoothness ?? GraphicsContextSystem.defaultOptions.bezierSmoothness)\n );\n let distanceTolerance = (PATH_DISTANCE_EPSILON - smoothing) / scale;\n\n distanceTolerance *= distanceTolerance;\n begin(sX, sY, cp1x, cp1y, eX, eY, points, distanceTolerance);\n\n return points;\n}\n\n// //// Based on:\n// //// https://github.com/pelson/antigrain/blob/master/agg-2.4/src/agg_curves.cpp\n\nfunction begin(\n sX: number, sY: number,\n cp1x: number, cp1y: number,\n eX: number, eY: number,\n points: number[],\n distanceTolerance: number\n)\n{\n recursive(points, sX, sY, cp1x, cp1y, eX, eY, distanceTolerance, 0);\n\n points.push(eX, eY);\n}\n\nfunction recursive(\n points: number[],\n x1: number, y1: number,\n x2: number, y2: number,\n x3: number, y3: number,\n distanceTolerance: number,\n level: number\n)\n{\n if (level > RECURSION_LIMIT)\n { return; }\n\n const pi = Math.PI;\n\n // Calculate all the mid-points of the line segments\n // ----------------------\n const x12 = (x1 + x2) / 2;\n const y12 = (y1 + y2) / 2;\n const x23 = (x2 + x3) / 2;\n const y23 = (y2 + y3) / 2;\n const x123 = (x12 + x23) / 2;\n const y123 = (y12 + y23) / 2;\n\n let dx = x3 - x1;\n let dy = y3 - y1;\n const d = Math.abs((((x2 - x3) * dy) - ((y2 - y3) * dx)));\n\n if (d > FLT_EPSILON)\n {\n // Regular care\n // -----------------\n if (d * d <= distanceTolerance * ((dx * dx) + (dy * dy)))\n {\n // If the curvature doesn't exceed the distance_tolerance value\n // we tend to finish subdivisions.\n // ----------------------\n if (mAngleTolerance < curveAngleToleranceEpsilon)\n {\n points.push(x123, y123);\n\n return;\n }\n\n // Angle & Cusp Condition\n // ----------------------\n let da = Math.abs(Math.atan2(y3 - y2, x3 - x2) - Math.atan2(y2 - y1, x2 - x1));\n\n if (da >= pi) da = (2 * pi) - da;\n\n if (da < mAngleTolerance)\n {\n // Finally we can stop the recursion\n // ----------------------\n points.push(x123, y123);\n\n return;\n }\n }\n }\n else\n {\n // Collinear case\n // -----------------\n dx = x123 - ((x1 + x3) / 2);\n dy = y123 - ((y1 + y3) / 2);\n if ((dx * dx) + (dy * dy) <= distanceTolerance)\n {\n points.push(x123, y123);\n\n return;\n }\n }\n\n // Continue subdivision\n // ----------------------\n recursive(points, x1, y1, x12, y12, x123, y123, distanceTolerance, level + 1);\n recursive(points, x123, y123, x23, y23, x3, y3, distanceTolerance, level + 1);\n}\n\n", "/**\n * @param points\n * @param x\n * @param y\n * @param radius\n * @param start\n * @param end\n * @param clockwise\n * @param steps\n * @internal\n */\nexport function buildArc(\n points: number[],\n x: number, y: number,\n radius: number,\n start: number,\n end: number,\n clockwise: boolean,\n steps?: number\n)\n{\n // determine distance between the two angles\n // ...probably a nicer way of writing this\n let dist = Math.abs(start - end);\n\n if (!clockwise && start > end)\n {\n dist = (2 * Math.PI) - dist;\n }\n else if (clockwise && end > start)\n {\n dist = (2 * Math.PI) - dist;\n }\n\n // approximate the # of steps using the cube root of the radius\n\n steps ||= Math.max(6, Math.floor(6 * Math.pow(radius, 1 / 3) * (dist / (Math.PI))));\n\n // ensure we have at least 3 steps..\n steps = Math.max(steps, 3);\n\n let f = dist / (steps);\n let t = start;\n\n // modify direction\n f *= clockwise ? -1 : 1;\n\n for (let i = 0; i < steps + 1; i++)\n {\n const cs = Math.cos(t);\n const sn = Math.sin(t);\n\n const nx = x + (cs * radius);\n const ny = y + (sn * radius);\n\n points.push(nx, ny);\n\n t += f;\n }\n}\n", "import { buildArc } from './buildArc';\n\n/**\n * The arcTo() method creates an arc/curve between two tangents on the canvas.\n *\n * \"borrowed\" from https://code.google.com/p/fxcanvas/ - thanks google!\n * @param points\n * @param x1\n * @param y1\n * @param x2\n * @param y2\n * @param radius\n * @internal\n */\nexport function buildArcTo(\n points: number[],\n x1: number, y1: number,\n x2: number, y2: number,\n radius: number,\n): void\n{\n const fromX = points[points.length - 2];\n const fromY = points[points.length - 1];\n\n const a1 = fromY - y1;\n const b1 = fromX - x1;\n const a2 = y2 - y1;\n const b2 = x2 - x1;\n const mm = Math.abs((a1 * b2) - (b1 * a2));\n\n if (mm < 1.0e-8 || radius === 0)\n {\n if (points[points.length - 2] !== x1 || points[points.length - 1] !== y1)\n {\n points.push(x1, y1);\n }\n\n return;\n }\n\n const dd = (a1 * a1) + (b1 * b1);\n const cc = (a2 * a2) + (b2 * b2);\n const tt = (a1 * a2) + (b1 * b2);\n const k1 = radius * Math.sqrt(dd) / mm;\n const k2 = radius * Math.sqrt(cc) / mm;\n const j1 = k1 * tt / dd;\n const j2 = k2 * tt / cc;\n const cx = (k1 * b2) + (k2 * b1);\n const cy = (k1 * a2) + (k2 * a1);\n const px = b1 * (k2 + j1);\n const py = a1 * (k2 + j1);\n const qx = b2 * (k1 + j2);\n const qy = a2 * (k1 + j2);\n const startAngle = Math.atan2(py - cy, px - cx);\n const endAngle = Math.atan2(qy - cy, qx - cx);\n\n buildArc(points,\n (cx + x1),\n (cy + y1),\n radius,\n startAngle,\n endAngle,\n b1 * a2 > b2 * a1\n );\n}\n", "import { buildAdaptiveBezier } from './buildAdaptiveBezier';\n\nconst TAU = Math.PI * 2;\n\nconst out = {\n centerX: 0,\n centerY: 0,\n ang1: 0,\n ang2: 0\n};\n\nconst mapToEllipse = (\n { x, y }: {x: number, y: number},\n rx: number, ry: number,\n cosPhi: number, sinPhi: number,\n centerX: number, centerY: number,\n out: {x: number, y: number}\n): {x: number, y: number} =>\n{\n x *= rx;\n y *= ry;\n\n const xp = (cosPhi * x) - (sinPhi * y);\n const yp = (sinPhi * x) + (cosPhi * y);\n\n out.x = xp + centerX;\n out.y = yp + centerY;\n\n return out;\n};\n\nfunction approxUnitArc(ang1: number, ang2: number): {x: number, y: number}[]\n{\n // If 90 degree circular arc, use a constant\n // as derived from http://spencermortensen.com/articles/bezier-circle\n\n const a1 = ang2 === -1.5707963267948966 ? -0.551915024494 : 4 / 3 * Math.tan(ang2 / 4);\n\n const a = ang2 === 1.5707963267948966 ? 0.551915024494 : a1;\n\n const x1 = Math.cos(ang1);\n const y1 = Math.sin(ang1);\n const x2 = Math.cos(ang1 + ang2);\n const y2 = Math.sin(ang1 + ang2);\n\n return [\n {\n x: x1 - (y1 * a),\n y: y1 + (x1 * a)\n },\n {\n x: x2 + (y2 * a),\n y: y2 - (x2 * a)\n },\n {\n x: x2,\n y: y2\n }\n ];\n}\n\nconst vectorAngle = (ux: number, uy: number, vx: number, vy: number) =>\n{\n const sign = ((ux * vy) - (uy * vx) < 0) ? -1 : 1;\n\n let dot = (ux * vx) + (uy * vy);\n\n if (dot > 1)\n {\n dot = 1;\n }\n\n if (dot < -1)\n {\n dot = -1;\n }\n\n return sign * Math.acos(dot);\n};\n\nconst getArcCenter = (\n px: number,\n py: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n largeArcFlag: number,\n sweepFlag: number,\n sinPhi: number,\n cosPhi: number,\n pxp: number,\n pyp: number,\n out: {\n centerX: number,\n centerY: number,\n ang1: number,\n ang2: number\n }\n// eslint-disable-next-line max-params\n) =>\n{\n const rxSq = Math.pow(rx, 2);\n const rySq = Math.pow(ry, 2);\n const pxpSq = Math.pow(pxp, 2);\n const pypSq = Math.pow(pyp, 2);\n\n let radicant = (rxSq * rySq) - (rxSq * pypSq) - (rySq * pxpSq);\n\n if (radicant < 0)\n {\n radicant = 0;\n }\n\n radicant /= (rxSq * pypSq) + (rySq * pxpSq);\n radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);\n\n const centerXp = radicant * rx / ry * pyp;\n const centerYp = radicant * -ry / rx * pxp;\n\n const centerX = (cosPhi * centerXp) - (sinPhi * centerYp) + ((px + cx) / 2);\n const centerY = (sinPhi * centerXp) + (cosPhi * centerYp) + ((py + cy) / 2);\n\n const vx1 = (pxp - centerXp) / rx;\n const vy1 = (pyp - centerYp) / ry;\n const vx2 = (-pxp - centerXp) / rx;\n const vy2 = (-pyp - centerYp) / ry;\n\n const ang1 = vectorAngle(1, 0, vx1, vy1);\n let ang2 = vectorAngle(vx1, vy1, vx2, vy2);\n\n if (sweepFlag === 0 && ang2 > 0)\n {\n ang2 -= TAU;\n }\n\n if (sweepFlag === 1 && ang2 < 0)\n {\n ang2 += TAU;\n }\n\n out.centerX = centerX;\n out.centerY = centerY;\n out.ang1 = ang1;\n out.ang2 = ang2;\n};\n\n/**\n * @param points\n * @param px\n * @param py\n * @param cx\n * @param cy\n * @param rx\n * @param ry\n * @param xAxisRotation\n * @param largeArcFlag\n * @param sweepFlag\n * @internal\n */\nexport function buildArcToSvg(\n points: number[],\n px: number,\n py: number,\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n xAxisRotation = 0,\n largeArcFlag = 0,\n sweepFlag = 0\n): void\n{\n if (rx === 0 || ry === 0)\n {\n return;\n }\n\n const sinPhi = Math.sin(xAxisRotation * TAU / 360);\n const cosPhi = Math.cos(xAxisRotation * TAU / 360);\n\n const pxp = (cosPhi * (px - cx) / 2) + (sinPhi * (py - cy) / 2);\n const pyp = (-sinPhi * (px - cx) / 2) + (cosPhi * (py - cy) / 2);\n\n if (pxp === 0 && pyp === 0)\n {\n return;\n }\n\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n\n const lambda = (Math.pow(pxp, 2) / Math.pow(rx, 2)) + (Math.pow(pyp, 2) / Math.pow(ry, 2));\n\n if (lambda > 1)\n {\n rx *= Math.sqrt(lambda);\n ry *= Math.sqrt(lambda);\n }\n\n getArcCenter(\n px,\n py,\n cx,\n cy,\n rx,\n ry,\n largeArcFlag,\n sweepFlag,\n sinPhi,\n cosPhi,\n pxp,\n pyp,\n out\n );\n\n let { ang1, ang2 } = out;\n const { centerX, centerY } = out;\n\n // If 'ang2' == 90.0000000001, then `ratio` will devalue to\n // 1.0000000001. This causes `segments` to be greater than one, which is an\n // unnecessary split, and adds extra points to the bezier curve. To alleviate\n // this issue, we round to 1.0 when the ratio is close to 1.0.\n let ratio = Math.abs(ang2) / (TAU / 4);\n\n if (Math.abs(1.0 - ratio) < 0.0000001)\n {\n ratio = 1.0;\n }\n\n const segments = Math.max(Math.ceil(ratio), 1);\n\n ang2 /= segments;\n\n let lastX = points[points.length - 2];\n let lastY = points[points.length - 1];\n\n const outCurvePoint = { x: 0, y: 0 };\n\n for (let i = 0; i < segments; i++)\n {\n const curve = approxUnitArc(ang1, ang2);\n\n const { x: x1, y: y1 } = mapToEllipse(curve[0], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);\n const { x: x2, y: y2 } = mapToEllipse(curve[1], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);\n const { x, y } = mapToEllipse(curve[2], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);\n\n buildAdaptiveBezier(\n points,\n lastX, lastY,\n x1, y1, x2, y2, x, y\n );\n\n lastX = x;\n lastY = y;\n\n ang1 += ang2;\n }\n}\n", "import type { PointData } from '../../../../maths/point/PointData';\nimport type { ShapePath } from './ShapePath';\n\n/**\n * Typed and cleaned up version of:\n * https://stackoverflow.com/questions/44855794/html5-canvas-triangle-with-rounded-corners/44856925#44856925\n * @param g - Graphics to be drawn on.\n * @param points - Corners of the shape to draw. Minimum length is 3.\n * @param radius - Corners default radius.\n * @ignore\n */\nexport function roundedShapeArc(\n g: ShapePath,\n points: RoundedPoint[],\n radius: number\n): void\n{\n const vecFrom = (p: PointData, pp: PointData) =>\n {\n const x = pp.x - p.x;\n const y = pp.y - p.y;\n const len = Math.sqrt((x * x) + (y * y));\n const nx = x / len;\n const ny = y / len;\n\n return { len, nx, ny };\n };\n\n const sharpCorner = (i: number, p: PointData) =>\n {\n if (i === 0)\n {\n g.moveTo(p.x, p.y);\n }\n else\n {\n g.lineTo(p.x, p.y);\n }\n };\n\n let p1 = points[points.length - 1];\n\n for (let i = 0; i < points.length; i++)\n {\n const p2 = points[i % points.length];\n const pRadius = p2.radius ?? radius;\n\n if (pRadius <= 0)\n {\n sharpCorner(i, p2);\n p1 = p2;\n continue;\n }\n\n const p3 = points[(i + 1) % points.length];\n const v1 = vecFrom(p2, p1);\n const v2 = vecFrom(p2, p3);\n\n if (v1.len < 1e-4 || v2.len < 1e-4)\n {\n sharpCorner(i, p2);\n p1 = p2;\n continue;\n }\n\n let angle = Math.asin((v1.nx * v2.ny) - (v1.ny * v2.nx));\n let radDirection = 1;\n let drawDirection = false;\n\n if ((v1.nx * v2.nx) - (v1.ny * -v2.ny) < 0)\n {\n if (angle < 0)\n {\n angle = Math.PI + angle;\n }\n else\n {\n angle = Math.PI - angle;\n radDirection = -1;\n drawDirection = true;\n }\n }\n else if (angle > 0)\n {\n radDirection = -1;\n drawDirection = true;\n }\n\n const halfAngle = angle / 2;\n\n let cRadius: number;\n let lenOut = Math.abs(\n (Math.cos(halfAngle) * pRadius) / Math.sin(halfAngle)\n );\n\n if (lenOut > Math.min(v1.len / 2, v2.len / 2))\n {\n lenOut = Math.min(v1.len / 2, v2.len / 2);\n cRadius = Math.abs((lenOut * Math.sin(halfAngle)) / Math.cos(halfAngle));\n }\n else\n {\n cRadius = pRadius;\n }\n\n const cX = p2.x + (v2.nx * lenOut) + (-v2.ny * cRadius * radDirection);\n const cY = p2.y + (v2.ny * lenOut) + (v2.nx * cRadius * radDirection);\n const startAngle = Math.atan2(v1.ny, v1.nx) + ((Math.PI / 2) * radDirection);\n const endAngle = Math.atan2(v2.ny, v2.nx) - ((Math.PI / 2) * radDirection);\n\n if (i === 0)\n {\n g.moveTo(\n cX + (Math.cos(startAngle) * cRadius),\n cY + (Math.sin(startAngle) * cRadius)\n );\n }\n\n g.arc(cX, cY, cRadius, startAngle, endAngle, drawDirection);\n\n p1 = p2;\n }\n}\n\n/**\n * Data structure for points with optional radius.\n * @category scene\n * @standard\n */\nexport type RoundedPoint = PointData & { radius?: number };\n\n/**\n * Typed and cleaned up version of:\n * https://stackoverflow.com/questions/44855794/html5-canvas-triangle-with-rounded-corners/56214413#56214413\n * @param g - Graphics to be drawn on.\n * @param points - Corners of the shape to draw. Minimum length is 3.\n * @param radius - Corners default radius.\n * @ignore\n */\nexport function roundedShapeQuadraticCurve(\n g: ShapePath,\n points: RoundedPoint[],\n radius: number,\n smoothness?: number,\n): void\n{\n const distance = (p1: PointData, p2: PointData) =>\n Math.sqrt(((p1.x - p2.x) ** 2) + ((p1.y - p2.y) ** 2));\n\n const pointLerp = (p1: PointData, p2: PointData, t: number) => ({\n x: p1.x + ((p2.x - p1.x) * t),\n y: p1.y + ((p2.y - p1.y) * t),\n });\n\n const numPoints = points.length;\n\n for (let i = 0; i < numPoints; i++)\n {\n const thisPoint = points[(i + 1) % numPoints];\n const pRadius = thisPoint.radius ?? radius;\n\n if (pRadius <= 0)\n {\n if (i === 0)\n {\n g.moveTo(thisPoint.x, thisPoint.y);\n }\n else\n {\n g.lineTo(thisPoint.x, thisPoint.y);\n }\n\n continue;\n }\n\n const lastPoint = points[i];\n const nextPoint = points[(i + 2) % numPoints];\n\n const lastEdgeLength = distance(lastPoint, thisPoint);\n let start;\n\n if (lastEdgeLength < 1e-4)\n {\n start = thisPoint;\n }\n else\n {\n const lastOffsetDistance = Math.min(lastEdgeLength / 2, pRadius);\n\n start = pointLerp(\n thisPoint,\n lastPoint,\n lastOffsetDistance / lastEdgeLength\n );\n }\n\n const nextEdgeLength = distance(nextPoint, thisPoint);\n let end;\n\n if (nextEdgeLength < 1e-4)\n {\n end = thisPoint;\n }\n else\n {\n const nextOffsetDistance = Math.min(nextEdgeLength / 2, pRadius);\n\n end = pointLerp(\n thisPoint,\n nextPoint,\n nextOffsetDistance / nextEdgeLength\n );\n }\n\n if (i === 0)\n {\n g.moveTo(start.x, start.y);\n }\n else\n {\n g.lineTo(start.x, start.y);\n }\n g.quadraticCurveTo(thisPoint.x, thisPoint.y, end.x, end.y, smoothness);\n }\n}\n", "// a shape lets you build out a shape with lines and curves and primitives..\n\nimport { Circle } from '../../../../maths/shapes/Circle';\nimport { Ellipse } from '../../../../maths/shapes/Ellipse';\nimport { Polygon } from '../../../../maths/shapes/Polygon';\nimport { Rectangle } from '../../../../maths/shapes/Rectangle';\nimport { RoundedRectangle } from '../../../../maths/shapes/RoundedRectangle';\nimport { Bounds } from '../../../container/bounds/Bounds';\nimport { buildAdaptiveBezier } from '../buildCommands/buildAdaptiveBezier';\nimport { buildAdaptiveQuadratic } from '../buildCommands/buildAdaptiveQuadratic';\nimport { buildArc } from '../buildCommands/buildArc';\nimport { buildArcTo } from '../buildCommands/buildArcTo';\nimport { buildArcToSvg } from '../buildCommands/buildArcToSvg';\nimport { roundedShapeArc, roundedShapeQuadraticCurve } from './roundShape';\n\nimport type { Matrix } from '../../../../maths/matrix/Matrix';\nimport type { PointData } from '../../../../maths/point/PointData';\nimport type { ShapePrimitive } from '../../../../maths/shapes/ShapePrimitive';\nimport type { GraphicsPath } from './GraphicsPath';\nimport type { RoundedPoint } from './roundShape';\n\nconst tempRectangle = new Rectangle();\n\n/**\n * A type representing a shape primitive with optional transformation and holes.\n * @category scene\n * @advanced\n */\nexport type ShapePrimitiveWithHoles = {\n shape: ShapePrimitive,\n transform?: Matrix,\n holes?: ShapePrimitiveWithHoles[]\n};\n\n/**\n * The `ShapePath` class acts as a bridge between high-level drawing commands\n * and the lower-level `GraphicsContext` rendering engine.\n * It translates drawing commands, such as those for creating lines, arcs, ellipses, rectangles, and complex polygons, into a\n * format that can be efficiently processed by a `GraphicsContext`. This includes handling path starts,\n * ends, and transformations for shapes.\n *\n * It is used internally by `GraphicsPath` to build up the path.\n * @category scene\n * @advanced\n */\nexport class ShapePath\n{\n /** The list of shape primitives that make up the path. */\n public shapePrimitives: ShapePrimitiveWithHoles[] = [];\n private _currentPoly: Polygon | null = null;\n private readonly _graphicsPath2D: GraphicsPath;\n private readonly _bounds = new Bounds();\n public readonly signed: boolean;\n\n constructor(graphicsPath2D: GraphicsPath)\n {\n this._graphicsPath2D = graphicsPath2D;\n this.signed = graphicsPath2D.checkForHoles;\n }\n\n /**\n * Sets the starting point for a new sub-path. Any subsequent drawing commands are considered part of this path.\n * @param x - The x-coordinate for the starting point.\n * @param y - The y-coordinate for the starting point.\n * @returns The instance of the current object for chaining.\n */\n public moveTo(x: number, y: number): this\n {\n this.startPoly(x, y);\n\n return this;\n }\n\n /**\n * Connects the current point to a new point with a straight line. This method updates the current path.\n * @param x - The x-coordinate of the new point to connect to.\n * @param y - The y-coordinate of the new point to connect to.\n * @returns The instance of the current object for chaining.\n */\n public lineTo(x: number, y: number): this\n {\n this._ensurePoly();\n\n const points = this._currentPoly.points;\n\n const fromX = points[points.length - 2];\n const fromY = points[points.length - 1];\n\n if (fromX !== x || fromY !== y)\n {\n points.push(x, y);\n }\n\n return this;\n }\n\n /**\n * Adds an arc to the path. The arc is centered at (x, y)\n * position with radius `radius` starting at `startAngle` and ending at `endAngle`.\n * @param x - The x-coordinate of the arc's center.\n * @param y - The y-coordinate of the arc's center.\n * @param radius - The radius of the arc.\n * @param startAngle - The starting angle of the arc, in radians.\n * @param endAngle - The ending angle of the arc, in radians.\n * @param counterclockwise - Specifies whether the arc should be drawn in the anticlockwise direction. False by default.\n * @returns The instance of the current object for chaining.\n */\n public arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise: boolean): this\n {\n // TODO - if its 360 degrees.. make it a circle object?\n\n this._ensurePoly(false);\n\n const points = this._currentPoly.points;\n\n buildArc(points, x, y, radius, startAngle, endAngle, counterclockwise);\n\n return this;\n }\n\n /**\n * Adds an arc to the path with the arc tangent to the line joining two specified points.\n * The arc radius is specified by `radius`.\n * @param x1 - The x-coordinate of the first point.\n * @param y1 - The y-coordinate of the first point.\n * @param x2 - The x-coordinate of the second point.\n * @param y2 - The y-coordinate of the second point.\n * @param radius - The radius of the arc.\n * @returns The instance of the current object for chaining.\n */\n public arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): this\n {\n this._ensurePoly();\n\n const points = this._currentPoly.points;\n\n buildArcTo(points, x1, y1, x2, y2, radius);\n\n return this;\n }\n\n /**\n * Adds an SVG-style arc to the path, allowing for elliptical arcs based on the SVG spec.\n * @param rx - The x-radius of the ellipse.\n * @param ry - The y-radius of the ellipse.\n * @param xAxisRotation - The rotation of the ellipse's x-axis relative\n * to the x-axis of the coordinate system, in degrees.\n * @param largeArcFlag - Determines if the arc should be greater than or less than 180 degrees.\n * @param sweepFlag - Determines if the arc should be swept in a positive angle direction.\n * @param x - The x-coordinate of the arc's end point.\n * @param y - The y-coordinate of the arc's end point.\n * @returns The instance of the current object for chaining.\n */\n public arcToSvg(\n rx: number, ry: number,\n xAxisRotation: number, largeArcFlag: number, sweepFlag: number,\n x: number, y: number\n ): this\n {\n const points = this._currentPoly.points;\n\n // this needs to work on both canvas and GPU backends so might want to move this to the Graphics2D path..\n buildArcToSvg(\n points,\n this._currentPoly.lastX,\n this._currentPoly.lastY,\n x,\n y,\n rx,\n ry,\n xAxisRotation,\n largeArcFlag,\n sweepFlag,\n );\n\n return this;\n }\n\n /**\n * Adds a cubic Bezier curve to the path.\n * It requires three points: the first two are control points and the third one is the end point.\n * The starting point is the last point in the current path.\n * @param cp1x - The x-coordinate of the first control point.\n * @param cp1y - The y-coordinate of the first control point.\n * @param cp2x - The x-coordinate of the second control point.\n * @param cp2y - The y-coordinate of the second control point.\n * @param x - The x-coordinate of the end point.\n * @param y - The y-coordinate of the end point.\n * @param smoothness - Optional parameter to adjust the smoothness of the curve.\n * @returns The instance of the current object for chaining.\n */\n public bezierCurveTo(\n cp1x: number, cp1y: number, cp2x: number, cp2y: number,\n x: number, y: number,\n smoothness?: number\n ): this\n {\n this._ensurePoly();\n\n const currentPoly = this._currentPoly;\n\n // ensure distance from last point to first control point is not too small\n\n // TODO - make this a plugin that people can override..\n buildAdaptiveBezier(\n this._currentPoly.points,\n currentPoly.lastX, currentPoly.lastY,\n cp1x, cp1y, cp2x, cp2y, x, y,\n smoothness,\n );\n\n return this;\n }\n\n /**\n * Adds a quadratic curve to the path. It requires two points: the control point and the end point.\n * The starting point is the last point in the current path.\n * @param cp1x - The x-coordinate of the control point.\n * @param cp1y - The y-coordinate of the control point.\n * @param x - The x-coordinate of the end point.\n * @param y - The y-coordinate of the end point.\n * @param smoothing - Optional parameter to adjust the smoothness of the curve.\n * @returns The instance of the current object for chaining.\n */\n public quadraticCurveTo(cp1x: number, cp1y: number, x: number, y: number, smoothing?: number): this\n {\n this._ensurePoly();\n\n const currentPoly = this._currentPoly;\n\n // ensure distance from last point to first control point is not too small\n\n // TODO - make this a plugin that people can override..\n buildAdaptiveQuadratic(\n this._currentPoly.points,\n currentPoly.lastX, currentPoly.lastY,\n cp1x, cp1y, x, y,\n smoothing,\n );\n\n return this;\n }\n\n /**\n * Closes the current path by drawing a straight line back to the start.\n * If the shape is already closed or there are no points in the path, this method does nothing.\n * @returns The instance of the current object for chaining.\n */\n public closePath(): this\n {\n this.endPoly(true);\n\n return this;\n }\n\n /**\n * Adds another path to the current path. This method allows for the combination of multiple paths into one.\n * @param path - The `GraphicsPath` object representing the path to add.\n * @param transform - An optional `Matrix` object to apply a transformation to the path before adding it.\n * @returns The instance of the current object for chaining.\n */\n public addPath(path: GraphicsPath, transform?: Matrix): this\n {\n this.endPoly();\n\n // Only clone if we need to transform\n if (transform && !transform.isIdentity())\n {\n path = path.clone(true);\n path.transform(transform);\n }\n\n const shapePrimitives = this.shapePrimitives;\n const start = shapePrimitives.length;\n\n for (let i = 0; i < path.instructions.length; i++)\n {\n const instruction = path.instructions[i];\n\n this[instruction.action](...(instruction.data as [never, never, never, never, never, never, never]));\n }\n\n // This section processes holes in polygons by checking if any polygon is contained within another.\n // If a polygon is found to be inside another polygon (mainShape), it's treated as a hole.\n // The hole polygon is removed from the main shapePrimitives array and added to the holes array\n // of the containing polygon. This allows for proper rendering of shapes with holes.\n if (path.checkForHoles && shapePrimitives.length - start > 1)\n {\n let mainShape = null;\n\n // Process in place instead of creating a removal array\n for (let i = start; i < shapePrimitives.length; i++)\n {\n const shapePrimitive = shapePrimitives[i];\n\n if (shapePrimitive.shape.type === 'polygon')\n {\n const polygon = shapePrimitive.shape as Polygon;\n const mainPolygon = mainShape?.shape as Polygon;\n\n if (mainPolygon && mainPolygon.containsPolygon(polygon))\n {\n // Initialize holes array only when needed\n mainShape.holes ||= [];\n mainShape.holes.push(shapePrimitive);\n\n // Remove the hole by moving elements left\n shapePrimitives.copyWithin(i, i + 1);\n shapePrimitives.length--;\n i--;\n }\n else\n {\n mainShape = shapePrimitive;\n }\n }\n }\n }\n\n return this;\n }\n\n /**\n * Finalizes the drawing of the current path. Optionally, it can close the path.\n * @param closePath - A boolean indicating whether to close the path after finishing. False by default.\n */\n public finish(closePath = false)\n {\n this.endPoly(closePath);\n }\n\n /**\n * Draws a rectangle shape. This method adds a new rectangle path to the current drawing.\n * @param x - The x-coordinate of the top-left corner of the rectangle.\n * @param y - The y-coordinate of the top-left corner of the rectangle.\n * @param w - The width of the rectangle.\n * @param h - The height of the rectangle.\n * @param transform - An optional `Matrix` object to apply a transformation to the rectangle.\n * @returns The instance of the current object for chaining.\n */\n public rect(x: number, y: number, w: number, h: number, transform?: Matrix): this\n {\n this.drawShape(new Rectangle(x, y, w, h), transform);\n\n return this;\n }\n\n /**\n * Draws a circle shape. This method adds a new circle path to the current drawing.\n * @param x - The x-coordinate of the center of the circle.\n * @param y - The y-coordinate of the center of the circle.\n * @param radius - The radius of the circle.\n * @param transform - An optional `Matrix` object to apply a transformation to the circle.\n * @returns The instance of the current object for chaining.\n */\n public circle(x: number, y: number, radius: number, transform?: Matrix): this\n {\n this.drawShape(new Circle(x, y, radius), transform);\n\n return this;\n }\n\n /**\n * Draws a polygon shape. This method allows for the creation of complex polygons by specifying a sequence of points.\n * @param points - An array of numbers, or or an array of PointData objects eg [{x,y}, {x,y}, {x,y}]\n * representing the x and y coordinates of the polygon's vertices, in sequence.\n * @param close - A boolean indicating whether to close the polygon path. True by default.\n * @param transform - An optional `Matrix` object to apply a transformation to the polygon.\n * @returns The instance of the current object for chaining.\n */\n public poly(points: number[] | PointData[], close?: boolean, transform?: Matrix): this\n {\n const polygon = new Polygon(points);\n\n polygon.closePath = close;\n\n this.drawShape(polygon, transform);\n\n return this;\n }\n\n /**\n * Draws a regular polygon with a specified number of sides. All sides and angles are equal.\n * @param x - The x-coordinate of the center of the polygon.\n * @param y - The y-coordinate of the center of the polygon.\n * @param radius - The radius of the circumscribed circle of the polygon.\n * @param sides - The number of sides of the polygon. Must be 3 or more.\n * @param rotation - The rotation angle of the polygon, in radians. Zero by default.\n * @param transform - An optional `Matrix` object to apply a transformation to the polygon.\n * @returns The instance of the current object for chaining.\n */\n public regularPoly(x: number, y: number, radius: number, sides: number, rotation = 0, transform?: Matrix): this\n {\n sides = Math.max(sides | 0, 3);\n const startAngle = (-1 * Math.PI / 2) + rotation;\n const delta = (Math.PI * 2) / sides;\n const polygon = [];\n\n for (let i = 0; i < sides; i++)\n {\n const angle = startAngle - (i * delta);\n\n polygon.push(\n x + (radius * Math.cos(angle)),\n y + (radius * Math.sin(angle))\n );\n }\n\n this.poly(polygon, true, transform);\n\n return this;\n }\n\n /**\n * Draws a polygon with rounded corners.\n * Similar to `regularPoly` but with the ability to round the corners of the polygon.\n * @param x - The x-coordinate of the center of the polygon.\n * @param y - The y-coordinate of the center of the polygon.\n * @param radius - The radius of the circumscribed circle of the polygon.\n * @param sides - The number of sides of the polygon. Must be 3 or more.\n * @param corner - The radius of the rounding of the corners.\n * @param rotation - The rotation angle of the polygon, in radians. Zero by default.\n * @param smoothness - Optional parameter to adjust the smoothness of the rounding.\n * @returns The instance of the current object for chaining.\n */\n public roundPoly(\n x: number, y: number,\n radius: number,\n sides: number, corner: number,\n rotation = 0,\n smoothness?: number,\n ): this\n {\n sides = Math.max((sides | 0), 3);\n\n if (corner <= 0)\n {\n return this.regularPoly(x, y, radius, sides, rotation);\n }\n\n const sideLength = (radius * Math.sin(Math.PI / sides)) - 0.001;\n\n corner = Math.min(corner, sideLength);\n\n const startAngle = (-1 * Math.PI / 2) + rotation;\n const delta = (Math.PI * 2) / sides;\n const internalAngle = ((sides - 2) * Math.PI) / sides / 2;\n\n for (let i = 0; i < sides; i++)\n {\n const angle = (i * delta) + startAngle;\n const x0 = x + (radius * Math.cos(angle));\n const y0 = y + (radius * Math.sin(angle));\n const a1 = angle + (Math.PI) + internalAngle;\n const a2 = angle - (Math.PI) - internalAngle;\n const x1 = x0 + (corner * Math.cos(a1));\n const y1 = y0 + (corner * Math.sin(a1));\n const x3 = x0 + (corner * Math.cos(a2));\n const y3 = y0 + (corner * Math.sin(a2));\n\n if (i === 0)\n {\n this.moveTo(x1, y1);\n }\n else\n {\n this.lineTo(x1, y1);\n }\n this.quadraticCurveTo(x0, y0, x3, y3, smoothness);\n }\n\n return this.closePath();\n }\n\n /**\n * Draws a shape with rounded corners. This function supports custom radius for each corner of the shape.\n * Optionally, corners can be rounded using a quadratic curve instead of an arc, providing a different aesthetic.\n * @param points - An array of `RoundedPoint` representing the corners of the shape to draw.\n * A minimum of 3 points is required.\n * @param radius - The default radius for the corners.\n * This radius is applied to all corners unless overridden in `points`.\n * @param useQuadratic - If set to true, rounded corners are drawn using a quadraticCurve\n * method instead of an arc method. Defaults to false.\n * @param smoothness - Specifies the smoothness of the curve when `useQuadratic` is true.\n * Higher values make the curve smoother.\n * @returns The instance of the current object for chaining.\n */\n public roundShape(points: RoundedPoint[], radius: number, useQuadratic = false, smoothness?: number): this\n {\n if (points.length < 3)\n {\n return this;\n }\n\n if (useQuadratic)\n {\n roundedShapeQuadraticCurve(this, points, radius, smoothness);\n }\n else\n {\n roundedShapeArc(this, points, radius);\n }\n\n return this.closePath();\n }\n\n /**\n * Draw Rectangle with fillet corners. This is much like rounded rectangle\n * however it support negative numbers as well for the corner radius.\n * @param x - Upper left corner of rect\n * @param y - Upper right corner of rect\n * @param width - Width of rect\n * @param height - Height of rect\n * @param fillet - accept negative or positive values\n */\n public filletRect(x: number, y: number, width: number, height: number, fillet: number): this\n {\n if (fillet === 0)\n {\n return this.rect(x, y, width, height);\n }\n\n const maxFillet = Math.min(width, height) / 2;\n const inset = Math.min(maxFillet, Math.max(-maxFillet, fillet));\n const right = x + width;\n const bottom = y + height;\n const dir = inset < 0 ? -inset : 0;\n const size = Math.abs(inset);\n\n return this\n .moveTo(x, y + size)\n .arcTo(x + dir, y + dir, x + size, y, size)\n .lineTo(right - size, y)\n .arcTo(right - dir, y + dir, right, y + size, size)\n .lineTo(right, bottom - size)\n .arcTo(right - dir, bottom - dir, x + width - size, bottom, size)\n .lineTo(x + size, bottom)\n .arcTo(x + dir, bottom - dir, x, bottom - size, size)\n .closePath();\n }\n\n /**\n * Draw Rectangle with chamfer corners. These are angled corners.\n * @param x - Upper left corner of rect\n * @param y - Upper right corner of rect\n * @param width - Width of rect\n * @param height - Height of rect\n * @param chamfer - non-zero real number, size of corner cutout\n * @param transform\n */\n public chamferRect(x: number, y: number, width: number, height: number, chamfer: number, transform?: Matrix): this\n {\n if (chamfer <= 0)\n {\n return this.rect(x, y, width, height);\n }\n\n const inset = Math.min(chamfer, Math.min(width, height) / 2);\n const right = x + width;\n const bottom = y + height;\n const points = [\n x + inset, y,\n right - inset, y,\n right, y + inset,\n right, bottom - inset,\n right - inset, bottom,\n x + inset, bottom,\n x, bottom - inset,\n x, y + inset,\n ];\n\n // Remove overlapping points\n for (let i = points.length - 1; i >= 2; i -= 2)\n {\n if (points[i] === points[i - 2] && points[i - 1] === points[i - 3])\n {\n points.splice(i - 1, 2);\n }\n }\n\n return this.poly(points, true, transform);\n }\n\n /**\n * Draws an ellipse at the specified location and with the given x and y radii.\n * An optional transformation can be applied, allowing for rotation, scaling, and translation.\n * @param x - The x-coordinate of the center of the ellipse.\n * @param y - The y-coordinate of the center of the ellipse.\n * @param radiusX - The horizontal radius of the ellipse.\n * @param radiusY - The vertical radius of the ellipse.\n * @param transform - An optional `Matrix` object to apply a transformation to the ellipse. This can include rotations.\n * @returns The instance of the current object for chaining.\n */\n public ellipse(x: number, y: number, radiusX: number, radiusY: number, transform?: Matrix): this\n {\n // TODO apply rotation to transform...\n\n this.drawShape(new Ellipse(x, y, radiusX, radiusY), transform);\n\n return this;\n }\n\n /**\n * Draws a rectangle with rounded corners.\n * The corner radius can be specified to determine how rounded the corners should be.\n * An optional transformation can be applied, which allows for rotation, scaling, and translation of the rectangle.\n * @param x - The x-coordinate of the top-left corner of the rectangle.\n * @param y - The y-coordinate of the top-left corner of the rectangle.\n * @param w - The width of the rectangle.\n * @param h - The height of the rectangle.\n * @param radius - The radius of the rectangle's corners. If not specified, corners will be sharp.\n * @param transform - An optional `Matrix` object to apply a transformation to the rectangle.\n * @returns The instance of the current object for chaining.\n */\n public roundRect(x: number, y: number, w: number, h: number, radius?: number, transform?: Matrix): this\n {\n this.drawShape(new RoundedRectangle(x, y, w, h, radius), transform);\n\n return this;\n }\n\n /**\n * Draws a given shape on the canvas.\n * This is a generic method that can draw any type of shape specified by the `ShapePrimitive` parameter.\n * An optional transformation matrix can be applied to the shape, allowing for complex transformations.\n * @param shape - The shape to draw, defined as a `ShapePrimitive` object.\n * @param matrix - An optional `Matrix` for transforming the shape. This can include rotations,\n * scaling, and translations.\n * @returns The instance of the current object for chaining.\n */\n public drawShape(shape: ShapePrimitive, matrix?: Matrix): this\n {\n this.endPoly();\n\n this.shapePrimitives.push({ shape, transform: matrix });\n\n return this;\n }\n\n /**\n * Starts a new polygon path from the specified starting point.\n * This method initializes a new polygon or ends the current one if it exists.\n * @param x - The x-coordinate of the starting point of the new polygon.\n * @param y - The y-coordinate of the starting point of the new polygon.\n * @returns The instance of the current object for chaining.\n */\n public startPoly(x: number, y: number): this\n {\n let currentPoly = this._currentPoly;\n\n if (currentPoly)\n {\n this.endPoly();\n }\n\n currentPoly = new Polygon();\n\n currentPoly.points.push(x, y);\n\n this._currentPoly = currentPoly;\n\n return this;\n }\n\n /**\n * Ends the current polygon path. If `closePath` is set to true,\n * the path is closed by connecting the last point to the first one.\n * This method finalizes the current polygon and prepares it for drawing or adding to the shape primitives.\n * @param closePath - A boolean indicating whether to close the polygon by connecting the last point\n * back to the starting point. False by default.\n * @returns The instance of the current object for chaining.\n */\n public endPoly(closePath = false): this\n {\n const shape = this._currentPoly;\n\n if (shape && shape.points.length > 2)\n {\n shape.closePath = closePath;\n\n this.shapePrimitives.push({ shape });\n }\n\n this._currentPoly = null;\n\n return this;\n }\n\n private _ensurePoly(start = true): void\n {\n if (this._currentPoly) return;\n\n this._currentPoly = new Polygon();\n\n if (start)\n {\n // get last points..\n const lastShape = this.shapePrimitives[this.shapePrimitives.length - 1];\n\n if (lastShape)\n {\n // i KNOW its a rect..\n let lx = lastShape.shape.x;\n let ly = lastShape.shape.y;\n\n if (lastShape.transform && !lastShape.transform.isIdentity())\n {\n const t = lastShape.transform;\n\n const tempX = lx;\n\n lx = (t.a * lx) + (t.c * ly) + t.tx;\n ly = (t.b * tempX) + (t.d * ly) + t.ty;\n }\n\n this._currentPoly.points.push(lx, ly);\n }\n else\n {\n this._currentPoly.points.push(0, 0);\n }\n }\n }\n\n /** Builds the path. */\n public buildPath()\n {\n const path = this._graphicsPath2D;\n\n this.shapePrimitives.length = 0;\n this._currentPoly = null;\n\n for (let i = 0; i < path.instructions.length; i++)\n {\n const instruction = path.instructions[i];\n\n // Sorry TS! this is the best we could do...\n this[instruction.action](...(instruction.data as [never, never, never, never, never, never, never]));\n }\n\n this.finish();\n }\n\n /** Gets the bounds of the path. */\n get bounds(): Bounds\n {\n const bounds = this._bounds;\n\n bounds.clear();\n\n const shapePrimitives = this.shapePrimitives;\n\n for (let i = 0; i < shapePrimitives.length; i++)\n {\n const shapePrimitive = shapePrimitives[i];\n\n const boundsRect = shapePrimitive.shape.getBounds(tempRectangle);\n\n if (shapePrimitive.transform)\n {\n bounds.addRect(boundsRect, shapePrimitive.transform);\n }\n else\n {\n bounds.addRect(boundsRect);\n }\n }\n\n return bounds;\n }\n}\n", "import { Point } from '../../../../maths/point/Point';\nimport { uid } from '../../../../utils/data/uid';\nimport { warn } from '../../../../utils/logging/warn';\nimport { parseSVGPath } from '../svg/parseSVGPath';\nimport { ShapePath } from './ShapePath';\n\nimport type { Matrix } from '../../../../maths/matrix/Matrix';\nimport type { PointData } from '../../../../maths/point/PointData';\nimport type { Bounds } from '../../../container/bounds/Bounds';\nimport type { RoundedPoint } from './roundShape';\n\n/**\n * Represents a single drawing instruction in a `GraphicsPath`.\n * Each instruction consists of an action type and associated data.\n * @category scene\n * @advanced\n */\nexport interface PathInstruction\n{\n action: 'moveTo' | 'lineTo' | 'quadraticCurveTo' |\n 'bezierCurveTo' | 'arc' | 'closePath' |\n 'addPath' | 'arcTo' | 'ellipse' |\n 'rect' | 'roundRect' | 'arcToSvg' |\n 'poly' | 'circle' |\n 'regularPoly' | 'roundPoly' | 'roundShape' | 'filletRect' | 'chamferRect'\n data: any[];\n}\n\n/**\n * The `GraphicsPath` class is designed to represent a graphical path consisting of multiple drawing instructions.\n * This class serves as a collection of drawing commands that can be executed to render shapes and paths on a canvas or\n * similar graphical context. It supports high-level drawing operations like lines, arcs, curves, and more, enabling\n * complex graphic constructions with relative ease.\n * @category scene\n * @advanced\n */\nexport class GraphicsPath\n{\n public instructions: PathInstruction[] = [];\n\n /** unique id for this graphics path */\n public readonly uid: number = uid('graphicsPath');\n\n private _dirty = true;\n // needed for hit testing and bounds calculations\n private _shapePath: ShapePath;\n\n /**\n * Controls whether shapes in this path should be checked for holes using the non-zero fill rule.\n * When true, any closed shape that is fully contained within another shape will become\n * a hole in that shape during filling operations.\n *\n * This follows SVG's non-zero fill rule where:\n * 1. Shapes are analyzed to find containment relationships\n * 2. If Shape B is fully contained within Shape A, Shape B becomes a hole in Shape A\n * 3. Multiple nested holes are supported\n *\n * Mainly used internally by the SVG parser to correctly handle holes in complex paths.\n * When false, all shapes are filled independently without checking for holes.\n */\n public checkForHoles: boolean;\n\n /**\n * Provides access to the internal shape path, ensuring it is up-to-date with the current instructions.\n * @returns The `ShapePath` instance associated with this `GraphicsPath`.\n */\n get shapePath(): ShapePath\n {\n if (!this._shapePath)\n {\n this._shapePath = new ShapePath(this);\n }\n\n if (this._dirty)\n {\n this._dirty = false;\n this._shapePath.buildPath();\n }\n\n return this._shapePath;\n }\n\n /**\n * Creates a `GraphicsPath` instance optionally from an SVG path string or an array of `PathInstruction`.\n * @param instructions - An SVG path string or an array of `PathInstruction` objects.\n * @param signed\n */\n constructor(instructions?: string | PathInstruction[], signed = false)\n {\n this.checkForHoles = signed;\n\n if (typeof instructions === 'string')\n {\n parseSVGPath(instructions, this);\n }\n else\n {\n this.instructions = instructions?.slice() ?? [];\n }\n }\n\n /**\n * Adds another `GraphicsPath` to this path, optionally applying a transformation.\n * @param path - The `GraphicsPath` to add.\n * @param transform - An optional transformation to apply to the added path.\n * @returns The instance of the current object for chaining.\n */\n public addPath(path: GraphicsPath, transform?: Matrix): this\n {\n path = path.clone();\n this.instructions.push({ action: 'addPath', data: [path, transform] });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Adds an arc to the path. The arc is centered at (x, y)\n * position with radius `radius` starting at `startAngle` and ending at `endAngle`.\n * @param x - The x-coordinate of the arc's center.\n * @param y - The y-coordinate of the arc's center.\n * @param radius - The radius of the arc.\n * @param startAngle - The starting angle of the arc, in radians.\n * @param endAngle - The ending angle of the arc, in radians.\n * @param counterclockwise - Specifies whether the arc should be drawn in the anticlockwise direction. False by default.\n * @returns The instance of the current object for chaining.\n */\n public arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;\n public arc(...args: [number, number, number, number, number, boolean]): this\n {\n this.instructions.push({ action: 'arc', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Adds an arc to the path with the arc tangent to the line joining two specified points.\n * The arc radius is specified by `radius`.\n * @param x1 - The x-coordinate of the first point.\n * @param y1 - The y-coordinate of the first point.\n * @param x2 - The x-coordinate of the second point.\n * @param y2 - The y-coordinate of the second point.\n * @param radius - The radius of the arc.\n * @returns The instance of the current object for chaining.\n */\n public arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): this;\n public arcTo(...args: [number, number, number, number, number]): this\n {\n this.instructions.push({ action: 'arcTo', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Adds an SVG-style arc to the path, allowing for elliptical arcs based on the SVG spec.\n * @param rx - The x-radius of the ellipse.\n * @param ry - The y-radius of the ellipse.\n * @param xAxisRotation - The rotation of the ellipse's x-axis relative\n * to the x-axis of the coordinate system, in degrees.\n * @param largeArcFlag - Determines if the arc should be greater than or less than 180 degrees.\n * @param sweepFlag - Determines if the arc should be swept in a positive angle direction.\n * @param x - The x-coordinate of the arc's end point.\n * @param y - The y-coordinate of the arc's end point.\n * @returns The instance of the current object for chaining.\n */\n // eslint-disable-next-line max-len\n public arcToSvg(rx: number, ry: number, xAxisRotation: number, largeArcFlag: number, sweepFlag: number, x: number, y: number): this;\n public arcToSvg(...args: [number, number, number, number, number, number, number]): this\n {\n this.instructions.push({ action: 'arcToSvg', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Adds a cubic Bezier curve to the path.\n * It requires three points: the first two are control points and the third one is the end point.\n * The starting point is the last point in the current path.\n * @param cp1x - The x-coordinate of the first control point.\n * @param cp1y - The y-coordinate of the first control point.\n * @param cp2x - The x-coordinate of the second control point.\n * @param cp2y - The y-coordinate of the second control point.\n * @param x - The x-coordinate of the end point.\n * @param y - The y-coordinate of the end point.\n * @param smoothness - Optional parameter to adjust the smoothness of the curve.\n * @returns The instance of the current object for chaining.\n */\n public bezierCurveTo(\n cp1x: number, cp1y: number, cp2x: number, cp2y: number,\n x: number, y: number,\n smoothness?: number\n ): this;\n public bezierCurveTo(...args: [number, number, number, number, number, number, number]): this\n {\n this.instructions.push({ action: 'bezierCurveTo', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Adds a cubic Bezier curve to the path.\n * It requires two points: the second control point and the end point. The first control point is assumed to be\n * The starting point is the last point in the current path.\n * @param cp2x - The x-coordinate of the second control point.\n * @param cp2y - The y-coordinate of the second control point.\n * @param x - The x-coordinate of the end point.\n * @param y - The y-coordinate of the end point.\n * @param smoothness - Optional parameter to adjust the smoothness of the curve.\n * @returns The instance of the current object for chaining.\n */\n public bezierCurveToShort(cp2x: number, cp2y: number, x: number, y: number, smoothness?: number): this\n {\n const last = this.instructions[this.instructions.length - 1];\n\n const lastPoint = this.getLastPoint(Point.shared);\n\n let cp1x = 0;\n let cp1y = 0;\n\n if (!last || last.action !== 'bezierCurveTo')\n {\n cp1x = lastPoint.x;\n cp1y = lastPoint.y;\n }\n else\n {\n cp1x = last.data[2];\n cp1y = last.data[3];\n\n const currentX = lastPoint.x;\n const currentY = lastPoint.y;\n\n cp1x = currentX + (currentX - cp1x);\n cp1y = currentY + (currentY - cp1y);\n }\n\n this.instructions.push({ action: 'bezierCurveTo', data: [cp1x, cp1y, cp2x, cp2y, x, y, smoothness] });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Closes the current path by drawing a straight line back to the start.\n * If the shape is already closed or there are no points in the path, this method does nothing.\n * @returns The instance of the current object for chaining.\n */\n public closePath(): this\n {\n this.instructions.push({ action: 'closePath', data: [] });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws an ellipse at the specified location and with the given x and y radii.\n * An optional transformation can be applied, allowing for rotation, scaling, and translation.\n * @param x - The x-coordinate of the center of the ellipse.\n * @param y - The y-coordinate of the center of the ellipse.\n * @param radiusX - The horizontal radius of the ellipse.\n * @param radiusY - The vertical radius of the ellipse.\n * @param matrix - An optional `Matrix` object to apply a transformation to the ellipse. This can include rotations.\n * @returns The instance of the current object for chaining.\n */\n public ellipse(x: number, y: number, radiusX: number, radiusY: number, matrix?: Matrix): this;\n public ellipse(...args: [number, number, number, number, Matrix]): this\n {\n this.instructions.push({ action: 'ellipse', data: args });\n\n // TODO nail this!\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Connects the current point to a new point with a straight line. This method updates the current path.\n * @param x - The x-coordinate of the new point to connect to.\n * @param y - The y-coordinate of the new point to connect to.\n * @returns The instance of the current object for chaining.\n */\n public lineTo(x: number, y: number): this;\n public lineTo(...args: [number, number]): this\n {\n this.instructions.push({ action: 'lineTo', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Sets the starting point for a new sub-path. Any subsequent drawing commands are considered part of this path.\n * @param x - The x-coordinate for the starting point.\n * @param y - The y-coordinate for the starting point.\n * @returns The instance of the current object for chaining.\n */\n public moveTo(x: number, y: number): this;\n public moveTo(...args: [number, number]): this\n {\n this.instructions.push({ action: 'moveTo', data: args });\n\n return this;\n }\n\n /**\n * Adds a quadratic curve to the path. It requires two points: the control point and the end point.\n * The starting point is the last point in the current path.\n * @param cpx - The x-coordinate of the control point.\n * @param cpy - The y-coordinate of the control point.\n * @param x - The x-coordinate of the end point.\n * @param y - The y-coordinate of the end point.\n * @param smoothness - Optional parameter to adjust the smoothness of the curve.\n * @returns The instance of the current object for chaining.\n */\n public quadraticCurveTo(cpx: number, cpy: number, x: number, y: number, smoothness?: number): this;\n public quadraticCurveTo(...args: [number, number, number, number, number]): this\n {\n this.instructions.push({ action: 'quadraticCurveTo', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Adds a quadratic curve to the path. It uses the previous point as the control point.\n * @param x - The x-coordinate of the end point.\n * @param y - The y-coordinate of the end point.\n * @param smoothness - Optional parameter to adjust the smoothness of the curve.\n * @returns The instance of the current object for chaining.\n */\n public quadraticCurveToShort(x: number, y: number, smoothness?: number): this\n {\n // check if we have a previous quadraticCurveTo\n const last = this.instructions[this.instructions.length - 1];\n\n const lastPoint = this.getLastPoint(Point.shared);\n\n let cpx1 = 0;\n let cpy1 = 0;\n\n if (!last || last.action !== 'quadraticCurveTo')\n {\n cpx1 = lastPoint.x;\n cpy1 = lastPoint.y;\n }\n else\n {\n cpx1 = last.data[0];\n cpy1 = last.data[1];\n\n const currentX = lastPoint.x;\n const currentY = lastPoint.y;\n\n cpx1 = currentX + (currentX - cpx1);\n cpy1 = currentY + (currentY - cpy1);\n }\n\n this.instructions.push({ action: 'quadraticCurveTo', data: [cpx1, cpy1, x, y, smoothness] });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws a rectangle shape. This method adds a new rectangle path to the current drawing.\n * @param x - The x-coordinate of the top-left corner of the rectangle.\n * @param y - The y-coordinate of the top-left corner of the rectangle.\n * @param w - The width of the rectangle.\n * @param h - The height of the rectangle.\n * @param transform - An optional `Matrix` object to apply a transformation to the rectangle.\n * @returns The instance of the current object for chaining.\n */\n public rect(x: number, y: number, w: number, h: number, transform?: Matrix): this\n {\n this.instructions.push({ action: 'rect', data: [x, y, w, h, transform] });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws a circle shape. This method adds a new circle path to the current drawing.\n * @param x - The x-coordinate of the center of the circle.\n * @param y - The y-coordinate of the center of the circle.\n * @param radius - The radius of the circle.\n * @param transform - An optional `Matrix` object to apply a transformation to the circle.\n * @returns The instance of the current object for chaining.\n */\n public circle(x: number, y: number, radius: number, transform?: Matrix): this\n {\n this.instructions.push({ action: 'circle', data: [x, y, radius, transform] });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws a rectangle with rounded corners.\n * The corner radius can be specified to determine how rounded the corners should be.\n * An optional transformation can be applied, which allows for rotation, scaling, and translation of the rectangle.\n * @param x - The x-coordinate of the top-left corner of the rectangle.\n * @param y - The y-coordinate of the top-left corner of the rectangle.\n * @param w - The width of the rectangle.\n * @param h - The height of the rectangle.\n * @param radius - The radius of the rectangle's corners. If not specified, corners will be sharp.\n * @param transform - An optional `Matrix` object to apply a transformation to the rectangle.\n * @returns The instance of the current object for chaining.\n */\n public roundRect(x: number, y: number, w: number, h: number, radius?: number, transform?: Matrix): this;\n public roundRect(...args: [number, number, number, number, number, Matrix?]): this\n {\n this.instructions.push({ action: 'roundRect', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws a polygon shape by specifying a sequence of points. This method allows for the creation of complex polygons,\n * which can be both open and closed. An optional transformation can be applied, enabling the polygon to be scaled,\n * rotated, or translated as needed.\n * @param points - An array of numbers representing the x and y coordinates of the polygon's vertices, in sequence.\n * @param close - A boolean indicating whether to close the polygon path. True by default.\n * @param transform - An optional `Matrix` object to apply a transformation to the polygon.\n * @returns The instance of the current object for chaining further drawing commands.\n */\n public poly(points: number[] | PointData[], close?: boolean, transform?: Matrix): this;\n public poly(...args: [number[] | PointData[], boolean, Matrix?]): this\n {\n this.instructions.push({ action: 'poly', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws a regular polygon with a specified number of sides. All sides and angles are equal.\n * @param x - The x-coordinate of the center of the polygon.\n * @param y - The y-coordinate of the center of the polygon.\n * @param radius - The radius of the circumscribed circle of the polygon.\n * @param sides - The number of sides of the polygon. Must be 3 or more.\n * @param rotation - The rotation angle of the polygon, in radians. Zero by default.\n * @param transform - An optional `Matrix` object to apply a transformation to the polygon.\n * @returns The instance of the current object for chaining.\n */\n public regularPoly(x: number, y: number, radius: number, sides: number, rotation?: number, transform?: Matrix): this;\n public regularPoly(...args: [number, number, number, number, number]): this\n {\n this.instructions.push({ action: 'regularPoly', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws a polygon with rounded corners.\n * Similar to `regularPoly` but with the ability to round the corners of the polygon.\n * @param x - The x-coordinate of the center of the polygon.\n * @param y - The y-coordinate of the center of the polygon.\n * @param radius - The radius of the circumscribed circle of the polygon.\n * @param sides - The number of sides of the polygon. Must be 3 or more.\n * @param corner - The radius of the rounding of the corners.\n * @param rotation - The rotation angle of the polygon, in radians. Zero by default.\n * @returns The instance of the current object for chaining.\n */\n public roundPoly(x: number, y: number, radius: number, sides: number, corner: number, rotation?: number): this;\n public roundPoly(...args: [number, number, number, number, number, number]): this\n {\n this.instructions.push({ action: 'roundPoly', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws a shape with rounded corners. This function supports custom radius for each corner of the shape.\n * Optionally, corners can be rounded using a quadratic curve instead of an arc, providing a different aesthetic.\n * @param points - An array of `RoundedPoint` representing the corners of the shape to draw.\n * A minimum of 3 points is required.\n * @param radius - The default radius for the corners.\n * This radius is applied to all corners unless overridden in `points`.\n * @param useQuadratic - If set to true, rounded corners are drawn using a quadraticCurve\n * method instead of an arc method. Defaults to false.\n * @param smoothness - Specifies the smoothness of the curve when `useQuadratic` is true.\n * Higher values make the curve smoother.\n * @returns The instance of the current object for chaining.\n */\n public roundShape(points: RoundedPoint[], radius: number, useQuadratic?: boolean, smoothness?: number): this;\n public roundShape(...args: [RoundedPoint[], number, boolean, number]): this\n {\n this.instructions.push({ action: 'roundShape', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draw Rectangle with fillet corners. This is much like rounded rectangle\n * however it support negative numbers as well for the corner radius.\n * @param x - Upper left corner of rect\n * @param y - Upper right corner of rect\n * @param width - Width of rect\n * @param height - Height of rect\n * @param fillet - accept negative or positive values\n */\n public filletRect(x: number, y: number, width: number, height: number, fillet: number): this;\n public filletRect(...args: [number, number, number, number, number]): this\n {\n this.instructions.push({ action: 'filletRect', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draw Rectangle with chamfer corners. These are angled corners.\n * @param x - Upper left corner of rect\n * @param y - Upper right corner of rect\n * @param width - Width of rect\n * @param height - Height of rect\n * @param chamfer - non-zero real number, size of corner cutout\n * @param transform\n */\n public chamferRect(x: number, y: number, width: number, height: number, chamfer: number, transform?: Matrix): this;\n public chamferRect(...args: [number, number, number, number, number]): this\n {\n this.instructions.push({ action: 'chamferRect', data: args });\n\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Draws a star shape centered at a specified location. This method allows for the creation\n * of stars with a variable number of points, outer radius, optional inner radius, and rotation.\n * The star is drawn as a closed polygon with alternating outer and inner vertices to create the star's points.\n * An optional transformation can be applied to scale, rotate, or translate the star as needed.\n * @param x - The x-coordinate of the center of the star.\n * @param y - The y-coordinate of the center of the star.\n * @param points - The number of points of the star.\n * @param radius - The outer radius of the star (distance from the center to the outer points).\n * @param innerRadius - Optional. The inner radius of the star\n * (distance from the center to the inner points between the outer points).\n * If not provided, defaults to half of the `radius`.\n * @param rotation - Optional. The rotation of the star in radians, where 0 is aligned with the y-axis.\n * Defaults to 0, meaning one point is directly upward.\n * @param transform - An optional `Matrix` object to apply a transformation to the star.\n * This can include rotations, scaling, and translations.\n * @returns The instance of the current object for chaining further drawing commands.\n */\n // eslint-disable-next-line max-len\n public star(x: number, y: number, points: number, radius: number, innerRadius?: number, rotation?: number, transform?: Matrix): this\n {\n innerRadius ||= radius / 2;\n\n const startAngle = (-1 * Math.PI / 2) + rotation;\n const len = points * 2;\n const delta = (Math.PI * 2) / len;\n const polygon = [];\n\n for (let i = 0; i < len; i++)\n {\n const r = i % 2 ? innerRadius : radius;\n const angle = (i * delta) + startAngle;\n\n polygon.push(\n x + (r * Math.cos(angle)),\n y + (r * Math.sin(angle))\n );\n }\n\n this.poly(polygon, true, transform);\n\n return this;\n }\n\n /**\n * Creates a copy of the current `GraphicsPath` instance. This method supports both shallow and deep cloning.\n * A shallow clone copies the reference of the instructions array, while a deep clone creates a new array and\n * copies each instruction individually, ensuring that modifications to the instructions of the cloned `GraphicsPath`\n * do not affect the original `GraphicsPath` and vice versa.\n * @param deep - A boolean flag indicating whether the clone should be deep.\n * @returns A new `GraphicsPath` instance that is a clone of the current instance.\n */\n public clone(deep = false): GraphicsPath\n {\n const newGraphicsPath2D = new GraphicsPath();\n\n newGraphicsPath2D.checkForHoles = this.checkForHoles;\n\n if (!deep)\n {\n newGraphicsPath2D.instructions = this.instructions.slice();\n }\n else\n {\n for (let i = 0; i < this.instructions.length; i++)\n {\n const instruction = this.instructions[i];\n\n newGraphicsPath2D.instructions.push({ action: instruction.action, data: instruction.data.slice() });\n }\n }\n\n return newGraphicsPath2D;\n }\n\n public clear(): this\n {\n this.instructions.length = 0;\n this._dirty = true;\n\n return this;\n }\n\n /**\n * Applies a transformation matrix to all drawing instructions within the `GraphicsPath`.\n * This method enables the modification of the path's geometry according to the provided\n * transformation matrix, which can include translations, rotations, scaling, and skewing.\n *\n * Each drawing instruction in the path is updated to reflect the transformation,\n * ensuring the visual representation of the path is consistent with the applied matrix.\n *\n * Note: The transformation is applied directly to the coordinates and control points of the drawing instructions,\n * not to the path as a whole. This means the transformation's effects are baked into the individual instructions,\n * allowing for fine-grained control over the path's appearance.\n * @param matrix - A `Matrix` object representing the transformation to apply.\n * @returns The instance of the current object for chaining further operations.\n */\n public transform(matrix: Matrix): this\n {\n if (matrix.isIdentity()) return this;\n\n const a = matrix.a;\n const b = matrix.b;\n const c = matrix.c;\n const d = matrix.d;\n const tx = matrix.tx;\n const ty = matrix.ty;\n\n let x = 0;\n let y = 0;\n\n let cpx1 = 0;\n let cpy1 = 0;\n let cpx2 = 0;\n let cpy2 = 0;\n\n let rx = 0;\n let ry = 0;\n\n for (let i = 0; i < this.instructions.length; i++)\n {\n const instruction = this.instructions[i];\n const data = instruction.data as any[];\n\n switch (instruction.action)\n {\n case 'moveTo':\n case 'lineTo':\n\n x = data[0];\n y = data[1];\n\n data[0] = (a * x) + (c * y) + tx;\n data[1] = (b * x) + (d * y) + ty;\n break;\n case 'bezierCurveTo':\n\n cpx1 = data[0];\n cpy1 = data[1];\n cpx2 = data[2];\n cpy2 = data[3];\n\n x = data[4];\n y = data[5];\n\n data[0] = (a * cpx1) + (c * cpy1) + tx;\n data[1] = (b * cpx1) + (d * cpy1) + ty;\n data[2] = (a * cpx2) + (c * cpy2) + tx;\n data[3] = (b * cpx2) + (d * cpy2) + ty;\n data[4] = (a * x) + (c * y) + tx;\n data[5] = (b * x) + (d * y) + ty;\n break;\n\n case 'quadraticCurveTo':\n\n cpx1 = data[0];\n cpy1 = data[1];\n\n x = data[2];\n y = data[3];\n\n data[0] = (a * cpx1) + (c * cpy1) + tx;\n data[1] = (b * cpx1) + (d * cpy1) + ty;\n\n data[2] = (a * x) + (c * y) + tx;\n data[3] = (b * x) + (d * y) + ty;\n\n break;\n\n case 'arcToSvg':\n\n x = data[5];\n y = data[6];\n\n rx = data[0];\n ry = data[1];\n\n // multiply the radius by the transform..\n\n data[0] = (a * rx) + (c * ry);\n data[1] = (b * rx) + (d * ry);\n\n data[5] = (a * x) + (c * y) + tx;\n data[6] = (b * x) + (d * y) + ty;\n\n break;\n\n case 'circle':\n data[4] = adjustTransform(data[3], matrix);\n break;\n case 'rect':\n data[4] = adjustTransform(data[4], matrix);\n break;\n case 'ellipse':\n data[8] = adjustTransform(data[8], matrix);\n break;\n case 'roundRect':\n data[5] = adjustTransform(data[5], matrix);\n break;\n case 'addPath':\n data[0].transform(matrix);\n break;\n case 'poly':\n data[2] = adjustTransform(data[2], matrix);\n break;\n default:\n // #if _DEBUG\n warn('unknown transform action', instruction.action);\n // #endif\n break;\n }\n }\n\n this._dirty = true;\n\n return this;\n }\n\n get bounds(): Bounds\n {\n return this.shapePath.bounds;\n }\n\n /**\n * Retrieves the last point from the current drawing instructions in the `GraphicsPath`.\n * This method is useful for operations that depend on the path's current endpoint,\n * such as connecting subsequent shapes or paths. It supports various drawing instructions,\n * ensuring the last point's position is accurately determined regardless of the path's complexity.\n *\n * If the last instruction is a `closePath`, the method iterates backward through the instructions\n * until it finds an actionable instruction that defines a point (e.g., `moveTo`, `lineTo`,\n * `quadraticCurveTo`, etc.). For compound paths added via `addPath`, it recursively retrieves\n * the last point from the nested path.\n * @param out - A `Point` object where the last point's coordinates will be stored.\n * This object is modified directly to contain the result.\n * @returns The `Point` object containing the last point's coordinates.\n */\n public getLastPoint(out: Point): Point\n {\n let index = this.instructions.length - 1;\n\n let lastInstruction = this.instructions[index];\n\n if (!lastInstruction)\n {\n out.x = 0;\n out.y = 0;\n\n return out;\n }\n\n while (lastInstruction.action === 'closePath')\n {\n index--;\n\n if (index < 0)\n {\n out.x = 0;\n out.y = 0;\n\n return out;\n }\n\n lastInstruction = this.instructions[index];\n }\n\n switch (lastInstruction.action)\n {\n case 'moveTo':\n case 'lineTo':\n out.x = lastInstruction.data[0];\n out.y = lastInstruction.data[1];\n break;\n case 'quadraticCurveTo':\n out.x = lastInstruction.data[2];\n out.y = lastInstruction.data[3];\n break;\n case 'bezierCurveTo':\n out.x = lastInstruction.data[4];\n out.y = lastInstruction.data[5];\n break;\n case 'arc':\n case 'arcToSvg':\n out.x = lastInstruction.data[5];\n out.y = lastInstruction.data[6];\n break;\n case 'addPath':\n // TODO prolly should transform the last point of the path\n lastInstruction.data[0].getLastPoint(out);\n break;\n }\n\n return out;\n }\n}\n\nfunction adjustTransform(currentMatrix?: Matrix, transform?: Matrix): Matrix\n{\n if (currentMatrix)\n {\n return currentMatrix.prepend(transform);\n }\n\n return transform.clone();\n}\n", "/**\n * Parses a float value from an SVG element's attribute.\n * This is commonly used for parsing numeric attributes like coordinates, dimensions,\n * and other measurements from SVG elements.\n * @param svg - The SVG element to get the attribute from\n * @param id - The name of the attribute to parse (e.g. 'x', 'y', 'width', etc)\n * @param defaultValue - The value to return if the attribute doesn't exist or can't be parsed\n * @returns The parsed float value, or the default value if parsing fails\n * @example\n * // For SVG: <rect x=\"10.5\" width=\"20\"/>\n * parseSVGFloatAttribute(rectElement, 'x', 0) // Returns 10.5\n * parseSVGFloatAttribute(rectElement, 'y', 0) // Returns 0 since y is not specified\n * @internal\n */\nexport function parseSVGFloatAttribute(svg: SVGElement, id: string, defaultValue: number): number\n{\n const value = svg.getAttribute(id) as string;\n\n return value ? Number(value) : defaultValue;\n}\n", "import { Color } from '../../../../color/Color';\nimport { warn } from '../../../../utils/logging/warn';\nimport { FillGradient } from '../fill/FillGradient';\nimport { parseSVGFloatAttribute } from './parseSVGFloatAttribute';\n\nimport type { Session } from './SVGParser';\n\n/**\n * Parses SVG gradient definitions and stores them in the session for later use.\n * Currently supports linear gradients and has placeholder support for radial gradients.\n * @param svg - The root SVG element to parse definitions from\n * @param session - The parsing session to store definitions in\n * @internal\n */\nexport function parseSVGDefinitions(svg: SVGElement, session: Session): void\n{\n // Find all <defs> elements in the SVG\n const definitions = svg.querySelectorAll('defs');\n\n // Process each <defs> element\n for (let i = 0; i < definitions.length; i++)\n {\n const definition = definitions[i];\n\n // Process each child element in the <defs>\n for (let j = 0; j < definition.children.length; j++)\n {\n const child = definition.children[j];\n\n // Handle different types of gradient definitions\n switch (child.nodeName.toLowerCase())\n {\n case 'lineargradient':\n // Store the parsed linear gradient in the session defs using the gradient's ID\n session.defs[child.id] = parseLinearGradient(child as SVGElement);\n break;\n case 'radialgradient':\n session.defs[child.id] = parseRadialGradient(child as SVGElement);\n break;\n default:\n break;\n }\n }\n }\n}\n\n/**\n * Parses an SVG linear gradient element into a FillGradient.\n * @param child - The SVG linear gradient element to parse\n * @returns A FillGradient configured based on the SVG element\n */\nfunction parseLinearGradient(child: SVGElement): FillGradient\n{\n // Parse the gradient vector coordinates (defaults: horizontal line from 0 to 1)\n const x0 = parseSVGFloatAttribute(child, 'x1', 0);\n const y0 = parseSVGFloatAttribute(child, 'y1', 0);\n const x1 = parseSVGFloatAttribute(child, 'x2', 1);\n const y1 = parseSVGFloatAttribute(child, 'y2', 0);\n\n // Get the gradient coordinate system\n const gradientUnit = child.getAttribute('gradientUnits') || 'objectBoundingBox';\n\n // Create gradient with coordinates and space mapping\n const gradient = new FillGradient(\n x0,\n y0,\n x1,\n y1,\n gradientUnit === 'objectBoundingBox' ? 'local' : 'global'\n );\n\n // Process each gradient stop\n for (let k = 0; k < child.children.length; k++)\n {\n const stop = child.children[k] as SVGElement;\n\n // Get stop position (0-1) and color\n const offset = parseSVGFloatAttribute(stop, 'offset', 0);\n const color = Color.shared.setValue(stop.getAttribute('stop-color')).toNumber();\n\n gradient.addColorStop(offset, color);\n }\n\n return gradient;\n}\n\n/**\n * Placeholder function for parsing SVG radial gradients.\n * Currently returns a simple horizontal linear gradient and logs a warning.\n * @param _child - The SVG radial gradient element (currently unused)\n * @returns A default linear gradient\n */\nfunction parseRadialGradient(_child: SVGElement): FillGradient\n{\n // #if _DEBUG\n warn('[SVG Parser] Radial gradients are not yet supported');\n // #endif\n\n return new FillGradient(0, 0, 1, 0);\n}\n", "/**\n * Extracts the ID from an SVG url() reference.\n *\n * This function handles all valid SVG url() formats including:\n * - url(#id)\n * - url('#id')\n * - url(\"#id\")\n * - url( #id )\n * - url( '#id' )\n * - url( \"#id\" )\n *\n * The regex pattern matches:\n * - url followed by optional whitespace\n * - opening parenthesis followed by optional whitespace\n * - optional single or double quotes with optional whitespace\n * - # followed by the ID (any chars except quotes, whitespace, or closing paren)\n * - optional single or double quotes with optional whitespace\n * - closing parenthesis\n * @param url - The SVG url() string to parse\n * @returns The extracted ID string, or empty string if no valid ID found\n * @internal\n */\nexport function extractSvgUrlId(url: string): string\n{\n // Handle all valid SVG url() formats\n const match = url.match(/url\\s*\\(\\s*['\"]?\\s*#([^'\"\\s)]+)\\s*['\"]?\\s*\\)/i);\n\n return match ? match[1] : '';\n}\n", "import { Color } from '../../../../color/Color';\nimport { extractSvgUrlId } from './utils/extractSvgUrlId';\n\nimport type { ConvertedFillStyle, ConvertedStrokeStyle, FillStyle, StrokeStyle } from '../FillTypes';\nimport type { Session } from './SVGParser';\n\n/**\n * A map of SVG style attributes and their default values.\n * Each attribute has a type and default value used for SVG parsing.\n * - 'paint' type can be a color or gradient\n * - 'number' type is a numeric value\n * - 'string' type is a text value\n * @category scene\n * @advanced\n */\nexport const styleAttributes = {\n // Fill properties\n fill: { type: 'paint', default: 0 }, // Fill color/gradient\n 'fill-opacity': { type: 'number', default: 1 }, // Fill transparency\n\n // Stroke properties\n stroke: { type: 'paint', default: 0 }, // Stroke color/gradient\n 'stroke-width': { type: 'number', default: 1 }, // Width of stroke\n 'stroke-opacity': { type: 'number', default: 1 }, // Stroke transparency\n 'stroke-linecap': { type: 'string', default: 'butt' }, // End cap style: butt, round, square\n 'stroke-linejoin': { type: 'string', default: 'miter' }, // Join style: miter, round, bevel\n 'stroke-miterlimit': { type: 'number', default: 10 }, // Limit on miter join sharpness\n 'stroke-dasharray': { type: 'string', default: 'none' }, // Dash pattern\n 'stroke-dashoffset': { type: 'number', default: 0 }, // Offset for dash pattern\n\n // Global properties\n opacity: { type: 'number', default: 1 }, // Overall opacity\n};\n\n/**\n * Represents the result of parsing SVG style attributes\n * @internal\n */\nexport type StyleResult = {\n /** The stroke style properties */\n strokeStyle: StrokeStyle;\n /** The fill style properties */\n fillStyle: FillStyle;\n /** Whether fill should be applied */\n useFill: boolean;\n /** Whether stroke should be applied */\n useStroke: boolean;\n};\n\n/**\n * Parses SVG style attributes and inline styles to determine fill and stroke properties.\n * Handles both direct attributes and CSS-style declarations in the style attribute.\n * @param svg - The SVG element to parse styles from\n * @param session - The current SVG parsing session containing definitions\n * @returns An object containing the parsed fill and stroke styles\n * @internal\n */\nexport function parseSVGStyle(svg: SVGElement, session: Session): StyleResult\n{\n const style = svg.getAttribute('style');\n\n const strokeStyle: StrokeStyle = {};\n\n const fillStyle: FillStyle = {};\n\n const result: StyleResult = {\n strokeStyle,\n fillStyle,\n useFill: false,\n useStroke: false,\n };\n\n // First parse direct style attributes\n for (const key in styleAttributes)\n {\n const attribute = svg.getAttribute(key);\n\n if (attribute)\n {\n parseAttribute(session, result, key, attribute.trim());\n }\n }\n\n // Then parse inline styles which override direct attributes\n if (style)\n {\n const styleParts = style.split(';');\n\n for (let i = 0; i < styleParts.length; i++)\n {\n const stylePart = styleParts[i].trim();\n\n const [key, value] = stylePart.split(':');\n\n if (styleAttributes[key as keyof typeof styleAttributes])\n {\n parseAttribute(session, result, key, value.trim());\n }\n }\n }\n\n return {\n strokeStyle: result.useStroke ? (strokeStyle as ConvertedStrokeStyle) : null,\n fillStyle: result.useFill ? (fillStyle as ConvertedFillStyle) : null,\n useFill: result.useFill,\n useStroke: result.useStroke,\n };\n}\n\n/**\n * Parses a single SVG style attribute and updates the style result accordingly.\n * Handles color values, gradients, opacities and other style properties.\n * @param session - The current SVG parsing session containing definitions\n * @param result - The style result object to update\n * @param id - The attribute name/id to parse\n * @param value - The attribute value to parse\n */\nfunction parseAttribute(\n session: Session,\n result: StyleResult,\n id: string,\n value: string\n): void\n{\n switch (id)\n {\n case 'stroke':\n if (value !== 'none')\n {\n if (value.startsWith('url('))\n {\n // Extract gradient/pattern id from url reference\n const id = extractSvgUrlId(value);\n\n result.strokeStyle.fill = session.defs[id];\n }\n else\n {\n // Parse as color value\n result.strokeStyle.color = Color.shared.setValue(value).toNumber();\n }\n\n result.useStroke = true;\n }\n\n break;\n case 'stroke-width':\n result.strokeStyle.width = Number(value);\n break;\n case 'fill':\n if (value !== 'none')\n {\n if (value.startsWith('url('))\n {\n // Extract gradient/pattern id from url reference\n const id = extractSvgUrlId(value);\n\n result.fillStyle.fill = session.defs[id];\n }\n else\n {\n // Parse as color value\n result.fillStyle.color = Color.shared.setValue(value).toNumber();\n }\n\n result.useFill = true;\n }\n break;\n case 'fill-opacity':\n result.fillStyle.alpha = Number(value);\n break;\n case 'stroke-opacity':\n result.strokeStyle.alpha = Number(value);\n break;\n case 'opacity':\n // Global opacity affects both fill and stroke\n result.fillStyle.alpha = Number(value);\n result.strokeStyle.alpha = Number(value);\n break;\n }\n}\n", "import type {\n FillInstruction,\n GraphicsContext,\n} from '../../GraphicsContext';\n\n/**\n * Determines if subpaths represent nested shapes or multiple holes pattern.\n * @param subpathsWithArea - Array of subpaths with their calculated areas\n * @returns True if nested pattern, false if multiple holes pattern\n * @internal\n */\nexport function checkForNestedPattern(subpathsWithArea: Array<{path: string, area: number}>): boolean\n{\n if (subpathsWithArea.length <= 2)\n {\n return true;\n }\n\n const areas = subpathsWithArea.map((s) => s.area).sort((a, b) => b - a);\n\n const [largestArea, secondArea] = areas;\n const smallestArea = areas[areas.length - 1];\n\n const largestToSecondRatio = largestArea / secondArea;\n const secondToSmallestRatio = secondArea / smallestArea;\n\n // If the largest shape is significantly bigger than the second (3x+)\n // AND the smaller shapes are similar in size (2x or less difference),\n // it suggests multiple holes pattern rather than nested shapes\n if (largestToSecondRatio > 3 && secondToSmallestRatio < 2)\n {\n return false; // Multiple holes\n }\n\n return true; // Default to nested\n}\n\n/**\n * Gets fill instruction data from a graphics context.\n * @param context - The graphics context\n * @param index - Index of the fill instruction (default: 0)\n * @returns The fill instruction data\n * @throws Error if instruction at index is not a fill instruction\n * @internal\n */\nexport function getFillInstructionData(context: GraphicsContext, index: number = 0)\n{\n const instruction = context.instructions[index];\n\n if (!instruction || instruction.action !== 'fill')\n {\n throw new Error(`Expected fill instruction at index ${index}, got ${instruction?.action || 'undefined'}`);\n }\n\n return (instruction as FillInstruction).data;\n}\n", "import { GraphicsPath } from '../../path/GraphicsPath';\n\n/**\n * Extracts individual subpaths from SVG path data by splitting on Move commands.\n * @param pathData - The SVG path data string\n * @returns Array of subpath strings\n * @internal\n */\nexport function extractSubpaths(pathData: string): string[]\n{\n // Split on Move commands (M or m) to get individual subpaths\n const parts = pathData.split(/(?=[Mm])/);\n const subpaths = parts.filter((part) => part.trim().length > 0);\n\n return subpaths;\n}\n\n/**\n * Calculates the area of a path using bounding box estimation.\n * @param pathData - The SVG path data string\n * @returns The estimated area of the path\n * @internal\n */\nexport function calculatePathArea(pathData: string): number\n{\n const coords = pathData.match(/[-+]?[0-9]*\\.?[0-9]+/g);\n\n if (!coords || coords.length < 4) return 0;\n\n const numbers = coords.map(Number);\n const xs = [];\n const ys = [];\n\n for (let i = 0; i < numbers.length; i += 2)\n {\n if (i + 1 < numbers.length)\n {\n xs.push(numbers[i]);\n ys.push(numbers[i + 1]);\n }\n }\n\n if (xs.length === 0 || ys.length === 0) return 0;\n\n const minX = Math.min(...xs);\n const maxX = Math.max(...xs);\n const minY = Math.min(...ys);\n const maxY = Math.max(...ys);\n\n const area = (maxX - minX) * (maxY - minY);\n\n return area;\n}\n\n/**\n * Parses SVG path data and appends instructions to a GraphicsPath.\n * @param pathData - The SVG path data string\n * @param graphicsPath - The GraphicsPath to append instructions to\n * @internal\n */\nexport function appendSVGPath(pathData: string, graphicsPath: GraphicsPath): void\n{\n const tempPath = new GraphicsPath(pathData, false);\n\n for (const instruction of tempPath.instructions)\n {\n graphicsPath.instructions.push(instruction);\n }\n}\n", "import { warn } from '../../../../utils/logging/warn';\nimport { GraphicsPath } from '../path/GraphicsPath';\nimport { parseSVGDefinitions } from './parseSVGDefinitions';\nimport { parseSVGFloatAttribute } from './parseSVGFloatAttribute';\nimport { parseSVGStyle } from './parseSVGStyle';\nimport { checkForNestedPattern } from './utils/fillOperations';\nimport { appendSVGPath, calculatePathArea, extractSubpaths } from './utils/pathOperations';\n\nimport type { FillGradient } from '../fill/FillGradient';\nimport type { FillStyle, StrokeStyle } from '../FillTypes';\nimport type {\n GraphicsContext,\n} from '../GraphicsContext';\n\n/**\n * Represents a session for SVG parsing. Contains the current state and resources needed during parsing.\n * @internal\n */\nexport interface Session\n{\n /** The graphics context to render to */\n context: GraphicsContext;\n /** The current path being constructed */\n path: GraphicsPath;\n /** Map of definitions by id */\n defs: Record<string, FillGradient>;\n}\n\n/**\n * Parses an SVG element or string and renders it to a graphics context.\n * Handles both SVG strings and SVG DOM elements as input.\n * @param svg - The SVG content to parse, either as a string or element\n * @param graphicsContext - Optional graphics context to render to\n * @returns The graphics context with the SVG rendered into it\n * @internal\n */\nexport function SVGParser(\n svg: string | SVGElement | SVGSVGElement,\n graphicsContext?: GraphicsContext\n): GraphicsContext\n{\n // Convert string input to SVG element\n if (typeof svg === 'string')\n {\n // eslint-disable-next-line no-restricted-globals\n const div = document.createElement('div');\n\n div.innerHTML = svg.trim();\n svg = div.querySelector('svg') as SVGElement;\n }\n\n // Initialize parsing session\n const session = {\n context: graphicsContext,\n defs: {},\n path: new GraphicsPath(),\n };\n\n // Parse definitions (gradients, etc) first\n parseSVGDefinitions(svg, session);\n\n // Process all child elements except defs\n const children = svg.children;\n\n const { fillStyle, strokeStyle } = parseSVGStyle(svg, session);\n\n for (let i = 0; i < children.length; i++)\n {\n const child = children[i] as SVGElement;\n\n if (child.nodeName.toLowerCase() === 'defs') continue;\n renderChildren(child, session, fillStyle, strokeStyle);\n }\n\n return graphicsContext;\n}\n\n/**\n * Recursively renders SVG elements and their children.\n * Handles styling inheritance and different SVG shape types.\n * @param svg - The SVG element to render\n * @param session - The current parsing session\n * @param fillStyle - The inherited fill style\n * @param strokeStyle - The inherited stroke style\n */\nfunction renderChildren(svg: SVGElement, session: Session, fillStyle: FillStyle, strokeStyle: StrokeStyle): void\n{\n const children = svg.children;\n\n // Parse element's style and merge with inherited styles\n const { fillStyle: f1, strokeStyle: s1 } = parseSVGStyle(svg, session);\n\n if (f1 && fillStyle)\n {\n fillStyle = { ...fillStyle, ...f1 };\n }\n else if (f1)\n {\n fillStyle = f1;\n }\n\n if (s1 && strokeStyle)\n {\n strokeStyle = { ...strokeStyle, ...s1 };\n }\n else if (s1)\n {\n strokeStyle = s1;\n }\n\n const noStyle = !fillStyle && !strokeStyle;\n\n // Default to black fill if no styles specified\n if (noStyle)\n {\n fillStyle = { color: 0 };\n }\n\n // Variables for shape attributes\n let x;\n let y;\n let x1;\n let y1;\n let x2;\n let y2;\n let cx;\n let cy;\n let r;\n let rx;\n let ry;\n let points;\n let pointsString;\n let d;\n let graphicsPath;\n let width;\n let height;\n\n // Handle different SVG element types\n switch (svg.nodeName.toLowerCase())\n {\n case 'path':\n {\n d = svg.getAttribute('d') as string;\n\n const fillRule = svg.getAttribute('fill-rule') as string;\n\n const subpaths = extractSubpaths(d);\n const hasExplicitEvenodd = fillRule === 'evenodd';\n const hasMultipleSubpaths = subpaths.length > 1;\n\n const shouldProcessHoles = hasExplicitEvenodd && hasMultipleSubpaths;\n\n if (shouldProcessHoles)\n {\n const subpathsWithArea = subpaths.map((subpath) => ({\n path: subpath,\n area: calculatePathArea(subpath)\n }));\n\n subpathsWithArea.sort((a, b) => b.area - a.area);\n\n // For complex cases, prefer multiple holes approach\n const useMultipleHolesApproach = subpaths.length > 3 || !checkForNestedPattern(subpathsWithArea);\n\n if (useMultipleHolesApproach)\n {\n // Multiple holes approach: first (largest) is fill, rest are holes\n for (let i = 0; i < subpathsWithArea.length; i++)\n {\n const subpath = subpathsWithArea[i];\n const isMainShape = i === 0;\n\n session.context.beginPath();\n const newPath = new GraphicsPath(undefined, true); // Always use evenodd for hole processing\n\n appendSVGPath(subpath.path, newPath);\n session.context.path(newPath);\n\n if (isMainShape)\n {\n if (fillStyle) session.context.fill(fillStyle);\n if (strokeStyle) session.context.stroke(strokeStyle);\n }\n else\n {\n session.context.cut();\n }\n }\n }\n else\n {\n // Nested holes approach: alternate between fill and cut\n for (let i = 0; i < subpathsWithArea.length; i++)\n {\n const subpath = subpathsWithArea[i];\n const isHole = i % 2 === 1; // Odd indices are holes\n\n session.context.beginPath();\n const newPath = new GraphicsPath(undefined, true); // Always use evenodd for hole processing\n\n appendSVGPath(subpath.path, newPath);\n session.context.path(newPath);\n\n if (isHole)\n {\n session.context.cut();\n }\n else\n {\n if (fillStyle) session.context.fill(fillStyle);\n if (strokeStyle) session.context.stroke(strokeStyle);\n }\n }\n }\n }\n else\n {\n const useEvenoddForGraphicsPath = fillRule ? (fillRule === 'evenodd') : true;\n\n graphicsPath = new GraphicsPath(d, useEvenoddForGraphicsPath);\n session.context.path(graphicsPath);\n if (fillStyle) session.context.fill(fillStyle);\n if (strokeStyle) session.context.stroke(strokeStyle);\n }\n break;\n }\n\n case 'circle':\n cx = parseSVGFloatAttribute(svg, 'cx', 0);\n cy = parseSVGFloatAttribute(svg, 'cy', 0);\n r = parseSVGFloatAttribute(svg, 'r', 0);\n session.context.ellipse(cx, cy, r, r);\n if (fillStyle) session.context.fill(fillStyle);\n if (strokeStyle) session.context.stroke(strokeStyle);\n break;\n\n case 'rect':\n x = parseSVGFloatAttribute(svg, 'x', 0);\n y = parseSVGFloatAttribute(svg, 'y', 0);\n width = parseSVGFloatAttribute(svg, 'width', 0);\n height = parseSVGFloatAttribute(svg, 'height', 0);\n rx = parseSVGFloatAttribute(svg, 'rx', 0);\n ry = parseSVGFloatAttribute(svg, 'ry', 0);\n\n if (rx || ry)\n {\n session.context.roundRect(x, y, width, height, rx || ry);\n }\n else\n {\n session.context.rect(x, y, width, height);\n }\n\n if (fillStyle) session.context.fill(fillStyle);\n if (strokeStyle) session.context.stroke(strokeStyle);\n break;\n\n case 'ellipse':\n cx = parseSVGFloatAttribute(svg, 'cx', 0);\n cy = parseSVGFloatAttribute(svg, 'cy', 0);\n rx = parseSVGFloatAttribute(svg, 'rx', 0);\n ry = parseSVGFloatAttribute(svg, 'ry', 0);\n\n session.context.beginPath();\n session.context.ellipse(cx, cy, rx, ry);\n\n if (fillStyle) session.context.fill(fillStyle);\n if (strokeStyle) session.context.stroke(strokeStyle);\n break;\n\n case 'line':\n x1 = parseSVGFloatAttribute(svg, 'x1', 0);\n y1 = parseSVGFloatAttribute(svg, 'y1', 0);\n x2 = parseSVGFloatAttribute(svg, 'x2', 0);\n y2 = parseSVGFloatAttribute(svg, 'y2', 0);\n\n session.context.beginPath();\n session.context.moveTo(x1, y1);\n session.context.lineTo(x2, y2);\n\n if (strokeStyle) session.context.stroke(strokeStyle);\n break;\n\n case 'polygon':\n pointsString = svg.getAttribute('points') as string;\n points = pointsString.match(/\\d+/g).map((n) => parseInt(n, 10));\n session.context.poly(points, true);\n if (fillStyle) session.context.fill(fillStyle);\n if (strokeStyle) session.context.stroke(strokeStyle);\n break;\n\n case 'polyline':\n pointsString = svg.getAttribute('points') as string;\n points = pointsString.match(/\\d+/g).map((n) => parseInt(n, 10));\n session.context.poly(points, false);\n if (strokeStyle) session.context.stroke(strokeStyle);\n break;\n\n // Group elements - just process children\n case 'g':\n case 'svg':\n break;\n\n default: {\n // Log unsupported elements\n warn(`[SVG parser] <${svg.nodeName}> elements unsupported`);\n break;\n }\n }\n\n if (noStyle)\n {\n fillStyle = null;\n }\n\n // Recursively process child elements\n for (let i = 0; i < children.length; i++)\n {\n renderChildren(children[i] as SVGElement, session, fillStyle, strokeStyle);\n }\n}\n", "import { Color } from '../../../../color/Color';\nimport { Texture } from '../../../../rendering/renderers/shared/texture/Texture';\nimport { FillGradient } from '../fill/FillGradient';\nimport { FillPattern } from '../fill/FillPattern';\n\nimport type { ColorSource } from '../../../../color/Color';\nimport type {\n ConvertedFillStyle,\n ConvertedStrokeStyle,\n FillInput,\n FillStyle,\n StrokeInput,\n} from '../FillTypes';\n\nfunction isColorLike(value: unknown): value is ColorSource\n{\n return Color.isColorLike(value as ColorSource);\n}\n\nfunction isFillPattern(value: unknown): value is FillPattern\n{\n return value instanceof FillPattern;\n}\n\nfunction isFillGradient(value: unknown): value is FillGradient\n{\n return value instanceof FillGradient;\n}\n\nfunction isTexture(value: unknown): value is Texture\n{\n return value instanceof Texture;\n}\n\n/**\n * Handles the case where the value is a ColorLike\n * @param fill\n * @param value\n * @param defaultStyle\n * @example\n * graphics.fill(0xff0000)\n * graphics.fill(new Color(0xff0000))\n * graphics.fill({ r: 255, g: 0, b: 0 })\n */\nfunction handleColorLike(\n fill: FillStyle,\n value: ColorSource,\n defaultStyle: ConvertedFillStyle\n): ConvertedFillStyle\n{\n const temp = Color.shared.setValue(value ?? 0);\n\n fill.color = temp.toNumber();\n fill.alpha = temp.alpha === 1 ? defaultStyle.alpha : temp.alpha;\n fill.texture = Texture.WHITE;\n\n return { ...defaultStyle, ...fill } as ConvertedFillStyle;\n}\n\n/**\n * Handles the case where the value is a Texture\n * @param fill\n * @param value\n * @param defaultStyle\n * @example\n * graphics.fill(new Texture(0xff0000))\n */\nfunction handleTexture(fill: FillStyle, value: Texture, defaultStyle: ConvertedFillStyle): ConvertedFillStyle\n{\n fill.texture = value;\n\n return { ...defaultStyle, ...fill } as ConvertedFillStyle;\n}\n\n/**\n * Handles the case where the value is a FillPattern\n * @param fill\n * @param value\n * @param defaultStyle\n * @example\n * graphics.fill(new FillPattern(0xff0000))\n */\nfunction handleFillPattern(\n fill: FillStyle,\n value: FillPattern,\n defaultStyle: ConvertedFillStyle\n): ConvertedFillStyle\n{\n fill.fill = value;\n fill.color = 0xffffff;\n fill.texture = value.texture;\n fill.matrix = value.transform;\n\n return { ...defaultStyle, ...fill } as ConvertedFillStyle;\n}\n\n/**\n * Handles the case where the value is a FillGradient\n * @param fill\n * @param value\n * @param defaultStyle\n * @example\n * graphics.fill(new FillGradient(0, 0, 200, 0))\n */\nfunction handleFillGradient(\n fill: FillStyle,\n value: FillGradient,\n defaultStyle: ConvertedFillStyle\n): ConvertedFillStyle\n{\n value.buildGradient();\n fill.fill = value;\n fill.color = 0xffffff;\n fill.texture = value.texture;\n fill.matrix = value.transform;\n fill.textureSpace = value.textureSpace;\n\n return { ...defaultStyle, ...fill } as ConvertedFillStyle;\n}\n\n/**\n * Handles the case where the value is not a direct Pixi Color, PatternFill, or GradientFill but instead\n * an object with potentially `color`\n * @example\n * {\n * color: new Color(0xff0000)\n * alpha: 0.5,\n * texture?: null,\n * matrix?: null,\n * }\n * @param value\n * @param defaultStyle\n */\nfunction handleFillObject(value: FillStyle, defaultStyle: ConvertedFillStyle): ConvertedFillStyle\n{\n const style = { ...defaultStyle, ...(value as FillStyle) };\n\n const color = Color.shared.setValue(style.color);\n\n style.alpha *= color.alpha;\n style.color = color.toNumber();\n\n return style as ConvertedFillStyle;\n}\n\n/**\n * Converts a value to a fill style, we do this as PixiJS has a number of ways to define a fill style\n * They can be a direct color, a texture, a gradient, or an object with these values in them\n * This function will take any of these input types and convert them into a single object\n * that PixiJS can understand and use internally.\n * @param value - The value to convert to a fill style\n * @param defaultStyle - The default fill style to use\n * @private\n */\nexport function toFillStyle<T extends FillInput>(\n value: T,\n defaultStyle: ConvertedFillStyle\n): ConvertedFillStyle\n{\n if (value === undefined || value === null)\n {\n return null;\n }\n\n const fill: ConvertedFillStyle = {} as ConvertedFillStyle;\n const objectStyle = value as FillStyle;\n\n if (isColorLike(value))\n {\n return handleColorLike(fill, value, defaultStyle);\n }\n else if (isTexture(value))\n {\n return handleTexture(fill, value, defaultStyle);\n }\n else if (isFillPattern(value))\n {\n return handleFillPattern(fill, value, defaultStyle);\n }\n else if (isFillGradient(value))\n {\n return handleFillGradient(fill, value, defaultStyle);\n }\n else if (objectStyle.fill && isFillPattern(objectStyle.fill))\n {\n return handleFillPattern(objectStyle, objectStyle.fill, defaultStyle);\n }\n else if (objectStyle.fill && isFillGradient(objectStyle.fill))\n {\n return handleFillGradient(objectStyle, objectStyle.fill, defaultStyle);\n }\n\n return handleFillObject(objectStyle, defaultStyle);\n}\n\n/**\n * Converts a value to a stroke style, similar to `toFillStyle` but for strokes\n * @param value - The value to convert to a stroke style\n * @param defaultStyle - The default stroke style to use\n * @private\n */\nexport function toStrokeStyle(value: StrokeInput, defaultStyle: ConvertedStrokeStyle): ConvertedStrokeStyle\n{\n const { width, alignment, miterLimit, cap, join, pixelLine, ...rest } = defaultStyle;\n const fill = toFillStyle(value, rest);\n\n if (!fill)\n {\n return null;\n }\n\n return {\n width,\n alignment,\n miterLimit,\n cap,\n join,\n pixelLine,\n ...fill,\n };\n}\n", "/* eslint-disable max-len */\nimport EventEmitter from 'eventemitter3';\nimport { Color, type ColorSource } from '../../../color/Color';\nimport { Matrix } from '../../../maths/matrix/Matrix';\nimport { Point } from '../../../maths/point/Point';\nimport { Texture } from '../../../rendering/renderers/shared/texture/Texture';\nimport { uid } from '../../../utils/data/uid';\nimport { deprecation, v8_0_0 } from '../../../utils/logging/deprecation';\nimport { Bounds } from '../../container/bounds/Bounds';\nimport { GraphicsPath } from './path/GraphicsPath';\nimport { SVGParser } from './svg/SVGParser';\nimport { toFillStyle, toStrokeStyle } from './utils/convertFillInputToFillStyle';\n\nimport type { PointData } from '../../../maths/point/PointData';\nimport type { Shader } from '../../../rendering/renderers/shared/shader/Shader';\nimport type { TextureDestroyOptions, TypeOrBool } from '../../container/destroyTypes';\nimport type { ConvertedFillStyle, ConvertedStrokeStyle, FillInput, StrokeInput } from './FillTypes';\nimport type { RoundedPoint } from './path/roundShape';\n\nconst tmpPoint = new Point();\n\n/**\n * The mode for batching graphics instructions.\n *\n * It can be:\n * - 'auto': Automatically determines whether to batch based on the number of instructions.\n * - 'batch': Forces batching of all instructions.\n * - 'no-batch': Disables batching, processing each instruction individually.\n * @category scene\n * @advanced\n */\nexport type BatchMode = 'auto' | 'batch' | 'no-batch';\n\n/** @internal */\nexport interface FillInstruction\n{\n action: 'fill' | 'cut'\n data: { style: ConvertedFillStyle, path: GraphicsPath, hole?: GraphicsPath }\n}\n\n/** @internal */\nexport interface StrokeInstruction\n{\n action: 'stroke'\n data: { style: ConvertedStrokeStyle, path: GraphicsPath, hole?: GraphicsPath }\n}\n\n/** @internal */\nexport interface TextureInstruction\n{\n action: 'texture'\n data: {\n image: Texture,\n\n dx: number\n dy: number\n\n dw: number\n dh: number\n\n transform: Matrix\n alpha: number\n style: number,\n }\n}\n\n/** @internal */\nexport type GraphicsInstructions = FillInstruction | StrokeInstruction | TextureInstruction;\n\nconst tempMatrix = new Matrix();\n\n/**\n * The GraphicsContext class allows for the creation of lightweight objects that contain instructions for drawing shapes and paths.\n * It is used internally by the Graphics class to draw shapes and paths, and can be used directly and shared between Graphics objects,\n *\n * This sharing of a `GraphicsContext` means that the intensive task of converting graphics instructions into GPU-ready geometry is done once, and the results are reused,\n * much like sprites reusing textures.\n * @category scene\n * @standard\n */\nexport class GraphicsContext extends EventEmitter<{\n update: GraphicsContext\n destroy: GraphicsContext\n}>\n{\n /** The default fill style to use when none is provided. */\n public static defaultFillStyle: ConvertedFillStyle = {\n /** The color to use for the fill. */\n color: 0xffffff,\n /** The alpha value to use for the fill. */\n alpha: 1,\n /** The texture to use for the fill. */\n texture: Texture.WHITE,\n /** The matrix to apply. */\n matrix: null,\n /** The fill pattern to use. */\n fill: null,\n /** Whether coordinates are 'global' or 'local' */\n textureSpace: 'local',\n };\n\n /** The default stroke style to use when none is provided. */\n public static defaultStrokeStyle: ConvertedStrokeStyle = {\n /** The width of the stroke. */\n width: 1,\n /** The color to use for the stroke. */\n color: 0xffffff,\n /** The alpha value to use for the stroke. */\n alpha: 1,\n /** The alignment of the stroke. */\n alignment: 0.5,\n /** The miter limit to use. */\n miterLimit: 10,\n /** The line cap style to use. */\n cap: 'butt',\n /** The line join style to use. */\n join: 'miter',\n /** The texture to use for the fill. */\n texture: Texture.WHITE,\n /** The matrix to apply. */\n matrix: null,\n /** The fill pattern to use. */\n fill: null,\n /** Whether coordinates are 'global' or 'local' */\n textureSpace: 'local',\n /** If the stroke is a pixel line. */\n pixelLine: false,\n };\n\n /**\n * unique id for this graphics context\n * @internal\n */\n public readonly uid: number = uid('graphicsContext');\n /**\n * Indicates whether content is updated and have to be re-rendered.\n * @internal\n */\n public dirty = true;\n /** The batch mode for this graphics context. It can be 'auto', 'batch', or 'no-batch'. */\n public batchMode: BatchMode = 'auto';\n /** @internal */\n public instructions: GraphicsInstructions[] = [];\n /**\n * Custom shader to apply to the graphics when rendering.\n * @advanced\n */\n public customShader?: Shader;\n\n private _activePath: GraphicsPath = new GraphicsPath();\n private _transform: Matrix = new Matrix();\n\n private _fillStyle: ConvertedFillStyle = { ...GraphicsContext.defaultFillStyle };\n private _strokeStyle: ConvertedStrokeStyle = { ...GraphicsContext.defaultStrokeStyle };\n private _stateStack: { fillStyle: ConvertedFillStyle; strokeStyle: ConvertedStrokeStyle, transform: Matrix }[] = [];\n\n private _tick = 0;\n\n private _bounds = new Bounds();\n private _boundsDirty = true;\n\n /**\n * Creates a new GraphicsContext object that is a clone of this instance, copying all properties,\n * including the current drawing state, transformations, styles, and instructions.\n * @returns A new GraphicsContext instance with the same properties and state as this one.\n */\n public clone(): GraphicsContext\n {\n const clone = new GraphicsContext();\n\n clone.batchMode = this.batchMode;\n clone.instructions = this.instructions.slice();\n clone._activePath = this._activePath.clone();\n clone._transform = this._transform.clone();\n clone._fillStyle = { ...this._fillStyle };\n clone._strokeStyle = { ...this._strokeStyle };\n clone._stateStack = this._stateStack.slice();\n clone._bounds = this._bounds.clone();\n clone._boundsDirty = true;\n\n return clone;\n }\n\n /**\n * The current fill style of the graphics context. This can be a color, gradient, pattern, or a more complex style defined by a FillStyle object.\n */\n get fillStyle(): ConvertedFillStyle\n {\n return this._fillStyle;\n }\n\n set fillStyle(value: FillInput)\n {\n this._fillStyle = toFillStyle(value, GraphicsContext.defaultFillStyle);\n }\n\n /**\n * The current stroke style of the graphics context. Similar to fill styles, stroke styles can encompass colors, gradients, patterns, or more detailed configurations via a StrokeStyle object.\n */\n get strokeStyle(): ConvertedStrokeStyle\n {\n return this._strokeStyle;\n }\n\n set strokeStyle(value: FillInput)\n {\n this._strokeStyle = toStrokeStyle(value, GraphicsContext.defaultStrokeStyle);\n }\n\n /**\n * Sets the current fill style of the graphics context. The fill style can be a color, gradient,\n * pattern, or a more complex style defined by a FillStyle object.\n * @param style - The fill style to apply. This can be a simple color, a gradient or pattern object,\n * or a FillStyle or ConvertedFillStyle object.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public setFillStyle(style: FillInput): this\n {\n this._fillStyle = toFillStyle(style, GraphicsContext.defaultFillStyle);\n\n return this;\n }\n\n /**\n * Sets the current stroke style of the graphics context. Similar to fill styles, stroke styles can\n * encompass colors, gradients, patterns, or more detailed configurations via a StrokeStyle object.\n * @param style - The stroke style to apply. Can be defined as a color, a gradient or pattern,\n * or a StrokeStyle or ConvertedStrokeStyle object.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public setStrokeStyle(style: StrokeInput): this\n {\n this._strokeStyle = toFillStyle(style, GraphicsContext.defaultStrokeStyle) as ConvertedStrokeStyle;\n\n return this;\n }\n\n /**\n * Adds a texture to the graphics context. This method supports multiple overloads for specifying the texture.\n * If only a texture is provided, it uses the texture's width and height for drawing.\n * @param texture - The Texture object to use.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public texture(texture: Texture): this;\n /**\n * Adds a texture to the graphics context. This method supports multiple overloads for specifying the texture,\n * tint, and dimensions. If only a texture is provided, it uses the texture's width and height for drawing.\n * Additional parameters allow for specifying a tint color, and custom dimensions for the texture drawing area.\n * @param texture - The Texture object to use.\n * @param tint - (Optional) A ColorSource to tint the texture. If not provided, defaults to white (0xFFFFFF).\n * @param dx - (Optional) The x-coordinate in the destination canvas at which to place the top-left corner of\n * the source image.\n * @param dy - (Optional) The y-coordinate in the destination canvas at which to place the top-left corner of\n * the source image.\n * @param dw - (Optional) The width of the rectangle within the source image to draw onto the destination canvas.\n * If not provided, uses the texture's frame width.\n * @param dh - (Optional) The height of the rectangle within the source image to draw onto the destination canvas.\n * If not provided, uses the texture's frame height.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public texture(texture: Texture, tint?: ColorSource, dx?: number, dy?: number, dw?: number, dh?: number): this;\n public texture(texture: Texture, tint?: ColorSource, dx?: number, dy?: number, dw?: number, dh?: number): this\n {\n this.instructions.push({\n action: 'texture',\n data: {\n image: texture,\n\n dx: dx || 0,\n dy: dy || 0,\n\n dw: dw || texture.frame.width,\n dh: dh || texture.frame.height,\n\n transform: this._transform.clone(),\n alpha: this._fillStyle.alpha,\n style: tint ? Color.shared.setValue(tint).toNumber() : 0xFFFFFF,\n }\n });\n\n this.onUpdate();\n\n return this;\n }\n\n /**\n * Resets the current path. Any previous path and its commands are discarded and a new path is\n * started. This is typically called before beginning a new shape or series of drawing commands.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public beginPath(): this\n {\n this._activePath = new GraphicsPath();\n\n return this;\n }\n\n /**\n * Fills the current or given path with the current fill style. This method can optionally take\n * a color and alpha for a simple fill, or a more complex FillInput object for advanced fills.\n * @param style - (Optional) The style to fill the path with. Can be a color, gradient, pattern, or a complex style object. If omitted, uses the current fill style.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public fill(style?: FillInput): this;\n /** @deprecated 8.0.0 */\n public fill(color: ColorSource, alpha: number): this;\n public fill(style?: FillInput, alpha?: number): this\n {\n let path: GraphicsPath;\n\n const lastInstruction = this.instructions[this.instructions.length - 1];\n\n if (this._tick === 0 && lastInstruction?.action === 'stroke')\n {\n path = lastInstruction.data.path;\n }\n else\n {\n path = this._activePath.clone();\n }\n\n if (!path) return this;\n\n // eslint-disable-next-line no-eq-null, eqeqeq\n if (style != null)\n {\n if (alpha !== undefined && typeof style === 'number')\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'GraphicsContext.fill(color, alpha) is deprecated, use GraphicsContext.fill({ color, alpha }) instead');\n // #endif\n\n style = { color: style, alpha };\n }\n this._fillStyle = toFillStyle(style, GraphicsContext.defaultFillStyle);\n }\n\n // TODO not a fan of the clone!!\n this.instructions.push({\n action: 'fill',\n // TODO copy fill style!\n data: { style: this.fillStyle, path }\n });\n\n this.onUpdate();\n\n this._initNextPathLocation();\n this._tick = 0;\n\n return this;\n }\n\n private _initNextPathLocation()\n {\n // Reset the _activePath with the last point of the current path\n const { x, y } = this._activePath.getLastPoint(Point.shared);\n\n this._activePath.clear();\n this._activePath.moveTo(x, y);\n }\n\n /**\n * Strokes the current path with the current stroke style. This method can take an optional\n * FillInput parameter to define the stroke's appearance, including its color, width, and other properties.\n * @param style - (Optional) The stroke style to apply. Can be defined as a simple color or a more complex style object. If omitted, uses the current stroke style.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public stroke(style?: StrokeInput): this\n {\n let path: GraphicsPath;\n\n const lastInstruction = this.instructions[this.instructions.length - 1];\n\n if (this._tick === 0 && lastInstruction?.action === 'fill')\n {\n path = lastInstruction.data.path;\n }\n else\n {\n path = this._activePath.clone();\n }\n\n if (!path) return this;\n\n // eslint-disable-next-line no-eq-null, eqeqeq\n if (style != null)\n {\n this._strokeStyle = toStrokeStyle(style, GraphicsContext.defaultStrokeStyle);\n }\n\n // TODO not a fan of the clone!!\n this.instructions.push({\n action: 'stroke',\n // TODO copy fill style!\n data: { style: this.strokeStyle, path }\n });\n\n this.onUpdate();\n\n this._initNextPathLocation();\n this._tick = 0;\n\n return this;\n }\n\n /**\n * Applies a cutout to the last drawn shape. This is used to create holes or complex shapes by\n * subtracting a path from the previously drawn path. If a hole is not completely in a shape, it will\n * fail to cut correctly!\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public cut(): this\n {\n for (let i = 0; i < 2; i++)\n {\n const lastInstruction = this.instructions[this.instructions.length - 1 - i];\n\n const holePath = this._activePath.clone();\n\n if (lastInstruction)\n {\n if (lastInstruction.action === 'stroke' || lastInstruction.action === 'fill')\n {\n if (lastInstruction.data.hole)\n {\n lastInstruction.data.hole.addPath(holePath);\n }\n else\n {\n lastInstruction.data.hole = holePath;\n break;\n }\n }\n }\n }\n\n this._initNextPathLocation();\n\n return this;\n }\n\n /**\n * Adds an arc to the current path, which is centered at (x, y) with the specified radius,\n * starting and ending angles, and direction.\n * @param x - The x-coordinate of the arc's center.\n * @param y - The y-coordinate of the arc's center.\n * @param radius - The arc's radius.\n * @param startAngle - The starting angle, in radians.\n * @param endAngle - The ending angle, in radians.\n * @param counterclockwise - (Optional) Specifies whether the arc is drawn counterclockwise (true) or clockwise (false). Defaults to false.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this\n {\n this._tick++;\n\n const t = this._transform;\n\n this._activePath.arc(\n (t.a * x) + (t.c * y) + t.tx,\n (t.b * x) + (t.d * y) + t.ty,\n radius,\n startAngle,\n endAngle,\n counterclockwise,\n );\n\n return this;\n }\n\n /**\n * Adds an arc to the current path with the given control points and radius, connected to the previous point\n * by a straight line if necessary.\n * @param x1 - The x-coordinate of the first control point.\n * @param y1 - The y-coordinate of the first control point.\n * @param x2 - The x-coordinate of the second control point.\n * @param y2 - The y-coordinate of the second control point.\n * @param radius - The arc's radius.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): this\n {\n this._tick++;\n\n const t = this._transform;\n\n this._activePath.arcTo(\n (t.a * x1) + (t.c * y1) + t.tx,\n (t.b * x1) + (t.d * y1) + t.ty,\n (t.a * x2) + (t.c * y2) + t.tx,\n (t.b * x2) + (t.d * y2) + t.ty,\n radius,\n );\n\n return this;\n }\n\n /**\n * Adds an SVG-style arc to the path, allowing for elliptical arcs based on the SVG spec.\n * @param rx - The x-radius of the ellipse.\n * @param ry - The y-radius of the ellipse.\n * @param xAxisRotation - The rotation of the ellipse's x-axis relative\n * to the x-axis of the coordinate system, in degrees.\n * @param largeArcFlag - Determines if the arc should be greater than or less than 180 degrees.\n * @param sweepFlag - Determines if the arc should be swept in a positive angle direction.\n * @param x - The x-coordinate of the arc's end point.\n * @param y - The y-coordinate of the arc's end point.\n * @returns The instance of the current object for chaining.\n */\n public arcToSvg(\n rx: number, ry: number,\n xAxisRotation: number,\n largeArcFlag: number,\n sweepFlag: number,\n x: number, y: number\n ): this\n {\n this._tick++;\n\n const t = this._transform;\n\n this._activePath.arcToSvg(\n rx, ry,\n xAxisRotation, // should we rotate this with transform??\n largeArcFlag,\n sweepFlag,\n (t.a * x) + (t.c * y) + t.tx,\n (t.b * x) + (t.d * y) + t.ty,\n );\n\n return this;\n }\n\n /**\n * Adds a cubic Bezier curve to the path.\n * It requires three points: the first two are control points and the third one is the end point.\n * The starting point is the last point in the current path.\n * @param cp1x - The x-coordinate of the first control point.\n * @param cp1y - The y-coordinate of the first control point.\n * @param cp2x - The x-coordinate of the second control point.\n * @param cp2y - The y-coordinate of the second control point.\n * @param x - The x-coordinate of the end point.\n * @param y - The y-coordinate of the end point.\n * @param smoothness - Optional parameter to adjust the smoothness of the curve.\n * @returns The instance of the current object for chaining.\n */\n public bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number, smoothness?: number): this\n {\n this._tick++;\n\n // TODO optimize for no transform\n const t = this._transform;\n\n this._activePath.bezierCurveTo(\n (t.a * cp1x) + (t.c * cp1y) + t.tx,\n (t.b * cp1x) + (t.d * cp1y) + t.ty,\n (t.a * cp2x) + (t.c * cp2y) + t.tx,\n (t.b * cp2x) + (t.d * cp2y) + t.ty,\n (t.a * x) + (t.c * y) + t.tx,\n (t.b * x) + (t.d * y) + t.ty,\n smoothness,\n );\n\n return this;\n }\n\n /**\n * Closes the current path by drawing a straight line back to the start.\n * If the shape is already closed or there are no points in the path, this method does nothing.\n * @returns The instance of the current object for chaining.\n */\n public closePath(): this\n {\n this._tick++;\n\n this._activePath?.closePath();\n\n return this;\n }\n\n /**\n * Draws an ellipse at the specified location and with the given x and y radii.\n * An optional transformation can be applied, allowing for rotation, scaling, and translation.\n * @param x - The x-coordinate of the center of the ellipse.\n * @param y - The y-coordinate of the center of the ellipse.\n * @param radiusX - The horizontal radius of the ellipse.\n * @param radiusY - The vertical radius of the ellipse.\n * @returns The instance of the current object for chaining.\n */\n public ellipse(x: number, y: number, radiusX: number, radiusY: number): this\n {\n this._tick++;\n\n this._activePath.ellipse(x, y, radiusX, radiusY, this._transform.clone());\n\n return this;\n }\n\n /**\n * Draws a circle shape. This method adds a new circle path to the current drawing.\n * @param x - The x-coordinate of the center of the circle.\n * @param y - The y-coordinate of the center of the circle.\n * @param radius - The radius of the circle.\n * @returns The instance of the current object for chaining.\n */\n public circle(x: number, y: number, radius: number): this\n {\n this._tick++;\n\n this._activePath.circle(x, y, radius, this._transform.clone());\n\n return this;\n }\n\n /**\n * Adds another `GraphicsPath` to this path, optionally applying a transformation.\n * @param path - The `GraphicsPath` to add.\n * @returns The instance of the current object for chaining.\n */\n public path(path: GraphicsPath): this\n {\n this._tick++;\n\n this._activePath.addPath(path, this._transform.clone());\n\n return this;\n }\n\n /**\n * Connects the current point to a new point with a straight line. This method updates the current path.\n * @param x - The x-coordinate of the new point to connect to.\n * @param y - The y-coordinate of the new point to connect to.\n * @returns The instance of the current object for chaining.\n */\n public lineTo(x: number, y: number): this\n {\n this._tick++;\n\n const t = this._transform;\n\n this._activePath.lineTo(\n (t.a * x) + (t.c * y) + t.tx,\n (t.b * x) + (t.d * y) + t.ty\n );\n\n return this;\n }\n\n /**\n * Sets the starting point for a new sub-path. Any subsequent drawing commands are considered part of this path.\n * @param x - The x-coordinate for the starting point.\n * @param y - The y-coordinate for the starting point.\n * @returns The instance of the current object for chaining.\n */\n public moveTo(x: number, y: number): this\n {\n this._tick++;\n\n const t = this._transform;\n\n const instructions = this._activePath.instructions;\n\n const transformedX = (t.a * x) + (t.c * y) + t.tx;\n const transformedY = (t.b * x) + (t.d * y) + t.ty;\n\n if (instructions.length === 1 && instructions[0].action === 'moveTo')\n {\n instructions[0].data[0] = transformedX;\n instructions[0].data[1] = transformedY;\n\n return this;\n }\n this._activePath.moveTo(\n transformedX,\n transformedY\n );\n\n return this;\n }\n\n /**\n * Adds a quadratic curve to the path. It requires two points: the control point and the end point.\n * The starting point is the last point in the current path.\n * @param cpx - The x-coordinate of the control point.\n * @param cpy - The y-coordinate of the control point.\n * @param x - The x-coordinate of the end point.\n * @param y - The y-coordinate of the end point.\n * @param smoothness - Optional parameter to adjust the smoothness of the curve.\n * @returns The instance of the current object for chaining.\n */\n public quadraticCurveTo(cpx: number, cpy: number, x: number, y: number, smoothness?: number): this\n {\n this._tick++;\n\n const t = this._transform;\n\n this._activePath.quadraticCurveTo(\n (t.a * cpx) + (t.c * cpy) + t.tx,\n (t.b * cpx) + (t.d * cpy) + t.ty,\n (t.a * x) + (t.c * y) + t.tx,\n (t.b * x) + (t.d * y) + t.ty,\n smoothness,\n );\n\n return this;\n }\n\n /**\n * Draws a rectangle shape. This method adds a new rectangle path to the current drawing.\n * @param x - The x-coordinate of the top-left corner of the rectangle.\n * @param y - The y-coordinate of the top-left corner of the rectangle.\n * @param w - The width of the rectangle.\n * @param h - The height of the rectangle.\n * @returns The instance of the current object for chaining.\n */\n public rect(x: number, y: number, w: number, h: number): this\n {\n this._tick++;\n\n this._activePath.rect(x, y, w, h, this._transform.clone());\n\n return this;\n }\n\n /**\n * Draws a rectangle with rounded corners.\n * The corner radius can be specified to determine how rounded the corners should be.\n * An optional transformation can be applied, which allows for rotation, scaling, and translation of the rectangle.\n * @param x - The x-coordinate of the top-left corner of the rectangle.\n * @param y - The y-coordinate of the top-left corner of the rectangle.\n * @param w - The width of the rectangle.\n * @param h - The height of the rectangle.\n * @param radius - The radius of the rectangle's corners. If not specified, corners will be sharp.\n * @returns The instance of the current object for chaining.\n */\n public roundRect(x: number, y: number, w: number, h: number, radius?: number): this\n {\n this._tick++;\n\n this._activePath.roundRect(x, y, w, h, radius, this._transform.clone());\n\n return this;\n }\n\n /**\n * Draws a polygon shape by specifying a sequence of points. This method allows for the creation of complex polygons,\n * which can be both open and closed. An optional transformation can be applied, enabling the polygon to be scaled,\n * rotated, or translated as needed.\n * @param points - An array of numbers, or an array of PointData objects eg [{x,y}, {x,y}, {x,y}]\n * representing the x and y coordinates, of the polygon's vertices, in sequence.\n * @param close - A boolean indicating whether to close the polygon path. True by default.\n */\n public poly(points: number[] | PointData[], close?: boolean): this\n {\n this._tick++;\n\n this._activePath.poly(points, close, this._transform.clone());\n\n return this;\n }\n\n /**\n * Draws a regular polygon with a specified number of sides. All sides and angles are equal.\n * @param x - The x-coordinate of the center of the polygon.\n * @param y - The y-coordinate of the center of the polygon.\n * @param radius - The radius of the circumscribed circle of the polygon.\n * @param sides - The number of sides of the polygon. Must be 3 or more.\n * @param rotation - The rotation angle of the polygon, in radians. Zero by default.\n * @param transform - An optional `Matrix` object to apply a transformation to the polygon.\n * @returns The instance of the current object for chaining.\n */\n public regularPoly(x: number, y: number, radius: number, sides: number, rotation = 0, transform?: Matrix): this\n {\n this._tick++;\n this._activePath.regularPoly(x, y, radius, sides, rotation, transform);\n\n return this;\n }\n\n /**\n * Draws a polygon with rounded corners.\n * Similar to `regularPoly` but with the ability to round the corners of the polygon.\n * @param x - The x-coordinate of the center of the polygon.\n * @param y - The y-coordinate of the center of the polygon.\n * @param radius - The radius of the circumscribed circle of the polygon.\n * @param sides - The number of sides of the polygon. Must be 3 or more.\n * @param corner - The radius of the rounding of the corners.\n * @param rotation - The rotation angle of the polygon, in radians. Zero by default.\n * @returns The instance of the current object for chaining.\n */\n public roundPoly(x: number, y: number, radius: number, sides: number, corner: number, rotation?: number): this\n {\n this._tick++;\n this._activePath.roundPoly(x, y, radius, sides, corner, rotation);\n\n return this;\n }\n\n /**\n * Draws a shape with rounded corners. This function supports custom radius for each corner of the shape.\n * Optionally, corners can be rounded using a quadratic curve instead of an arc, providing a different aesthetic.\n * @param points - An array of `RoundedPoint` representing the corners of the shape to draw.\n * A minimum of 3 points is required.\n * @param radius - The default radius for the corners.\n * This radius is applied to all corners unless overridden in `points`.\n * @param useQuadratic - If set to true, rounded corners are drawn using a quadraticCurve\n * method instead of an arc method. Defaults to false.\n * @param smoothness - Specifies the smoothness of the curve when `useQuadratic` is true.\n * Higher values make the curve smoother.\n * @returns The instance of the current object for chaining.\n */\n public roundShape(points: RoundedPoint[], radius: number, useQuadratic?: boolean, smoothness?: number): this\n {\n this._tick++;\n this._activePath.roundShape(points, radius, useQuadratic, smoothness);\n\n return this;\n }\n\n /**\n * Draw Rectangle with fillet corners. This is much like rounded rectangle\n * however it support negative numbers as well for the corner radius.\n * @param x - Upper left corner of rect\n * @param y - Upper right corner of rect\n * @param width - Width of rect\n * @param height - Height of rect\n * @param fillet - accept negative or positive values\n */\n public filletRect(x: number, y: number, width: number, height: number, fillet: number): this\n {\n this._tick++;\n this._activePath.filletRect(x, y, width, height, fillet);\n\n return this;\n }\n\n /**\n * Draw Rectangle with chamfer corners. These are angled corners.\n * @param x - Upper left corner of rect\n * @param y - Upper right corner of rect\n * @param width - Width of rect\n * @param height - Height of rect\n * @param chamfer - non-zero real number, size of corner cutout\n * @param transform\n */\n public chamferRect(x: number, y: number, width: number, height: number, chamfer: number, transform?: Matrix): this\n {\n this._tick++;\n this._activePath.chamferRect(x, y, width, height, chamfer, transform);\n\n return this;\n }\n\n /**\n * Draws a star shape centered at a specified location. This method allows for the creation\n * of stars with a variable number of points, outer radius, optional inner radius, and rotation.\n * The star is drawn as a closed polygon with alternating outer and inner vertices to create the star's points.\n * An optional transformation can be applied to scale, rotate, or translate the star as needed.\n * @param x - The x-coordinate of the center of the star.\n * @param y - The y-coordinate of the center of the star.\n * @param points - The number of points of the star.\n * @param radius - The outer radius of the star (distance from the center to the outer points).\n * @param innerRadius - Optional. The inner radius of the star\n * (distance from the center to the inner points between the outer points).\n * If not provided, defaults to half of the `radius`.\n * @param rotation - Optional. The rotation of the star in radians, where 0 is aligned with the y-axis.\n * Defaults to 0, meaning one point is directly upward.\n * @returns The instance of the current object for chaining further drawing commands.\n */\n public star(x: number, y: number, points: number, radius: number, innerRadius = 0, rotation = 0): this\n {\n this._tick++;\n\n this._activePath.star(x, y, points, radius, innerRadius, rotation, this._transform.clone());\n\n return this;\n }\n\n /**\n * Parses and renders an SVG string into the graphics context. This allows for complex shapes and paths\n * defined in SVG format to be drawn within the graphics context.\n * @param svg - The SVG string to be parsed and rendered.\n */\n public svg(svg: string): this\n {\n this._tick++;\n\n SVGParser(svg, this);\n\n return this;\n }\n\n /**\n * Restores the most recently saved graphics state by popping the top of the graphics state stack.\n * This includes transformations, fill styles, and stroke styles.\n */\n public restore(): this\n {\n const state = this._stateStack.pop();\n\n if (state)\n {\n this._transform = state.transform;\n this._fillStyle = state.fillStyle;\n this._strokeStyle = state.strokeStyle;\n }\n\n return this;\n }\n\n /** Saves the current graphics state, including transformations, fill styles, and stroke styles, onto a stack. */\n public save(): this\n {\n this._stateStack.push({\n transform: this._transform.clone(),\n fillStyle: { ...this._fillStyle },\n strokeStyle: { ...this._strokeStyle },\n });\n\n return this;\n }\n\n /**\n * Returns the current transformation matrix of the graphics context.\n * @returns The current transformation matrix.\n */\n public getTransform(): Matrix\n {\n return this._transform;\n }\n\n /**\n * Resets the current transformation matrix to the identity matrix, effectively removing any transformations (rotation, scaling, translation) previously applied.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public resetTransform(): this\n {\n this._transform.identity();\n\n return this;\n }\n\n /**\n * Applies a rotation transformation to the graphics context around the current origin.\n * @param angle - The angle of rotation in radians.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public rotate(angle: number): this\n {\n this._transform.rotate(angle);\n\n return this;\n }\n\n /**\n * Applies a scaling transformation to the graphics context, scaling drawings by x horizontally and by y vertically.\n * @param x - The scale factor in the horizontal direction.\n * @param y - (Optional) The scale factor in the vertical direction. If not specified, the x value is used for both directions.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public scale(x: number, y: number = x): this\n {\n this._transform.scale(x, y);\n\n return this;\n }\n\n /**\n * Sets the current transformation matrix of the graphics context to the specified matrix or values.\n * This replaces the current transformation matrix.\n * @param transform - The matrix to set as the current transformation matrix.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public setTransform(transform: Matrix): this;\n /**\n * Sets the current transformation matrix of the graphics context to the specified matrix or values.\n * This replaces the current transformation matrix.\n * @param a - The value for the a property of the matrix, or a Matrix object to use directly.\n * @param b - The value for the b property of the matrix.\n * @param c - The value for the c property of the matrix.\n * @param d - The value for the d property of the matrix.\n * @param dx - The value for the tx (translate x) property of the matrix.\n * @param dy - The value for the ty (translate y) property of the matrix.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public setTransform(a: number, b: number, c: number, d: number, dx: number, dy: number): this;\n public setTransform(a: number | Matrix, b?: number, c?: number, d?: number, dx?: number, dy?: number): this\n {\n if (a instanceof Matrix)\n {\n this._transform.set(a.a, a.b, a.c, a.d, a.tx, a.ty);\n\n return this;\n }\n\n this._transform.set(a, b, c, d, dx, dy);\n\n return this;\n }\n\n /**\n * Applies the specified transformation matrix to the current graphics context by multiplying\n * the current matrix with the specified matrix.\n * @param transform - The matrix to apply to the current transformation.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public transform(transform: Matrix): this;\n /**\n * Applies the specified transformation matrix to the current graphics context by multiplying\n * the current matrix with the specified matrix.\n * @param a - The value for the a property of the matrix, or a Matrix object to use directly.\n * @param b - The value for the b property of the matrix.\n * @param c - The value for the c property of the matrix.\n * @param d - The value for the d property of the matrix.\n * @param dx - The value for the tx (translate x) property of the matrix.\n * @param dy - The value for the ty (translate y) property of the matrix.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public transform(a: number, b: number, c: number, d: number, dx: number, dy: number): this;\n public transform(a: number | Matrix, b?: number, c?: number, d?: number, dx?: number, dy?: number): this\n {\n if (a instanceof Matrix)\n {\n this._transform.append(a);\n\n return this;\n }\n\n tempMatrix.set(a, b, c, d, dx, dy);\n this._transform.append(tempMatrix);\n\n return this;\n }\n\n /**\n * Applies a translation transformation to the graphics context, moving the origin by the specified amounts.\n * @param x - The amount to translate in the horizontal direction.\n * @param y - (Optional) The amount to translate in the vertical direction. If not specified, the x value is used for both directions.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public translate(x: number, y: number = x): this\n {\n this._transform.translate(x, y);\n\n return this;\n }\n\n /**\n * Clears all drawing commands from the graphics context, effectively resetting it. This includes clearing the path,\n * and optionally resetting transformations to the identity matrix.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public clear(): this\n {\n this._activePath.clear();\n this.instructions.length = 0;\n this.resetTransform();\n\n this.onUpdate();\n\n return this;\n }\n\n protected onUpdate(): void\n {\n // Every time the content is updated - we must invalidate bounds, regardless rendering `dirty` state.\n // Bounds can be read multiple times per frame.\n this._boundsDirty = true;\n\n // Visual updates happen only once per frame.\n // There is no need to dispatch an `update` in if it was already dispatched this frame.\n if (this.dirty) return;\n this.emit('update', this, 0x10);\n this.dirty = true;\n }\n\n /** The bounds of the graphic shape. */\n get bounds(): Bounds\n {\n if (!this._boundsDirty) return this._bounds;\n\n this._boundsDirty = false;\n\n // TODO switch to idy dirty with tick..\n const bounds = this._bounds;\n\n bounds.clear();\n\n for (let i = 0; i < this.instructions.length; i++)\n {\n const instruction = this.instructions[i];\n const action = instruction.action;\n\n if (action === 'fill')\n {\n const data = instruction.data as FillInstruction['data'];\n\n bounds.addBounds(data.path.bounds);\n }\n else if (action === 'texture')\n {\n const data = instruction.data as TextureInstruction['data'];\n\n bounds.addFrame(data.dx, data.dy, data.dx + data.dw, data.dy + data.dh, data.transform);\n }\n if (action === 'stroke')\n {\n const data = instruction.data as StrokeInstruction['data'];\n\n const alignment = data.style.alignment;\n\n const outerPadding = (data.style.width * (1 - alignment));\n\n const _bounds = data.path.bounds;\n\n bounds.addFrame(\n _bounds.minX - outerPadding,\n _bounds.minY - outerPadding,\n _bounds.maxX + outerPadding,\n _bounds.maxY + outerPadding\n );\n }\n }\n\n return bounds;\n }\n\n /**\n * Check to see if a point is contained within this geometry.\n * @param point - Point to check if it's contained.\n * @returns {boolean} `true` if the point is contained within geometry.\n */\n public containsPoint(point: PointData): boolean\n {\n // early out if the bounding box is not hit\n if (!this.bounds.containsPoint(point.x, point.y)) return false;\n\n const instructions = this.instructions;\n let hasHit = false;\n\n for (let k = 0; k < instructions.length; k++)\n {\n const instruction = instructions[k];\n\n const data = instruction.data as FillInstruction['data'];\n const path = data.path;\n\n if (!instruction.action || !path) continue;\n\n const style = data.style;\n const shapes = path.shapePath.shapePrimitives;\n\n for (let i = 0; i < shapes.length; i++)\n {\n const shape = shapes[i].shape;\n\n if (!style || !shape) continue;\n\n const transform = shapes[i].transform;\n\n const transformedPoint = transform ? transform.applyInverse(point, tmpPoint) : point;\n\n if (instruction.action === 'fill')\n {\n hasHit = shape.contains(transformedPoint.x, transformedPoint.y);\n }\n else\n {\n const strokeStyle = (style as ConvertedStrokeStyle);\n\n hasHit = shape.strokeContains(transformedPoint.x, transformedPoint.y, strokeStyle.width, strokeStyle.alignment);\n }\n\n const holes = data.hole;\n\n if (holes)\n {\n const holeShapes = holes.shapePath?.shapePrimitives;\n\n if (holeShapes)\n {\n for (let j = 0; j < holeShapes.length; j++)\n {\n if (holeShapes[j].shape.contains(transformedPoint.x, transformedPoint.y))\n {\n hasHit = false;\n }\n }\n }\n }\n\n if (hasHit)\n {\n return true;\n }\n }\n }\n\n return hasHit;\n }\n\n /**\n * Destroys the GraphicsData object.\n * @param options - Options parameter. A boolean will act as if all options\n * have been set to that value\n * @example\n * context.destroy();\n * context.destroy(true);\n * context.destroy({ texture: true, textureSource: true });\n */\n public destroy(options: TypeOrBool<TextureDestroyOptions> = false): void\n {\n this._stateStack.length = 0;\n this._transform = null;\n\n this.emit('destroy', this);\n this.removeAllListeners();\n\n const destroyTexture = typeof options === 'boolean' ? options : options?.texture;\n\n if (destroyTexture)\n {\n const destroyTextureSource = typeof options === 'boolean' ? options : options?.textureSource;\n\n if (this._fillStyle.texture)\n {\n this._fillStyle.fill && 'uid' in this._fillStyle.fill\n ? this._fillStyle.fill.destroy()\n : this._fillStyle.texture.destroy(destroyTextureSource);\n }\n\n if (this._strokeStyle.texture)\n {\n this._strokeStyle.fill && 'uid' in this._strokeStyle.fill\n ? this._strokeStyle.fill.destroy()\n : this._strokeStyle.texture.destroy(destroyTextureSource);\n }\n }\n\n this._fillStyle = null;\n this._strokeStyle = null;\n\n this.instructions = null;\n this._activePath = null;\n this._bounds = null;\n this._stateStack = null;\n this.customShader = null;\n this._transform = null;\n }\n}\n", "import EventEmitter from 'eventemitter3';\nimport { Color, type ColorSource } from '../../color/Color';\nimport { type Filter } from '../../filters/Filter';\nimport { uid } from '../../utils/data/uid';\nimport { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\nimport { warn } from '../../utils/logging/warn';\nimport { FillGradient } from '../graphics/shared/fill/FillGradient';\nimport { FillPattern } from '../graphics/shared/fill/FillPattern';\nimport { GraphicsContext } from '../graphics/shared/GraphicsContext';\nimport { toFillStyle, toStrokeStyle } from '../graphics/shared/utils/convertFillInputToFillStyle';\n\nimport type { TextureDestroyOptions, TypeOrBool } from '../container/destroyTypes';\nimport type {\n ConvertedFillStyle,\n ConvertedStrokeStyle,\n FillInput,\n FillStyle,\n StrokeInput,\n StrokeStyle\n} from '../graphics/shared/FillTypes';\n\n/**\n * The alignment of the text.\n *\n * - 'left': Aligns text to the left edge.\n * - 'center': Centers text horizontally.\n * - 'right': Aligns text to the right edge.\n * - 'justify': Justifies text, aligning both left and right edges.\n * @example\n * ```ts\n * import { TextStyle } from 'pixi.js';\n * const style = new TextStyle({\n * align: 'center', // or 'left', 'right', 'justify'\n * });\n * ```\n * @category text\n * @standard\n */\nexport type TextStyleAlign = 'left' | 'center' | 'right' | 'justify';\n/**\n * The fill style input for text styles.\n *\n * This can be:\n * - A color string like 'red', '#00FF00', or 'rgba(255,0,0,0.5)'\n * - A hex number like 0xff0000 for red\n * - A FillStyle object with properties like { color: 0xff0000, alpha: 0.5 }\n * - A FillGradient for gradient fills\n * - A FillPattern for pattern/texture fills\n * @example\n * ```ts\n * // Simple Fills\n * new TextStyle({ fill: 'red' }); // Color string\n * new TextStyle({ fill: 0x00ff00 }); // Hex color\n * new TextStyle({ fill: 'rgb(255,0,0)' }); // RGB string\n * // Gradients\n * new TextStyle({\n * fill: new FillGradient({\n * end: { x: 1, y: 1 },\n * stops: [\n * { color: 0xff0000, offset: 0 }, // Red at start\n * { color: 0x0000ff, offset: 1 }, // Blue at end\n * ]\n * }),\n * });\n * // Patterns\n * new TextStyle({\n * fill: new FillPattern(Assets.get('pattern.png'))\n * });\n * ```\n * @category text\n * @standard\n */\nexport type TextStyleFill = string | string[] | number | number[] | CanvasGradient | CanvasPattern;\n/**\n * The font style input for text styles. Controls the slant or italicization of the text.\n * @example\n * ```ts\n * // Create text with normal font style\n * const normalText = new Text({\n * text: 'Normal Style Text',\n * style: {\n * fontStyle: 'normal',\n * fontSize: 24\n * }\n * });\n *\n * // Create italic text\n * const italicText = new Text({\n * text: 'Italic Style Text',\n * style: {\n * fontStyle: 'italic',\n * fontSize: 24,\n * fontFamily: 'Arial'\n * }\n * });\n *\n * // Create oblique text\n * const obliqueText = new Text({\n * text: 'Oblique Style Text',\n * style: {\n * fontStyle: 'oblique',\n * fontSize: 24,\n * fontFamily: 'Times New Roman'\n * }\n * });\n *\n * // Dynamic style changes\n * let isItalic = false;\n * text.style = {\n * ...text.style,\n * fontStyle: isItalic ? 'italic' : 'normal'\n * };\n * ```\n *\n * Supported values:\n * - 'normal': Regular upright text with no slant\n * - 'italic': True italics using specifically designed italic glyphs\n * - 'oblique': Slanted version of the regular glyphs\n * @remarks\n * - 'italic' uses specially designed glyphs with cursive characteristics\n * - 'oblique' is a mechanical slant of the normal glyphs\n * - Not all fonts include true italic designs; some may fall back to oblique\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-style | MDN font-style}\n * @category text\n * @standard\n */\nexport type TextStyleFontStyle = 'normal' | 'italic' | 'oblique';\n/**\n * The font variant input for text styles. Controls the capitalization and presentation of letters.\n * Used to enable special rendering like small caps.\n * @example\n * ```ts\n * // Create text with normal font variant\n * const normalText = new Text({\n * text: 'Normal Text',\n * style: {\n * fontVariant: 'normal',\n * fontSize: 24\n * }\n * });\n *\n * // Create text with small-caps variant\n * const smallCapsText = new Text({\n * text: 'Small Caps Text',\n * style: {\n * fontVariant: 'small-caps',\n * fontSize: 24,\n * fontFamily: 'Arial'\n * }\n * });\n *\n * // Use in a TextStyle instance\n * const style = new TextStyle({\n * fontVariant: 'small-caps',\n * fontSize: 32,\n * fill: 0x4a4a4a\n * });\n *\n * // Update variant dynamically\n * text.style = {\n * ...text.style,\n * fontVariant: text.style.fontVariant === 'normal' ? 'small-caps' : 'normal'\n * };\n * ```\n *\n * Supported values:\n * - 'normal': Regular text rendering with standard capitalization\n * - 'small-caps': Renders lowercase letters as smaller versions of capital letters\n * @remarks\n * Small caps are only available if the font supports them.\n * Not all fonts include true small caps glyphs.\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant | MDN font-variant}\n * @category text\n * @standard\n */\nexport type TextStyleFontVariant = 'normal' | 'small-caps';\n/**\n * The font weight input for text styles. Controls the thickness or boldness of the text.\n * @example\n * ```ts\n * // Create text with different font weights\n * const normalText = new Text({\n * text: 'Normal Weight',\n * style: { fontWeight: 'normal' }\n * });\n *\n * const boldText = new Text({\n * text: 'Bold Weight',\n * style: { fontWeight: 'bold' }\n * });\n *\n * // Using numeric weights\n * const lightText = new Text({\n * text: 'Light Weight',\n * style: { fontWeight: '300' }\n * });\n *\n * const mediumText = new Text({\n * text: 'Medium Weight',\n * style: { fontWeight: '500' }\n * });\n *\n * const heavyText = new Text({\n * text: 'Heavy Weight',\n * style: { fontWeight: '900' }\n * });\n *\n * // Responsive weight changes\n * const adaptiveText = new Text({\n * text: 'Adaptive Weight',\n * style: { fontWeight: window.innerWidth > 600 ? 'bold' : 'normal' }\n * });\n * ```\n *\n * Supported values:\n * - 'normal': Standard weight (equivalent to 400)\n * - 'bold': Bold weight (equivalent to 700)\n * - 'bolder': One weight darker than the parent element\n * - 'lighter': One weight lighter than the parent element\n * - '100': Thin (Hairline)\n * - '200': Extra Light (Ultra Light)\n * - '300': Light\n * - '400': Normal\n * - '500': Medium\n * - '600': Semi Bold (Demi Bold)\n * - '700': Bold\n * - '800': Extra Bold (Ultra Bold)\n * - '900': Heavy (Black)\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight | MDN font-weight}\n * @category text\n * @standard\n */\nexport type TextStyleFontWeight =\n | 'normal' // Standard weight (400)\n | 'bold' // Bold weight (700)\n | 'bolder' // Relative weight increase\n | 'lighter' // Relative weight decrease\n | '100' // Thin\n | '200' // Extra Light\n | '300' // Light\n | '400' // Normal\n | '500' // Medium\n | '600' // Semi Bold\n | '700' // Bold\n | '800' // Extra Bold\n | '900'; // Heavy\n/**\n * The line join style for text strokes. Determines how lines connect at corners.\n * @example\n * ```ts\n * // Create text with miter joins (sharp corners)\n * const sharpText = new Text({\n * text: 'Sharp Corners',\n * style: {\n * fontSize: 36,\n * stroke: {\n * color: '#4a1850',\n * width: 4,\n * lineJoin: 'miter' // Sharp corners\n * }\n * }\n * });\n *\n * // Create text with round joins\n * const roundText = new Text({\n * text: 'Rounded Corners',\n * style: {\n * fontSize: 36,\n * stroke: {\n * color: '#4a1850',\n * width: 4,\n * lineJoin: 'round' // Smooth rounded corners\n * }\n * }\n * });\n *\n * // Create text with beveled joins\n * const bevelText = new Text({\n * text: 'Beveled Corners',\n * style: {\n * fontSize: 36,\n * stroke: {\n * color: '#4a1850',\n * width: 4,\n * lineJoin: 'bevel' // Flattened corners\n * }\n * }\n * });\n * ```\n * Available values:\n * - 'miter': Creates sharp corners by extending the outer edges until they meet\n * - 'round': Creates smooth, rounded corners using a circular arc\n * - 'bevel': Creates flattened corners by filling an additional triangle between the outer edges\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin | MDN lineJoin}\n * @category text\n * @standard\n */\nexport type TextStyleLineJoin = 'miter' | 'round' | 'bevel';\n/**\n * The text baseline for text styles.\n *\n * This can be:\n * - 'alphabetic': The alphabetic baseline\n * - 'top': The top of the text\n * - 'hanging': The hanging baseline\n * - 'middle': The middle of the text\n * - 'ideographic': The ideographic baseline\n * - 'bottom': The bottom of the text\n * @category text\n * @standard\n */\nexport type TextStyleTextBaseline = 'alphabetic' | 'top' | 'hanging' | 'middle' | 'ideographic' | 'bottom';\n/**\n * Controls how whitespace (spaces, tabs, and line breaks) is handled within the text.\n * This affects text wrapping and spacing behavior.\n * @example\n * ```ts\n * // Normal mode (collapse spaces and newlines)\n * const normalText = new Text({\n * text: 'Hello World\\n\\nNew Line',\n * style: {\n * whiteSpace: 'normal',\n * fontSize: 24\n * }\n * }); // Renders as: \"Hello World New Line\"\n *\n * // Pre mode (preserve all whitespace)\n * const preText = new Text({\n * text: 'Hello World\\n\\nNew Line',\n * style: {\n * whiteSpace: 'pre',\n * fontSize: 24\n * }\n * }); // Preserves spaces and line breaks exactly\n *\n * // Pre-line mode (preserve newlines, collapse spaces)\n * const preLineText = new Text({\n * text: 'Hello World\\n\\nNew Line',\n * style: {\n * whiteSpace: 'pre-line',\n * fontSize: 24\n * }\n * }); // Preserves line breaks, collapses multiple spaces\n *\n * // With word wrap enabled\n * const wrappedText = new Text({\n * text: 'A long text with multiple spaces\\nand line breaks',\n * style: {\n * whiteSpace: 'pre-line',\n * wordWrap: true,\n * wordWrapWidth: 200,\n * fontSize: 24\n * }\n * });\n * ```\n *\n * Supported values:\n * - 'normal': Collapses all whitespace (spaces, tabs, line breaks) into a single space\n * - 'pre': Preserves all whitespace characters exactly as written\n * - 'pre-line': Preserves line breaks but collapses multiple spaces into a single space\n * @remarks\n * - 'normal' is best for single-line text or when you want to ignore formatting\n * - 'pre' is useful for code blocks or when exact spacing is important\n * - 'pre-line' is good for formatted text where you want to keep line breaks but clean up spaces\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/white-space | MDN white-space}\n * @see {@link TextStyle#wordWrap} For controlling text wrapping\n * @category text\n * @standard\n */\nexport type TextStyleWhiteSpace = 'normal' | 'pre' | 'pre-line';\n\n/**\n * Defines a drop shadow effect for text rendering.\n * Drop shadows add depth and emphasis to text by creating a shadow offset from the text.\n * @example\n * ```ts\n * // Create text with basic drop shadow\n * const text = new Text({\n * text: 'Shadow Text',\n * style: {\n * fontSize: 48,\n * dropShadow: {\n * alpha: 0.5, // 50% opacity shadow\n * angle: Math.PI / 6, // 30 degrees\n * blur: 4, // Soft shadow edge\n * color: '#000000', // Black shadow\n * distance: 6 // Shadow offset\n * }\n * }\n * });\n *\n * // Dynamic shadow updates\n * text.style.dropShadow = {\n * alpha: Math.sin(Date.now() / 1000) * 0.5 + 0.5, // Pulsing opacity\n * angle: Date.now() / 1000, // Rotating angle\n * blur: 4,\n * color: '#000000',\n * distance: 6\n * };\n * ```\n * @category text\n * @standard\n */\nexport type TextDropShadow = {\n /**\n * The opacity of the drop shadow.\n * - Range: 0 to 1\n * - 0 = fully transparent\n * - 1 = fully opaque\n * @example\n * ```ts\n * // Set drop shadow opacity to 50%\n * dropShadow: {\n * alpha: 0.5\n * }\n * ```\n * @default 1\n */\n alpha: number;\n\n /**\n * The angle of the drop shadow in radians.\n * - 0 = right\n * - Math.PI/2 = down\n * - Math.PI = left\n * - Math.PI*1.5 = up\n * @example\n * ```ts\n * // Set drop shadow angle to 30 degrees\n * dropShadow: {\n * angle: Math.PI / 6 // 30 degrees\n * }\n * ```\n * @default Math.PI/6 (30 degrees)\n */\n angle: number;\n\n /**\n * The blur radius of the shadow.\n * - 0 = sharp shadow\n * - Higher values = softer shadow\n * @example\n * ```ts\n * // Set drop shadow blur radius to 10 pixels\n * dropShadow: {\n * blur: 10\n * }\n * ```\n * @default 0\n */\n blur: number;\n\n /**\n * The color of the drop shadow.\n * Accepts any valid CSS color string, hex number, or RGB/RGBA values.\n * @example '#000000', 'rgba(0,0,0,0.5)', 0x000000\n * @default 'black'\n */\n color: ColorSource;\n\n /**\n * The distance of the drop shadow from the text.\n * Measured in pixels.\n * @example\n * ```ts\n * // Set drop shadow distance to 5 pixels\n * dropShadow: {\n * distance: 5\n * }\n * ```\n * @default 5\n */\n distance: number;\n};\n\n/**\n * Constructor options used for `TextStyle` instances. Defines the visual appearance and layout of text.\n * @example\n * ```ts\n * // Basic text style\n * const basicStyle = new TextStyle({\n * fontSize: 24,\n * fill: 'black',\n * fontFamily: 'Arial'\n * });\n *\n * // Rich text style with multiple features\n * const richStyle = new TextStyle({\n * fontFamily: ['Arial', 'Helvetica', 'sans-serif'],\n * fontSize: 36,\n * fontWeight: 'bold',\n * fill: 'red',\n * stroke: { color: '#4a1850', width: 5 },\n * align: 'center',\n * dropShadow: {\n * color: '#000000',\n * blur: 4,\n * distance: 6,\n * angle: Math.PI / 6\n * },\n * wordWrap: true,\n * wordWrapWidth: 440,\n * lineHeight: 40,\n * textBaseline: 'middle'\n * });\n * ```\n * @see {@link TextStyle} For the main style class\n * @category text\n * @standard\n */\nexport interface TextStyleOptions\n{\n /**\n * Alignment for multiline text, does not affect single line text\n * @default 'left'\n */\n align?: TextStyleAlign;\n /**\n * Whether to allow line breaks within words.\n * Requires wordWrap to be true.\n * @example\n * ```ts\n * // Enable word breaking\n * const style = new TextStyle({\n * breakWords: true,\n * wordWrap: true,\n * wordWrapWidth: 200\n * });\n * ```\n * @default false\n */\n breakWords?: boolean;\n /**\n * Drop shadow configuration for the text.\n * Can be boolean or a TextDropShadow object.\n * @default null\n */\n dropShadow?: boolean | Partial<TextDropShadow>;\n /**\n * Fill style for the text.\n * Can be a color, gradient, or pattern.\n * @default 'black'\n */\n fill?: FillInput;\n /**\n * Font family or families to use.\n * Can be single name or array of fallbacks.\n * @example\n * ```ts\n * // Single font family\n * fontFamily: 'Arial'\n * // Multiple font families\n * fontFamily: ['Helvetica', 'Arial', 'sans-serif']\n * ```\n * @default 'Arial'\n */\n fontFamily?: string | string[];\n /**\n * Font size in pixels or as string.\n *\n * Equivalents are '26px','20pt','160%' or '1.6em')\n * @example\n * ```ts\n * // Numeric size\n * fontSize: 26\n * // String size\n * fontSize: '26px'\n * // Percentage size\n * fontSize: '160%' // 1.6 times the parent element's font size\n * // Em size\n * fontSize: '1.6em' // 1.6 times the parent element's font size\n * @default 26\n */\n fontSize?: number | string;\n /**\n * Font style (normal, italic, oblique).\n * @default 'normal'\n */\n fontStyle?: TextStyleFontStyle;\n /**\n * Font variant (normal, small-caps).\n * @default 'normal'\n */\n fontVariant?: TextStyleFontVariant;\n /**\n * Font weight (normal, bold, bolder, lighter, 100-900).\n * @default 'normal'\n */\n fontWeight?: TextStyleFontWeight;\n /** The height of the line, a number that represents the vertical space that a letter uses. */\n leading?: number;\n /** The amount of spacing between letters, default is 0 */\n letterSpacing?: number;\n /** The line height, a number that represents the vertical space that a letter uses */\n lineHeight?: number;\n /**\n * Padding around the text.\n *\n * Occasionally some fonts are cropped. Adding some padding will prevent this from\n * happening by adding padding to all sides of the text.\n */\n padding?: number;\n /**\n * Stroke style for text outline.\n * @default null\n */\n stroke?: StrokeInput;\n /**\n * Vertical alignment baseline.\n * @default 'alphabetic'\n */\n textBaseline?: TextStyleTextBaseline;\n /**\n * Whether to trim transparent edges.\n * > [!NOTE] This is an expensive operation and should only be used when necessary.\n * @default false\n */\n trim?: boolean;\n /**\n * How to handle whitespace.\n *\n * It needs wordWrap to be set to true for this to have an effect.\n * @default 'pre'\n */\n whiteSpace?: TextStyleWhiteSpace;\n /** Indicates if word wrap should be used */\n wordWrap?: boolean;\n /** The width at which text will wrap, it needs wordWrap to be set to true */\n wordWrapWidth?: number;\n /**\n * Array of filters to apply to the text.\n *\n * These filters will be applied to the text as it is created, resulting in faster rendering for static text\n * compared to applying the filter directly to the text object (which would be applied at run time).\n * @default undefined\n */\n filters?: Filter[] | readonly Filter[];\n}\n\n/**\n * A TextStyle Object contains information to decorate Text objects.\n * An instance can be shared between multiple Text objects; then changing the style will update all text objects using it.\n * @example\n * ```ts\n * // Create a basic text style\n * const style = new TextStyle({\n * fontFamily: ['Helvetica', 'Arial', 'sans-serif'],\n * fontSize: 36,\n * fill: 0xff1010,\n * align: 'center'\n * });\n *\n * // Create a rich text style with multiple features\n * const richStyle = new TextStyle({\n * fontFamily: 'Arial',\n * fontSize: 32,\n * fill: 'white',\n * stroke: {\n * color: '#4a1850',\n * width: 5\n * },\n * dropShadow: {\n * color: '#000000',\n * blur: 4,\n * distance: 6,\n * angle: Math.PI / 6\n * },\n * wordWrap: true,\n * wordWrapWidth: 440,\n * lineHeight: 40,\n * align: 'center'\n * });\n *\n * // Share style between multiple text objects\n * const text1 = new Text({\n * text: 'Hello',\n * style: richStyle\n * });\n *\n * const text2 = new Text({\n * text: 'World',\n * style: richStyle\n * });\n *\n * // Update style dynamically - affects all text objects\n * richStyle.fontSize = 48;\n * richStyle.fill = 0x00ff00;\n * ```\n *\n * Key Features:\n * - Shared styling between multiple text objects\n * - Rich text formatting options\n * - Gradient and pattern fills\n * - Drop shadows and strokes\n * - Word wrapping and alignment\n * - Dynamic updates\n * @category text\n * @standard\n */\nexport class TextStyle extends EventEmitter<{\n update: TextDropShadow\n}>\n{\n /**\n * Default drop shadow settings used when enabling drop shadows on text.\n * These values are used as the base configuration when drop shadows are enabled without specific settings.\n * @example\n * ```ts\n * // Customize default settings globally\n * TextStyle.defaultDropShadow.alpha = 0.5; // 50% opacity for all shadows\n * TextStyle.defaultDropShadow.blur = 2; // 2px blur for all shadows\n * TextStyle.defaultDropShadow.color = 'blue'; // Blue shadows by default\n * ```\n */\n public static defaultDropShadow: TextDropShadow = {\n alpha: 1,\n angle: Math.PI / 6,\n blur: 0,\n color: 'black',\n distance: 5\n };\n\n /**\n * Unique identifier for the TextStyle class.\n * This is used to track instances and ensure uniqueness.\n * @internal\n */\n public uid = uid('textStyle');\n /**\n * Internal tick counter used to track updates and changes.\n * This is incremented whenever the style is modified, allowing for efficient change detection.\n * @internal\n */\n public _tick = 0;\n\n /**\n * Default text style settings used when creating new text objects.\n * These values serve as the base configuration and can be customized globally.\n * @example\n * ```ts\n * // Customize default text style globally\n * TextStyle.defaultTextStyle.fontSize = 16;\n * TextStyle.defaultTextStyle.fill = 0x333333;\n * TextStyle.defaultTextStyle.fontFamily = ['Arial', 'Helvetica', 'sans-serif'];\n * ```\n */\n public static defaultTextStyle: TextStyleOptions = {\n align: 'left',\n breakWords: false,\n dropShadow: null,\n fill: 'black',\n fontFamily: 'Arial',\n fontSize: 26,\n fontStyle: 'normal',\n fontVariant: 'normal',\n fontWeight: 'normal',\n leading: 0,\n letterSpacing: 0,\n lineHeight: 0,\n padding: 0,\n stroke: null,\n textBaseline: 'alphabetic',\n trim: false,\n whiteSpace: 'pre',\n wordWrap: false,\n wordWrapWidth: 100\n };\n\n // colors!!\n /** @internal */\n public _fill: ConvertedFillStyle;\n private _originalFill: FillInput;\n\n /** @internal */\n public _stroke: ConvertedStrokeStyle;\n private _originalStroke: StrokeInput;\n\n private _dropShadow: TextDropShadow;\n\n private _fontFamily: string | string[];\n private _fontSize: number;\n private _fontStyle: TextStyleFontStyle;\n private _fontVariant: TextStyleFontVariant;\n private _fontWeight: TextStyleFontWeight;\n\n private _breakWords: boolean;\n private _align: TextStyleAlign;\n private _leading: number;\n private _letterSpacing: number;\n private _lineHeight: number;\n\n private _textBaseline: TextStyleTextBaseline;\n private _whiteSpace: TextStyleWhiteSpace;\n private _wordWrap: boolean;\n private _wordWrapWidth: number;\n private _filters: readonly Filter[];\n\n private _padding: number;\n\n private _trim: boolean;\n\n constructor(style: Partial<TextStyleOptions> = {})\n {\n super();\n\n convertV7Tov8Style(style);\n\n const fullStyle = { ...TextStyle.defaultTextStyle, ...style };\n\n for (const key in fullStyle)\n {\n const thisKey = key as keyof typeof this;\n\n this[thisKey] = fullStyle[key as keyof TextStyleOptions] as any;\n }\n\n this.update();\n this._tick = 0;\n }\n\n /**\n * Alignment for multiline text, does not affect single line text.\n * @type {'left'|'center'|'right'|'justify'}\n */\n get align(): TextStyleAlign { return this._align; }\n\n set align(value: TextStyleAlign)\n {\n if (this._align === value) return;\n\n this._align = value;\n this.update();\n }\n\n /** Indicates if lines can be wrapped within words, it needs wordWrap to be set to true. */\n get breakWords(): boolean { return this._breakWords; }\n\n set breakWords(value: boolean)\n {\n if (this._breakWords === value) return;\n\n this._breakWords = value;\n this.update();\n }\n\n /** Set a drop shadow for the text. */\n get dropShadow(): TextDropShadow { return this._dropShadow; }\n\n set dropShadow(value: boolean | TextDropShadow)\n {\n if (this._dropShadow === value) return;\n\n if (value !== null && typeof value === 'object')\n {\n this._dropShadow = this._createProxy({ ...TextStyle.defaultDropShadow, ...value });\n }\n else\n {\n this._dropShadow = value ? this._createProxy({ ...TextStyle.defaultDropShadow }) : null;\n }\n\n this.update();\n }\n\n /** The font family, can be a single font name, or a list of names where the first is the preferred font. */\n get fontFamily(): string | string[] { return this._fontFamily; }\n\n set fontFamily(value: string | string[])\n {\n if (this._fontFamily === value) return;\n\n this._fontFamily = value;\n this.update();\n }\n\n /** The font size (as a number it converts to px, but as a string, equivalents are '26px','20pt','160%' or '1.6em') */\n get fontSize(): number { return this._fontSize; }\n\n set fontSize(value: string | number)\n {\n if (this._fontSize === value) return;\n\n if (typeof value === 'string')\n {\n // eg '34px' to number\n this._fontSize = parseInt(value as string, 10);\n }\n else\n {\n this._fontSize = value as number;\n }\n this.update();\n }\n\n /**\n * The font style.\n * @type {'normal'|'italic'|'oblique'}\n */\n get fontStyle(): TextStyleFontStyle { return this._fontStyle; }\n\n set fontStyle(value: TextStyleFontStyle)\n {\n if (this._fontStyle === value) return;\n\n this._fontStyle = value.toLowerCase() as TextStyleFontStyle;\n this.update();\n }\n\n /**\n * The font variant.\n * @type {'normal'|'small-caps'}\n */\n get fontVariant(): TextStyleFontVariant { return this._fontVariant; }\n\n set fontVariant(value: TextStyleFontVariant)\n {\n if (this._fontVariant === value) return;\n\n this._fontVariant = value;\n this.update();\n }\n\n /**\n * The font weight.\n * @type {'normal'|'bold'|'bolder'|'lighter'|'100'|'200'|'300'|'400'|'500'|'600'|'700'|'800'|'900'}\n */\n get fontWeight(): TextStyleFontWeight { return this._fontWeight; }\n\n set fontWeight(value: TextStyleFontWeight)\n {\n if (this._fontWeight === value) return;\n\n this._fontWeight = value;\n this.update();\n }\n\n /** The space between lines. */\n get leading(): number { return this._leading; }\n\n set leading(value: number)\n {\n if (this._leading === value) return;\n\n this._leading = value;\n this.update();\n }\n\n /** The amount of spacing between letters, default is 0. */\n get letterSpacing(): number { return this._letterSpacing; }\n\n set letterSpacing(value: number)\n {\n if (this._letterSpacing === value) return;\n\n this._letterSpacing = value;\n this.update();\n }\n\n /** The line height, a number that represents the vertical space that a letter uses. */\n get lineHeight(): number { return this._lineHeight; }\n\n set lineHeight(value: number)\n {\n if (this._lineHeight === value) return;\n\n this._lineHeight = value;\n this.update();\n }\n\n /**\n * Occasionally some fonts are cropped. Adding some padding will prevent this from happening\n * by adding padding to all sides of the text.\n * > [!NOTE] This will NOT affect the positioning or bounds of the text.\n */\n get padding(): number { return this._padding; }\n\n set padding(value: number)\n {\n if (this._padding === value) return;\n\n this._padding = value;\n this.update();\n }\n\n /**\n * An optional filter or array of filters to apply to the text, allowing for advanced visual effects.\n * These filters will be applied to the text as it is created, resulting in faster rendering for static text\n * compared to applying the filter directly to the text object (which would be applied at run time).\n * @default null\n */\n get filters(): readonly Filter[] { return this._filters; }\n\n set filters(value: Filter[])\n {\n if (this._filters === value) return;\n\n this._filters = Object.freeze(value);\n this.update();\n }\n\n /**\n * Trim transparent borders from the text texture.\n * > [!IMPORTANT] PERFORMANCE WARNING:\n * > This is a costly operation as it requires scanning pixel alpha values.\n * > Avoid using `trim: true` for dynamic text, as it could significantly impact performance.\n */\n get trim(): boolean { return this._trim; }\n\n set trim(value: boolean)\n {\n if (this._trim === value) return;\n\n this._trim = value;\n this.update();\n }\n\n /**\n * The baseline of the text that is rendered.\n * @type {'alphabetic'|'top'|'hanging'|'middle'|'ideographic'|'bottom'}\n */\n get textBaseline(): TextStyleTextBaseline { return this._textBaseline; }\n\n set textBaseline(value: TextStyleTextBaseline)\n {\n if (this._textBaseline === value) return;\n\n this._textBaseline = value;\n this.update();\n }\n\n /**\n * How newlines and spaces should be handled.\n * Default is 'pre' (preserve, preserve).\n *\n * value | New lines | Spaces\n * --- | --- | ---\n * 'normal' | Collapse | Collapse\n * 'pre' | Preserve | Preserve\n * 'pre-line' | Preserve | Collapse\n * @type {'normal'|'pre'|'pre-line'}\n */\n get whiteSpace(): TextStyleWhiteSpace { return this._whiteSpace; }\n\n set whiteSpace(value: TextStyleWhiteSpace)\n {\n if (this._whiteSpace === value) return;\n\n this._whiteSpace = value;\n this.update();\n }\n\n /** Indicates if word wrap should be used. */\n get wordWrap(): boolean { return this._wordWrap; }\n\n set wordWrap(value: boolean)\n {\n if (this._wordWrap === value) return;\n\n this._wordWrap = value;\n this.update();\n }\n\n /** The width at which text will wrap, it needs wordWrap to be set to true. */\n get wordWrapWidth(): number { return this._wordWrapWidth; }\n\n set wordWrapWidth(value: number)\n {\n if (this._wordWrapWidth === value) return;\n\n this._wordWrapWidth = value;\n this.update();\n }\n\n /**\n * The fill style that will be used to color the text.\n * This can be:\n * - A color string like 'red', '#00FF00', or 'rgba(255,0,0,0.5)'\n * - A hex number like 0xff0000 for red\n * - A FillStyle object with properties like { color: 0xff0000, alpha: 0.5 }\n * - A FillGradient for gradient fills\n * - A FillPattern for pattern/texture fills\n *\n * When using a FillGradient, vertical gradients (angle of 90 degrees) are applied per line of text,\n * while gradients at any other angle are spread across the entire text body as a whole.\n * @example\n * // Vertical gradient applied per line\n * const verticalGradient = new FillGradient(0, 0, 0, 1)\n * .addColorStop(0, 0xff0000)\n * .addColorStop(1, 0x0000ff);\n *\n * const text = new Text({\n * text: 'Line 1\\nLine 2',\n * style: { fill: verticalGradient }\n * });\n *\n * To manage the gradient in a global scope, set the textureSpace property of the FillGradient to 'global'.\n * @type {string|number|FillStyle|FillGradient|FillPattern}\n */\n get fill(): FillInput\n {\n return this._originalFill;\n }\n\n set fill(value: FillInput)\n {\n if (value === this._originalFill) return;\n\n this._originalFill = value;\n\n if (this._isFillStyle(value))\n {\n this._originalFill = this._createProxy({ ...GraphicsContext.defaultFillStyle, ...value }, () =>\n {\n this._fill = toFillStyle(\n { ...this._originalFill as FillStyle },\n GraphicsContext.defaultFillStyle\n );\n });\n }\n\n this._fill = toFillStyle(\n value === 0x0 ? 'black' : value,\n GraphicsContext.defaultFillStyle\n );\n this.update();\n }\n\n /** A fillstyle that will be used on the text stroke, e.g., 'blue', '#FCFF00'. */\n get stroke(): StrokeInput\n {\n return this._originalStroke;\n }\n\n set stroke(value: StrokeInput)\n {\n if (value === this._originalStroke) return;\n\n this._originalStroke = value;\n\n if (this._isFillStyle(value))\n {\n this._originalStroke = this._createProxy({ ...GraphicsContext.defaultStrokeStyle, ...value }, () =>\n {\n this._stroke = toStrokeStyle(\n { ...this._originalStroke as StrokeStyle },\n GraphicsContext.defaultStrokeStyle\n );\n });\n }\n\n this._stroke = toStrokeStyle(value, GraphicsContext.defaultStrokeStyle);\n this.update();\n }\n\n public update()\n {\n this._tick++;\n this.emit('update', this);\n }\n\n /** Resets all properties to the default values */\n public reset()\n {\n const defaultStyle = TextStyle.defaultTextStyle;\n\n for (const key in defaultStyle)\n {\n this[key as keyof typeof this] = defaultStyle[key as keyof TextStyleOptions] as any;\n }\n }\n\n /**\n * Returns a unique key for this instance.\n * This key is used for caching.\n * @returns {string} Unique key for the instance\n */\n public get styleKey(): string\n {\n return `${this.uid}-${this._tick}`;\n }\n\n /**\n * Creates a new TextStyle object with the same values as this one.\n * @returns New cloned TextStyle object\n */\n public clone(): TextStyle\n {\n return new TextStyle({\n align: this.align,\n breakWords: this.breakWords,\n dropShadow: this._dropShadow ? { ...this._dropShadow } : null,\n fill: this._fill,\n fontFamily: this.fontFamily,\n fontSize: this.fontSize,\n fontStyle: this.fontStyle,\n fontVariant: this.fontVariant,\n fontWeight: this.fontWeight,\n leading: this.leading,\n letterSpacing: this.letterSpacing,\n lineHeight: this.lineHeight,\n padding: this.padding,\n stroke: this._stroke,\n textBaseline: this.textBaseline,\n whiteSpace: this.whiteSpace,\n wordWrap: this.wordWrap,\n wordWrapWidth: this.wordWrapWidth,\n filters: this._filters ? [...this._filters] : undefined\n });\n }\n\n /**\n * Returns the final padding for the text style, taking into account any filters applied.\n * Used internally for correct measurements\n * @internal\n * @returns {number} The final padding for the text style.\n */\n public _getFinalPadding(): number\n {\n let filterPadding = 0;\n\n if (this._filters)\n {\n for (let i = 0; i < this._filters.length; i++)\n {\n filterPadding += this._filters[i].padding;\n }\n }\n\n return Math.max(this._padding, filterPadding);\n }\n\n /**\n * Destroys this text style.\n * @param options - Options parameter. A boolean will act as if all options\n * have been set to that value\n * @example\n * // Destroy the text style and its textures\n * textStyle.destroy({ texture: true, textureSource: true });\n * textStyle.destroy(true);\n */\n public destroy(options: TypeOrBool<TextureDestroyOptions> = false)\n {\n this.removeAllListeners();\n\n const destroyTexture = typeof options === 'boolean' ? options : options?.texture;\n\n if (destroyTexture)\n {\n const destroyTextureSource = typeof options === 'boolean' ? options : options?.textureSource;\n\n if (this._fill?.texture)\n {\n this._fill.texture.destroy(destroyTextureSource);\n }\n\n if ((this._originalFill as FillStyle)?.texture)\n {\n (this._originalFill as FillStyle).texture.destroy(destroyTextureSource);\n }\n\n if (this._stroke?.texture)\n {\n this._stroke.texture.destroy(destroyTextureSource);\n }\n\n if ((this._originalStroke as FillStyle)?.texture)\n {\n (this._originalStroke as FillStyle).texture.destroy(destroyTextureSource);\n }\n }\n\n this._fill = null;\n this._stroke = null;\n this.dropShadow = null;\n this._originalStroke = null;\n this._originalFill = null;\n }\n\n private _createProxy<T extends object>(value: T, cb?: (property: string, newValue: any) => void): T\n {\n return new Proxy<T>(value, {\n set: (target, property, newValue) =>\n {\n if (target[property as keyof T] === newValue) return true;\n\n target[property as keyof T] = newValue;\n cb?.(property as string, newValue);\n this.update();\n\n return true;\n }\n });\n }\n\n private _isFillStyle(value: FillInput): value is FillStyle\n {\n return ((value ?? null) !== null\n && !(Color.isColorLike(value) || value instanceof FillGradient || value instanceof FillPattern));\n }\n}\n\nfunction convertV7Tov8Style(style: TextStyleOptions)\n{\n const oldStyle = style as TextStyleOptions & {\n dropShadowAlpha?: number;\n dropShadowAngle?: number;\n dropShadowBlur?: number;\n dropShadowColor?: number;\n dropShadowDistance?: number;\n fillGradientStops?: number[];\n strokeThickness?: number;\n };\n\n if (typeof oldStyle.dropShadow === 'boolean' && oldStyle.dropShadow)\n {\n const defaults = TextStyle.defaultDropShadow;\n\n style.dropShadow = {\n alpha: oldStyle.dropShadowAlpha ?? defaults.alpha,\n angle: oldStyle.dropShadowAngle ?? defaults.angle,\n blur: oldStyle.dropShadowBlur ?? defaults.blur,\n color: oldStyle.dropShadowColor ?? defaults.color,\n distance: oldStyle.dropShadowDistance ?? defaults.distance\n };\n }\n\n if (oldStyle.strokeThickness !== undefined)\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'strokeThickness is now a part of stroke');\n // #endif\n\n const color = oldStyle.stroke;\n let obj: FillStyle = {};\n\n // handles stroke: 0x0, stroke: { r: 0, g: 0, b: 0, a: 0 } stroke: new Color(0x0)\n if (Color.isColorLike(color as ColorSource))\n {\n obj.color = color as ColorSource;\n }\n // handles stroke: new FillGradient()\n else if (color instanceof FillGradient || color instanceof FillPattern)\n {\n obj.fill = color as FillGradient | FillPattern;\n }\n // handles stroke: { color: 0x0 } or stroke: { fill: new FillGradient() }\n else if (Object.hasOwnProperty.call(color, 'color') || Object.hasOwnProperty.call(color, 'fill'))\n {\n obj = color as FillStyle;\n }\n else\n {\n throw new Error('Invalid stroke value.');\n }\n\n style.stroke = {\n ...obj,\n width: oldStyle.strokeThickness\n };\n }\n\n if (Array.isArray(oldStyle.fillGradientStops))\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'gradient fill is now a fill pattern: `new FillGradient(...)`');\n // #endif\n\n if (!Array.isArray(oldStyle.fill) || oldStyle.fill.length === 0)\n {\n throw new Error('Invalid fill value. Expected an array of colors for gradient fill.');\n }\n\n if (oldStyle.fill.length !== oldStyle.fillGradientStops.length)\n {\n // #if _DEBUG\n warn('The number of fill colors must match the number of fill gradient stops.');\n // #endif\n }\n\n const gradientFill = new FillGradient({\n start: { x: 0, y: 0 },\n end: { x: 0, y: 1 },\n textureSpace: 'local'\n });\n\n const fillGradientStops = oldStyle.fillGradientStops.slice();\n const fills: number[] = oldStyle.fill\n .map((color: ColorSource) => Color.shared.setValue(color).toNumber());\n\n fillGradientStops.forEach((stop, index) =>\n {\n gradientFill.addColorStop(stop, fills[index]);\n });\n\n style.fill = {\n fill: gradientFill\n };\n }\n}\n\n", "import { type ImageLike } from '../../../environment/ImageLike';\nimport { TexturePool } from '../../../rendering/renderers/shared/texture/TexturePool';\nimport { Bounds } from '../../container/bounds/Bounds';\n\nimport type { ICanvas } from '../../../environment/canvas/ICanvas';\nimport type { Texture } from '../../../rendering/renderers/shared/texture/Texture';\n\nconst tempBounds = new Bounds();\n\n/**\n * Takes an image and creates a texture from it, using a power of 2 texture from the texture pool.\n * Remember to return the texture when you don't need it any more!\n * @param image - The image to create a texture from\n * @param width - the frame width of the texture\n * @param height - the frame height of the texture\n * @param resolution - The resolution of the texture\n * @returns - The texture\n * @internal\n */\nexport function getPo2TextureFromSource(\n image: ImageLike | HTMLCanvasElement | ICanvas,\n width: number,\n height: number,\n resolution: number\n): Texture\n{\n const bounds = tempBounds;\n\n bounds.minX = 0;\n bounds.minY = 0;\n\n bounds.maxX = (image.width / resolution) | 0;\n bounds.maxY = (image.height / resolution) | 0;\n\n const texture = TexturePool.getOptimalTexture(\n bounds.width,\n bounds.height,\n resolution,\n false\n );\n\n texture.source.uploadMethodId = 'image';\n texture.source.resource = image;\n texture.source.alphaMode = 'premultiply-alpha-on-upload';\n\n texture.frame.width = width / resolution;\n texture.frame.height = height / resolution;\n\n // We want to update the resource on the GPU,\n // but we do not want to resize the texture.\n // calling `texture.source.update` will fit the resource to the texture\n // causing a resize of the texture on the GPU.\n // which is not what we want!\n texture.source.emit('update', texture.source);\n\n texture.updateUvs();\n\n return texture;\n}\n", "import { DOMAdapter } from '../../environment/adapter';\nimport { nextPow2 } from '../../maths/misc/pow2';\nimport { Rectangle } from '../../maths/shapes/Rectangle';\n\nimport type { ICanvas } from '../../environment/canvas/ICanvas';\nimport type { ICanvasRenderingContext2D } from '../../environment/canvas/ICanvasRenderingContext2D';\n\n// Internal canvas for measuring bounds\nlet _internalCanvas: ICanvas | null = null;\nlet _internalContext: ICanvasRenderingContext2D | null = null;\n\nfunction ensureInternalCanvas(width: number, height: number): void\n{\n if (!_internalCanvas)\n {\n _internalCanvas = DOMAdapter.get().createCanvas(256, 128);\n _internalContext = _internalCanvas.getContext('2d', { willReadFrequently: true });\n _internalContext.globalCompositeOperation = 'copy';\n _internalContext.globalAlpha = 1;\n }\n\n if (_internalCanvas.width < width || _internalCanvas.height < height)\n {\n // Use power-of-two dimensions for better performance\n _internalCanvas.width = nextPow2(width);\n _internalCanvas.height = nextPow2(height);\n }\n}\n\nfunction checkRow(data: Uint8ClampedArray, width: number, y: number)\n{\n for (let x = 0, index = 4 * y * width; x < width; ++x, index += 4)\n {\n if (data[index + 3] !== 0) return false;\n }\n\n return true;\n}\n\nfunction checkColumn(data: Uint8ClampedArray, width: number, x: number, top: number, bottom: number)\n{\n const stride = 4 * width;\n\n for (let y = top, index = (top * stride) + (4 * x); y <= bottom; ++y, index += stride)\n {\n if (data[index + 3] !== 0) return false;\n }\n\n return true;\n}\n\n/** @internal */\nexport interface GetCanvasBoundingBoxOptions\n{\n /** The canvas to measure */\n canvas: ICanvas;\n /** Optional. The width to analyze (defaults to canvas.width) */\n width?: number;\n /** Optional. The height to analyze (defaults to canvas.height) */\n height?: number;\n /**\n * Optional. The resolution at which to analyze the canvas, between 0-1.\n * Lower values improve performance for large canvases but may be less precise.\n * Default is 1 (full resolution).\n */\n resolution?: number;\n /** Optional. The rectangle to store the result in. */\n output?: Rectangle;\n}\n\n/**\n * Measures the bounding box of a canvas's visible (non-transparent) pixels.\n *\n * This function analyzes the alpha channel of the canvas pixels to find the smallest\n * rectangle containing all non-transparent pixels. It's useful for optimizing sprite\n * rendering by trimming transparent borders.\n *\n * Uses an internal canvas with `willReadFrequently: true` for efficient pixel data access.\n * This internal canvas is reused between calls for better performance.\n * @example\n * ```typescript\n * // Basic usage - get trim bounds at full resolution\n * const bounds = getCanvasBoundingBox({ canvas: myCanvas });\n * console.log(bounds); // Rectangle{x: 10, y: 5, width: 100, height: 200}\n * // Optimized for performance with lower resolution scanning\n * const fastBounds = getCanvasBoundingBox({\n * canvas: largeCanvas,\n * width: largeCanvas.width,\n * height: largeCanvas.height,\n * resolution: 0.5\n * });\n * // Resolution of 0.5 means scanning at half size, much faster for large canvases\n *\n * // Using custom dimensions - only analyze part of the canvas\n * const partialBounds = getCanvasBoundingBox({ canvas: myCanvas, width: 100, height: 100 });\n * // Only analyzes a 100x100 region starting from top-left\n * ```\n * @param options - The options for measuring the bounding box, including the canvas to measure.\n * @returns The bounding box as a Rectangle containing the visible content.\n * Returns Rectangle.EMPTY if the canvas is completely transparent.\n * @internal\n */\nexport function getCanvasBoundingBox(\n options: GetCanvasBoundingBoxOptions,\n): Rectangle;\n/**\n * @param canvas\n * @param resolution\n * @internal\n * @deprecated since 8.10.0\n */\nexport function getCanvasBoundingBox(canvas: ICanvas, resolution?: number): Rectangle;\n/**\n * @param {...any} args\n * @internal\n */\nexport function getCanvasBoundingBox(...args: [GetCanvasBoundingBoxOptions] | [ICanvas, number?]): Rectangle\n{\n let options = args[0] as GetCanvasBoundingBoxOptions;\n\n if (!options.canvas)\n {\n options = { canvas: args[0] as ICanvas, resolution: args[1] };\n }\n\n const { canvas } = options; // canvas is correctly extracted from options\n\n // Cap resolution at 1\n const resolution = Math.min(options.resolution ?? 1, 1);\n const width = options.width ?? canvas.width;\n const height = options.height ?? canvas.height;\n let output = options.output;\n\n // Ensure internal canvas is large enough\n ensureInternalCanvas(width, height);\n\n if (!_internalContext)\n {\n throw new TypeError('Failed to get canvas 2D context');\n }\n\n // Set up for pixel replacement (no blending)\n _internalContext.drawImage(\n canvas as unknown as CanvasImageSource,\n 0, 0,\n width, height,\n 0, 0,\n width * resolution, height * resolution\n );\n\n // Get the image data at full resolution\n const imageData = _internalContext.getImageData(0, 0, width, height);\n const data = imageData.data;\n\n let left = 0;\n let top = 0;\n let right = width - 1;\n let bottom = height - 1;\n\n while (top < height && checkRow(data, width, top)) ++top;\n if (top === height) return Rectangle.EMPTY;\n while (checkRow(data, width, bottom)) --bottom;\n while (checkColumn(data, width, left, top, bottom)) ++left;\n while (checkColumn(data, width, right, top, bottom)) --right;\n\n ++right;\n ++bottom;\n\n _internalContext.globalCompositeOperation = 'source-over';\n // draw the rect on the canvas\n _internalContext.strokeRect(left, top, right - left, bottom - top);\n _internalContext.globalCompositeOperation = 'copy';\n\n output ??= new Rectangle();\n\n output.set(left / resolution, top / resolution, (right - left) / resolution, (bottom - top) / resolution);\n\n return output;\n}\n\n", "/**\n * tiny-lru\n *\n * @copyright 2025 Jason Mulligan <jason.mulligan@avoidwork.com>\n * @license BSD-3-Clause\n * @version 11.4.5\n */\n/**\n * A high-performance Least Recently Used (LRU) cache implementation with optional TTL support.\n * Items are automatically evicted when the cache reaches its maximum size,\n * removing the least recently used items first. All core operations (get, set, delete) are O(1).\n *\n * @class LRU\n * @example\n * // Create a cache with max 100 items\n * const cache = new LRU(100);\n * cache.set('key1', 'value1');\n * console.log(cache.get('key1')); // 'value1'\n *\n * @example\n * // Create a cache with TTL\n * const cache = new LRU(100, 5000); // 5 second TTL\n * cache.set('key1', 'value1');\n * // After 5 seconds, key1 will be expired\n */\nclass LRU {\n\t/**\n\t * Creates a new LRU cache instance.\n\t * Note: Constructor does not validate parameters. Use lru() factory function for parameter validation.\n\t *\n\t * @constructor\n\t * @param {number} [max=0] - Maximum number of items to store. 0 means unlimited.\n\t * @param {number} [ttl=0] - Time to live in milliseconds. 0 means no expiration.\n\t * @param {boolean} [resetTtl=false] - Whether to reset TTL when accessing existing items via get().\n\t * @example\n\t * const cache = new LRU(1000, 60000, true); // 1000 items, 1 minute TTL, reset on access\n\t * @see {@link lru} For parameter validation\n\t * @since 1.0.0\n\t */\n\tconstructor (max = 0, ttl = 0, resetTtl = false) {\n\t\tthis.first = null;\n\t\tthis.items = Object.create(null);\n\t\tthis.last = null;\n\t\tthis.max = max;\n\t\tthis.resetTtl = resetTtl;\n\t\tthis.size = 0;\n\t\tthis.ttl = ttl;\n\t}\n\n\t/**\n\t * Removes all items from the cache.\n\t *\n\t * @method clear\n\t * @memberof LRU\n\t * @returns {LRU} The LRU instance for method chaining.\n\t * @example\n\t * cache.clear();\n\t * console.log(cache.size); // 0\n\t * @since 1.0.0\n\t */\n\tclear () {\n\t\tthis.first = null;\n\t\tthis.items = Object.create(null);\n\t\tthis.last = null;\n\t\tthis.size = 0;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes an item from the cache by key.\n\t *\n\t * @method delete\n\t * @memberof LRU\n\t * @param {string} key - The key of the item to delete.\n\t * @returns {LRU} The LRU instance for method chaining.\n\t * @example\n\t * cache.set('key1', 'value1');\n\t * cache.delete('key1');\n\t * console.log(cache.has('key1')); // false\n\t * @see {@link LRU#has}\n\t * @see {@link LRU#clear}\n\t * @since 1.0.0\n\t */\n\tdelete (key) {\n\t\tif (this.has(key)) {\n\t\t\tconst item = this.items[key];\n\n\t\t\tdelete this.items[key];\n\t\t\tthis.size--;\n\n\t\t\tif (item.prev !== null) {\n\t\t\t\titem.prev.next = item.next;\n\t\t\t}\n\n\t\t\tif (item.next !== null) {\n\t\t\t\titem.next.prev = item.prev;\n\t\t\t}\n\n\t\t\tif (this.first === item) {\n\t\t\t\tthis.first = item.next;\n\t\t\t}\n\n\t\t\tif (this.last === item) {\n\t\t\t\tthis.last = item.prev;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns an array of [key, value] pairs for the specified keys.\n\t * Order follows LRU order (least to most recently used).\n\t *\n\t * @method entries\n\t * @memberof LRU\n\t * @param {string[]} [keys=this.keys()] - Array of keys to get entries for. Defaults to all keys.\n\t * @returns {Array<Array<*>>} Array of [key, value] pairs in LRU order.\n\t * @example\n\t * cache.set('a', 1).set('b', 2);\n\t * console.log(cache.entries()); // [['a', 1], ['b', 2]]\n\t * console.log(cache.entries(['a'])); // [['a', 1]]\n\t * @see {@link LRU#keys}\n\t * @see {@link LRU#values}\n\t * @since 11.1.0\n\t */\n\tentries (keys = this.keys()) {\n\t\treturn keys.map(key => [key, this.get(key)]);\n\t}\n\n\t/**\n\t * Removes the least recently used item from the cache.\n\t *\n\t * @method evict\n\t * @memberof LRU\n\t * @param {boolean} [bypass=false] - Whether to force eviction even when cache is empty.\n\t * @returns {LRU} The LRU instance for method chaining.\n\t * @example\n\t * cache.set('old', 'value').set('new', 'value');\n\t * cache.evict(); // Removes 'old' item\n\t * @see {@link LRU#setWithEvicted}\n\t * @since 1.0.0\n\t */\n\tevict (bypass = false) {\n\t\tif (bypass || this.size > 0) {\n\t\t\tconst item = this.first;\n\n\t\t\tdelete this.items[item.key];\n\n\t\t\tif (--this.size === 0) {\n\t\t\t\tthis.first = null;\n\t\t\t\tthis.last = null;\n\t\t\t} else {\n\t\t\t\tthis.first = item.next;\n\t\t\t\tthis.first.prev = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns the expiration timestamp for a given key.\n\t *\n\t * @method expiresAt\n\t * @memberof LRU\n\t * @param {string} key - The key to check expiration for.\n\t * @returns {number|undefined} The expiration timestamp in milliseconds, or undefined if key doesn't exist.\n\t * @example\n\t * const cache = new LRU(100, 5000); // 5 second TTL\n\t * cache.set('key1', 'value1');\n\t * console.log(cache.expiresAt('key1')); // timestamp 5 seconds from now\n\t * @see {@link LRU#get}\n\t * @see {@link LRU#has}\n\t * @since 1.0.0\n\t */\n\texpiresAt (key) {\n\t\tlet result;\n\n\t\tif (this.has(key)) {\n\t\t\tresult = this.items[key].expiry;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Retrieves a value from the cache by key. Updates the item's position to most recently used.\n\t *\n\t * @method get\n\t * @memberof LRU\n\t * @param {string} key - The key to retrieve.\n\t * @returns {*} The value associated with the key, or undefined if not found or expired.\n\t * @example\n\t * cache.set('key1', 'value1');\n\t * console.log(cache.get('key1')); // 'value1'\n\t * console.log(cache.get('nonexistent')); // undefined\n\t * @see {@link LRU#set}\n\t * @see {@link LRU#has}\n\t * @since 1.0.0\n\t */\n\tget (key) {\n\t\tconst item = this.items[key];\n\n\t\tif (item !== undefined) {\n\t\t\t// Check TTL only if enabled to avoid unnecessary Date.now() calls\n\t\t\tif (this.ttl > 0) {\n\t\t\t\tif (item.expiry <= Date.now()) {\n\t\t\t\t\tthis.delete(key);\n\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fast LRU update without full set() overhead\n\t\t\tthis.moveToEnd(item);\n\n\t\t\treturn item.value;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Checks if a key exists in the cache.\n\t *\n\t * @method has\n\t * @memberof LRU\n\t * @param {string} key - The key to check for.\n\t * @returns {boolean} True if the key exists, false otherwise.\n\t * @example\n\t * cache.set('key1', 'value1');\n\t * console.log(cache.has('key1')); // true\n\t * console.log(cache.has('nonexistent')); // false\n\t * @see {@link LRU#get}\n\t * @see {@link LRU#delete}\n\t * @since 9.0.0\n\t */\n\thas (key) {\n\t\treturn key in this.items;\n\t}\n\n\t/**\n\t * Efficiently moves an item to the end of the LRU list (most recently used position).\n\t * This is an internal optimization method that avoids the overhead of the full set() operation\n\t * when only LRU position needs to be updated.\n\t *\n\t * @method moveToEnd\n\t * @memberof LRU\n\t * @param {Object} item - The cache item with prev/next pointers to reposition.\n\t * @private\n\t * @since 11.3.5\n\t */\n\tmoveToEnd (item) {\n\t\t// If already at the end, nothing to do\n\t\tif (this.last === item) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove item from current position in the list\n\t\tif (item.prev !== null) {\n\t\t\titem.prev.next = item.next;\n\t\t}\n\n\t\tif (item.next !== null) {\n\t\t\titem.next.prev = item.prev;\n\t\t}\n\n\t\t// Update first pointer if this was the first item\n\t\tif (this.first === item) {\n\t\t\tthis.first = item.next;\n\t\t}\n\n\t\t// Add item to the end\n\t\titem.prev = this.last;\n\t\titem.next = null;\n\n\t\tif (this.last !== null) {\n\t\t\tthis.last.next = item;\n\t\t}\n\n\t\tthis.last = item;\n\n\t\t// Handle edge case: if this was the only item, it's also first\n\t\tif (this.first === null) {\n\t\t\tthis.first = item;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an array of all keys in the cache, ordered from least to most recently used.\n\t *\n\t * @method keys\n\t * @memberof LRU\n\t * @returns {string[]} Array of keys in LRU order.\n\t * @example\n\t * cache.set('a', 1).set('b', 2);\n\t * cache.get('a'); // Move 'a' to most recent\n\t * console.log(cache.keys()); // ['b', 'a']\n\t * @see {@link LRU#values}\n\t * @see {@link LRU#entries}\n\t * @since 9.0.0\n\t */\n\tkeys () {\n\t\tconst result = [];\n\t\tlet x = this.first;\n\n\t\twhile (x !== null) {\n\t\t\tresult.push(x.key);\n\t\t\tx = x.next;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Sets a value in the cache and returns any evicted item.\n\t *\n\t * @method setWithEvicted\n\t * @memberof LRU\n\t * @param {string} key - The key to set.\n\t * @param {*} value - The value to store.\n\t * @param {boolean} [resetTtl=this.resetTtl] - Whether to reset the TTL for this operation.\n\t * @returns {Object|null} The evicted item (if any) with shape {key, value, expiry, prev, next}, or null.\n\t * @example\n\t * const cache = new LRU(2);\n\t * cache.set('a', 1).set('b', 2);\n\t * const evicted = cache.setWithEvicted('c', 3); // evicted = {key: 'a', value: 1, ...}\n\t * @see {@link LRU#set}\n\t * @see {@link LRU#evict}\n\t * @since 11.3.0\n\t */\n\tsetWithEvicted (key, value, resetTtl = this.resetTtl) {\n\t\tlet evicted = null;\n\n\t\tif (this.has(key)) {\n\t\t\tthis.set(key, value, true, resetTtl);\n\t\t} else {\n\t\t\tif (this.max > 0 && this.size === this.max) {\n\t\t\t\tevicted = {...this.first};\n\t\t\t\tthis.evict(true);\n\t\t\t}\n\n\t\t\tlet item = this.items[key] = {\n\t\t\t\texpiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,\n\t\t\t\tkey: key,\n\t\t\t\tprev: this.last,\n\t\t\t\tnext: null,\n\t\t\t\tvalue\n\t\t\t};\n\n\t\t\tif (++this.size === 1) {\n\t\t\t\tthis.first = item;\n\t\t\t} else {\n\t\t\t\tthis.last.next = item;\n\t\t\t}\n\n\t\t\tthis.last = item;\n\t\t}\n\n\t\treturn evicted;\n\t}\n\n\t/**\n\t * Sets a value in the cache. Updates the item's position to most recently used.\n\t *\n\t * @method set\n\t * @memberof LRU\n\t * @param {string} key - The key to set.\n\t * @param {*} value - The value to store.\n\t * @param {boolean} [bypass=false] - Internal parameter for setWithEvicted method.\n\t * @param {boolean} [resetTtl=this.resetTtl] - Whether to reset the TTL for this operation.\n\t * @returns {LRU} The LRU instance for method chaining.\n\t * @example\n\t * cache.set('key1', 'value1')\n\t * .set('key2', 'value2')\n\t * .set('key3', 'value3');\n\t * @see {@link LRU#get}\n\t * @see {@link LRU#setWithEvicted}\n\t * @since 1.0.0\n\t */\n\tset (key, value, bypass = false, resetTtl = this.resetTtl) {\n\t\tlet item = this.items[key];\n\n\t\tif (bypass || item !== undefined) {\n\t\t\t// Existing item: update value and position\n\t\t\titem.value = value;\n\n\t\t\tif (bypass === false && resetTtl) {\n\t\t\t\titem.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;\n\t\t\t}\n\n\t\t\t// Always move to end, but the bypass parameter affects TTL reset behavior\n\t\t\tthis.moveToEnd(item);\n\t\t} else {\n\t\t\t// New item: check for eviction and create\n\t\t\tif (this.max > 0 && this.size === this.max) {\n\t\t\t\tthis.evict(true);\n\t\t\t}\n\n\t\t\titem = this.items[key] = {\n\t\t\t\texpiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,\n\t\t\t\tkey: key,\n\t\t\t\tprev: this.last,\n\t\t\t\tnext: null,\n\t\t\t\tvalue\n\t\t\t};\n\n\t\t\tif (++this.size === 1) {\n\t\t\t\tthis.first = item;\n\t\t\t} else {\n\t\t\t\tthis.last.next = item;\n\t\t\t}\n\n\t\t\tthis.last = item;\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns an array of all values in the cache for the specified keys.\n\t * Order follows LRU order (least to most recently used).\n\t *\n\t * @method values\n\t * @memberof LRU\n\t * @param {string[]} [keys=this.keys()] - Array of keys to get values for. Defaults to all keys.\n\t * @returns {Array<*>} Array of values corresponding to the keys in LRU order.\n\t * @example\n\t * cache.set('a', 1).set('b', 2);\n\t * console.log(cache.values()); // [1, 2]\n\t * console.log(cache.values(['a'])); // [1]\n\t * @see {@link LRU#keys}\n\t * @see {@link LRU#entries}\n\t * @since 11.1.0\n\t */\n\tvalues (keys = this.keys()) {\n\t\treturn keys.map(key => this.get(key));\n\t}\n}\n\n/**\n * Factory function to create a new LRU cache instance with parameter validation.\n *\n * @function lru\n * @param {number} [max=1000] - Maximum number of items to store. Must be >= 0. Use 0 for unlimited size.\n * @param {number} [ttl=0] - Time to live in milliseconds. Must be >= 0. Use 0 for no expiration.\n * @param {boolean} [resetTtl=false] - Whether to reset TTL when accessing existing items via get().\n * @returns {LRU} A new LRU cache instance.\n * @throws {TypeError} When parameters are invalid (negative numbers or wrong types).\n * @example\n * // Create cache with factory function\n * const cache = lru(100, 5000, true);\n * cache.set('key', 'value');\n *\n * @example\n * // Error handling\n * try {\n * const cache = lru(-1); // Invalid max\n * } catch (error) {\n * console.error(error.message); // \"Invalid max value\"\n * }\n * @see {@link LRU}\n * @since 1.0.0\n */\nfunction lru (max = 1000, ttl = 0, resetTtl = false) {\n\tif (isNaN(max) || max < 0) {\n\t\tthrow new TypeError(\"Invalid max value\");\n\t}\n\n\tif (isNaN(ttl) || ttl < 0) {\n\t\tthrow new TypeError(\"Invalid ttl value\");\n\t}\n\n\tif (typeof resetTtl !== \"boolean\") {\n\t\tthrow new TypeError(\"Invalid resetTtl value\");\n\t}\n\n\treturn new LRU(max, ttl, resetTtl);\n}export{LRU,lru};", "import type { TextStyle } from '../../TextStyle';\n\nconst genericFontFamilies = [\n 'serif',\n 'sans-serif',\n 'monospace',\n 'cursive',\n 'fantasy',\n 'system-ui',\n];\n\n/**\n * Generates a font style string to use for `TextMetrics.measureFont()`.\n * @param style\n * @returns Font style string, for passing to `TextMetrics.measureFont()`\n * @internal\n */\nexport function fontStringFromTextStyle(style: TextStyle): string\n{\n // build canvas api font setting from individual components. Convert a numeric style.fontSize to px\n const fontSizeString = (typeof style.fontSize === 'number') ? `${style.fontSize}px` : style.fontSize;\n\n // Clean-up fontFamily property by quoting each font name\n // this will support font names with spaces\n let fontFamilies: string | string[] = style.fontFamily;\n\n if (!Array.isArray(style.fontFamily))\n {\n fontFamilies = style.fontFamily.split(',');\n }\n\n for (let i = fontFamilies.length - 1; i >= 0; i--)\n {\n // Trim any extra white-space\n let fontFamily = fontFamilies[i].trim();\n\n // Check if font already contains strings\n if (!(/([\\\"\\'])[^\\'\\\"]+\\1/).test(fontFamily) && !genericFontFamilies.includes(fontFamily))\n {\n fontFamily = `\"${fontFamily}\"`;\n }\n (fontFamilies as string[])[i] = fontFamily;\n }\n\n // eslint-disable-next-line max-len\n return `${style.fontStyle} ${style.fontVariant} ${style.fontWeight} ${fontSizeString} ${(fontFamilies as string[]).join(',')}`;\n}\n", "import { lru } from 'tiny-lru';\nimport { DOMAdapter } from '../../../environment/adapter';\nimport { fontStringFromTextStyle } from './utils/fontStringFromTextStyle';\n\nimport type { ICanvas, ICanvasRenderingContext2DSettings } from '../../../environment/canvas/ICanvas';\nimport type { ICanvasRenderingContext2D } from '../../../environment/canvas/ICanvasRenderingContext2D';\nimport type { TextStyle, TextStyleWhiteSpace } from '../TextStyle';\n\n// The type for Intl.Segmenter is only available since TypeScript 4.7.2, so let's make a polyfill for it.\ninterface ISegmentData\n{\n segment: string;\n}\ninterface ISegments\n{\n [Symbol.iterator](): IterableIterator<ISegmentData>;\n}\ninterface ISegmenter\n{\n segment(input: string): ISegments;\n}\ninterface IIntl\n{\n Segmenter?: {\n prototype: ISegmenter;\n /**\n * Creates a new Intl.Segmenter object.\n * @returns A new Intl.Segmenter object.\n */\n new(): ISegmenter;\n };\n}\n\n/**\n * A number, or a string containing a number.\n * @category text\n * @typedef {object} FontMetrics\n * @property {number} ascent - Font ascent\n * @property {number} descent - Font descent\n * @property {number} fontSize - Font size\n * @advanced\n */\nexport interface FontMetrics\n{\n ascent: number;\n descent: number;\n fontSize: number;\n}\n\ntype CharacterWidthCache = Record<string, number>;\n\n// Default settings used for all getContext calls\nconst contextSettings: ICanvasRenderingContext2DSettings = {\n // TextMetrics requires getImageData readback for measuring fonts.\n willReadFrequently: true,\n};\n\n/**\n * The TextMetrics object represents the measurement of a block of text with a specified style.\n * @example\n * import { CanvasTextMetrics, TextStyle } from 'pixi.js';\n *\n * const style = new TextStyle({\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * });\n * const textMetrics = CanvasTextMetrics.measureText('Your text', style);\n * @category text\n * @advanced\n */\nexport class CanvasTextMetrics\n{\n /** The text that was measured. */\n public text: string;\n\n /** The style that was measured. */\n public style: TextStyle;\n\n /** The measured width of the text. */\n public width: number;\n\n /** The measured height of the text. */\n public height: number;\n\n /** An array of lines of the text broken by new lines and wrapping is specified in style. */\n public lines: string[];\n\n /** An array of the line widths for each line matched to `lines`. */\n public lineWidths: number[];\n\n /** The measured line height for this style. */\n public lineHeight: number;\n\n /** The maximum line width for all measured lines. */\n public maxLineWidth: number;\n\n /** The font properties object from TextMetrics.measureFont. */\n public fontProperties: FontMetrics;\n\n /**\n * String used for calculate font metrics.\n * These characters are all tall to help calculate the height required for text.\n */\n public static METRICS_STRING = '|ÉqÅ';\n\n /** Baseline symbol for calculate font metrics. */\n public static BASELINE_SYMBOL = 'M';\n\n /** Baseline multiplier for calculate font metrics. */\n public static BASELINE_MULTIPLIER = 1.4;\n\n /** Height multiplier for setting height of canvas to calculate font metrics. */\n public static HEIGHT_MULTIPLIER = 2.0;\n\n /**\n * A Unicode \"character\", or \"grapheme cluster\", can be composed of multiple Unicode code points,\n * such as letters with diacritical marks (e.g. `'\\u0065\\u0301'`, letter e with acute)\n * or emojis with modifiers (e.g. `'\\uD83E\\uDDD1\\u200D\\uD83D\\uDCBB'`, technologist).\n * The new `Intl.Segmenter` API in ES2022 can split the string into grapheme clusters correctly. If it is not available,\n * PixiJS will fallback to use the iterator of String, which can only spilt the string into code points.\n * If you want to get full functionality in environments that don't support `Intl.Segmenter` (such as Firefox),\n * you can use other libraries such as [grapheme-splitter]{@link https://www.npmjs.com/package/grapheme-splitter}\n * or [graphemer]{@link https://www.npmjs.com/package/graphemer} to create a polyfill. Since these libraries can be\n * relatively large in size to handle various Unicode grapheme clusters properly, PixiJS won't use them directly.\n */\n public static graphemeSegmenter: (s: string) => string[] = (() =>\n {\n if (typeof (Intl as IIntl)?.Segmenter === 'function')\n {\n const segmenter = new (Intl as IIntl).Segmenter();\n\n return (s: string) =>\n {\n const segments = segmenter.segment(s);\n const result = [];\n\n let i = 0;\n\n for (const segment of segments)\n {\n result[i++] = (segment.segment);\n }\n\n return result;\n };\n }\n\n return (s: string) => [...s];\n })();\n\n public static _experimentalLetterSpacingSupported?: boolean;\n\n /**\n * Checking that we can use modern canvas 2D API.\n *\n * Note: This is an unstable API, Chrome < 94 use `textLetterSpacing`, later versions use `letterSpacing`.\n * @see TextMetrics.experimentalLetterSpacing\n * @see https://developer.mozilla.org/en-US/docs/Web/API/ICanvasRenderingContext2D/letterSpacing\n * @see https://developer.chrome.com/origintrials/#/view_trial/3585991203293757441\n */\n public static get experimentalLetterSpacingSupported(): boolean\n {\n let result = CanvasTextMetrics._experimentalLetterSpacingSupported;\n\n if (result === undefined)\n {\n const proto = DOMAdapter.get().getCanvasRenderingContext2D().prototype;\n\n result\n = CanvasTextMetrics._experimentalLetterSpacingSupported\n = 'letterSpacing' in proto || 'textLetterSpacing' in proto;\n }\n\n return result;\n }\n\n /**\n * New rendering behavior for letter-spacing which uses Chrome's new native API. This will\n * lead to more accurate letter-spacing results because it does not try to manually draw\n * each character. However, this Chrome API is experimental and may not serve all cases yet.\n * @see TextMetrics.experimentalLetterSpacingSupported\n */\n public static experimentalLetterSpacing = false;\n\n /** Cache of {@link TextMetrics.FontMetrics} objects. */\n private static _fonts: Record<string, FontMetrics> = {};\n\n /** Cache of new line chars. */\n private static readonly _newlines: number[] = [\n 0x000A, // line feed\n 0x000D, // carriage return\n ];\n\n /** Cache of breaking spaces. */\n private static readonly _breakingSpaces: number[] = [\n 0x0009, // character tabulation\n 0x0020, // space\n 0x2000, // en quad\n 0x2001, // em quad\n 0x2002, // en space\n 0x2003, // em space\n 0x2004, // three-per-em space\n 0x2005, // four-per-em space\n 0x2006, // six-per-em space\n 0x2008, // punctuation space\n 0x2009, // thin space\n 0x200A, // hair space\n 0x205F, // medium mathematical space\n 0x3000, // ideographic space\n ];\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private static __canvas: ICanvas;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private static __context: ICanvasRenderingContext2D;\n\n /** Cache for measured text metrics */\n private static readonly _measurementCache = lru<CanvasTextMetrics>(1000);\n\n /**\n * @param text - the text that was measured\n * @param style - the style that was measured\n * @param width - the measured width of the text\n * @param height - the measured height of the text\n * @param lines - an array of the lines of text broken by new lines and wrapping if specified in style\n * @param lineWidths - an array of the line widths for each line matched to `lines`\n * @param lineHeight - the measured line height for this style\n * @param maxLineWidth - the maximum line width for all measured lines\n * @param {FontMetrics} fontProperties - the font properties object from TextMetrics.measureFont\n */\n constructor(text: string, style: TextStyle, width: number, height: number, lines: string[], lineWidths: number[],\n lineHeight: number, maxLineWidth: number, fontProperties: FontMetrics)\n {\n this.text = text;\n this.style = style;\n this.width = width;\n this.height = height;\n this.lines = lines;\n this.lineWidths = lineWidths;\n this.lineHeight = lineHeight;\n this.maxLineWidth = maxLineWidth;\n this.fontProperties = fontProperties;\n }\n\n /**\n * Measures the supplied string of text and returns a Rectangle.\n * @param text - The text to measure.\n * @param style - The text style to use for measuring\n * @param canvas - optional specification of the canvas to use for measuring.\n * @param wordWrap\n * @returns Measured width and height of the text.\n */\n public static measureText(\n text = ' ',\n style: TextStyle,\n canvas: ICanvas = CanvasTextMetrics._canvas,\n wordWrap: boolean = style.wordWrap,\n ): CanvasTextMetrics\n {\n const textKey = `${text}-${style.styleKey}-wordWrap-${wordWrap}`;\n\n // check if we have already measured this text with the same style\n if (CanvasTextMetrics._measurementCache.has(textKey))\n {\n return CanvasTextMetrics._measurementCache.get(textKey);\n }\n\n const font = fontStringFromTextStyle(style);\n const fontProperties = CanvasTextMetrics.measureFont(font);\n\n // fallback in case UA disallow canvas data extraction\n if (fontProperties.fontSize === 0)\n {\n fontProperties.fontSize = style.fontSize as number;\n fontProperties.ascent = style.fontSize as number;\n }\n\n const context = CanvasTextMetrics.__context; // canvas.getContext('2d', contextSettings);\n\n context.font = font;\n\n const outputText = wordWrap ? CanvasTextMetrics._wordWrap(text, style, canvas) : text;\n const lines = outputText.split(/(?:\\r\\n|\\r|\\n)/);\n const lineWidths = new Array<number>(lines.length);\n let maxLineWidth = 0;\n\n for (let i = 0; i < lines.length; i++)\n {\n const lineWidth = CanvasTextMetrics._measureText(lines[i], style.letterSpacing, context);\n\n lineWidths[i] = lineWidth;\n maxLineWidth = Math.max(maxLineWidth, lineWidth);\n }\n\n const strokeWidth = style._stroke?.width || 0;\n\n let width = maxLineWidth + strokeWidth;\n\n if (style.dropShadow)\n {\n width += style.dropShadow.distance;\n }\n\n const lineHeight = style.lineHeight || fontProperties.fontSize;\n\n let height = Math.max(lineHeight, fontProperties.fontSize + (strokeWidth))\n + ((lines.length - 1) * (lineHeight + style.leading));\n\n if (style.dropShadow)\n {\n height += style.dropShadow.distance;\n }\n\n const measurements = new CanvasTextMetrics(\n text,\n style,\n width,\n height,\n lines,\n lineWidths,\n lineHeight + style.leading,\n maxLineWidth,\n fontProperties\n );\n\n // cache the measurements\n CanvasTextMetrics._measurementCache.set(textKey, measurements);\n\n return measurements;\n }\n\n private static _measureText(\n text: string,\n letterSpacing: number,\n context: ICanvasRenderingContext2D\n )\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 const metrics = context.measureText(text);\n let metricWidth = metrics.width;\n const actualBoundingBoxLeft = -metrics.actualBoundingBoxLeft;\n const actualBoundingBoxRight = metrics.actualBoundingBoxRight;\n let boundsWidth = actualBoundingBoxRight - actualBoundingBoxLeft;\n\n if (metricWidth > 0)\n {\n if (useExperimentalLetterSpacing)\n {\n metricWidth -= letterSpacing;\n boundsWidth -= letterSpacing;\n }\n else\n {\n const val = (CanvasTextMetrics.graphemeSegmenter(text).length - 1) * letterSpacing;\n\n metricWidth += val;\n boundsWidth += val;\n }\n }\n\n // NOTE: this is a bit of a hack as metrics.width and the bounding box width do not measure the same thing\n // We can't seem to exclusively use one or the other, so are taking the largest of the two\n return Math.max(metricWidth, boundsWidth);\n }\n\n /**\n * Applies newlines to a string to have it optimally fit into the horizontal\n * bounds set by the Text object's wordWrapWidth property.\n * @param text - String to apply word wrapping to\n * @param style - the style to use when wrapping\n * @param canvas - optional specification of the canvas to use for measuring.\n * @returns New string with new lines applied where required\n */\n private static _wordWrap(\n text: string,\n style: TextStyle,\n canvas: ICanvas = CanvasTextMetrics._canvas\n ): string\n {\n const context = canvas.getContext('2d', contextSettings);\n\n let width = 0;\n let line = '';\n let lines = '';\n\n const cache: CharacterWidthCache = Object.create(null);\n const { letterSpacing, whiteSpace } = style;\n\n // How to handle whitespaces\n const collapseSpaces = CanvasTextMetrics._collapseSpaces(whiteSpace);\n const collapseNewlines = CanvasTextMetrics._collapseNewlines(whiteSpace);\n\n // whether or not spaces may be added to the beginning of lines\n let canPrependSpaces = !collapseSpaces;\n\n // There is letterSpacing after every char except the last one\n // t_h_i_s_' '_i_s_' '_a_n_' '_e_x_a_m_p_l_e_' '_!\n // so for convenience the above needs to be compared to width + 1 extra letterSpace\n // t_h_i_s_' '_i_s_' '_a_n_' '_e_x_a_m_p_l_e_' '_!_\n // ________________________________________________\n // And then the final space is simply no appended to each line\n const wordWrapWidth = style.wordWrapWidth + letterSpacing;\n\n // break text into words, spaces and newline chars\n const tokens = CanvasTextMetrics._tokenize(text);\n\n for (let i = 0; i < tokens.length; i++)\n {\n // get the word, space or newlineChar\n let token = tokens[i];\n\n // if word is a new line\n if (CanvasTextMetrics._isNewline(token))\n {\n // keep the new line\n if (!collapseNewlines)\n {\n lines += CanvasTextMetrics._addLine(line);\n canPrependSpaces = !collapseSpaces;\n line = '';\n width = 0;\n continue;\n }\n\n // if we should collapse new lines\n // we simply convert it into a space\n token = ' ';\n }\n\n // if we should collapse repeated whitespaces\n if (collapseSpaces)\n {\n // check both this and the last tokens for spaces\n const currIsBreakingSpace = CanvasTextMetrics.isBreakingSpace(token);\n const lastIsBreakingSpace = CanvasTextMetrics.isBreakingSpace(line[line.length - 1]);\n\n if (currIsBreakingSpace && lastIsBreakingSpace)\n {\n continue;\n }\n }\n\n // get word width from cache if possible\n const tokenWidth = CanvasTextMetrics._getFromCache(token, letterSpacing, cache, context);\n\n // word is longer than desired bounds\n if (tokenWidth > wordWrapWidth)\n {\n // if we are not already at the beginning of a line\n if (line !== '')\n {\n // start newlines for overflow words\n lines += CanvasTextMetrics._addLine(line);\n line = '';\n width = 0;\n }\n\n // break large word over multiple lines\n if (CanvasTextMetrics.canBreakWords(token, style.breakWords))\n {\n // break word into characters\n const characters = CanvasTextMetrics.wordWrapSplit(token);\n\n // loop the characters\n for (let j = 0; j < characters.length; j++)\n {\n let char = characters[j];\n let lastChar = char;\n\n let k = 1;\n\n // we are not at the end of the token\n while (characters[j + k])\n {\n const nextChar = characters[j + k];\n\n // should not split chars\n if (!CanvasTextMetrics.canBreakChars(lastChar, nextChar, token, j, style.breakWords))\n {\n // combine chars & move forward one\n char += nextChar;\n }\n else\n {\n break;\n }\n\n lastChar = nextChar;\n k++;\n }\n\n j += k - 1;\n\n const characterWidth = CanvasTextMetrics._getFromCache(char, letterSpacing, cache, context);\n\n if (characterWidth + width > wordWrapWidth)\n {\n lines += CanvasTextMetrics._addLine(line);\n canPrependSpaces = false;\n line = '';\n width = 0;\n }\n\n line += char;\n width += characterWidth;\n }\n }\n\n // run word out of the bounds\n else\n {\n // if there are words in this line already\n // finish that line and start a new one\n if (line.length > 0)\n {\n lines += CanvasTextMetrics._addLine(line);\n line = '';\n width = 0;\n }\n\n const isLastToken = i === tokens.length - 1;\n\n // give it its own line if it's not the end\n lines += CanvasTextMetrics._addLine(token, !isLastToken);\n canPrependSpaces = false;\n line = '';\n width = 0;\n }\n }\n\n // word could fit\n else\n {\n // word won't fit because of existing words\n // start a new line\n if (tokenWidth + width > wordWrapWidth)\n {\n // if its a space we don't want it\n canPrependSpaces = false;\n\n // add a new line\n lines += CanvasTextMetrics._addLine(line);\n\n // start a new line\n line = '';\n width = 0;\n }\n\n // don't add spaces to the beginning of lines\n if (line.length > 0 || !CanvasTextMetrics.isBreakingSpace(token) || canPrependSpaces)\n {\n // add the word to the current line\n line += token;\n\n // update width counter\n width += tokenWidth;\n }\n }\n }\n\n lines += CanvasTextMetrics._addLine(line, false);\n\n return lines;\n }\n\n /**\n * Convenience function for logging each line added during the wordWrap method.\n * @param line - The line of text to add\n * @param newLine - Add new line character to end\n * @returns A formatted line\n */\n private static _addLine(line: string, newLine = true): string\n {\n line = CanvasTextMetrics._trimRight(line);\n\n line = (newLine) ? `${line}\\n` : line;\n\n return line;\n }\n\n /**\n * Gets & sets the widths of calculated characters in a cache object\n * @param key - The key\n * @param letterSpacing - The letter spacing\n * @param cache - The cache\n * @param context - The canvas context\n * @returns The from cache.\n */\n private static _getFromCache(key: string, letterSpacing: number, cache: CharacterWidthCache,\n context: ICanvasRenderingContext2D): number\n {\n let width = cache[key];\n\n if (typeof width !== 'number')\n {\n width = CanvasTextMetrics._measureText(key, letterSpacing, context) + letterSpacing;\n cache[key] = width;\n }\n\n return width;\n }\n\n /**\n * Determines whether we should collapse breaking spaces.\n * @param whiteSpace - The TextStyle property whiteSpace\n * @returns Should collapse\n */\n private static _collapseSpaces(whiteSpace: TextStyleWhiteSpace): boolean\n {\n return (whiteSpace === 'normal' || whiteSpace === 'pre-line');\n }\n\n /**\n * Determines whether we should collapse newLine chars.\n * @param whiteSpace - The white space\n * @returns should collapse\n */\n private static _collapseNewlines(whiteSpace: TextStyleWhiteSpace): boolean\n {\n return (whiteSpace === 'normal');\n }\n\n /**\n * Trims breaking whitespaces from string.\n * @param text - The text\n * @returns Trimmed string\n */\n private static _trimRight(text: string): string\n {\n if (typeof text !== 'string')\n {\n return '';\n }\n\n for (let i = text.length - 1; i >= 0; i--)\n {\n const char = text[i];\n\n if (!CanvasTextMetrics.isBreakingSpace(char))\n {\n break;\n }\n\n text = text.slice(0, -1);\n }\n\n return text;\n }\n\n /**\n * Determines if char is a newline.\n * @param char - The character\n * @returns True if newline, False otherwise.\n */\n private static _isNewline(char: string): boolean\n {\n if (typeof char !== 'string')\n {\n return false;\n }\n\n return CanvasTextMetrics._newlines.includes(char.charCodeAt(0));\n }\n\n /**\n * Determines if char is a breaking whitespace.\n *\n * It allows one to determine whether char should be a breaking whitespace\n * For example certain characters in CJK langs or numbers.\n * It must return a boolean.\n * @param char - The character\n * @param [_nextChar] - The next character\n * @returns True if whitespace, False otherwise.\n */\n public static isBreakingSpace(char: string, _nextChar?: string): boolean\n {\n if (typeof char !== 'string')\n {\n return false;\n }\n\n return CanvasTextMetrics._breakingSpaces.includes(char.charCodeAt(0));\n }\n\n /**\n * Splits a string into words, breaking-spaces and newLine characters\n * @param text - The text\n * @returns A tokenized array\n */\n private static _tokenize(text: string): string[]\n {\n const tokens: string[] = [];\n let token = '';\n\n if (typeof text !== 'string')\n {\n return tokens;\n }\n\n for (let i = 0; i < text.length; i++)\n {\n const char = text[i];\n const nextChar = text[i + 1];\n\n if (CanvasTextMetrics.isBreakingSpace(char, nextChar) || CanvasTextMetrics._isNewline(char))\n {\n if (token !== '')\n {\n tokens.push(token);\n token = '';\n }\n\n // treat \\r\\n as a single new line token\n if (char === '\\r' && nextChar === '\\n')\n {\n tokens.push('\\r\\n');\n i++;\n }\n else\n {\n tokens.push(char);\n }\n\n continue;\n }\n\n token += char;\n }\n\n if (token !== '')\n {\n tokens.push(token);\n }\n\n return tokens;\n }\n\n /**\n * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.\n *\n * It allows one to customise which words should break\n * Examples are if the token is CJK or numbers.\n * It must return a boolean.\n * @param _token - The token\n * @param breakWords - The style attr break words\n * @returns Whether to break word or not\n */\n public static canBreakWords(_token: string, breakWords: boolean): boolean\n {\n return breakWords;\n }\n\n /**\n * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.\n *\n * It allows one to determine whether a pair of characters\n * should be broken by newlines\n * For example certain characters in CJK langs or numbers.\n * It must return a boolean.\n * @param _char - The character\n * @param _nextChar - The next character\n * @param _token - The token/word the characters are from\n * @param _index - The index in the token of the char\n * @param _breakWords - The style attr break words\n * @returns whether to break word or not\n */\n public static canBreakChars(_char: string, _nextChar: string, _token: string, _index: number,\n _breakWords: boolean): boolean\n {\n return true;\n }\n\n /**\n * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.\n *\n * It is called when a token (usually a word) has to be split into separate pieces\n * in order to determine the point to break a word.\n * It must return an array of characters.\n * @param token - The token to split\n * @returns The characters of the token\n * @see CanvasTextMetrics.graphemeSegmenter\n */\n public static wordWrapSplit(token: string): string[]\n {\n return CanvasTextMetrics.graphemeSegmenter(token);\n }\n\n /**\n * Calculates the ascent, descent and fontSize of a given font-style\n * @param font - String representing the style of the font\n * @returns Font properties object\n */\n public static measureFont(font: string): FontMetrics\n {\n // as this method is used for preparing assets, don't recalculate things if we don't need to\n if (CanvasTextMetrics._fonts[font])\n {\n return CanvasTextMetrics._fonts[font];\n }\n\n const context = CanvasTextMetrics._context;\n\n context.font = font;\n const metrics = context.measureText(CanvasTextMetrics.METRICS_STRING + CanvasTextMetrics.BASELINE_SYMBOL);\n\n const properties = {\n ascent: metrics.actualBoundingBoxAscent,\n descent: metrics.actualBoundingBoxDescent,\n fontSize: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent\n };\n\n CanvasTextMetrics._fonts[font] = properties;\n\n return properties;\n }\n\n /**\n * Clear font metrics in metrics cache.\n * @param {string} [font] - font name. If font name not set then clear cache for all fonts.\n */\n public static clearMetrics(font = ''): void\n {\n if (font)\n {\n delete CanvasTextMetrics._fonts[font];\n }\n else\n {\n CanvasTextMetrics._fonts = {};\n }\n }\n\n /**\n * Cached canvas element for measuring text\n * TODO: this should be private, but isn't because of backward compat, will fix later.\n * @ignore\n */\n public static get _canvas(): ICanvas\n {\n if (!CanvasTextMetrics.__canvas)\n {\n let canvas: ICanvas;\n\n try\n {\n // OffscreenCanvas2D measureText can be up to 40% faster.\n const c = new OffscreenCanvas(0, 0);\n const context = c.getContext('2d', contextSettings);\n\n if (context?.measureText)\n {\n CanvasTextMetrics.__canvas = c as ICanvas;\n\n return c as ICanvas;\n }\n\n canvas = DOMAdapter.get().createCanvas();\n }\n catch (_cx)\n {\n canvas = DOMAdapter.get().createCanvas();\n }\n canvas.width = canvas.height = 10;\n CanvasTextMetrics.__canvas = canvas;\n }\n\n return CanvasTextMetrics.__canvas;\n }\n\n /**\n * TODO: this should be private, but isn't because of backward compat, will fix later.\n * @ignore\n */\n public static get _context(): ICanvasRenderingContext2D\n {\n if (!CanvasTextMetrics.__context)\n {\n CanvasTextMetrics.__context = CanvasTextMetrics._canvas.getContext('2d', contextSettings);\n }\n\n return CanvasTextMetrics.__context;\n }\n}\n", "import { Color } from '../../../../color/Color';\nimport { Matrix } from '../../../../maths/matrix/Matrix';\nimport { Texture } from '../../../../rendering/renderers/shared/texture/Texture';\nimport { warn } from '../../../../utils/logging/warn';\nimport { FillGradient } from '../../../graphics/shared/fill/FillGradient';\nimport { FillPattern } from '../../../graphics/shared/fill/FillPattern';\n\nimport type { ICanvasRenderingContext2D } from '../../../../environment/canvas/ICanvasRenderingContext2D';\nimport type { ConvertedFillStyle } from '../../../graphics/shared/FillTypes';\nimport type { CanvasTextMetrics } from '../CanvasTextMetrics';\n\n// 5 decimal places\nconst PRECISION = 100000;\n\n/**\n * Converts a PixiJS fill style into a Canvas-compatible fill style.\n * Handles solid colors, textures, patterns, and gradients.\n * @param fillStyle - The PixiJS fill style to convert\n * @param context - The canvas rendering context\n * @param textMetrics - Metrics about the text being rendered\n * @param padding - Padding to add to the text metrics (used to ensure that the gradient accommodates the stroke width)\n * @returns Canvas-compatible fill style (string, CanvasGradient, or CanvasPattern)\n * @internal\n */\nexport function getCanvasFillStyle(\n fillStyle: ConvertedFillStyle,\n context: ICanvasRenderingContext2D,\n textMetrics?: CanvasTextMetrics,\n padding = 0\n): string | CanvasGradient | CanvasPattern\n{\n // Solid color fill\n if (fillStyle.texture === Texture.WHITE && !fillStyle.fill)\n {\n return Color.shared.setValue(fillStyle.color).setAlpha(fillStyle.alpha ?? 1).toHexa();\n }\n // Basic texture fill\n else if (!fillStyle.fill)\n {\n const pattern = context.createPattern(fillStyle.texture.source.resource, 'repeat');\n const tempMatrix = fillStyle.matrix.copyTo(Matrix.shared);\n\n tempMatrix.scale(fillStyle.texture.frame.width, fillStyle.texture.frame.height);\n pattern.setTransform(tempMatrix);\n\n return pattern;\n }\n // Pattern fill\n else if (fillStyle.fill instanceof FillPattern)\n {\n const fillPattern = fillStyle.fill;\n const pattern = context.createPattern(fillPattern.texture.source.resource, 'repeat');\n const tempMatrix = fillPattern.transform.copyTo(Matrix.shared);\n\n tempMatrix.scale(\n fillPattern.texture.frame.width,\n fillPattern.texture.frame.height\n );\n\n pattern.setTransform(tempMatrix);\n\n return pattern;\n }\n // Gradient fill\n else if (fillStyle.fill instanceof FillGradient)\n {\n const fillGradient = fillStyle.fill;\n\n const isLinear = fillGradient.type === 'linear';\n const isLocal = fillGradient.textureSpace === 'local';\n\n let width = 1;\n let height = 1;\n\n // Use text dimensions if in local space\n if (isLocal && textMetrics)\n {\n width = textMetrics.width + padding;\n height = textMetrics.height + padding;\n }\n\n let gradient: CanvasGradient;\n let isNearlyVertical = false;\n\n if (isLinear)\n {\n const { start, end } = fillGradient;\n\n gradient = context.createLinearGradient(\n start.x * width,\n start.y * height,\n end.x * width,\n end.y * height\n );\n\n // Check if gradient is nearly vertical (10% threshold)\n isNearlyVertical = Math.abs(end.x - start.x) < Math.abs((end.y - start.y) * 0.1);\n }\n else\n {\n const { center, innerRadius, outerCenter, outerRadius } = fillGradient;\n\n gradient = context.createRadialGradient(\n center.x * width,\n center.y * height,\n innerRadius * width,\n outerCenter.x * width,\n outerCenter.y * height,\n outerRadius * width\n );\n }\n\n // For vertical gradients in local space, repeat gradient per text line\n if (isNearlyVertical && isLocal && textMetrics)\n {\n const ratio = (textMetrics.lineHeight) / height;\n\n for (let i = 0; i < textMetrics.lines.length; i++)\n {\n const start = ((i * textMetrics.lineHeight) + (padding / 2)) / height;\n\n fillGradient.colorStops.forEach((stop) =>\n {\n // Convert to global space\n const globalStop = start + (stop.offset * ratio);\n\n gradient.addColorStop(\n // fix to 5 decimal places to avoid floating point precision issues\n Math.floor(globalStop * PRECISION) / PRECISION,\n Color.shared.setValue(stop.color).toHex()\n );\n });\n }\n }\n else\n {\n // Standard global space gradient handling\n fillGradient.colorStops.forEach((stop) =>\n {\n gradient.addColorStop(stop.offset, Color.shared.setValue(stop.color).toHex());\n });\n }\n\n return gradient;\n }\n\n // #if _DEBUG\n warn('FillStyle not recognised', fillStyle);\n // #endif\n\n return 'red';\n}\n", "import { Color } from '../../../color/Color';\nimport { Rectangle } from '../../../maths/shapes/Rectangle';\nimport { type CanvasAndContext, CanvasPool } from '../../../rendering/renderers/shared/texture/CanvasPool';\nimport { getCanvasBoundingBox } from '../../../utils/canvas/getCanvasBoundingBox';\nimport { type TextStyle } from '../TextStyle';\nimport { CanvasTextMetrics } from './CanvasTextMetrics';\nimport { fontStringFromTextStyle } from './utils/fontStringFromTextStyle';\nimport { getCanvasFillStyle } from './utils/getCanvasFillStyle';\n\n/**\n * Temporary rectangle for getting the bounding box of the text.\n * @internal\n */\nconst tempRect = new Rectangle();\n\n/**\n * Utility for generating and managing canvas-based text rendering.\n *\n * This class is responsible for rendering text to canvas elements based on provided styles,\n * measuring the resulting text dimensions, and managing the lifecycle of canvas resources.\n *\n * CanvasTextGenerator supports:\n * - Text rendering with various styles (fill, stroke, gradient, etc.)\n * - Drop shadows and letter spacing\n * - Automatic trimming of transparent pixels\n * - Canvas resource pooling\n *\n * As a singleton, it's accessed via the exported `CanvasTextGenerator` constant.\n * @example\n * ```typescript\n * // Basic usage - render text to a canvas\n * import { CanvasTextGenerator } from 'pixi.js';\n * import { TextStyle } from 'pixi.js';\n *\n * // Create a text style\n * const style = new TextStyle({\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * });\n *\n * // Get a canvas with the text rendered to it\n * const { canvasAndContext, frame } = CanvasTextGenerator.getCanvasAndContext({\n * text: 'Hello Pixi!',\n * style,\n * resolution: 1\n * });\n *\n * @internal\n */\nclass CanvasTextGeneratorClass\n{\n /**\n * Creates a canvas with the specified text rendered to it.\n *\n * Generates a canvas of appropriate size, renders the text with the provided style,\n * and returns both the canvas/context and a Rectangle representing the text bounds.\n *\n * When trim is enabled in the style, the frame will represent the bounds of the\n * non-transparent pixels, which can be smaller than the full canvas.\n * @param options - The options for generating the text canvas\n * @param options.text - The text to render\n * @param options.style - The style to apply to the text\n * @param options.resolution - The resolution of the canvas (defaults to 1)\n * @param options.padding\n * @returns An object containing the canvas/context and the frame (bounds) of the text\n */\n public getCanvasAndContext(options: {text: string, style: TextStyle, resolution?: number, padding?: number})\n {\n const { text, style, resolution = 1 } = options;\n\n const padding = (style as TextStyle)._getFinalPadding();\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) + (padding * 2))) * resolution);\n const height = Math.ceil(Math.ceil((Math.max(1, measured.height) + (padding * 2))) * resolution);\n\n const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(width, height);\n\n this._renderTextToCanvas(text, style, padding, resolution, canvasAndContext);\n\n const frame = style.trim\n ? getCanvasBoundingBox({ canvas: canvasAndContext.canvas, width, height, resolution: 1, output: tempRect })\n : tempRect.set(0, 0, width, height);\n\n return {\n canvasAndContext,\n frame\n };\n }\n\n /**\n * Returns a canvas and context to the pool.\n *\n * This should be called when you're done with the canvas to allow reuse\n * and prevent memory leaks.\n * @param canvasAndContext - The canvas and context to return to the pool\n */\n public returnCanvasAndContext(canvasAndContext: CanvasAndContext): void\n {\n CanvasPool.returnCanvasAndContext(canvasAndContext);\n }\n\n /**\n * Renders text to its canvas, and updates its texture.\n * @param text - The text to render\n * @param style - The style of the text\n * @param padding - The padding of the text\n * @param resolution - The resolution of the text\n * @param canvasAndContext - The canvas and context to render the text to\n */\n private _renderTextToCanvas(\n text: string,\n style: TextStyle,\n padding: number,\n resolution: number,\n canvasAndContext: CanvasAndContext\n ): 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 context.scale(resolution, resolution);\n context.textBaseline = style.textBaseline;\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) + (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.fillStyle = style._fill ? getCanvasFillStyle(style._fill, context, measured, padding * 2) : null;\n\n if (style._stroke?.width)\n {\n const strokePadding = (style._stroke.width * 0.5) + (padding * 2);\n\n context.strokeStyle = getCanvasFillStyle(style._stroke, context, measured, strokePadding);\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 + padding,\n linePositionY + 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 + padding,\n linePositionY + padding - dsOffsetText\n );\n }\n }\n }\n }\n\n /**\n * Render the text with letter-spacing.\n *\n * This method handles rendering text with the correct letter spacing, using either:\n * 1. Native letter spacing if supported by the browser\n * 2. Manual letter spacing calculation if not natively supported\n *\n * For manual letter spacing, it calculates the position of each character\n * based on its width and the desired spacing.\n * @param text - The text to draw\n * @param style - The text style to apply\n * @param canvasAndContext - The canvas and context to draw to\n * @param x - Horizontal position to draw the text\n * @param y - Vertical position to draw the text\n * @param isStroke - Whether to render the stroke (true) or fill (false)\n * @private\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\n/** @internal */\nexport const CanvasTextGenerator = new CanvasTextGeneratorClass();\n", "import { ExtensionType } from '../../../extensions/Extensions';\nimport { type Filter } from '../../../filters/Filter';\nimport { TexturePool } from '../../../rendering/renderers/shared/texture/TexturePool';\nimport { TextureStyle } from '../../../rendering/renderers/shared/texture/TextureStyle';\nimport { deprecation } from '../../../utils/logging/deprecation';\nimport { type CanvasTextOptions, type Text } from '../Text';\nimport { TextStyle } from '../TextStyle';\nimport { getPo2TextureFromSource } from '../utils/getPo2TextureFromSource';\nimport { CanvasTextGenerator } from './CanvasTextGenerator';\n\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';\n\n/**\n * System plugin to the renderer to manage canvas text.\n * @category rendering\n * @advanced\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 readonly _renderer: Renderer;\n\n private readonly _activeTextures: Record<string, {\n texture: Texture,\n usageCount: number,\n }> = {};\n\n constructor(_renderer: Renderer)\n {\n this._renderer = _renderer;\n }\n\n /** @deprecated since 8.0.0 */\n public getTexture(text: string, resolution: number, style: TextStyle, textKey: string): Texture;\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 public getTexture(options: CanvasTextOptions): Texture;\n public getTexture(\n options: CanvasTextOptions | string,\n _resolution?: number,\n _style?: TextStyle,\n _textKey?: string\n ): Texture\n {\n if (typeof options === 'string')\n {\n // #if _DEBUG\n deprecation('8.0.0', 'CanvasTextSystem.getTexture: Use object TextOptions instead of separate arguments');\n // #endif\n\n options = {\n text: options,\n style: _style,\n resolution: _resolution,\n };\n }\n\n if (!(options.style instanceof TextStyle))\n {\n options.style = new TextStyle(options.style);\n }\n\n if (!(options.textureStyle instanceof TextureStyle))\n {\n options.textureStyle = new TextureStyle(options.textureStyle);\n }\n\n if (typeof options.text !== 'string')\n {\n options.text = options.text.toString();\n }\n\n const { text, style, textureStyle } = options;\n\n const resolution = options.resolution ?? this._renderer.resolution;\n\n const { frame, canvasAndContext } = CanvasTextGenerator.getCanvasAndContext({\n text: text as string,\n style: style as TextStyle,\n resolution,\n });\n\n const texture = getPo2TextureFromSource(canvasAndContext.canvas, frame.width, frame.height, resolution);\n\n if (textureStyle) texture.source.style = textureStyle as TextureStyle;\n\n if (style.trim)\n {\n // reapply the padding to the frame\n frame.pad(style.padding);\n texture.frame.copyFrom(frame);\n\n // We initially increased the frame size by a resolution factor\n // to achieve a crisper display. Now we need to scale down the already\n // trimmed frame to render the texture in the expected size.\n texture.frame.scale(1 / resolution);\n texture.updateUvs();\n }\n\n if (style.filters)\n {\n // apply the filters to the texture if required..\n // this returns a new texture with the filters applied\n const filteredTexture = this._applyFilters(texture, style.filters as Filter[]);\n\n // return the original texture to the pool so we can reuse the next frame\n this.returnTexture(texture);\n\n CanvasTextGenerator.returnCanvasAndContext(canvasAndContext);\n\n // return the new texture with the filters applied\n return filteredTexture;\n }\n\n this._renderer.texture.initSource(texture._source);\n\n CanvasTextGenerator.returnCanvasAndContext(canvasAndContext);\n\n return texture;\n }\n\n /**\n * Returns a texture that was created wit the above `getTexture` function.\n * Handy if you are done with a texture and want to return it to the pool.\n * @param texture - The texture to be returned.\n */\n public returnTexture(texture: Texture)\n {\n const source = texture.source;\n\n source.resource = null;\n source.uploadMethodId = 'unknown';\n source.alphaMode = 'no-premultiply-alpha';\n\n TexturePool.returnTexture(texture, true);\n }\n\n /**\n * Renders text to its canvas, and updates its texture.\n * @deprecated since 8.10.0\n */\n public renderTextToCanvas(): void\n {\n // #if _DEBUG\n deprecation(\n '8.10.0',\n 'CanvasTextSystem.renderTextToCanvas: no longer supported, use CanvasTextSystem.getTexture instead'\n );\n // #endif\n }\n\n /**\n * Gets or creates a managed texture for a Text object. This method handles texture reuse and reference counting.\n * @param text - The Text object that needs a texture\n * @returns A Texture instance that represents the rendered text\n * @remarks\n * This method performs the following:\n * 1. Sets the appropriate resolution based on auto-resolution settings\n * 2. Checks if a texture already exists for the text's style\n * 3. Creates a new texture if needed or returns an existing one\n * 4. Manages reference counting for texture reuse\n */\n public getManagedTexture(text: Text)\n {\n text._resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n const textKey = text.styleKey;\n\n if (this._activeTextures[textKey])\n {\n this._increaseReferenceCount(textKey);\n\n return this._activeTextures[textKey].texture;\n }\n\n const texture = this.getTexture({\n text: text.text,\n style: text.style,\n resolution: text._resolution,\n textureStyle: text.textureStyle,\n });\n\n this._activeTextures[textKey] = {\n texture,\n usageCount: 1,\n };\n\n return texture;\n }\n\n /**\n * Decreases the reference count for a texture associated with a text key.\n * When the reference count reaches zero, the texture is returned to the pool.\n * @param textKey - The unique key identifying the text style configuration\n * @remarks\n * This method is crucial for memory management, ensuring textures are properly\n * cleaned up when they are no longer needed by any Text instances.\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 this.returnTexture(activeTexture.texture);\n this._activeTextures[textKey] = null;\n }\n }\n\n /**\n * Gets the current reference count for a texture associated with a text key.\n * @param textKey - The unique key identifying the text style configuration\n * @returns The number of Text instances currently using this texture\n */\n public getReferenceCount(textKey: string)\n {\n return this._activeTextures[textKey]?.usageCount ?? 0;\n }\n\n private _increaseReferenceCount(textKey: string)\n {\n this._activeTextures[textKey].usageCount++;\n }\n\n /**\n * Applies the specified filters to the given texture.\n *\n * This method takes a texture and a list of filters, applies the filters to the texture,\n * and returns the resulting texture. It also ensures that the alpha mode of the resulting\n * texture is set to 'premultiplied-alpha'.\n * @param {Texture} texture - The texture to which the filters will be applied.\n * @param {Filter[]} filters - The filters to apply to the texture.\n * @returns {Texture} The resulting texture after all filters have been applied.\n */\n private _applyFilters(texture: Texture, filters: Filter[]): Texture\n {\n // Save the current render target so it can be restored later\n const currentRenderTarget = this._renderer.renderTarget.renderTarget;\n\n // Apply the filters to the texture and get the resulting texture\n const resultTexture = this._renderer.filter.generateFilteredTexture({\n texture,\n filters,\n });\n\n // Set the alpha mode of the resulting texture to 'premultiplied-alpha'\n\n // Restore the previous render target\n this._renderer.renderTarget.bind(currentRenderTarget, false);\n\n // Return the resulting texture with the filters applied\n return resultTexture;\n }\n\n public destroy(): void\n {\n (this._renderer as null) = null;\n // Clean up active textures\n for (const key in this._activeTextures)\n {\n if (this._activeTextures[key]) this.returnTexture(this._activeTextures[key].texture);\n }\n (this._activeTextures as null) = null;\n }\n}\n", "import { deprecation, v8_0_0 } from '../../../utils/logging/deprecation';\nimport { ViewContainer, type ViewContainerOptions } from '../../view/ViewContainer';\nimport { GraphicsContext } from './GraphicsContext';\nimport { type GraphicsGpuData } from './GraphicsPipe';\n\nimport type { ColorSource } from '../../../color/Color';\nimport type { Matrix } from '../../../maths/matrix/Matrix';\nimport type { PointData } from '../../../maths/point/PointData';\nimport type { Instruction } from '../../../rendering/renderers/shared/instructions/Instruction';\nimport type { Texture } from '../../../rendering/renderers/shared/texture/Texture';\nimport type { Bounds } from '../../container/bounds/Bounds';\nimport type { ContextDestroyOptions, DestroyOptions } from '../../container/destroyTypes';\nimport type { FillInput, FillStyle, StrokeStyle } from './FillTypes';\nimport type { GraphicsPath } from './path/GraphicsPath';\nimport type { RoundedPoint } from './path/roundShape';\n\n/**\n * Constructor options used for Graphics instances.\n * Configures the initial state and behavior of a Graphics object.\n * @example\n * ```ts\n * const graphics = new Graphics({\n * roundPixels: true,\n * position: { x: 100.5, y: 100.5 }\n * });\n *\n * // Reuse graphics context\n * const sharedContext = new GraphicsContext();\n * const graphics1 = new Graphics({ context: sharedContext });\n * const graphics2 = new Graphics({ context: sharedContext });\n * ```\n * @see {@link Graphics} For the graphics class implementation\n * @see {@link GraphicsContext} For the graphics context API\n * @category scene\n * @standard\n */\nexport interface GraphicsOptions extends PixiMixins.GraphicsOptions, ViewContainerOptions\n{\n /**\n * The GraphicsContext to use, useful for reuse and optimisation\n * If not provided, a new GraphicsContext will be created.\n * @example\n * ```ts\n * const sharedContext = new GraphicsContext();\n * const graphics1 = new Graphics({ context: sharedContext });\n * const graphics2 = new Graphics({ context: sharedContext });\n * ```\n */\n context?: GraphicsContext;\n /**\n * Whether or not to round the x/y position.\n * @default false\n * @example\n * ```ts\n * const graphics = new Graphics({ roundPixels: true });\n * ```\n */\n roundPixels?: boolean;\n}\n// eslint-disable-next-line requireExport/require-export-jsdoc, requireMemberAPI/require-member-api-doc\nexport interface Graphics extends PixiMixins.Graphics, ViewContainer<GraphicsGpuData> {}\n\n/**\n * The Graphics class is primarily used to render primitive shapes such as lines, circles and\n * rectangles to the display, and to color and fill them. It can also be used to create complex\n * masks and hit areas for interaction.\n * @example\n * ```ts\n * // Create a new graphics object\n * const graphics = new Graphics();\n *\n * // Draw a filled rectangle with a stroke\n * graphics\n * .rect(0, 0, 100, 100)\n * .fill({ color: 0xff0000 }) // Fill with red\n * .stroke({ width: 2, color: 0x000000 }); // Stroke with black\n *\n * // Draw a complex shape\n * graphics\n * .moveTo(50, 50)\n * .lineTo(100, 100)\n * .arc(100, 100, 50, 0, Math.PI)\n * .closePath()\n * .fill({ color: 0x00ff00, alpha: 0.5 }); // Fill the shape\n *\n * // Use as a mask\n * sprite.mask = graphics;\n * ```\n * @see {@link GraphicsContext} For the underlying drawing API\n * @see {@link GraphicsPath} For path creation\n * @category scene\n * @standard\n */\nexport class Graphics extends ViewContainer<GraphicsGpuData> implements Instruction\n{\n /** @internal */\n public override readonly renderPipeId: string = 'graphics';\n /** @internal */\n public batched: boolean;\n\n private _context: GraphicsContext;\n private readonly _ownedContext: GraphicsContext;\n\n /**\n * Creates a new Graphics object.\n * @param options - Options for the Graphics.\n */\n constructor(options?: GraphicsOptions | GraphicsContext)\n {\n if (options instanceof GraphicsContext)\n {\n options = { context: options };\n }\n\n const { context, roundPixels, ...rest } = options || {};\n\n super({\n label: 'Graphics',\n ...rest\n });\n\n if (!context)\n {\n this._context = this._ownedContext = new GraphicsContext();\n }\n else\n {\n this._context = context;\n }\n\n this._context.on('update', this.onViewUpdate, this);\n\n this.didViewUpdate = true;\n\n this.allowChildren = false;\n this.roundPixels = roundPixels ?? false;\n }\n\n set context(context: GraphicsContext)\n {\n if (context === this._context) return;\n\n this._context.off('update', this.onViewUpdate, this);\n\n this._context = context;\n\n // TODO store this bound function somewhere else..\n this._context.on('update', this.onViewUpdate, this);\n\n this.onViewUpdate();\n }\n\n /**\n * The underlying graphics context used for drawing operations.\n * Controls how shapes and paths are rendered.\n * @example\n * ```ts\n * // Create a shared context\n * const sharedContext = new GraphicsContext();\n *\n * // Create graphics objects sharing the same context\n * const graphics1 = new Graphics();\n * const graphics2 = new Graphics();\n *\n * // Assign shared context\n * graphics1.context = sharedContext;\n * graphics2.context = sharedContext;\n *\n * // Both graphics will show the same shapes\n * sharedContext\n * .rect(0, 0, 100, 100)\n * .fill({ color: 0xff0000 });\n * ```\n * @see {@link GraphicsContext} For drawing operations\n * @see {@link GraphicsOptions} For context configuration\n */\n get context(): GraphicsContext\n {\n return this._context;\n }\n\n /**\n * The local bounds of the graphics object.\n * Returns the boundaries after all graphical operations but before any transforms.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a shape\n * graphics\n * .rect(0, 0, 100, 100)\n * .fill({ color: 0xff0000 });\n *\n * // Get bounds information\n * const bounds = graphics.bounds;\n * console.log(bounds.width); // 100\n * console.log(bounds.height); // 100\n * ```\n * @readonly\n * @see {@link Bounds} For bounds operations\n * @see {@link Container#getBounds} For transformed bounds\n */\n override get bounds(): Bounds\n {\n return this._context.bounds;\n }\n\n /**\n * Graphics objects do not need to update their bounds as the context handles this.\n * @private\n */\n protected updateBounds(): void { /** */ }\n\n /**\n * Checks if the object contains the given point.\n * Returns true if the point lies within the Graphics object's rendered area.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a shape\n * graphics\n * .rect(0, 0, 100, 100)\n * .fill({ color: 0xff0000 });\n *\n * // Check point intersection\n * if (graphics.containsPoint({ x: 50, y: 50 })) {\n * console.log('Point is inside rectangle!');\n * }\n * ```\n * @param point - The point to check in local coordinates\n * @returns True if the point is inside the Graphics object\n * @see {@link Graphics#bounds} For bounding box checks\n * @see {@link PointData} For point data structure\n */\n public override containsPoint(point: PointData)\n {\n return this._context.containsPoint(point);\n }\n\n /**\n * Destroys this graphics renderable and optionally its context.\n * @param options - Options parameter. A boolean will act as if all options\n *\n * If the context was created by this graphics and `destroy(false)` or `destroy()` is called\n * then the context will still be destroyed.\n *\n * If you want to explicitly not destroy this context that this graphics created,\n * then you should pass destroy({ context: false })\n *\n * If the context was passed in as an argument to the constructor then it will not be destroyed\n * @example\n * ```ts\n * // Destroy the graphics and its context\n * graphics.destroy();\n * graphics.destroy(true);\n * graphics.destroy({ context: true, texture: true, textureSource: true });\n * ```\n */\n public override destroy(options?: DestroyOptions): void\n {\n if (this._ownedContext && !options)\n {\n this._ownedContext.destroy(options);\n }\n else if (options === true || (options as ContextDestroyOptions)?.context === true)\n {\n this._context.destroy(options);\n }\n\n (this._ownedContext as null) = null;\n this._context = null;\n\n super.destroy(options);\n }\n\n private _callContextMethod(method: keyof GraphicsContext, args: any[]): this\n {\n (this.context as any)[method](...args);\n\n return this;\n }\n\n // --------------------------------------- GraphicsContext methods ---------------------------------------\n /**\n * Sets the current fill style of the graphics context.\n * The fill style can be a color, gradient, pattern, or a complex style object.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Basic color fill\n * graphics\n * .setFillStyle({ color: 0xff0000 }) // Red fill\n * .rect(0, 0, 100, 100)\n * .fill();\n *\n * // Gradient fill\n * const gradient = new FillGradient({\n * end: { x: 1, y: 0 },\n * colorStops: [\n * { offset: 0, color: 0xff0000 }, // Red at start\n * { offset: 0.5, color: 0x00ff00 }, // Green at middle\n * { offset: 1, color: 0x0000ff }, // Blue at end\n * ],\n * });\n *\n * graphics\n * .setFillStyle(gradient)\n * .circle(100, 100, 50)\n * .fill();\n *\n * // Pattern fill\n * const pattern = new FillPattern(texture);\n * graphics\n * .setFillStyle({\n * fill: pattern,\n * alpha: 0.5\n * })\n * .rect(0, 0, 200, 200)\n * .fill();\n * ```\n * @param {FillInput} args - The fill style to apply\n * @returns The Graphics instance for chaining\n * @see {@link FillStyle} For fill style options\n * @see {@link FillGradient} For gradient fills\n * @see {@link FillPattern} For pattern fills\n */\n public setFillStyle(...args: Parameters<GraphicsContext['setFillStyle']>): this\n {\n return this._callContextMethod('setFillStyle', args);\n }\n\n /**\n * Sets the current stroke style of the graphics context.\n * Similar to fill styles, stroke styles can encompass colors, gradients, patterns, or more detailed configurations.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Basic color stroke\n * graphics\n * .setStrokeStyle({\n * width: 2,\n * color: 0x000000\n * })\n * .rect(0, 0, 100, 100)\n * .stroke();\n *\n * // Complex stroke style\n * graphics\n * .setStrokeStyle({\n * width: 4,\n * color: 0xff0000,\n * alpha: 0.5,\n * join: 'round',\n * cap: 'round',\n * alignment: 0.5\n * })\n * .circle(100, 100, 50)\n * .stroke();\n *\n * // Gradient stroke\n * const gradient = new FillGradient({\n * end: { x: 1, y: 0 },\n * colorStops: [\n * { offset: 0, color: 0xff0000 }, // Red at start\n * { offset: 0.5, color: 0x00ff00 }, // Green at middle\n * { offset: 1, color: 0x0000ff }, // Blue at end\n * ],\n * });\n *\n * graphics\n * .setStrokeStyle({\n * width: 10,\n * fill: gradient\n * })\n * .poly([0,0, 100,50, 0,100])\n * .stroke();\n * ```\n * @param {StrokeInput} args - The stroke style to apply\n * @returns The Graphics instance for chaining\n * @see {@link StrokeStyle} For stroke style options\n * @see {@link FillGradient} For gradient strokes\n * @see {@link FillPattern} For pattern strokes\n */\n public setStrokeStyle(...args: Parameters<GraphicsContext['setStrokeStyle']>): this\n {\n return this._callContextMethod('setStrokeStyle', args);\n }\n\n /**\n * Fills the current or given path with the current fill style or specified style.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Fill with direct color\n * graphics\n * .circle(50, 50, 25)\n * .fill('red'); // Red fill\n *\n * // Fill with texture\n * graphics\n * .rect(0, 0, 100, 100)\n * .fill(myTexture); // Fill with texture\n *\n * // Fill with complex style\n * graphics\n * .rect(0, 0, 100, 100)\n * .fill({\n * color: 0x00ff00,\n * alpha: 0.5,\n * texture: myTexture,\n * matrix: new Matrix()\n * });\n *\n * // Fill with gradient\n * const gradient = new FillGradient({\n * end: { x: 1, y: 0 },\n * colorStops: [\n * { offset: 0, color: 0xff0000 },\n * { offset: 0.5, color: 0x00ff00 },\n * { offset: 1, color: 0x0000ff },\n * ],\n * });\n *\n * graphics\n * .circle(100, 100, 50)\n * .fill(gradient);\n * ```\n * @param {FillInput} style - The style to fill the path with. Can be:\n * - A ColorSource\n * - A gradient\n * - A pattern\n * - A complex style object\n * If omitted, uses current fill style.\n * @returns The Graphics instance for chaining\n * @see {@link FillStyle} For fill style options\n * @see {@link FillGradient} For gradient fills\n * @see {@link FillPattern} For pattern fills\n */\n public fill(style?: FillInput): this;\n /** @deprecated 8.0.0 */\n public fill(color: ColorSource, alpha?: number): this;\n public fill(...args: [FillStyle | ColorSource, number?]): this\n {\n return this._callContextMethod('fill', args);\n }\n /**\n * Strokes the current path with the current stroke style or specified style.\n * Outlines the shape using the stroke settings.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Stroke with direct color\n * graphics\n * .circle(50, 50, 25)\n * .stroke({\n * width: 2,\n * color: 0xff0000\n * }); // 2px red stroke\n *\n * // Fill with texture\n * graphics\n * .rect(0, 0, 100, 100)\n * .stroke(myTexture); // Fill with texture\n *\n * // Stroke with gradient\n * const gradient = new FillGradient({\n * end: { x: 1, y: 0 },\n * colorStops: [\n * { offset: 0, color: 0xff0000 },\n * { offset: 0.5, color: 0x00ff00 },\n * { offset: 1, color: 0x0000ff },\n * ],\n * });\n *\n * graphics\n * .rect(0, 0, 100, 100)\n * .stroke({\n * width: 4,\n * fill: gradient,\n * alignment: 0.5,\n * join: 'round'\n * });\n * ```\n * @param {StrokeStyle} args - Optional stroke style to apply. Can be:\n * - A stroke style object with width, color, etc.\n * - A gradient\n * - A pattern\n * If omitted, uses current stroke style.\n * @returns The Graphics instance for chaining\n * @see {@link StrokeStyle} For stroke style options\n * @see {@link FillGradient} For gradient strokes\n * @see {@link setStrokeStyle} For setting default stroke style\n */\n public stroke(...args: Parameters<GraphicsContext['stroke']>): this\n {\n return this._callContextMethod('stroke', args);\n }\n /**\n * Adds a texture to the graphics context. This method supports multiple ways to draw textures\n * including basic textures, tinted textures, and textures with custom dimensions.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Basic texture drawing\n * graphics.texture(myTexture);\n *\n * // Tinted texture with position\n * graphics.texture(myTexture, 0xff0000); // Red tint\n *\n * // Texture with custom position and dimensions\n * graphics\n * .texture(\n * myTexture, // texture\n * 0xffffff, // white tint\n * 100, 100, // position\n * 200, 150 // dimensions\n * );\n * ```\n * Basic texture drawing:\n * @param texture - The Texture object to use.\n * @returns The instance of the current Graphics for chaining.\n *\n * Extended texture drawing:\n * @param texture - The Texture object to use.\n * tint - A ColorSource to tint the texture (defaults to white).\n * dx - The x-coordinate for the texture placement.\n * dy - The y-coordinate for the texture placement.\n * dw - The width to draw the texture (defaults to texture width).\n * dh - The height to draw the texture (defaults to texture height).\n * @returns The instance of the current Graphics for chaining.\n * @see {@link Texture} For texture creation\n * @see {@link FillPattern} For pattern fills\n */\n public texture(texture: Texture): this;\n public texture(texture: Texture, tint?: ColorSource, dx?: number, dy?: number, dw?: number, dh?: number): this;\n public texture(...args: [Texture, number?, number?, number?, number?, number?]): this\n {\n return this._callContextMethod('texture', args);\n }\n /**\n * Resets the current path. Any previous path and its commands are discarded and a new path is\n * started. This is typically called before beginning a new shape or series of drawing commands.\n * @example\n * ```ts\n * const graphics = new Graphics();\n * graphics\n * .circle(150, 150, 50)\n * .fill({ color: 0x00ff00 })\n * .beginPath() // Starts a new path\n * .circle(250, 150, 50)\n * .fill({ color: 0x0000ff });\n * ```\n * @returns The Graphics instance for chaining\n * @see {@link Graphics#moveTo} For starting a new subpath\n * @see {@link Graphics#closePath} For closing the current path\n */\n public beginPath(): this\n {\n return this._callContextMethod('beginPath', []);\n }\n /**\n * Applies a cutout to the last drawn shape. This is used to create holes or complex shapes by\n * subtracting a path from the previously drawn path.\n *\n * If a hole is not completely in a shape, it will fail to cut correctly.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw outer circle\n * graphics\n * .circle(100, 100, 50)\n * .fill({ color: 0xff0000 });\n * .circle(100, 100, 25) // Inner circle\n * .cut() // Cuts out the inner circle from the outer circle\n * ```\n */\n public cut(): this\n {\n return this._callContextMethod('cut', []);\n }\n /**\n * Adds an arc to the current path, which is centered at (x, y) with the specified radius,\n * starting and ending angles, and direction.\n * @example\n * ```ts\n * // Draw a simple arc (quarter circle)\n * const graphics = new Graphics();\n * graphics\n * .arc(100, 100, 50, 0, Math.PI/2)\n * .stroke({ width: 2, color: 0xff0000 });\n *\n * // Draw a full circle using an arc\n * graphics\n * .arc(200, 200, 30, 0, Math.PI * 2)\n * .stroke({ color: 0x00ff00 });\n *\n * // Draw a counterclockwise arc\n * graphics\n * .arc(150, 150, 40, Math.PI, 0, true)\n * .stroke({ width: 2, color: 0x0000ff });\n * ```\n * @param x - The x-coordinate of the arc's center\n * @param y - The y-coordinate of the arc's center\n * @param radius - The arc's radius (must be positive)\n * @param startAngle - The starting point of the arc, in radians\n * @param endAngle - The end point of the arc, in radians\n * @param counterclockwise - Optional. If true, draws the arc counterclockwise.\n * If false (default), draws clockwise.\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#circle} For drawing complete circles\n * @see {@link Graphics#arcTo} For drawing arcs between points\n * @see {@link Graphics#arcToSvg} For SVG-style arc drawing\n */\n public arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;\n public arc(...args: Parameters<GraphicsContext['arc']>): this\n {\n return this._callContextMethod('arc', args);\n }\n /**\n * Adds an arc to the current path that connects two points using a radius.\n * The arc is drawn between the current point and the specified end point,\n * using the given control point to determine the curve of the arc.\n * @example\n * ```ts\n * // Draw a simple curved corner\n * const graphics = new Graphics();\n * graphics\n * .moveTo(50, 50)\n * .arcTo(100, 50, 100, 100, 20) // Rounded corner with 20px radius\n * .stroke({ width: 2, color: 0xff0000 });\n *\n * // Create a rounded rectangle using arcTo\n * graphics\n * .moveTo(150, 150)\n * .arcTo(250, 150, 250, 250, 30) // Top right corner\n * .arcTo(250, 250, 150, 250, 30) // Bottom right corner\n * .arcTo(150, 250, 150, 150, 30) // Bottom left corner\n * .arcTo(150, 150, 250, 150, 30) // Top left corner\n * .fill({ color: 0x00ff00 });\n * ```\n * @param x1 - The x-coordinate of the control point\n * @param y1 - The y-coordinate of the control point\n * @param x2 - The x-coordinate of the end point\n * @param y2 - The y-coordinate of the end point\n * @param radius - The radius of the arc in pixels (must be positive)\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#arc} For drawing arcs using center point and angles\n * @see {@link Graphics#arcToSvg} For SVG-style arc drawing\n * @see {@link Graphics#roundRect} For drawing rectangles with rounded corners\n */\n public arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): this;\n public arcTo(...args: Parameters<GraphicsContext['arcTo']>): this\n {\n return this._callContextMethod('arcTo', args);\n }\n /**\n * Adds an SVG-style arc to the path, allowing for elliptical arcs based on the SVG spec.\n * This is particularly useful when converting SVG paths to Graphics or creating complex curved shapes.\n * @example\n * ```ts\n * // Draw a simple elliptical arc\n * const graphics = new Graphics();\n * graphics\n * .moveTo(100, 100)\n * .arcToSvg(50, 30, 0, 0, 1, 200, 100)\n * .stroke({ width: 2, color: 0xff0000 });\n *\n * // Create a complex path with rotated elliptical arc\n * graphics\n * .moveTo(150, 150)\n * .arcToSvg(\n * 60, // rx\n * 30, // ry\n * 45, // x-axis rotation (45 degrees)\n * 1, // large arc flag\n * 0, // sweep flag\n * 250, // end x\n * 200 // end y\n * )\n * .stroke({ width: 4, color: 0x00ff00 });\n *\n * // Chain multiple arcs for complex shapes\n * graphics\n * .moveTo(300, 100)\n * .arcToSvg(40, 20, 0, 0, 1, 350, 150)\n * .arcToSvg(40, 20, 0, 0, 1, 300, 200)\n * .fill({ color: 0x0000ff, alpha: 0.5 });\n * ```\n * @param rx - The x-radius of the ellipse (must be non-negative)\n * @param ry - The y-radius of the ellipse (must be non-negative)\n * @param xAxisRotation - The rotation of the ellipse's x-axis relative to the x-axis, in degrees\n * @param largeArcFlag - Either 0 or 1, determines if the larger of the two possible arcs is chosen (1) or not (0)\n * @param sweepFlag - Either 0 or 1, determines if the arc should be swept in\n * a positive angle direction (1) or negative (0)\n * @param x - The x-coordinate of the arc's end point\n * @param y - The y-coordinate of the arc's end point\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#arc} For simple circular arcs\n * @see {@link Graphics#arcTo} For connecting points with circular arcs\n * @see {@link Graphics#svg} For parsing complete SVG paths\n */\n public arcToSvg(\n rx: number, ry: number, xAxisRotation: number, largeArcFlag: number, sweepFlag: number, x: number, y: number\n ): this;\n public arcToSvg(...args: Parameters<GraphicsContext['arcToSvg']>): this\n {\n return this._callContextMethod('arcToSvg', args);\n }\n /**\n * Adds a cubic Bézier curve to the path, from the current point to the specified end point.\n * The curve is influenced by two control points that define its shape and curvature.\n * @example\n * ```ts\n * // Draw a simple curved line\n * const graphics = new Graphics();\n * graphics\n * .moveTo(50, 50)\n * .bezierCurveTo(\n * 100, 25, // First control point\n * 150, 75, // Second control point\n * 200, 50 // End point\n * )\n * .stroke({ width: 2, color: 0xff0000 });\n *\n * // Adjust curve smoothness\n * graphics\n * .moveTo(50, 200)\n * .bezierCurveTo(\n * 100, 150,\n * 200, 250,\n * 250, 200,\n * 0.5 // Smoothness factor\n * )\n * .stroke({ width: 4, color: 0x0000ff });\n * ```\n * @param cp1x - The x-coordinate of the first control point\n * @param cp1y - The y-coordinate of the first control point\n * @param cp2x - The x-coordinate of the second control point\n * @param cp2y - The y-coordinate of the second control point\n * @param x - The x-coordinate of the end point\n * @param y - The y-coordinate of the end point\n * @param smoothness - Optional parameter to adjust the curve's smoothness (0-1)\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#quadraticCurveTo} For simpler curves with one control point\n * @see {@link Graphics#arc} For circular arcs\n * @see {@link Graphics#arcTo} For connecting points with circular arcs\n */\n public bezierCurveTo(\n cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number, smoothness?: number\n ): this;\n public bezierCurveTo(...args: Parameters<GraphicsContext['bezierCurveTo']>): this\n {\n return this._callContextMethod('bezierCurveTo', args);\n }\n /**\n * Closes the current path by drawing a straight line back to the start point.\n *\n * This is useful for completing shapes and ensuring they are properly closed for fills.\n * @example\n * ```ts\n * // Create a triangle with closed path\n * const graphics = new Graphics();\n * graphics\n * .moveTo(50, 50)\n * .lineTo(100, 100)\n * .lineTo(0, 100)\n * .closePath()\n * ```\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#beginPath} For starting a new path\n * @see {@link Graphics#fill} For filling closed paths\n * @see {@link Graphics#stroke} For stroking paths\n */\n public closePath(): this\n {\n return this._callContextMethod('closePath', []);\n }\n /**\n * Draws an ellipse at the specified location and with the given x and y radii.\n * An optional transformation can be applied, allowing for rotation, scaling, and translation.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a basic ellipse\n * graphics\n * .ellipse(100, 100, 50, 30)\n * .fill({ color: 0xff0000 });\n *\n * // Draw an ellipse with stroke\n * graphics\n * .ellipse(200, 100, 70, 40)\n * .stroke({ width: 2, color: 0x00ff00 });\n * ```\n * @param x - The x-coordinate of the center of the ellipse\n * @param y - The y-coordinate of the center of the ellipse\n * @param radiusX - The horizontal radius of the ellipse\n * @param radiusY - The vertical radius of the ellipse\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#circle} For drawing perfect circles\n * @see {@link Graphics#arc} For drawing partial circular arcs\n */\n public ellipse(x: number, y: number, radiusX: number, radiusY: number): this;\n public ellipse(...args: Parameters<GraphicsContext['ellipse']>): this\n {\n return this._callContextMethod('ellipse', args);\n }\n /**\n * Draws a circle shape at the specified location with the given radius.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a simple filled circle\n * graphics\n * .circle(100, 100, 50)\n * .fill({ color: 0xff0000 });\n *\n * // Draw a circle with gradient fill\n * const gradient = new FillGradient({\n * end: { x: 1, y: 0 },\n * colorStops: [\n * { offset: 0, color: 0xff0000 }, // Red at start\n * { offset: 0.5, color: 0x00ff00 }, // Green at middle\n * { offset: 1, color: 0x0000ff }, // Blue at end\n * ],\n * });\n *\n * graphics\n * .circle(250, 100, 40)\n * .fill({ fill: gradient });\n * ```\n * @param x - The x-coordinate of the center of the circle\n * @param y - The y-coordinate of the center of the circle\n * @param radius - The radius of the circle\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#ellipse} For drawing ellipses\n * @see {@link Graphics#arc} For drawing partial circles\n */\n public circle(x: number, y: number, radius: number): this;\n public circle(...args: Parameters<GraphicsContext['circle']>): this\n {\n return this._callContextMethod('circle', args);\n }\n /**\n * Adds another `GraphicsPath` to this path, optionally applying a transformation.\n * This allows for reuse of complex paths and shapes across different graphics instances.\n * @example\n * ```ts\n * const graphics = new Graphics();\n * // Create a reusable path\n * const heartPath = new GraphicsPath()\n * .moveTo(0, 0)\n * .bezierCurveTo(-50, -25, -50, -75, 0, -100)\n * .bezierCurveTo(50, -75, 50, -25, 0, 0);\n *\n * // Use the path multiple times\n * graphics\n * .path(heartPath)\n * .fill({ color: 0xff0000 })\n * .translateTransform(200, 200)\n * .path(heartPath)\n * .fill({ color: 0xff0000, alpha: 0.5 });\n * ```\n * @param path - The `GraphicsPath` to add to the current path\n * @returns The Graphics instance for method chaining\n * @see {@link GraphicsPath} For creating reusable paths\n * @see {@link Matrix} For creating transformations\n * @see {@link Graphics#transform} For applying transformations\n */\n public path(path: GraphicsPath): this;\n public path(...args: Parameters<GraphicsContext['path']>): this\n {\n return this._callContextMethod('path', args);\n }\n /**\n * Connects the current point to a new point with a straight line.\n * Any subsequent drawing commands will start from this new point.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a triangle\n * graphics\n * .moveTo(50, 50)\n * .lineTo(100, 100)\n * .lineTo(0, 100)\n * .fill({ color: 0xff0000 });\n *\n * // Create a complex shape with multiple lines\n * graphics\n * .moveTo(200, 50)\n * .lineTo(250, 50)\n * .lineTo(250, 100)\n * .lineTo(200, 100)\n * .stroke({ width: 2, color: 0x00ff00 });\n * ```\n * @param x - The x-coordinate of the line's end point\n * @param y - The y-coordinate of the line's end point\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#moveTo} For starting a new sub-path\n */\n public lineTo(x: number, y: number): this;\n public lineTo(...args: Parameters<GraphicsContext['lineTo']>): this\n {\n return this._callContextMethod('lineTo', args);\n }\n /**\n * Sets the starting point for a new sub-path.\n *\n * Moves the \"pen\" to a new location without drawing a line.\n * Any subsequent drawing commands will start from this point.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Create multiple separate lines\n * graphics\n * .moveTo(50, 50)\n * .lineTo(100, 50)\n * .moveTo(50, 100) // Start a new line\n * .lineTo(100, 100)\n * .stroke({ width: 2, color: 0xff0000 });\n *\n * // Create disconnected shapes\n * graphics\n * .moveTo(150, 50)\n * .rect(150, 50, 50, 50)\n * .fill({ color: 0x00ff00 })\n * .moveTo(250, 50) // Start a new shape\n * .circle(250, 75, 25)\n * .fill({ color: 0x0000ff });\n *\n * // Position before curved paths\n * graphics\n * .moveTo(300, 50)\n * .bezierCurveTo(\n * 350, 25, // Control point 1\n * 400, 75, // Control point 2\n * 450, 50 // End point\n * )\n * .stroke({ width: 3, color: 0xff00ff });\n * ```\n * @param x - The x-coordinate to move to\n * @param y - The y-coordinate to move to\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#lineTo} For drawing lines\n * @see {@link Graphics#beginPath} For starting a completely new path\n */\n public moveTo(x: number, y: number): this;\n public moveTo(...args: Parameters<GraphicsContext['moveTo']>): this\n {\n return this._callContextMethod('moveTo', args);\n }\n /**\n * Adds a quadratic curve to the path. It requires two points: the control point and the end point.\n * The starting point is the last point in the current path.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a simple curve\n * graphics\n * .moveTo(50, 50)\n * .quadraticCurveTo(100, 25, 150, 50)\n * .stroke({ width: 2, color: 0xff0000 });\n *\n * // Adjust curve smoothness\n * graphics\n * .moveTo(50, 200)\n * .quadraticCurveTo(\n * 150, 150, // Control point\n * 250, 200, // End point\n * 0.5 // Smoothness factor\n * )\n * .stroke({\n * width: 4,\n * color: 0x0000ff,\n * alpha: 0.7\n * });\n * ```\n * @param cpx - The x-coordinate of the control point\n * @param cpy - The y-coordinate of the control point\n * @param x - The x-coordinate of the end point\n * @param y - The y-coordinate of the end point\n * @param smoothness - Optional parameter to adjust the curve's smoothness (0-1)\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#bezierCurveTo} For curves with two control points\n * @see {@link Graphics#arc} For circular arcs\n * @see {@link Graphics#arcTo} For connecting points with circular arcs\n */\n public quadraticCurveTo(cpx: number, cpy: number, x: number, y: number, smoothness?: number): this;\n public quadraticCurveTo(...args: Parameters<GraphicsContext['quadraticCurveTo']>): this\n {\n return this._callContextMethod('quadraticCurveTo', args);\n }\n /**\n * Draws a rectangle shape.\n *\n * This method adds a new rectangle path to the current drawing.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a simple filled rectangle\n * graphics\n * .rect(50, 50, 100, 75)\n * .fill({ color: 0xff0000 });\n *\n * // Rectangle with stroke\n * graphics\n * .rect(200, 50, 100, 75)\n * .stroke({ width: 2, color: 0x00ff00 });\n * ```\n * @param x - The x-coordinate of the top-left corner of the rectangle\n * @param y - The y-coordinate of the top-left corner of the rectangle\n * @param w - The width of the rectangle\n * @param h - The height of the rectangle\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#roundRect} For drawing rectangles with rounded corners\n * @see {@link Graphics#filletRect} For drawing rectangles with filleted corners\n * @see {@link Graphics#chamferRect} For drawing rectangles with chamfered corners\n */\n\n public rect(x: number, y: number, w: number, h: number): this;\n public rect(...args: Parameters<GraphicsContext['rect']>): this\n {\n return this._callContextMethod('rect', args);\n }\n /**\n * Draws a rectangle with rounded corners. The corner radius can be specified to\n * determine how rounded the corners should be.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Basic rounded rectangle\n * graphics\n * .roundRect(50, 50, 100, 75, 15)\n * .fill({ color: 0xff0000 });\n * ```\n * @param x - The x-coordinate of the top-left corner of the rectangle\n * @param y - The y-coordinate of the top-left corner of the rectangle\n * @param w - The width of the rectangle\n * @param h - The height of the rectangle\n * @param radius - The radius of the rectangle's corners (must be non-negative)\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#rect} For drawing rectangles with sharp corners\n * @see {@link Graphics#filletRect} For drawing rectangles with filleted corners\n * @see {@link Graphics#chamferRect} For drawing rectangles with chamfered corners\n */\n public roundRect(x: number, y: number, w: number, h: number, radius?: number): this;\n public roundRect(...args: Parameters<GraphicsContext['roundRect']>): this\n {\n return this._callContextMethod('roundRect', args);\n }\n /**\n * Draws a polygon shape by specifying a sequence of points. This method allows for the creation of complex polygons,\n * which can be both open and closed.\n *\n * An optional transformation can be applied, enabling the polygon to be scaled,\n * rotated, or translated as needed.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a triangle using array of numbers [x1,y1, x2,y2, x3,y3]\n * graphics\n * .poly([50,50, 100,100, 0,100], true)\n * .fill({ color: 0xff0000 });\n *\n * // Draw a polygon using point objects\n * graphics\n * .poly([\n * { x: 200, y: 50 },\n * { x: 250, y: 100 },\n * { x: 200, y: 150 },\n * { x: 150, y: 100 }\n * ])\n * .fill({ color: 0x00ff00 });\n *\n * // Draw an open polygon with stroke\n * graphics\n * .poly([300,50, 350,50, 350,100, 300,100], false)\n * .stroke({\n * width: 2,\n * color: 0x0000ff,\n * join: 'round'\n * });\n * ```\n * @param points - An array of numbers [x1,y1, x2,y2, ...] or an array of point objects [{x,y}, ...]\n * representing the vertices of the polygon in sequence\n * @param close - Whether to close the polygon path by connecting the last point to the first.\n * Default is true.\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#regularPoly} For drawing regular polygons\n * @see {@link Graphics#roundPoly} For drawing polygons with rounded corners\n * @see {@link Graphics#star} For drawing star shapes\n */\n public poly(points: number[] | PointData[], close?: boolean): this;\n public poly(...args: Parameters<GraphicsContext['poly']>): this\n {\n return this._callContextMethod('poly', args);\n }\n /**\n * Draws a regular polygon with a specified number of sides. All sides and angles are equal,\n * making shapes like triangles, squares, pentagons, etc.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a simple triangle (3 sides)\n * graphics\n * .regularPoly(100, 100, 50, 3)\n * .fill({ color: 0xff0000 });\n *\n * // Draw a hexagon (6 sides) with rotation\n * graphics\n * .regularPoly(\n * 250, 100, // center position\n * 40, // radius\n * 6, // sides\n * Math.PI / 6 // rotation (30 degrees)\n * )\n * .fill({ color: 0x00ff00 })\n * .stroke({ width: 2, color: 0x000000 });\n *\n * // Draw an octagon (8 sides) with transform\n * const transform = new Matrix()\n * .scale(1.5, 1) // stretch horizontally\n * .rotate(Math.PI/4); // rotate 45 degrees\n *\n * graphics\n * .regularPoly(400, 100, 30, 8, 0, transform)\n * .fill({ color: 0x0000ff, alpha: 0.5 });\n * ```\n * @param x - The x-coordinate of the center of the polygon\n * @param y - The y-coordinate of the center of the polygon\n * @param radius - The radius of the circumscribed circle of the polygon\n * @param sides - The number of sides of the polygon (must be 3 or more)\n * @param rotation - The rotation angle of the polygon in radians (default: 0)\n * @param transform - Optional Matrix to transform the polygon's shape\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#poly} For drawing custom polygons\n * @see {@link Graphics#roundPoly} For drawing polygons with rounded corners\n * @see {@link Graphics#star} For drawing star shapes\n */\n public regularPoly(x: number, y: number, radius: number, sides: number, rotation?: number, transform?: Matrix): this;\n public regularPoly(...args: Parameters<GraphicsContext['regularPoly']>): this\n {\n return this._callContextMethod('regularPoly', args);\n }\n /**\n * Draws a polygon with rounded corners.\n *\n * Similar to `regularPoly` but with the ability to round the corners of the polygon.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a basic rounded triangle\n * graphics\n * .roundPoly(100, 100, 50, 3, 10)\n * .fill({ color: 0xff0000 });\n *\n * // Draw a rounded hexagon with rotation\n * graphics\n * .roundPoly(\n * 250, 150, // center position\n * 40, // radius\n * 6, // sides\n * 8, // corner radius\n * Math.PI / 6 // rotation (30 degrees)\n * )\n * .fill({ color: 0x00ff00 })\n * .stroke({ width: 2, color: 0x000000 });\n * ```\n * @param x - The x-coordinate of the center of the polygon\n * @param y - The y-coordinate of the center of the polygon\n * @param radius - The radius of the circumscribed circle of the polygon\n * @param sides - The number of sides of the polygon (must be 3 or more)\n * @param corner - The radius of the corner rounding (must be non-negative)\n * @param rotation - The rotation angle of the polygon in radians (default: 0)\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#regularPoly} For drawing polygons without rounded corners\n * @see {@link Graphics#poly} For drawing custom polygons\n * @see {@link Graphics#roundRect} For drawing rectangles with rounded corners\n */\n public roundPoly(x: number, y: number, radius: number, sides: number, corner: number, rotation?: number): this;\n public roundPoly(...args: Parameters<GraphicsContext['roundPoly']>): this\n {\n return this._callContextMethod('roundPoly', args);\n }\n /**\n * Draws a shape with rounded corners. This function supports custom radius for each corner of the shape.\n * Optionally, corners can be rounded using a quadratic curve instead of an arc, providing a different aesthetic.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a custom shape with rounded corners\n * graphics\n * .roundShape([\n * { x: 100, y: 100, radius: 20 },\n * { x: 200, y: 100, radius: 10 },\n * { x: 200, y: 200, radius: 15 },\n * { x: 100, y: 200, radius: 5 }\n * ], 10)\n * .fill({ color: 0xff0000 });\n *\n * // Using quadratic curves for corners\n * graphics\n * .roundShape([\n * { x: 250, y: 100 },\n * { x: 350, y: 100 },\n * { x: 350, y: 200 },\n * { x: 250, y: 200 }\n * ], 15, true, 0.5)\n * .fill({ color: 0x00ff00 })\n * .stroke({ width: 2, color: 0x000000 });\n *\n * // Shape with varying corner radii\n * graphics\n * .roundShape([\n * { x: 400, y: 100, radius: 30 },\n * { x: 500, y: 100, radius: 5 },\n * { x: 450, y: 200, radius: 15 }\n * ], 10)\n * .fill({ color: 0x0000ff, alpha: 0.5 });\n * ```\n * @param points - An array of `RoundedPoint` representing the corners of the shape.\n * Each point can have its own radius or use the default.\n * A minimum of 3 points is required.\n * @param radius - The default radius for corners without a specific radius defined.\n * Applied to any point that doesn't specify its own radius.\n * @param useQuadratic - When true, corners are drawn using quadratic curves instead\n * of arcs, creating a different visual style. Defaults to false.\n * @param smoothness - Controls the smoothness of quadratic corners when useQuadratic\n * is true. Values range from 0-1, higher values create smoother curves.\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#roundRect} For drawing rectangles with rounded corners\n * @see {@link Graphics#roundPoly} For drawing regular polygons with rounded corners\n */\n public roundShape(points: RoundedPoint[], radius: number, useQuadratic?: boolean, smoothness?: number): this;\n public roundShape(...args: Parameters<GraphicsContext['roundShape']>): this\n {\n return this._callContextMethod('roundShape', args);\n }\n /**\n * Draws a rectangle with fillet corners. Unlike rounded rectangles, this supports negative corner\n * radii which create external rounded corners rather than internal ones.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a rectangle with internal fillets\n * graphics\n * .filletRect(50, 50, 100, 80, 15)\n * .fill({ color: 0xff0000 });\n *\n * // Draw a rectangle with external fillets\n * graphics\n * .filletRect(200, 50, 100, 80, -20)\n * .fill({ color: 0x00ff00 })\n * .stroke({ width: 2, color: 0x000000 });\n * ```\n * @param x - The x-coordinate of the top-left corner of the rectangle\n * @param y - The y-coordinate of the top-left corner of the rectangle\n * @param width - The width of the rectangle\n * @param height - The height of the rectangle\n * @param fillet - The radius of the corner fillets (can be positive or negative)\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#roundRect} For standard rounded corners\n * @see {@link Graphics#chamferRect} For angled corners\n */\n public filletRect(x: number, y: number, width: number, height: number, fillet: number): this;\n public filletRect(...args: Parameters<GraphicsContext['filletRect']>): this\n {\n return this._callContextMethod('filletRect', args);\n }\n /**\n * Draws a rectangle with chamfered (angled) corners. Each corner is cut off at\n * a 45-degree angle based on the chamfer size.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a basic chamfered rectangle\n * graphics\n * .chamferRect(50, 50, 100, 80, 15)\n * .fill({ color: 0xff0000 });\n *\n * // Add transform and stroke\n * const transform = new Matrix()\n * .rotate(Math.PI / 4); // 45 degrees\n *\n * graphics\n * .chamferRect(200, 50, 100, 80, 20, transform)\n * .fill({ color: 0x00ff00 })\n * .stroke({ width: 2, color: 0x000000 });\n * ```\n * @param x - The x-coordinate of the top-left corner of the rectangle\n * @param y - The y-coordinate of the top-left corner of the rectangle\n * @param width - The width of the rectangle\n * @param height - The height of the rectangle\n * @param chamfer - The size of the corner chamfers (must be non-zero)\n * @param transform - Optional Matrix to transform the rectangle\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#roundRect} For rounded corners\n * @see {@link Graphics#filletRect} For rounded corners with negative radius support\n */\n public chamferRect(x: number, y: number, width: number, height: number, chamfer: number, transform?: Matrix): this;\n public chamferRect(...args: Parameters<GraphicsContext['chamferRect']>): this\n {\n return this._callContextMethod('chamferRect', args);\n }\n /**\n * Draws a star shape centered at a specified location. This method allows for the creation\n * of stars with a variable number of points, outer radius, optional inner radius, and rotation.\n *\n * The star is drawn as a closed polygon with alternating outer and inner vertices to create the star's points.\n * An optional transformation can be applied to scale, rotate, or translate the star as needed.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw a basic 5-pointed star\n * graphics\n * .star(100, 100, 5, 50)\n * .fill({ color: 0xff0000 });\n *\n * // Star with custom inner radius\n * graphics\n * .star(250, 100, 6, 50, 20)\n * .fill({ color: 0x00ff00 })\n * .stroke({ width: 2, color: 0x000000 });\n * ```\n * @param x - The x-coordinate of the center of the star\n * @param y - The y-coordinate of the center of the star\n * @param points - The number of points on the star (must be >= 3)\n * @param radius - The outer radius of the star (distance from center to point tips)\n * @param innerRadius - Optional. The inner radius of the star (distance from center to inner vertices).\n * If not specified, defaults to half of the outer radius\n * @param rotation - Optional. The rotation of the star in radians. Default is 0,\n * which aligns one point straight up\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#regularPoly} For drawing regular polygons\n * @see {@link Graphics#poly} For drawing custom polygons\n * @see {@link Graphics#path} For creating custom shapes\n */\n public star(x: number, y: number, points: number, radius: number, innerRadius?: number, rotation?: number): this;\n public star(...args: Parameters<GraphicsContext['star']>): this\n {\n return this._callContextMethod('star', args);\n }\n /**\n * Parses and renders an SVG string into the graphics context. This allows for complex shapes\n * and paths defined in SVG format to be drawn within the graphics context.\n * @example\n * ```ts\n * const graphics = new Graphics();\n * graphics\n * .svg(`\n * <path d=\"M 50,50 L 100,50 L 100,100 L 50,100 Z\"\n * fill=\"blue\" />\n * <circle cx=\"150\" cy=\"75\" r=\"25\"\n * fill=\"green\" />\n * `)\n * .stroke({ width: 2, color: 0x000000 });\n * ```\n * @param svg - The SVG string to be parsed and rendered\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#path} For adding custom paths\n * @see {@link Graphics#fill} For filling shapes after SVG parsing\n * @see {@link Graphics#stroke} For stroking shapes after SVG parsing\n */\n public svg(svg: string): this;\n public svg(...args: Parameters<GraphicsContext['svg']>): this\n {\n return this._callContextMethod('svg', args);\n }\n /**\n * Restores the most recently saved graphics state by popping the top of the graphics state stack.\n * This includes transformations, fill styles, and stroke styles.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Save current state\n * graphics.save();\n *\n * // Make temporary changes\n * graphics\n * .translateTransform(100, 100)\n * .setFillStyle({ color: 0xff0000 })\n * .circle(0, 0, 50)\n * .fill();\n *\n * // Restore to previous state\n * graphics.restore();\n *\n * // Draw with original transform and styles\n * graphics\n * .circle(50, 50, 30)\n * .fill();\n * ```\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#save} For saving the current state\n */\n public restore(): this;\n public restore(...args: Parameters<GraphicsContext['restore']>): this\n {\n return this._callContextMethod('restore', args);\n }\n /**\n * Saves the current graphics state onto a stack. The state includes:\n * - Current transformation matrix\n * - Current fill style\n * - Current stroke style\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Save state before complex operations\n * graphics.save();\n *\n * // Create transformed and styled shape\n * graphics\n * .translateTransform(100, 100)\n * .rotateTransform(Math.PI / 4)\n * .setFillStyle({\n * color: 0xff0000,\n * alpha: 0.5\n * })\n * .rect(-25, -25, 50, 50)\n * .fill();\n *\n * // Restore to original state\n * graphics.restore();\n *\n * // Continue drawing with previous state\n * graphics\n * .circle(50, 50, 25)\n * .fill();\n * ```\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#restore} For restoring the saved state\n * @see {@link Graphics#setTransform} For setting transformations\n */\n public save(): this\n {\n return this._callContextMethod('save', []);\n }\n /**\n * Returns the current transformation matrix of the graphics context.\n * This matrix represents all accumulated transformations including translate, scale, and rotate.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Apply some transformations\n * graphics\n * .translateTransform(100, 100)\n * .rotateTransform(Math.PI / 4);\n *\n * // Get the current transform matrix\n * const matrix = graphics.getTransform();\n * console.log(matrix.tx, matrix.ty); // 100, 100\n *\n * // Use the matrix for other operations\n * graphics\n * .setTransform(matrix)\n * .circle(0, 0, 50)\n * .fill({ color: 0xff0000 });\n * ```\n * @returns The current transformation matrix.\n * @see {@link Graphics#setTransform} For setting the transform matrix\n * @see {@link Matrix} For matrix operations\n */\n public getTransform(): Matrix\n {\n return this.context.getTransform();\n }\n /**\n * Resets the current transformation matrix to the identity matrix, effectively removing\n * any transformations (rotation, scaling, translation) previously applied.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Apply transformations\n * graphics\n * .translateTransform(100, 100)\n * .scaleTransform(2, 2)\n * .circle(0, 0, 25)\n * .fill({ color: 0xff0000 });\n * // Reset transform to default state\n * graphics\n * .resetTransform()\n * .circle(50, 50, 25) // Will draw at actual coordinates\n * .fill({ color: 0x00ff00 });\n * ```\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#getTransform} For getting the current transform\n * @see {@link Graphics#setTransform} For setting a specific transform\n * @see {@link Graphics#save} For saving the current transform state\n * @see {@link Graphics#restore} For restoring a previous transform state\n */\n public resetTransform(): this\n {\n return this._callContextMethod('resetTransform', []);\n }\n /**\n * Applies a rotation transformation to the graphics context around the current origin.\n * Positive angles rotate clockwise, while negative angles rotate counterclockwise.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Rotate 45 degrees clockwise\n * graphics\n * .rotateTransform(Math.PI / 4)\n * .rect(-25, -25, 50, 50)\n * .fill({ color: 0xff0000 });\n * ```\n * @param angle - The angle of rotation in radians\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#scaleTransform} For scaling transformations\n * @see {@link Graphics#translateTransform} For position transformations\n */\n public rotateTransform(angle: number): this;\n public rotateTransform(...args: Parameters<GraphicsContext['rotate']>): this\n {\n return this._callContextMethod('rotate', args);\n }\n /**\n * Applies a scaling transformation to the graphics context, scaling drawings by x horizontally\n * and by y vertically relative to the current origin.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Uniform scaling\n * graphics\n * .scaleTransform(2) // Scale both dimensions by 2\n * .circle(0, 0, 25)\n * .fill({ color: 0xff0000 });\n *\n * // Non-uniform scaling\n * graphics\n * .scaleTransform(0.5, 2) // Half width, double height\n * .rect(100, 100, 50, 50)\n * .fill({ color: 0x00ff00 });\n * ```\n * @param x - The scale factor in the horizontal direction\n * @param y - The scale factor in the vertical direction. If omitted, equals x\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#rotateTransform} For rotation transformations\n * @see {@link Graphics#translateTransform} For position transformations\n */\n public scaleTransform(x: number, y?: number): this;\n public scaleTransform(...args: Parameters<GraphicsContext['scale']>): this\n {\n return this._callContextMethod('scale', args);\n }\n /**\n * Sets the current transformation matrix of the graphics context.\n *\n * This method can either\n * take a Matrix object or individual transform values to create a new transformation matrix.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Using a Matrix object\n * const matrix = new Matrix()\n * .translate(100, 100)\n * .rotate(Math.PI / 4);\n *\n * graphics\n * .setTransform(matrix)\n * .rect(0, 0, 50, 50)\n * .fill({ color: 0xff0000 });\n *\n * // Using individual transform values\n * graphics\n * .setTransform(\n * 2, 0, // scale x by 2\n * 0, 1, // no skew\n * 100, 100 // translate x,y by 100\n * )\n * .circle(0, 0, 25)\n * .fill({ color: 0x00ff00 });\n * ```\n * @param transform - The matrix to set as the current transformation matrix.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public setTransform(transform: Matrix): this;\n /**\n * Sets the current transformation matrix of the graphics context to the specified matrix or values.\n * This replaces the current transformation matrix.\n * @param a - The value for the a property of the matrix, or a Matrix object to use directly.\n * @param b - The value for the b property of the matrix.\n * @param c - The value for the c property of the matrix.\n * @param d - The value for the d property of the matrix.\n * @param dx - The value for the tx (translate x) property of the matrix.\n * @param dy - The value for the ty (translate y) property of the matrix.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public setTransform(a: number, b: number, c: number, d: number, dx: number, dy: number): this;\n public setTransform(a: number | Matrix, b?: number, c?: number, d?: number, dx?: number, dy?: number): this;\n public setTransform(...args: [Matrix] | [number, number, number, number, number, number]): this\n {\n return this._callContextMethod('setTransform', args);\n }\n /**\n * Applies a transformation matrix to the current graphics context by multiplying\n * the current matrix with the specified matrix. This allows for complex transformations\n * combining multiple operations.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Using a Matrix object\n * const matrix = new Matrix()\n * .scale(2, 1) // Scale horizontally\n * .rotate(Math.PI/6); // Rotate 30 degrees\n *\n * graphics\n * .transform(matrix)\n * .rect(0, 0, 50, 50)\n * .fill({ color: 0xff0000 });\n *\n * // Using individual transform values\n * graphics\n * .transform(\n * 1, 0.5, // Skew horizontally\n * 0, 1, // No vertical skew\n * 100, 100 // Translate\n * )\n * .circle(0, 0, 25)\n * .fill({ color: 0x00ff00 });\n * ```\n * @param transform - The matrix to apply to the current transformation.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public transform(transform: Matrix): this;\n /**\n * Applies the specified transformation matrix to the current graphics context by multiplying\n * the current matrix with the specified matrix.\n * @param a - The value for the a property of the matrix, or a Matrix object to use directly.\n * @param b - The value for the b property of the matrix.\n * @param c - The value for the c property of the matrix.\n * @param d - The value for the d property of the matrix.\n * @param dx - The value for the tx (translate x) property of the matrix.\n * @param dy - The value for the ty (translate y) property of the matrix.\n * @returns The instance of the current GraphicsContext for method chaining.\n */\n public transform(a: number, b: number, c: number, d: number, dx: number, dy: number): this;\n public transform(a: number | Matrix, b?: number, c?: number, d?: number, dx?: number, dy?: number): this;\n public transform(...args: [Matrix] | [number, number, number, number, number, number]): this\n {\n return this._callContextMethod('transform', args);\n }\n /**\n * Applies a translation transformation to the graphics context, moving the origin by the specified amounts.\n * This affects all subsequent drawing operations.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Basic translation\n * graphics\n * .translateTransform(100, 100)\n * .circle(0, 0, 25)\n * .fill({ color: 0xff0000 });\n * ```\n * @param x - The amount to translate in the horizontal direction\n * @param y - The amount to translate in the vertical direction. If omitted, equals x\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#setTransform} For setting absolute transformations\n * @see {@link Graphics#transform} For applying complex transformations\n * @see {@link Graphics#save} For saving the current transform state\n */\n public translateTransform(x: number, y?: number): this;\n public translateTransform(...args: Parameters<GraphicsContext['translate']>): this\n {\n return this._callContextMethod('translate', args);\n }\n /**\n * Clears all drawing commands from the graphics context, effectively resetting it.\n * This includes clearing the current path, fill style, stroke style, and transformations.\n *\n * > [!NOTE] Graphics objects are not designed to be continuously cleared and redrawn.\n * > Instead, they are intended to be used for static or semi-static graphics that\n * > can be redrawn as needed. Frequent clearing and redrawing may lead to performance issues.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Draw some shapes\n * graphics\n * .circle(100, 100, 50)\n * .fill({ color: 0xff0000 })\n * .rect(200, 100, 100, 50)\n * .fill({ color: 0x00ff00 });\n *\n * // Clear all graphics\n * graphics.clear();\n *\n * // Start fresh with new shapes\n * graphics\n * .circle(150, 150, 30)\n * .fill({ color: 0x0000ff });\n * ```\n * @returns The Graphics instance for method chaining\n * @see {@link Graphics#beginPath} For starting a new path without clearing styles\n * @see {@link Graphics#save} For saving the current state\n * @see {@link Graphics#restore} For restoring a previous state\n */\n public clear(): this\n {\n return this._callContextMethod('clear', []);\n }\n /**\n * Gets or sets the current fill style for the graphics context. The fill style determines\n * how shapes are filled when using the fill() method.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Basic color fill\n * graphics.fillStyle = {\n * color: 0xff0000, // Red\n * alpha: 1\n * };\n *\n * // Using gradients\n * const gradient = new FillGradient({\n * end: { x: 0, y: 1 }, // Vertical gradient\n * stops: [\n * { offset: 0, color: 0xff0000, alpha: 1 }, // Start color\n * { offset: 1, color: 0x0000ff, alpha: 1 } // End color\n * ]\n * });\n *\n * graphics.fillStyle = {\n * fill: gradient,\n * alpha: 0.8\n * };\n *\n * // Using patterns\n * graphics.fillStyle = {\n * texture: myTexture,\n * alpha: 1,\n * matrix: new Matrix()\n * .scale(0.5, 0.5)\n * .rotate(Math.PI / 4)\n * };\n * ```\n * @type {ConvertedFillStyle}\n * @see {@link FillStyle} For all available fill style options\n * @see {@link FillGradient} For creating gradient fills\n * @see {@link Graphics#fill} For applying the fill to paths\n */\n get fillStyle(): GraphicsContext['fillStyle']\n {\n return this._context.fillStyle;\n }\n set fillStyle(value: FillInput)\n {\n this._context.fillStyle = value;\n }\n /**\n * Gets or sets the current stroke style for the graphics context. The stroke style determines\n * how paths are outlined when using the stroke() method.\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Basic stroke style\n * graphics.strokeStyle = {\n * width: 2,\n * color: 0xff0000,\n * alpha: 1\n * };\n *\n * // Using with gradients\n * const gradient = new FillGradient({\n * end: { x: 0, y: 1 },\n * stops: [\n * { offset: 0, color: 0xff0000, alpha: 1 },\n * { offset: 1, color: 0x0000ff, alpha: 1 }\n * ]\n * });\n *\n * graphics.strokeStyle = {\n * width: 4,\n * fill: gradient,\n * alignment: 0.5,\n * join: 'round',\n * cap: 'round'\n * };\n *\n * // Complex stroke settings\n * graphics.strokeStyle = {\n * width: 6,\n * color: 0x00ff00,\n * alpha: 0.5,\n * join: 'miter',\n * miterLimit: 10,\n * };\n * ```\n * @see {@link StrokeStyle} For all available stroke style options\n * @see {@link Graphics#stroke} For applying the stroke to paths\n */\n get strokeStyle(): GraphicsContext['strokeStyle']\n {\n return this._context.strokeStyle;\n }\n set strokeStyle(value: StrokeStyle)\n {\n this._context.strokeStyle = value;\n }\n\n /**\n * Creates a new Graphics object that copies the current graphics content.\n * The clone can either share the same context (shallow clone) or have its own independent\n * context (deep clone).\n * @example\n * ```ts\n * const graphics = new Graphics();\n *\n * // Create original graphics content\n * graphics\n * .circle(100, 100, 50)\n * .fill({ color: 0xff0000 });\n *\n * // Create a shallow clone (shared context)\n * const shallowClone = graphics.clone();\n *\n * // Changes to original affect the clone\n * graphics\n * .circle(200, 100, 30)\n * .fill({ color: 0x00ff00 });\n *\n * // Create a deep clone (independent context)\n * const deepClone = graphics.clone(true);\n *\n * // Modify deep clone independently\n * deepClone\n * .translateTransform(100, 100)\n * .circle(0, 0, 40)\n * .fill({ color: 0x0000ff });\n * ```\n * @param deep - Whether to create a deep clone of the graphics object.\n * If false (default), the context will be shared between objects.\n * If true, creates an independent copy of the context.\n * @returns A new Graphics instance with either shared or copied context\n * @see {@link Graphics#context} For accessing the underlying graphics context\n * @see {@link GraphicsContext} For understanding the shared context behavior\n */\n public clone(deep = false): Graphics\n {\n if (deep)\n {\n return new Graphics(this._context.clone());\n }\n\n (this._ownedContext as null) = null;\n const clone = new Graphics(this._context);\n\n return clone;\n }\n\n // -------- v7 deprecations ---------\n\n /**\n * @param width\n * @param color\n * @param alpha\n * @deprecated since 8.0.0 Use {@link Graphics#setStrokeStyle} instead\n */\n public lineStyle(width?: number, color?: ColorSource, alpha?: number): this\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'Graphics#lineStyle is no longer needed. Use Graphics#setStrokeStyle to set the stroke style.');\n // #endif\n\n const strokeStyle: Partial<StrokeStyle> = {};\n\n // avoid undefined assignment\n width && (strokeStyle.width = width);\n color && (strokeStyle.color = color);\n alpha && (strokeStyle.alpha = alpha);\n\n this.context.strokeStyle = strokeStyle;\n\n return this;\n }\n\n /**\n * @param color\n * @param alpha\n * @deprecated since 8.0.0 Use {@link Graphics#fill} instead\n */\n public beginFill(color: ColorSource, alpha?: number)\n {\n // #if _DEBUG\n // eslint-disable-next-line max-len\n deprecation(v8_0_0, 'Graphics#beginFill is no longer needed. Use Graphics#fill to fill the shape with the desired style.');\n // #endif\n\n const fillStyle: Partial<FillStyle> = {};\n\n // avoid undefined assignment\n if (color !== undefined) fillStyle.color = color;\n if (alpha !== undefined) fillStyle.alpha = alpha;\n\n this.context.fillStyle = fillStyle;\n\n return this;\n }\n\n /**\n * @deprecated since 8.0.0 Use {@link Graphics#fill} instead\n */\n public endFill()\n {\n // #if _DEBUG\n // eslint-disable-next-line max-len\n deprecation(v8_0_0, 'Graphics#endFill is no longer needed. Use Graphics#fill to fill the shape with the desired style.');\n // #endif\n\n this.context.fill();\n const strokeStyle = this.context.strokeStyle;\n\n if (strokeStyle.width !== GraphicsContext.defaultStrokeStyle.width\n || strokeStyle.color !== GraphicsContext.defaultStrokeStyle.color\n || strokeStyle.alpha !== GraphicsContext.defaultStrokeStyle.alpha)\n {\n this.context.stroke();\n }\n\n return this;\n }\n\n /**\n * @param {...any} args\n * @deprecated since 8.0.0 Use {@link Graphics#circle} instead\n */\n public drawCircle(...args: Parameters<GraphicsContext['circle']>): this\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'Graphics#drawCircle has been renamed to Graphics#circle');\n // #endif\n\n return this._callContextMethod('circle', args);\n }\n\n /**\n * @param {...any} args\n * @deprecated since 8.0.0 Use {@link Graphics#ellipse} instead\n */\n public drawEllipse(...args: Parameters<GraphicsContext['ellipse']>): this\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'Graphics#drawEllipse has been renamed to Graphics#ellipse');\n // #endif\n\n return this._callContextMethod('ellipse', args);\n }\n\n /**\n * @param {...any} args\n * @deprecated since 8.0.0 Use {@link Graphics#poly} instead\n */\n public drawPolygon(...args: Parameters<GraphicsContext['poly']>): this\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'Graphics#drawPolygon has been renamed to Graphics#poly');\n // #endif\n\n return this._callContextMethod('poly', args);\n }\n\n /**\n * @param {...any} args\n * @deprecated since 8.0.0 Use {@link Graphics#rect} instead\n */\n public drawRect(...args: Parameters<GraphicsContext['rect']>): this\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'Graphics#drawRect has been renamed to Graphics#rect');\n // #endif\n\n return this._callContextMethod('rect', args);\n }\n\n /**\n * @param {...any} args\n * @deprecated since 8.0.0 Use {@link Graphics#roundRect} instead\n */\n public drawRoundedRect(...args: Parameters<GraphicsContext['roundRect']>): this\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'Graphics#drawRoundedRect has been renamed to Graphics#roundRect');\n // #endif\n\n return this._callContextMethod('roundRect', args);\n }\n\n /**\n * @param {...any} args\n * @deprecated since 8.0.0 Use {@link Graphics#star} instead\n */\n public drawStar(...args: Parameters<GraphicsContext['star']>): this\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'Graphics#drawStar has been renamed to Graphics#star');\n // #endif\n\n return this._callContextMethod('star', args);\n }\n}\n", "// TODO eventually we should not use this bit, but instead use the localUniformBit\n// have the MSDF bit be merged in with the localUniformBit\n\n/** @internal */\nexport const localUniformMSDFBit = {\n name: 'local-uniform-msdf-bit',\n vertex: {\n header: /* wgsl */`\n struct LocalUniforms {\n uColor:vec4<f32>,\n uTransformMatrix:mat3x3<f32>,\n uDistance: f32,\n uRound:f32,\n }\n\n @group(2) @binding(0) var<uniform> localUniforms : LocalUniforms;\n `,\n main: /* wgsl */`\n vColor *= localUniforms.uColor;\n modelMatrix *= localUniforms.uTransformMatrix;\n `,\n end: /* wgsl */`\n if(localUniforms.uRound == 1)\n {\n vPosition = vec4(roundPixels(vPosition.xy, globalUniforms.uResolution), vPosition.zw);\n }\n `\n },\n fragment: {\n header: /* wgsl */`\n struct LocalUniforms {\n uColor:vec4<f32>,\n uTransformMatrix:mat3x3<f32>,\n uDistance: f32\n }\n\n @group(2) @binding(0) var<uniform> localUniforms : LocalUniforms;\n `,\n main: /* wgsl */`\n outColor = vec4<f32>(calculateMSDFAlpha(outColor, localUniforms.uColor, localUniforms.uDistance));\n `\n\n }\n};\n\n/** @internal */\nexport const localUniformMSDFBitGl = {\n name: 'local-uniform-msdf-bit',\n vertex: {\n header: /* glsl */`\n uniform mat3 uTransformMatrix;\n uniform vec4 uColor;\n uniform float uRound;\n `,\n main: /* glsl */`\n vColor *= uColor;\n modelMatrix *= uTransformMatrix;\n `,\n end: /* glsl */`\n if(uRound == 1.)\n {\n gl_Position.xy = roundPixels(gl_Position.xy, uResolution);\n }\n `\n },\n fragment: {\n header: /* glsl */`\n uniform float uDistance;\n `,\n main: /* glsl */`\n outColor = vec4(calculateMSDFAlpha(outColor, vColor, uDistance));\n `\n\n }\n};\n", "/** @internal */\nexport const mSDFBit = {\n name: 'msdf-bit',\n fragment: {\n header: /* wgsl */`\n fn calculateMSDFAlpha(msdfColor:vec4<f32>, shapeColor:vec4<f32>, distance:f32) -> f32 {\n\n // MSDF\n var median = msdfColor.r + msdfColor.g + msdfColor.b -\n min(msdfColor.r, min(msdfColor.g, msdfColor.b)) -\n max(msdfColor.r, max(msdfColor.g, msdfColor.b));\n\n // SDF\n median = min(median, msdfColor.a);\n\n var screenPxDistance = distance * (median - 0.5);\n var alpha = clamp(screenPxDistance + 0.5, 0.0, 1.0);\n if (median < 0.01) {\n alpha = 0.0;\n } else if (median > 0.99) {\n alpha = 1.0;\n }\n\n // Gamma correction for coverage-like alpha\n var luma: f32 = dot(shapeColor.rgb, vec3<f32>(0.299, 0.587, 0.114));\n var gamma: f32 = mix(1.0, 1.0 / 2.2, luma);\n var coverage: f32 = pow(shapeColor.a * alpha, gamma);\n\n return coverage;\n\n }\n `,\n }\n\n};\n\n/** @internal */\nexport const mSDFBitGl = {\n name: 'msdf-bit',\n fragment: {\n header: /* glsl */`\n float calculateMSDFAlpha(vec4 msdfColor, vec4 shapeColor, float distance) {\n\n // MSDF\n float median = msdfColor.r + msdfColor.g + msdfColor.b -\n min(msdfColor.r, min(msdfColor.g, msdfColor.b)) -\n max(msdfColor.r, max(msdfColor.g, msdfColor.b));\n\n // SDF\n median = min(median, msdfColor.a);\n\n float screenPxDistance = distance * (median - 0.5);\n float alpha = clamp(screenPxDistance + 0.5, 0.0, 1.0);\n\n if (median < 0.01) {\n alpha = 0.0;\n } else if (median > 0.99) {\n alpha = 1.0;\n }\n\n // Gamma correction for coverage-like alpha\n float luma = dot(shapeColor.rgb, vec3(0.299, 0.587, 0.114));\n float gamma = mix(1.0, 1.0 / 2.2, luma);\n float coverage = pow(shapeColor.a * alpha, gamma);\n\n return coverage;\n }\n `,\n }\n\n};\n", "import { Matrix } from '../../../maths/matrix/Matrix';\nimport {\n compileHighShaderGlProgram,\n compileHighShaderGpuProgram\n} from '../../../rendering/high-shader/compileHighShaderToProgram';\nimport { colorBit, colorBitGl } from '../../../rendering/high-shader/shader-bits/colorBit';\nimport {\n generateTextureBatchBit,\n generateTextureBatchBitGl\n} from '../../../rendering/high-shader/shader-bits/generateTextureBatchBit';\nimport { roundPixelsBit, roundPixelsBitGl } from '../../../rendering/high-shader/shader-bits/roundPixelsBit';\nimport { getBatchSamplersUniformGroup } from '../../../rendering/renderers/gl/shader/getBatchSamplersUniformGroup';\nimport { Shader } from '../../../rendering/renderers/shared/shader/Shader';\nimport { UniformGroup } from '../../../rendering/renderers/shared/shader/UniformGroup';\nimport { localUniformMSDFBit, localUniformMSDFBitGl } from './shader-bits/localUniformMSDFBit';\nimport { mSDFBit, mSDFBitGl } from './shader-bits/mSDFBit';\n\nimport type { GlProgram } from '../../../rendering/renderers/gl/shader/GlProgram';\nimport type { GpuProgram } from '../../../rendering/renderers/gpu/shader/GpuProgram';\n\nlet gpuProgram: GpuProgram;\nlet glProgram: GlProgram;\n\n/** @internal */\nexport class SdfShader extends Shader\n{\n constructor(maxTextures: number)\n {\n const uniforms = new UniformGroup({\n uColor: { value: new Float32Array([1, 1, 1, 1]), type: 'vec4<f32>' },\n uTransformMatrix: { value: new Matrix(), type: 'mat3x3<f32>' },\n uDistance: { value: 4, type: 'f32' },\n uRound: { value: 0, type: 'f32' },\n });\n\n gpuProgram ??= compileHighShaderGpuProgram({\n name: 'sdf-shader',\n bits: [\n colorBit,\n generateTextureBatchBit(maxTextures),\n localUniformMSDFBit,\n mSDFBit,\n roundPixelsBit\n ]\n });\n\n glProgram ??= compileHighShaderGlProgram({\n name: 'sdf-shader',\n bits: [\n colorBitGl,\n generateTextureBatchBitGl(maxTextures),\n localUniformMSDFBitGl,\n mSDFBitGl,\n roundPixelsBitGl,\n ]\n });\n\n super({\n glProgram,\n gpuProgram,\n resources: {\n localUniforms: uniforms,\n batchSamplers: getBatchSamplersUniformGroup(maxTextures),\n }\n });\n }\n}\n", "import EventEmitter from 'eventemitter3';\nimport { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\n\nimport type { Texture } from '../../rendering/renderers/shared/texture/Texture';\nimport type { FontMetrics } from '../text/canvas/CanvasTextMetrics';\n\n/**\n * @category text\n * @advanced\n */\nexport interface CharData\n{\n /** Unique id of character */\n id: number;\n /** x-offset to apply when rendering character */\n xOffset: number;\n /** y-offset to apply when rendering character. */\n yOffset: number;\n /** Advancement to apply to next character. */\n xAdvance: number;\n /** The kerning values for this character. */\n kerning: Record<string, number>;\n /** The texture of the character. */\n texture?: Texture;\n}\n\n/**\n * The raw data of a character in a bitmap font.\n * @category text\n * @advanced\n */\nexport interface RawCharData extends Omit<CharData, 'texture'>\n{\n /** The page of the font texture that the character is on. */\n page: number;\n /** The x position of the character in the page. */\n x: number;\n /** The y position of the character in the page. */\n y: number;\n /** The width of the character in the page. */\n width: number;\n /** The height of the character in the page. */\n height: number;\n /** The letter of the character. */\n letter: string;\n}\n\n/**\n * The raw data of a bitmap font.\n * @category text\n * @advanced\n */\nexport interface BitmapFontData\n{\n /** The offset of the font face from the baseline. */\n baseLineOffset: number;\n /** The map of characters by character code. */\n chars: Record<string, RawCharData>;\n /** The map of base page textures (i.e., sheets of glyphs). */\n pages: {\n /** Unique id for bitmap texture */\n id: number;\n /** File name */\n file: string\n }[];\n /** The line-height of the font face in pixels. */\n lineHeight: number;\n /** The size of the font face in pixels. */\n fontSize: number;\n /** The name of the font face. */\n fontFamily: string;\n /** The range and type of the distance field for this font. */\n distanceField?: {\n /** Type of distance field */\n type: 'sdf' | 'msdf' | 'none';\n /** Range of the distance field in pixels */\n range: number;\n };\n}\n\ninterface BitmapFontEvents<Type>\n{\n destroy: [Type];\n}\n\n/**\n * An abstract representation of a bitmap font.\n * @category text\n * @advanced\n */\nexport abstract class AbstractBitmapFont<FontType>\n extends EventEmitter<BitmapFontEvents<FontType>>\n implements Omit<BitmapFontData, 'chars' | 'pages' | 'fontSize'>\n{\n /** The map of characters by character code. */\n public readonly chars: Record<string, CharData> = Object.create(null);\n\n /**\n * The line-height of the font face in pixels.\n * @type {number}\n */\n public readonly lineHeight: BitmapFontData['lineHeight'] = 0;\n\n /**\n * The name of the font face\n * @type {string}\n */\n public readonly fontFamily: BitmapFontData['fontFamily'] = '';\n /** The metrics of the font face. */\n public readonly fontMetrics: FontMetrics = { fontSize: 0, ascent: 0, descent: 0 };\n /**\n * The offset of the font face from the baseline.\n * @type {number}\n */\n public readonly baseLineOffset: BitmapFontData['baseLineOffset'] = 0;\n /** The range and type of the distance field for this font. */\n public readonly distanceField: BitmapFontData['distanceField'] = { type: 'none', range: 0 };\n /** The map of base page textures (i.e., sheets of glyphs). */\n public readonly pages: { texture: Texture }[] = [];\n /** should the fill for this font be applied as a tint to the text. */\n public applyFillAsTint = true;\n\n /** The size of the font face in pixels. */\n public readonly baseMeasurementFontSize: number = 100;\n protected baseRenderedFontSize = 100;\n\n /**\n * The name of the font face.\n * @deprecated since 8.0.0 Use `fontFamily` instead.\n */\n public get font(): BitmapFontData['fontFamily']\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'BitmapFont.font is deprecated, please use BitmapFont.fontFamily instead.');\n // #endif\n\n return this.fontFamily;\n }\n\n /**\n * The map of base page textures (i.e., sheets of glyphs).\n * @deprecated since 8.0.0 Use `pages` instead.\n */\n public get pageTextures(): AbstractBitmapFont<FontType>['pages']\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'BitmapFont.pageTextures is deprecated, please use BitmapFont.pages instead.');\n // #endif\n\n return this.pages;\n }\n\n /**\n * The size of the font face in pixels.\n * @deprecated since 8.0.0 Use `fontMetrics.fontSize` instead.\n */\n public get size(): BitmapFontData['fontSize']\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'BitmapFont.size is deprecated, please use BitmapFont.fontMetrics.fontSize instead.');\n // #endif\n\n return this.fontMetrics.fontSize;\n }\n\n /**\n * The kind of distance field for this font or \"none\".\n * @deprecated since 8.0.0 Use `distanceField.type` instead.\n */\n public get distanceFieldRange(): NonNullable<BitmapFontData['distanceField']>['range']\n {\n // #if _DEBUG\n // eslint-disable-next-line max-len\n deprecation(v8_0_0, 'BitmapFont.distanceFieldRange is deprecated, please use BitmapFont.distanceField.range instead.');\n // #endif\n\n return this.distanceField.range;\n }\n\n /**\n * The range of the distance field in pixels.\n * @deprecated since 8.0.0 Use `distanceField.range` instead.\n */\n public get distanceFieldType(): NonNullable<BitmapFontData['distanceField']>['type']\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'BitmapFont.distanceFieldType is deprecated, please use BitmapFont.distanceField.type instead.');\n // #endif\n\n return this.distanceField.type;\n }\n\n public destroy(destroyTextures = false): void\n {\n this.emit('destroy', this as unknown as FontType);\n\n this.removeAllListeners();\n\n for (const i in this.chars)\n {\n // texture may not exist if the char is \" \", \\n, \\r, or \\t.\n this.chars[i].texture?.destroy();\n }\n\n (this.chars as null) = null;\n\n if (destroyTextures)\n {\n this.pages.forEach((page) => page.texture.destroy(true));\n (this.pages as any) = null;\n }\n }\n}\n", "import { Color } from '../../color/Color';\nimport { Rectangle } from '../../maths/shapes/Rectangle';\nimport { CanvasPool } from '../../rendering/renderers/shared/texture/CanvasPool';\nimport { ImageSource } from '../../rendering/renderers/shared/texture/sources/ImageSource';\nimport { Texture } from '../../rendering/renderers/shared/texture/Texture';\nimport { TextureStyle, type TextureStyleOptions } from '../../rendering/renderers/shared/texture/TextureStyle';\nimport { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\nimport { CanvasTextMetrics } from '../text/canvas/CanvasTextMetrics';\nimport { fontStringFromTextStyle } from '../text/canvas/utils/fontStringFromTextStyle';\nimport { getCanvasFillStyle } from '../text/canvas/utils/getCanvasFillStyle';\nimport { TextStyle } from '../text/TextStyle';\nimport { AbstractBitmapFont } from './AbstractBitmapFont';\n\nimport type { ICanvasRenderingContext2D } from '../../environment/canvas/ICanvasRenderingContext2D';\nimport type { CanvasAndContext } from '../../rendering/renderers/shared/texture/CanvasPool';\nimport type { FontMetrics } from '../text/canvas/CanvasTextMetrics';\n\n/** @internal */\nexport interface DynamicBitmapFontOptions\n{\n style: TextStyle\n skipKerning?: boolean\n resolution?: number\n padding?: number\n overrideFill?: boolean\n overrideSize?: boolean\n textureSize?: number\n mipmap?: boolean\n textureStyle?: TextureStyle | TextureStyleOptions\n}\n\n/**\n * A BitmapFont that generates its glyphs dynamically.\n * @category text\n * @internal\n */\nexport class DynamicBitmapFont extends AbstractBitmapFont<DynamicBitmapFont>\n{\n public static defaultOptions: DynamicBitmapFontOptions = {\n textureSize: 512,\n style: new TextStyle(),\n mipmap: true,\n };\n /**\n * this is a resolution modifier for the font size..\n * texture resolution will also be used to scale texture according to its font size also\n */\n public resolution = 1;\n /** The pages of the font. */\n public override readonly pages: {canvasAndContext?: CanvasAndContext, texture: Texture}[] = [];\n\n private readonly _padding: number = 0;\n private readonly _measureCache: Record<string, number> = Object.create(null);\n private _currentChars: string[] = [];\n private _currentX = 0;\n private _currentY = 0;\n private _currentMaxCharHeight = 0;\n private _currentPageIndex = -1;\n private readonly _style: TextStyle;\n private readonly _skipKerning: boolean = false;\n private readonly _textureSize: number;\n private readonly _mipmap: boolean;\n private readonly _textureStyle?: TextureStyle;\n\n /**\n * @param options - The options for the dynamic bitmap font.\n */\n constructor(options: DynamicBitmapFontOptions)\n {\n super();\n\n const dynamicOptions = { ...DynamicBitmapFont.defaultOptions, ...options };\n\n this._textureSize = dynamicOptions.textureSize;\n this._mipmap = dynamicOptions.mipmap;\n\n const style = dynamicOptions.style.clone();\n\n if (dynamicOptions.overrideFill)\n {\n // assuming no shape fill..\n style._fill.color = 0xffffff;\n style._fill.alpha = 1;\n style._fill.texture = Texture.WHITE;\n style._fill.fill = null;\n }\n\n this.applyFillAsTint = dynamicOptions.overrideFill;\n\n const requestedFontSize = style.fontSize;\n\n // adjust font size to match the base measurement size\n style.fontSize = this.baseMeasurementFontSize;\n\n const font = fontStringFromTextStyle(style);\n\n if (dynamicOptions.overrideSize)\n {\n if (style._stroke)\n {\n // we want the stroke to fit the size of the requested text, so we need to scale it\n // accordingly (eg font size 20, with stroke 10 - stroke is 50% of size,\n // as dynamic font is size 100, the stroke should be adjusted to 50 to make it look right)\n style._stroke.width *= this.baseRenderedFontSize / requestedFontSize;\n }\n }\n else\n {\n style.fontSize = this.baseRenderedFontSize = requestedFontSize;\n }\n\n this._style = style;\n this._skipKerning = dynamicOptions.skipKerning ?? false;\n this.resolution = dynamicOptions.resolution ?? 1;\n this._padding = dynamicOptions.padding ?? 4;\n\n if (dynamicOptions.textureStyle)\n {\n this._textureStyle = dynamicOptions.textureStyle instanceof TextureStyle\n ? dynamicOptions.textureStyle\n : new TextureStyle(dynamicOptions.textureStyle);\n }\n\n (this.fontMetrics as FontMetrics) = CanvasTextMetrics.measureFont(font);\n (this.lineHeight as number) = style.lineHeight || this.fontMetrics.fontSize || style.fontSize;\n }\n\n public ensureCharacters(chars: string): void\n {\n const charList = CanvasTextMetrics.graphemeSegmenter(chars)\n .filter((char) => !this._currentChars.includes(char))\n .filter((char, index, self) => self.indexOf(char) === index);\n // filter returns..\n\n if (!charList.length) return;\n\n this._currentChars = [...this._currentChars, ...charList];\n\n let pageData;\n\n if (this._currentPageIndex === -1)\n {\n pageData = this._nextPage();\n }\n else\n {\n pageData = this.pages[this._currentPageIndex];\n }\n\n let { canvas, context } = pageData.canvasAndContext;\n let textureSource = pageData.texture.source;\n\n const style = this._style;\n\n let currentX = this._currentX;\n let currentY = this._currentY;\n let currentMaxCharHeight = this._currentMaxCharHeight;\n\n const fontScale = this.baseRenderedFontSize / this.baseMeasurementFontSize;\n const padding = this._padding * fontScale;\n\n let skipTexture = false;\n\n const maxTextureWidth = canvas.width / this.resolution;\n const maxTextureHeight = canvas.height / this.resolution;\n\n for (let i = 0; i < charList.length; i++)\n {\n const char = charList[i];\n\n const metrics = CanvasTextMetrics.measureText(char, style, canvas, false);\n\n // override the line height.. we want this to be the glyps height\n // not the user specified one.\n metrics.lineHeight = metrics.height;\n\n const width = metrics.width * fontScale;\n // This is ugly - but italics are given more space so they don't overlap\n const textureGlyphWidth = Math.ceil((style.fontStyle === 'italic' ? 2 : 1) * width);\n\n const height = (metrics.height) * fontScale;\n\n const paddedWidth = textureGlyphWidth + (padding * 2);\n const paddedHeight = height + (padding * 2);\n\n skipTexture = false;\n // don't let empty characters count towards the maxCharHeight\n if (char !== '\\n' && char !== '\\r' && char !== '\\t' && char !== ' ')\n {\n skipTexture = true;\n currentMaxCharHeight = Math.ceil(Math.max(paddedHeight, currentMaxCharHeight));\n }\n\n if (currentX + paddedWidth > maxTextureWidth)\n {\n currentY += currentMaxCharHeight;\n\n // reset the line x and height..\n currentMaxCharHeight = paddedHeight;\n currentX = 0;\n\n if (currentY + currentMaxCharHeight > maxTextureHeight)\n {\n textureSource.update();\n\n const pageData = this._nextPage();\n\n canvas = pageData.canvasAndContext.canvas;\n context = pageData.canvasAndContext.context;\n textureSource = pageData.texture.source;\n\n currentX = 0;\n currentY = 0;\n currentMaxCharHeight = 0;\n }\n }\n\n const xAdvance = (width / fontScale)\n - (style.dropShadow?.distance ?? 0)\n - (style._stroke?.width ?? 0);\n\n // This is in coord space of the measurements.. not the texture\n this.chars[char] = {\n id: char.codePointAt(0),\n xOffset: -this._padding,\n yOffset: -this._padding,\n xAdvance,\n kerning: {},\n };\n\n if (skipTexture)\n {\n this._drawGlyph(\n context,\n metrics,\n currentX + padding,\n currentY + padding,\n fontScale,\n style,\n );\n\n const px = textureSource.width * fontScale;\n const py = textureSource.height * fontScale;\n\n const frame = new Rectangle(\n ((currentX) / px) * textureSource.width,\n ((currentY) / py) * textureSource.height,\n ((paddedWidth) / px) * textureSource.width,\n ((paddedHeight) / py) * textureSource.height,\n );\n\n this.chars[char].texture = new Texture({\n source: textureSource,\n frame,\n });\n\n currentX += Math.ceil(paddedWidth);\n }\n }\n\n textureSource.update();\n\n this._currentX = currentX;\n this._currentY = currentY;\n this._currentMaxCharHeight = currentMaxCharHeight;\n\n // now apply kerning..\n this._skipKerning && this._applyKerning(charList, context);\n }\n\n /**\n * @deprecated since 8.0.0\n * The map of base page textures (i.e., sheets of glyphs).\n */\n public override get pageTextures(): DynamicBitmapFont['pages']\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'BitmapFont.pageTextures is deprecated, please use BitmapFont.pages instead.');\n // #endif\n\n return this.pages;\n }\n\n private _applyKerning(newChars: string[], context: ICanvasRenderingContext2D): void\n {\n const measureCache = this._measureCache;\n\n for (let i = 0; i < newChars.length; i++)\n {\n const first = newChars[i];\n\n for (let j = 0; j < this._currentChars.length; j++)\n {\n // first go through new char being first\n const second = this._currentChars[j];\n\n let c1 = measureCache[first];\n\n if (!c1) c1 = measureCache[first] = context.measureText(first).width;\n\n let c2 = measureCache[second];\n\n if (!c2) c2 = measureCache[second] = context.measureText(second).width;\n\n let total = context.measureText(first + second).width;\n let amount = total - (c1 + c2);\n\n if (amount)\n {\n this.chars[first].kerning[second] = amount;\n }\n\n // then go through new char being second\n total = context.measureText(first + second).width;\n amount = total - (c1 + c2);\n\n if (amount)\n {\n this.chars[second].kerning[first] = amount;\n }\n }\n }\n }\n\n private _nextPage(): {canvasAndContext: CanvasAndContext, texture: Texture}\n {\n this._currentPageIndex++;\n\n const textureResolution = this.resolution;\n const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(\n this._textureSize,\n this._textureSize,\n textureResolution\n );\n\n this._setupContext(canvasAndContext.context, this._style, textureResolution);\n\n const resolution = textureResolution * (this.baseRenderedFontSize / this.baseMeasurementFontSize);\n const texture = new Texture({\n source: new ImageSource({\n resource: canvasAndContext.canvas,\n resolution,\n alphaMode: 'premultiply-alpha-on-upload',\n autoGenerateMipmaps: this._mipmap,\n }),\n\n });\n\n if (this._textureStyle)\n {\n texture.source.style = this._textureStyle;\n }\n\n const pageData = {\n canvasAndContext,\n texture,\n };\n\n this.pages[this._currentPageIndex] = pageData;\n\n return pageData;\n }\n\n // canvas style!\n private _setupContext(context: ICanvasRenderingContext2D, style: TextStyle, resolution: number): void\n {\n style.fontSize = this.baseRenderedFontSize;\n context.scale(resolution, resolution);\n context.font = fontStringFromTextStyle(style);\n style.fontSize = this.baseMeasurementFontSize;\n context.textBaseline = style.textBaseline;\n\n const stroke = style._stroke;\n const strokeThickness = stroke?.width ?? 0;\n\n if (stroke)\n {\n context.lineWidth = strokeThickness;\n context.lineJoin = stroke.join;\n context.miterLimit = stroke.miterLimit;\n\n // TODO prolly cache this??\n context.strokeStyle = getCanvasFillStyle(stroke, context);\n }\n\n if (style._fill)\n {\n // set canvas text styles\n context.fillStyle = getCanvasFillStyle(style._fill, context);\n }\n\n if (style.dropShadow)\n {\n const shadowOptions = style.dropShadow;\n const rgb = Color.shared.setValue(shadowOptions.color).toArray();\n\n const dropShadowBlur = shadowOptions.blur * resolution;\n const dropShadowDistance = shadowOptions.distance * resolution;\n\n context.shadowColor = `rgba(${rgb[0] * 255},${rgb[1] * 255},${rgb[2] * 255},${shadowOptions.alpha})`;\n context.shadowBlur = dropShadowBlur;\n context.shadowOffsetX = Math.cos(shadowOptions.angle) * dropShadowDistance;\n context.shadowOffsetY = Math.sin(shadowOptions.angle) * dropShadowDistance;\n }\n else\n {\n context.shadowColor = 'black';\n context.shadowBlur = 0;\n context.shadowOffsetX = 0;\n context.shadowOffsetY = 0;\n }\n }\n\n private _drawGlyph(\n context: ICanvasRenderingContext2D,\n metrics: CanvasTextMetrics,\n x: number,\n y: number,\n fontScale: number,\n style: TextStyle\n ): void\n {\n const char = metrics.text;\n const fontProperties = metrics.fontProperties;\n const stroke = style._stroke;\n\n const strokeThickness = (stroke?.width ?? 0) * fontScale;\n\n const tx = x + (strokeThickness / 2);\n const ty = y - (strokeThickness / 2);\n\n const descent = fontProperties.descent * fontScale;\n const lineHeight = metrics.lineHeight * fontScale;\n\n let removeShadow = false;\n\n if (style.stroke && strokeThickness)\n {\n removeShadow = true;\n context.strokeText(char, tx, ty + lineHeight - descent);\n }\n\n const { shadowBlur, shadowOffsetX, shadowOffsetY } = context;\n\n if (style._fill)\n {\n if (removeShadow)\n {\n context.shadowBlur = 0;\n context.shadowOffsetX = 0;\n context.shadowOffsetY = 0;\n }\n context.fillText(char, tx, ty + lineHeight - descent);\n }\n\n if (removeShadow)\n {\n context.shadowBlur = shadowBlur;\n context.shadowOffsetX = shadowOffsetX;\n context.shadowOffsetY = shadowOffsetY;\n }\n }\n\n public override destroy(): void\n {\n super.destroy();\n\n for (let i = 0; i < this.pages.length; i++)\n {\n const { canvasAndContext, texture } = this.pages[i];\n\n CanvasPool.returnCanvasAndContext(canvasAndContext);\n texture.destroy(true);\n }\n\n (this.pages as null) = null;\n }\n}\n", "import type { TextStyle } from '../../text/TextStyle';\nimport type { AbstractBitmapFont } from '../AbstractBitmapFont';\n\n/**\n * The layout data for a bitmap text.\n * This contains the width, height, scale, offsetY and lines of text.\n * Each line contains its width, character positions, characters, space width and spaces index.\n * @category text\n * @internal\n */\nexport interface BitmapTextLayoutData\n{\n width: number;\n height: number;\n scale: number;\n offsetY: number;\n lines: {\n width: number\n charPositions: number[],\n chars: string[],\n // / spaces: number\n spaceWidth: number\n spacesIndex: number[]\n }[];\n}\n\n/**\n * @param chars\n * @param style\n * @param font\n * @param trimEnd\n * @internal\n */\nexport function getBitmapTextLayout(\n chars: string[],\n style: TextStyle,\n font: AbstractBitmapFont<any>,\n trimEnd: boolean\n): BitmapTextLayoutData\n{\n const layoutData: BitmapTextLayoutData = {\n width: 0,\n height: 0,\n offsetY: 0,\n scale: style.fontSize / font.baseMeasurementFontSize,\n lines: [{\n width: 0,\n charPositions: [] as number[],\n spaceWidth: 0,\n spacesIndex: [],\n chars: [],\n }]\n };\n\n layoutData.offsetY = font.baseLineOffset;\n\n let currentLine = layoutData.lines[0];\n\n let previousChar: string = null;\n let firstWord = true;\n // let spaceCount = 0;\n\n const currentWord = {\n spaceWord: false,\n width: 0,\n start: 0,\n index: 0, // use index to not modify the array as we use it a lot!\n positions: [] as number[],\n chars: [] as string[],\n };\n\n const scale = font.baseMeasurementFontSize / style.fontSize;\n\n const adjustedLetterSpacing = style.letterSpacing * scale;\n const adjustedWordWrapWidth = style.wordWrapWidth * scale;\n const adjustedLineHeight = style.lineHeight ? style.lineHeight * scale : font.lineHeight;\n\n const breakWords = style.wordWrap && style.breakWords;\n\n const nextWord = (word: typeof currentWord) =>\n {\n const start = currentLine.width;\n\n for (let j = 0; j < currentWord.index; j++)\n {\n const position = word.positions[j];\n\n currentLine.chars.push(word.chars[j]);\n currentLine.charPositions.push(position + start);\n }\n\n currentLine.width += word.width;\n\n firstWord = false;\n\n // reset the word..\n currentWord.width = 0;\n currentWord.index = 0;\n currentWord.chars.length = 0;\n\n // spaceCount = 0;\n };\n\n const nextLine = () =>\n {\n let index = currentLine.chars.length - 1;\n\n if (trimEnd)\n {\n let lastChar = currentLine.chars[index];\n\n while (lastChar === ' ')\n {\n currentLine.width -= font.chars[lastChar].xAdvance;\n lastChar = currentLine.chars[--index];\n }\n }\n\n layoutData.width = Math.max(layoutData.width, currentLine.width);\n\n currentLine = {\n width: 0,\n charPositions: [],\n chars: [],\n spaceWidth: 0,\n spacesIndex: [],\n };\n\n firstWord = true;\n layoutData.lines.push(currentLine);\n layoutData.height += adjustedLineHeight;\n };\n\n const checkIsOverflow = (lineWidth: number) =>\n lineWidth - adjustedLetterSpacing > adjustedWordWrapWidth;\n\n // loop an extra time to force a line break..\n for (let i = 0; i < chars.length + 1; i++)\n {\n let char: string;\n\n const isEnd = i === chars.length;\n\n if (!isEnd)\n {\n char = chars[i];\n }\n\n const charData = font.chars[char] || font.chars[' '];\n\n const isSpace = (/(?:\\s)/).test(char);\n const isWordBreak = isSpace || char === '\\r' || char === '\\n' || isEnd;\n\n // spaceCount++;\n // wasSpace = isSpace;\n\n if (isWordBreak)\n {\n const addWordToNextLine = !firstWord && style.wordWrap && checkIsOverflow(currentLine.width + currentWord.width);\n\n if (addWordToNextLine)\n {\n nextLine();\n\n nextWord(currentWord);\n\n if (!isEnd)\n {\n currentLine.charPositions.push(0);\n }\n }\n else\n {\n currentWord.start = currentLine.width;\n\n nextWord(currentWord);\n\n if (!isEnd)\n {\n currentLine.charPositions.push(0);\n }\n }\n\n if (char === '\\r' || char === '\\n')\n {\n nextLine();\n }\n else if (!isEnd)\n {\n const spaceWidth = charData.xAdvance + (charData.kerning[previousChar] || 0) + adjustedLetterSpacing;\n\n currentLine.width += spaceWidth;\n\n currentLine.spaceWidth = spaceWidth;\n currentLine.spacesIndex.push(currentLine.charPositions.length);\n currentLine.chars.push(char);\n\n // spaceCount++;\n }\n }\n else\n {\n const kerning = charData.kerning[previousChar] || 0;\n\n const nextCharWidth = charData.xAdvance + kerning + adjustedLetterSpacing;\n\n const addWordToNextLine = breakWords && checkIsOverflow(currentLine.width + currentWord.width + nextCharWidth);\n\n if (addWordToNextLine)\n {\n nextWord(currentWord);\n nextLine();\n }\n\n currentWord.positions[currentWord.index++] = currentWord.width + kerning;\n currentWord.chars.push(char);\n\n currentWord.width += nextCharWidth;\n }\n\n previousChar = char;\n // lastChar = char;\n }\n\n nextLine();\n\n if (style.align === 'center')\n {\n alignCenter(layoutData);\n }\n else if (style.align === 'right')\n {\n alignRight(layoutData);\n }\n else if (style.align === 'justify')\n {\n alignJustify(layoutData);\n }\n\n return layoutData;\n}\n\nfunction alignCenter(measurementData: BitmapTextLayoutData)\n{\n for (let i = 0; i < measurementData.lines.length; i++)\n {\n const line = measurementData.lines[i];\n const offset = ((measurementData.width / 2) - (line.width / 2));\n\n for (let j = 0; j < line.charPositions.length; j++)\n {\n line.charPositions[j] += offset;\n }\n }\n}\n\nfunction alignRight(measurementData: BitmapTextLayoutData)\n{\n for (let i = 0; i < measurementData.lines.length; i++)\n {\n const line = measurementData.lines[i];\n const offset = ((measurementData.width) - (line.width));\n\n for (let j = 0; j < line.charPositions.length; j++)\n {\n line.charPositions[j] += offset;\n }\n }\n}\n\nfunction alignJustify(measurementData: BitmapTextLayoutData)\n{\n const width = measurementData.width;\n\n for (let i = 0; i < measurementData.lines.length; i++)\n {\n const line = measurementData.lines[i];\n\n let indy = 0;\n let spaceIndex = line.spacesIndex[indy++];\n\n let offset = 0;\n\n const totalSpaces = line.spacesIndex.length;\n\n const newSpaceWidth = (width - line.width) / totalSpaces;\n\n const spaceWidth = newSpaceWidth;\n\n for (let j = 0; j < line.charPositions.length; j++)\n {\n if (j === spaceIndex)\n {\n spaceIndex = line.spacesIndex[indy++];\n\n offset += spaceWidth;\n }\n\n line.charPositions[j] += offset;\n }\n }\n}\n", "/**\n * Processes the passed character set data and returns a flattened array of all the characters.\n *\n * Ignored because not directly exposed.\n * @ignore\n * @param {string | string[] | string[][] } chars\n * @returns {string[]} the flattened array of characters\n */\nexport function resolveCharacters(chars: string | (string | string[])[]): string[]\n{\n // Skip unexpected 'empty set' check at end\n if (chars === '')\n {\n return [];\n }\n\n // Split the chars string into individual characters\n if (typeof chars === 'string')\n {\n chars = [chars];\n }\n\n // Handle an array of characters+ranges\n const result: string[] = [];\n\n for (let i = 0, j = chars.length; i < j; i++)\n {\n const item = chars[i];\n\n // Handle range delimited by start/end chars\n if (Array.isArray(item))\n {\n if (item.length !== 2)\n {\n throw new Error(`[BitmapFont]: Invalid character range length, expecting 2 got ${item.length}.`);\n }\n if (item[0].length === 0 || item[1].length === 0)\n {\n throw new Error('[BitmapFont]: Invalid character delimiter.');\n }\n\n const startCode = item[0].charCodeAt(0);\n const endCode = item[1].charCodeAt(0);\n\n if (endCode < startCode)\n {\n throw new Error('[BitmapFont]: Invalid character range.');\n }\n\n for (let i = startCode, j = endCode; i <= j; i++)\n {\n result.push(String.fromCharCode(i));\n }\n }\n else\n {\n result.push(...Array.from(item));\n }\n }\n\n if (result.length === 0)\n {\n throw new Error('[BitmapFont]: Empty set when resolving characters.');\n }\n\n return result;\n}\n", "import { lru } from 'tiny-lru';\nimport { Cache } from '../../assets/cache/Cache';\nimport { type TextureStyle, type TextureStyleOptions } from '../../rendering/renderers/shared/texture/TextureStyle';\nimport { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\nimport { warn } from '../../utils/logging/warn';\nimport { CanvasTextMetrics } from '../text/canvas/CanvasTextMetrics';\nimport { TextStyle } from '../text/TextStyle';\nimport { DynamicBitmapFont } from './DynamicBitmapFont';\nimport { getBitmapTextLayout } from './utils/getBitmapTextLayout';\nimport { resolveCharacters } from './utils/resolveCharacters';\n\nimport type { TextStyleOptions } from '../text/TextStyle';\nimport type { BitmapFont } from './BitmapFont';\nimport type { BitmapTextLayoutData } from './utils/getBitmapTextLayout';\n\nlet fontCount = 0;\n\n/**\n * The options for installing a new BitmapFont. Once installed, the font will be available\n * for use in BitmapText objects through the fontFamily property of TextStyle.\n * @example\n * ```ts\n * import { BitmapFont, BitmapText } from 'pixi.js';\n *\n * // Basic font installation\n * BitmapFont.install({\n * name: 'BasicFont',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: '#ffffff'\n * }\n * });\n *\n * // Advanced font installation\n * BitmapFont.install({\n * name: 'AdvancedFont',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 32,\n * fill: '#ff0000',\n * stroke: { color: '#000000', width: 2 }\n * },\n * // Include specific character ranges\n * chars: [\n * ['a', 'z'], // lowercase letters\n * ['A', 'Z'], // uppercase letters\n * ['0', '9'], // numbers\n * '!@#$%^&*()_+-=[]{}' // symbols\n * ],\n * resolution: 2, // High-DPI support\n * padding: 4, // Glyph padding\n * skipKerning: false, // Enable kerning\n * textureStyle: {\n * scaleMode: 'linear',\n * }\n * });\n *\n * // Using the installed font\n * const text = new BitmapText({\n * text: 'Hello World',\n * style: {\n * fontFamily: 'AdvancedFont',\n * fontSize: 48\n * }\n * });\n * ```\n * @category text\n * @standard\n */\nexport interface BitmapFontInstallOptions\n{\n /**\n * The name of the font. This will be used as the fontFamily in text styles to access this font.\n * Must be unique across all installed bitmap fonts.\n * @example\n * ```ts\n * BitmapFont.install({\n * name: 'MyCustomFont',\n * style: { fontFamily: 'Arial' }\n * });\n * ```\n */\n name?: string;\n\n /**\n * Characters included in the font set. You can specify individual characters or ranges.\n * Don't forget to include spaces ' ' in your character set!\n * @default BitmapFont.ALPHANUMERIC\n * @example\n * ```ts\n * // Different ways to specify characters\n * BitmapFont.install({\n * name: 'RangeFont',\n * chars: [\n * ['a', 'z'], // Range of characters\n * '0123456789', // String of characters\n * [['0', '9'], ['A', 'Z']] // Multiple ranges\n * ]\n * });\n * ```\n */\n chars?: string | (string | string[])[];\n\n /**\n * Render resolution for glyphs. Higher values create sharper text at the cost of memory.\n * Useful for supporting high-DPI displays.\n * @default 1\n * @example\n * ```ts\n * BitmapFont.install({\n * name: 'HiDPIFont',\n * resolution: window.devicePixelRatio || 2\n * });\n * ```\n */\n resolution?: number;\n\n /**\n * Padding between glyphs on texture atlas. Balances visual quality with texture space.\n * - Lower values: More compact, but may have visual artifacts\n * - Higher values: Better quality, but uses more texture space\n * @default 4\n * @example\n * ```ts\n * BitmapFont.install({\n * name: 'PaddedFont',\n * padding: 8 // More padding for better quality\n * });\n * ```\n */\n padding?: number;\n\n /**\n * Skip generation of kerning information for the BitmapFont.\n * - true: Faster generation, but text may have inconsistent spacing\n * - false: Better text appearance, but slower generation\n * @default false\n * @example\n * ```ts\n * BitmapFont.install({\n * name: 'FastFont',\n * skipKerning: true // Prioritize performance\n * });\n * ```\n */\n skipKerning?: boolean;\n\n /**\n * Style options to render the BitmapFont with.\n * Supports all TextStyle properties including fill, stroke, and shadow effects.\n * @example\n * ```ts\n * BitmapFont.install({\n * name: 'StyledFont',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 32,\n * fill: 'white',\n * stroke: { color: '#000000', width: 2 },\n * dropShadow: {\n * color: '#000000',\n * blur: 2,\n * distance: 3\n * }\n * }\n * });\n * ```\n */\n style?: TextStyle | TextStyleOptions;\n\n /**\n * Optional texture style to use when creating the font textures.\n * Controls how the font textures are rendered and filtered.\n * @example\n * ```ts\n * BitmapFont.install({\n * name: 'CrispFont',\n * textureStyle: {\n * scaleMode: 'nearest',\n * }\n * });\n * ```\n */\n textureStyle?: TextureStyle | TextureStyleOptions;\n\n /**\n * Whether to allow overriding the fill color with a tint at runtime.\n *\n * When enabled, the font can be dynamically tinted using the `tint` property of BitmapText,\n * allowing a single font to display multiple colors without creating separate font textures.\n * This is memory efficient but requires the font to be rendered with white fill color.\n *\n * When disabled, the fill color is permanently baked into the font texture. This allows\n * any fill color but prevents runtime tinting - each color variation requires a separate font.\n * @default false (automatically determined based on style)\n *\n * **Requirements for tinting:**\n * - Fill color must be white (`0xFFFFFF` or `'#ffffff'`)\n * - No stroke effects\n * - No drop shadows (or only black shadows)\n * - No gradient or pattern fills\n *\n * **Performance considerations:**\n * - ✅ Enabled: One font texture, multiple colors via tinting (memory efficient)\n * - ❌ Disabled: Separate font texture per color (higher memory usage)\n * @example\n * ```ts\n * // Correct usage - white fill with tinting enabled\n * BitmapFont.install({\n * name: 'TintableFont',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xFFFFFF // Must be white for tinting\n * },\n * dynamicFill: true\n * });\n *\n * // Use the font with different colors via tinting\n * const redText = new BitmapText({\n * text: 'Red Text',\n * style: { fontFamily: 'TintableFont', fill: 'red }, // Red tint\n * });\n *\n * const blueText = new BitmapText({\n * text: 'Blue Text',\n * style: { fontFamily: 'TintableFont', fill: 'blue' }, // Blue tint\n * });\n * ```\n * @example\n * ```ts\n * // Incorrect usage - colored fill with tinting enabled\n * BitmapFont.install({\n * name: 'BadTintFont',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xFF0000 // ❌ Red fill won't tint properly\n * },\n * dynamicFill: true // ❌ Will not work as expected\n * });\n * ```\n * @example\n * ```ts\n * // Alternative - baked colors (no tinting)\n * BitmapFont.install({\n * name: 'BakedColorFont',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xFF0000, // Any color works\n * stroke: { color: 0x000000, width: 2 } // Strokes allowed\n * },\n * dynamicFill: false // Color is baked in\n * });\n * ```\n */\n dynamicFill?: boolean;\n}\n\n/** @advanced */\nclass BitmapFontManagerClass\n{\n /**\n * This character set includes all the letters in the alphabet (both lower- and upper- case).\n * @type {string[][]}\n * @example\n * BitmapFont.from('ExampleFont', style, { chars: BitmapFont.ALPHA })\n */\n public readonly ALPHA = [['a', 'z'], ['A', 'Z'], ' '];\n\n /**\n * This character set includes all decimal digits (from 0 to 9).\n * @type {string[][]}\n * @example\n * BitmapFont.from('ExampleFont', style, { chars: BitmapFont.NUMERIC })\n */\n public readonly NUMERIC = [['0', '9']];\n\n /**\n * This character set is the union of `BitmapFont.ALPHA` and `BitmapFont.NUMERIC`.\n * @type {string[][]}\n */\n public readonly ALPHANUMERIC = [['a', 'z'], ['A', 'Z'], ['0', '9'], ' '];\n\n /**\n * This character set consists of all the ASCII table.\n * @type {string[][]}\n * @see http://www.asciitable.com/\n */\n public readonly ASCII = [[' ', '~']];\n\n /** Default options for installing a new BitmapFont. */\n public defaultOptions: Omit<BitmapFontInstallOptions, 'style'> = {\n chars: this.ALPHANUMERIC,\n resolution: 1,\n padding: 4,\n skipKerning: false,\n textureStyle: null,\n };\n\n /** Cache for measured text layouts to avoid recalculating them multiple times. */\n public readonly measureCache = lru<BitmapTextLayoutData>(1000);\n\n /**\n * Get a font for the specified text and style.\n * @param text - The text to get the font for\n * @param style - The style to use\n */\n public getFont(text: string, style: TextStyle): BitmapFont\n {\n let fontFamilyKey = `${style.fontFamily as string}-bitmap`;\n let overrideFill = true;\n\n // assuming there is no texture we can use a tint!\n if (style._fill.fill && !style._stroke)\n {\n fontFamilyKey += style._fill.fill.styleKey;\n overrideFill = false;\n }\n else if (style._stroke || style.dropShadow)\n {\n // if there is a stoke, we need to use the style key as this the font generated cannot be tinted\n // due to the fact the font has at least two colors.\n fontFamilyKey = `${style.styleKey}-bitmap`;\n overrideFill = false;\n }\n\n // first get us the the right font...\n if (!Cache.has(fontFamilyKey))\n {\n const styleCopy = Object.create(style);\n\n // Override the lineHeight, let the BitmapFont calculate the lineHeight\n // from the fontMetrics instead using a custom lineHeight from BitmapText parameter\n styleCopy.lineHeight = 0;\n\n const fnt = new DynamicBitmapFont({\n style: styleCopy,\n overrideFill,\n overrideSize: true,\n ...this.defaultOptions,\n });\n\n fontCount++;\n\n // warn users if they have created too many dynamic fonts\n if (fontCount > 50)\n {\n // eslint-disable-next-line max-len\n warn('BitmapText', `You have dynamically created ${fontCount} bitmap fonts, this can be inefficient. Try pre installing your font styles using \\`BitmapFont.install({name:\"style1\", style})\\``);\n }\n\n fnt.once('destroy', () =>\n {\n fontCount--;\n Cache.remove(fontFamilyKey);\n });\n\n Cache.set(\n fontFamilyKey as string,\n fnt\n );\n }\n\n const dynamicFont = Cache.get(fontFamilyKey);\n\n (dynamicFont as DynamicBitmapFont).ensureCharacters?.(text);\n\n return dynamicFont;\n }\n\n /**\n * Get the layout of a text for the specified style.\n * @param text - The text to get the layout for\n * @param style - The style to use\n * @param trimEnd - Whether to ignore whitespaces at the end of each line\n */\n public getLayout(text: string, style: TextStyle, trimEnd: boolean = true): BitmapTextLayoutData\n {\n const bitmapFont = this.getFont(text, style);\n\n const id = `${text}-${style.styleKey}-${trimEnd}`;\n\n // Check if we have a cached layout\n if (this.measureCache.has(id))\n {\n return this.measureCache.get(id);\n }\n\n const segments = CanvasTextMetrics.graphemeSegmenter(text);\n\n // Generate the layout data\n const layoutData = getBitmapTextLayout(segments, style, bitmapFont, trimEnd);\n\n this.measureCache.set(id, layoutData);\n\n return layoutData;\n }\n\n /**\n * Measure the text using the specified style.\n * @param text - The text to measure\n * @param style - The style to use\n * @param trimEnd - Whether to ignore whitespaces at the end of each line\n */\n public measureText(\n text: string,\n style: TextStyle,\n trimEnd: boolean = true\n ): { width: number; height: number; scale: number; offsetY: number }\n {\n return this.getLayout(text, style, trimEnd);\n }\n\n /**\n * Generates a bitmap-font for the given style and character set\n * @param options - Setup options for font generation.\n * @returns Font generated by style options.\n * @example\n * import { BitmapFontManager, BitmapText } from 'pixi.js';\n *\n * BitmapFontManager.install('TitleFont', {\n * fontFamily: 'Arial',\n * fontSize: 12,\n * strokeThickness: 2,\n * fill: 'purple',\n * });\n *\n * const title = new BitmapText({ text: 'This is the title', fontFamily: 'TitleFont' });\n */\n public install(options: BitmapFontInstallOptions): BitmapFont;\n /** @deprecated since 7.0.0 */\n public install(name: string, style?: TextStyle | TextStyleOptions, options?: BitmapFontInstallOptions): BitmapFont;\n // eslint-disable-next-line max-len\n public install(...args: [string | BitmapFontInstallOptions, (TextStyle | TextStyleOptions)?, BitmapFontInstallOptions?]): BitmapFont\n {\n let options = args[0] as BitmapFontInstallOptions;\n\n if (typeof options === 'string')\n {\n options = {\n name: options,\n style: args[1],\n chars: args[2]?.chars,\n resolution: args[2]?.resolution,\n padding: args[2]?.padding,\n skipKerning: args[2]?.skipKerning,\n } as BitmapFontInstallOptions;\n\n // #if _DEBUG\n // eslint-disable-next-line max-len\n deprecation(v8_0_0, 'BitmapFontManager.install(name, style, options) is deprecated, use BitmapFontManager.install({name, style, ...options})');\n // #endif\n }\n\n const name = options?.name;\n\n if (!name)\n {\n throw new Error('[BitmapFontManager] Property `name` is required.');\n }\n\n options = { ...this.defaultOptions, ...options };\n\n const textStyle = options.style;\n\n const style = textStyle instanceof TextStyle ? textStyle : new TextStyle(textStyle);\n const overrideFill = options.dynamicFill ?? this._canUseTintForStyle(style);\n const font = new DynamicBitmapFont({\n style,\n overrideFill,\n skipKerning: options.skipKerning,\n padding: options.padding,\n resolution: options.resolution,\n overrideSize: false,\n textureStyle: options.textureStyle,\n });\n\n const flatChars = resolveCharacters(options.chars);\n\n font.ensureCharacters(flatChars.join(''));\n\n Cache.set(`${name}-bitmap`, font);\n\n font.once('destroy', () => Cache.remove(`${name}-bitmap`));\n\n return font;\n }\n\n /**\n * Uninstalls a bitmap font from the cache.\n * @param {string} name - The name of the bitmap font to uninstall.\n */\n public uninstall(name: string)\n {\n const cacheKey = `${name}-bitmap`;\n const font = Cache.get<BitmapFont>(cacheKey);\n\n if (font)\n {\n font.destroy();\n }\n }\n\n /**\n * Determines if a style can use tinting instead of baking colors into the bitmap.\n * Tinting is more efficient as it allows reusing the same bitmap with different colors.\n * @param style - The text style to evaluate\n * @returns true if the style can use tinting, false if colors must be baked in\n * @private\n */\n private _canUseTintForStyle(style: TextStyle): boolean\n {\n // Exclude strokes, non black shadows and ensure\n // we have a non gradient or pattern fill,\n // and the fill color is white\n return !style._stroke\n && (!style.dropShadow || style.dropShadow.color === 0x000000)\n && !style._fill.fill\n && style._fill.color === 0xFFFFFF;\n }\n}\n\n/**\n * The BitmapFontManager is a helper that exists to install and uninstall fonts\n * into the cache for BitmapText objects.\n * @category text\n * @advanced\n * @class\n * @example\n * import { BitmapFontManager, BitmapText } from 'pixi.js';\n *\n * BitmapFontManager.install({\n * name: 'TitleFont',\n * style: {}\n * });\n *\n * const title = new BitmapText({ text: 'This is the title', style: { fontFamily: 'TitleFont' }});\n */\nexport const BitmapFontManager = new BitmapFontManagerClass();\n", "import { Cache } from '../../assets/cache/Cache';\nimport { ExtensionType } from '../../extensions/Extensions';\nimport { Graphics } from '../graphics/shared/Graphics';\nimport { CanvasTextMetrics } from '../text/canvas/CanvasTextMetrics';\nimport { SdfShader } from '../text/sdfShader/SdfShader';\nimport { BitmapFontManager } from './BitmapFontManager';\nimport { getBitmapTextLayout } from './utils/getBitmapTextLayout';\n\nimport type { InstructionSet } from '../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderable } from '../../rendering/renderers/shared/Renderable';\nimport type { Renderer } from '../../rendering/renderers/types';\nimport type { BitmapText } from './BitmapText';\n\n/** @internal */\nexport class BitmapTextGraphics extends Graphics\n{\n public destroy()\n {\n if (this.context.customShader)\n {\n this.context.customShader.destroy();\n }\n\n super.destroy();\n }\n}\n\n/** @internal */\nexport class BitmapTextPipe implements RenderPipe<BitmapText>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'bitmapText',\n } as const;\n\n private _renderer: Renderer;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n }\n\n public validateRenderable(bitmapText: BitmapText): boolean\n {\n const graphicsRenderable = this._getGpuBitmapText(bitmapText);\n\n return this._renderer.renderPipes.graphics.validateRenderable(graphicsRenderable);\n\n // TODO - need to shift all the verts in the graphicsData to the new anchor\n\n // update the anchor...\n }\n\n public addRenderable(bitmapText: BitmapText, instructionSet: InstructionSet)\n {\n const graphicsRenderable = this._getGpuBitmapText(bitmapText);\n\n // sync..\n syncWithProxy(bitmapText, graphicsRenderable);\n\n if (bitmapText._didTextUpdate)\n {\n bitmapText._didTextUpdate = false;\n\n this._updateContext(bitmapText, graphicsRenderable);\n }\n\n this._renderer.renderPipes.graphics.addRenderable(graphicsRenderable, instructionSet);\n\n if (graphicsRenderable.context.customShader)\n {\n this._updateDistanceField(bitmapText);\n }\n }\n\n public updateRenderable(bitmapText: BitmapText)\n {\n const graphicsRenderable = this._getGpuBitmapText(bitmapText);\n\n // sync..\n syncWithProxy(bitmapText, graphicsRenderable);\n\n this._renderer.renderPipes.graphics.updateRenderable(graphicsRenderable);\n\n if (graphicsRenderable.context.customShader)\n {\n this._updateDistanceField(bitmapText);\n }\n }\n\n private _updateContext(bitmapText: BitmapText, proxyGraphics: Graphics)\n {\n const { context } = proxyGraphics;\n\n const bitmapFont = BitmapFontManager.getFont(bitmapText.text, bitmapText._style);\n\n context.clear();\n\n if (bitmapFont.distanceField.type !== 'none')\n {\n if (!context.customShader)\n {\n // TODO: Check if this is a WebGL renderer before asserting type\n context.customShader = new SdfShader(this._renderer.limits.maxBatchableTextures);\n }\n }\n\n const chars = CanvasTextMetrics.graphemeSegmenter(bitmapText.text);\n const style = bitmapText._style;\n\n let currentY = bitmapFont.baseLineOffset;\n\n // measure our text...\n const bitmapTextLayout = getBitmapTextLayout(chars, style, bitmapFont, true);\n\n const padding = style.padding;\n const scale = bitmapTextLayout.scale;\n\n let tx = bitmapTextLayout.width;\n let ty = bitmapTextLayout.height + bitmapTextLayout.offsetY;\n\n if (style._stroke)\n {\n tx += style._stroke.width / scale;\n ty += style._stroke.width / scale;\n }\n\n context\n .translate((-bitmapText._anchor._x * tx) - padding, (-bitmapText._anchor._y * ty) - padding)\n .scale(scale, scale);\n\n const tint = bitmapFont.applyFillAsTint ? style._fill.color : 0xFFFFFF;\n\n let fontSize = bitmapFont.fontMetrics.fontSize;\n let lineHeight = bitmapFont.lineHeight;\n\n if (style.lineHeight)\n {\n fontSize = style.fontSize / scale;\n lineHeight = style.lineHeight / scale;\n }\n\n let linePositionYShift = (lineHeight - fontSize) / 2;\n\n // if `currentY` is no longer starts from `baseLineOffset`\n // the `baseLineOffset` below may also need to be removed\n if (linePositionYShift - bitmapFont.baseLineOffset < 0)\n {\n linePositionYShift = 0;\n }\n\n for (let i = 0; i < bitmapTextLayout.lines.length; i++)\n {\n const line = bitmapTextLayout.lines[i];\n\n for (let j = 0; j < line.charPositions.length; j++)\n {\n const char = line.chars[j];\n const charData = bitmapFont.chars[char];\n\n if (charData?.texture)\n {\n const texture = charData.texture;\n\n context.texture(\n texture,\n tint ? tint : 'black',\n Math.round(line.charPositions[j] + charData.xOffset),\n Math.round(currentY + charData.yOffset + linePositionYShift),\n texture.orig.width,\n texture.orig.height,\n );\n }\n }\n\n currentY += lineHeight;\n }\n }\n\n private _getGpuBitmapText(bitmapText: BitmapText)\n {\n return bitmapText._gpuData[this._renderer.uid] || this.initGpuText(bitmapText);\n }\n\n public initGpuText(bitmapText: BitmapText)\n {\n // TODO we could keep a bunch of contexts around and reuse one that has the same style!\n const proxyRenderable = new BitmapTextGraphics();\n\n bitmapText._gpuData[this._renderer.uid] = proxyRenderable;\n\n this._updateContext(bitmapText, proxyRenderable);\n\n return proxyRenderable;\n }\n\n private _updateDistanceField(bitmapText: BitmapText)\n {\n const context = this._getGpuBitmapText(bitmapText).context;\n\n const fontFamily = bitmapText._style.fontFamily as string;\n const dynamicFont = Cache.get(`${fontFamily as string}-bitmap`);\n\n // Inject the shader code with the correct value\n const { a, b, c, d } = bitmapText.groupTransform;\n\n const dx = Math.sqrt((a * a) + (b * b));\n const dy = Math.sqrt((c * c) + (d * d));\n const worldScale = (Math.abs(dx) + Math.abs(dy)) / 2;\n\n const fontScale = dynamicFont.baseRenderedFontSize / bitmapText._style.fontSize;\n\n const distance = worldScale * dynamicFont.distanceField.range * (1 / fontScale);\n\n context.customShader.resources.localUniforms.uniforms.uDistance = distance;\n }\n\n public destroy()\n {\n this._renderer = null;\n }\n}\n\nfunction syncWithProxy(container: Renderable, proxy: Renderable)\n{\n proxy.groupTransform = container.groupTransform;\n proxy.groupColorAlpha = container.groupColorAlpha;\n proxy.groupColor = container.groupColor;\n proxy.groupBlendMode = container.groupBlendMode;\n proxy.globalDisplayStatus = container.globalDisplayStatus;\n proxy.groupTransform = container.groupTransform;\n proxy.localDisplayStatus = container.localDisplayStatus;\n proxy.groupAlpha = container.groupAlpha;\n proxy._roundPixels = container._roundPixels;\n}\n", "import { type Texture } from '../../rendering/renderers/shared/texture/Texture';\nimport { BatchableSprite } from '../sprite/BatchableSprite';\n\nimport type { Renderer } from '../../rendering/renderers/types';\nimport type { HTMLText } from './HTMLText';\n\n/**\n * The BatchableHTMLText class extends the BatchableSprite class and is used to handle HTML text rendering.\n * It includes a promise for the texture as generating the HTML texture takes some time.\n * @internal\n */\nexport class BatchableHTMLText extends BatchableSprite\n{\n private readonly _renderer: Renderer;\n public texturePromise: Promise<Texture>;\n public generatingTexture = false;\n public currentKey: string = '--';\n\n /**\n * Creates an instance of BatchableHTMLText.\n * @param renderer - The renderer instance to be used.\n */\n constructor(renderer: Renderer)\n {\n super();\n\n // Next step is to make canvasTextSystem a GLOBAL object.\n // so this is ok for now..\n this._renderer = renderer;\n\n renderer.runners.resolutionChange.add(this);\n }\n\n /** Handles resolution changes for the HTML text. If the text has auto resolution enabled, it triggers a view update. */\n public resolutionChange()\n {\n const text = this.renderable as HTMLText;\n\n if (text._autoResolution)\n {\n text.onViewUpdate();\n }\n }\n\n /** Destroys the BatchableHTMLText instance. Returns the texture promise to the renderer and cleans up references. */\n public destroy()\n {\n const { htmlText } = this._renderer;\n\n htmlText.getReferenceCount(this.currentKey) === null\n ? htmlText.returnTexturePromise(this.texturePromise)\n : htmlText.decreaseReferenceCount(this.currentKey);\n this._renderer.runners.resolutionChange.remove(this);\n this.texturePromise = null;\n (this._renderer as null) = null;\n }\n}\n", "import { ExtensionType } from '../../extensions/Extensions';\nimport { Texture } from '../../rendering/renderers/shared/texture/Texture';\nimport { updateTextBounds } from '../text/utils/updateTextBounds';\nimport { BatchableHTMLText } from './BatchableHTMLText';\n\nimport type { InstructionSet } from '../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderer } from '../../rendering/renderers/types';\nimport type { HTMLText } from './HTMLText';\n\n/**\n * The HTMLTextPipe class is responsible for rendering HTML text.\n * @internal\n */\nexport class HTMLTextPipe implements RenderPipe<HTMLText>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'htmlText',\n } as const;\n\n private _renderer: Renderer;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n }\n\n public validateRenderable(htmlText: HTMLText): boolean\n {\n const gpuText = this._getGpuText(htmlText);\n\n const newKey = htmlText.styleKey;\n\n if (gpuText.currentKey !== newKey)\n {\n return true;\n }\n\n return false;\n }\n\n public addRenderable(htmlText: HTMLText, instructionSet: InstructionSet)\n {\n const batchableHTMLText = this._getGpuText(htmlText);\n\n if (htmlText._didTextUpdate)\n {\n const resolution = htmlText._autoResolution ? this._renderer.resolution : htmlText.resolution;\n\n if (batchableHTMLText.currentKey !== htmlText.styleKey || htmlText.resolution !== resolution)\n {\n // If the text has changed, we need to update the GPU text\n this._updateGpuText(htmlText).catch((e) =>\n {\n console.error(e);\n });\n }\n\n htmlText._didTextUpdate = false;\n\n updateTextBounds(batchableHTMLText, htmlText);\n }\n\n this._renderer.renderPipes.batch.addToBatch(batchableHTMLText, instructionSet);\n }\n\n public updateRenderable(htmlText: HTMLText)\n {\n const batchableHTMLText = this._getGpuText(htmlText);\n\n batchableHTMLText._batcher.updateElement(batchableHTMLText);\n }\n\n private async _updateGpuText(htmlText: HTMLText)\n {\n htmlText._didTextUpdate = false;\n const batchableHTMLText = this._getGpuText(htmlText);\n\n if (batchableHTMLText.generatingTexture) return;\n\n // We need to preserve the current texture and don't release it until the new texture is generated.\n // It's necessary to ensure that the texture won't be captured by another field and overwritten with their\n // content, while our texture is still in progress.\n const oldTexturePromise = batchableHTMLText.texturePromise;\n\n batchableHTMLText.texturePromise = null;\n\n batchableHTMLText.generatingTexture = true;\n\n htmlText._resolution = htmlText._autoResolution ? this._renderer.resolution : htmlText.resolution;\n\n let texturePromise = this._renderer.htmlText.getTexturePromise(htmlText);\n\n if (oldTexturePromise)\n {\n // Release old texture after new one is generated.\n texturePromise = texturePromise.finally(() =>\n {\n this._renderer.htmlText.decreaseReferenceCount(batchableHTMLText.currentKey);\n this._renderer.htmlText.returnTexturePromise(oldTexturePromise);\n });\n }\n\n batchableHTMLText.texturePromise = texturePromise;\n batchableHTMLText.currentKey = htmlText.styleKey;\n\n batchableHTMLText.texture = await texturePromise;\n\n // need a rerender...\n const renderGroup = htmlText.renderGroup || htmlText.parentRenderGroup;\n\n if (renderGroup)\n {\n // need a rebuild of the render group\n renderGroup.structureDidChange = true;\n }\n\n batchableHTMLText.generatingTexture = false;\n\n updateTextBounds(batchableHTMLText, htmlText);\n }\n\n private _getGpuText(htmlText: HTMLText)\n {\n return htmlText._gpuData[this._renderer.uid] || this.initGpuText(htmlText);\n }\n\n public initGpuText(htmlText: HTMLText)\n {\n const batchableHTMLText = new BatchableHTMLText(this._renderer);\n\n batchableHTMLText.renderable = htmlText;\n batchableHTMLText.transform = htmlText.groupTransform;\n batchableHTMLText.texture = Texture.EMPTY;\n batchableHTMLText.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 };\n batchableHTMLText.roundPixels = (this._renderer._roundPixels | htmlText._roundPixels) as 0 | 1;\n\n htmlText._resolution = htmlText._autoResolution ? this._renderer.resolution : htmlText.resolution;\n htmlText._gpuData[this._renderer.uid] = batchableHTMLText;\n\n return batchableHTMLText;\n }\n\n public destroy()\n {\n this._renderer = null;\n }\n}\n\n", "import { DOMAdapter } from '../../environment/adapter';\n\n/**\n * Checks if the current browser is Safari.\n * @returns {boolean} True if the browser is Safari, false otherwise.\n * @internal\n */\nexport function isSafari(): boolean\n{\n const { userAgent } = DOMAdapter.get().getNavigator();\n\n return (/^((?!chrome|android).)*safari/i).test(userAgent);\n}\n", "/* eslint-disable no-restricted-globals */\nimport { DOMAdapter } from '../../environment/adapter';\nimport { type ImageLike } from '../../environment/ImageLike';\n\nimport type { CanvasAndContext } from '../../rendering/renderers/shared/texture/CanvasPool';\n\n/** @internal */\nconst nssvg = 'http://www.w3.org/2000/svg';\n/** @internal */\nconst nsxhtml = 'http://www.w3.org/1999/xhtml';\n\n/** @internal */\nexport class HTMLTextRenderData\n{\n public svgRoot = document.createElementNS(nssvg, 'svg');\n public foreignObject = document.createElementNS(nssvg, 'foreignObject');\n public domElement = document.createElementNS(nsxhtml, 'div');\n public styleElement = document.createElementNS(nsxhtml, 'style');\n public image: ImageLike;\n public canvasAndContext?: CanvasAndContext;\n\n constructor()\n {\n const { foreignObject, svgRoot, styleElement, domElement } = this;\n // Arbitrary max size\n\n foreignObject.setAttribute('width', '10000');\n foreignObject.setAttribute('height', '10000');\n foreignObject.style.overflow = 'hidden';\n\n svgRoot.appendChild(foreignObject);\n\n foreignObject.appendChild(styleElement);\n foreignObject.appendChild(domElement);\n\n this.image = DOMAdapter.get().createImage();\n }\n\n public destroy(): void\n {\n this.svgRoot.remove();\n this.foreignObject.remove();\n this.styleElement.remove();\n this.domElement.remove();\n this.image.src = '';\n this.image.remove();\n\n this.svgRoot = null;\n this.foreignObject = null;\n this.styleElement = null;\n this.domElement = null;\n this.image = null;\n this.canvasAndContext = null;\n }\n}\n", "import type { HTMLTextStyle } from '../HTMLTextStyle';\n\n/**\n * Extracts font families from text. It will extract font families from the style, tagStyles and any font families\n * embedded in the text. It should also strip out duplicates as it goes.\n * @param text - The text to extract font families from\n * @param style - The style to extract font families from\n * @returns {string[]} - The font families as an array of strings\n * @internal\n */\nexport function extractFontFamilies(text: string, style: HTMLTextStyle): string[]\n{\n const fontFamily = style.fontFamily;\n const fontFamilies: string[] = [];\n const dedupe: Record<string, boolean> = {};\n\n // first ensure fonts are loaded inline..\n // find any font..\n const regex = /font-family:([^;\"\\s]+)/g;\n\n const matches = text.match(regex);\n\n function addFontFamily(fontFamily: string)\n {\n if (!dedupe[fontFamily])\n {\n fontFamilies.push(fontFamily);\n\n dedupe[fontFamily] = true;\n }\n }\n\n if (Array.isArray(fontFamily))\n {\n for (let i = 0; i < fontFamily.length; i++)\n {\n addFontFamily(fontFamily[i]);\n }\n }\n else\n {\n addFontFamily(fontFamily);\n }\n\n if (matches)\n {\n matches.forEach((match) =>\n {\n const fontFamily = match.split(':')[1].trim();\n\n addFontFamily(fontFamily);\n });\n }\n\n for (const i in style.tagStyles)\n {\n const fontFamily = style.tagStyles[i].fontFamily;\n\n addFontFamily(fontFamily as string);\n }\n\n return fontFamilies;\n}\n", "import { DOMAdapter } from '../../../environment/adapter';\n\n/**\n * Resolves a font url to a base64 string\n * @param url - The url to load the font from\n * @returns - The font as a base64 string\n * @internal\n */\nexport async function loadFontAsBase64(url: string): Promise<string>\n{\n const response = await DOMAdapter.get().fetch(url);\n\n const blob = await response.blob();\n\n const reader = new FileReader();\n\n const dataSrc: string = await new Promise((resolve, reject) =>\n {\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n\n return dataSrc;\n}\n", "import { loadFontAsBase64 } from './loadFontAsBase64';\n\n/**\n * Options for the font CSS style\n * @category text\n * @internal\n */\nexport interface FontCSSStyleOptions\n{\n /**\n * The font family to use in the CSS\n * @example\n * 'Arial' or ['Arial', 'Helvetica']\n */\n fontFamily: string | string[]\n /**\n * The font weight to use in the CSS\n * @example\n * 'normal', 'bold', '100', '200', etc.\n */\n fontWeight: string\n /**\n * The font style to use in the CSS\n * @example\n * 'normal', 'italic', 'oblique'\n */\n fontStyle: string\n}\n\n/**\n * This will take a font url and a style and return a css string that can be injected into a style tag\n * This will contain inlined base64 font and the font family information\n * @param style - the style to generate the css for\n * @param url - The url to load the font from\n * @returns - The css string\n * @internal\n */\nexport async function loadFontCSS(style: FontCSSStyleOptions, url: string): Promise<string>\n{\n const dataSrc = await loadFontAsBase64(url);\n\n return `@font-face {\n font-family: \"${style.fontFamily}\";\n font-weight: ${style.fontWeight};\n font-style: ${style.fontStyle};\n src: url('${dataSrc}');\n }`;\n}\n", "import { Cache } from '../../../assets/cache/Cache';\nimport { type FontFaceCache } from '../../../assets/loader/parsers/loadWebFont';\nimport { loadFontCSS } from './loadFontCSS';\n\n/** @internal */\nexport const FontStylePromiseCache = new Map<string, Promise<string>>();\n\n/**\n * takes the font families and returns a css string that can be injected into a style tag\n * It will contain the font families and the font urls encoded as base64\n * @param fontFamilies - The font families to load\n * @returns - The css string\n * @internal\n */\nexport async function getFontCss(\n fontFamilies: string[],\n)\n{\n const fontPromises = fontFamilies\n .filter((fontFamily) => Cache.has(`${fontFamily}-and-url`))\n .map((fontFamily) =>\n {\n if (!FontStylePromiseCache.has(fontFamily))\n {\n const { entries } = Cache.get<FontFaceCache>(`${fontFamily}-and-url`);\n const promises: Promise<string>[] = [];\n\n entries.forEach((entry) =>\n {\n const url = entry.url;\n const faces = entry.faces;\n\n const out = faces.map((face) => ({ weight: face.weight, style: face.style }));\n\n // load each out font with the correct style\n promises.push(\n ...out.map((style) =>\n loadFontCSS(\n {\n fontWeight: style.weight,\n fontStyle: style.style,\n fontFamily,\n },\n url,\n ),\n ),\n );\n });\n FontStylePromiseCache.set(\n fontFamily,\n Promise.all(promises).then((css) => css.join('\\n')),\n );\n }\n\n return FontStylePromiseCache.get(fontFamily);\n });\n\n return (await Promise.all(fontPromises)).join('\\n');\n}\n", "import type { HTMLTextRenderData } from '../HTMLTextRenderData';\nimport type { HTMLTextStyle } from '../HTMLTextStyle';\n\n/**\n * takes all the data and returns a svg url string can be loaded by an image element\n * @param text - The text to measure\n * @param style - The style to use\n * @param resolution - The resolution to use\n * @param fontCSS - The font css to use\n * @param htmlTextData - The HTMLTextRenderData to write the SVG to\n * @returns - The SVG as a url string\n * @internal\n */\nexport function getSVGUrl(\n text: string,\n style: HTMLTextStyle,\n resolution: number,\n fontCSS: string,\n htmlTextData: HTMLTextRenderData\n)\n{\n const { domElement, styleElement, svgRoot } = htmlTextData;\n\n domElement.innerHTML = `<style>${style.cssStyle}</style><div style='padding:0;'>${text}</div>`;\n domElement.setAttribute('style', `transform: scale(${resolution});transform-origin: top left; display: inline-block`);\n styleElement.textContent = fontCSS;\n\n const { width, height } = htmlTextData.image;\n\n svgRoot.setAttribute('width', width.toString());\n svgRoot.setAttribute('height', height.toString());\n\n return new XMLSerializer().serializeToString(svgRoot);\n}\n", "import { type ImageLike } from '../../../environment/ImageLike';\nimport { CanvasPool } from '../../../rendering/renderers/shared/texture/CanvasPool';\n\nimport type { CanvasAndContext } from '../../../rendering/renderers/shared/texture/CanvasPool';\n\n/**\n * This function converts an image to a canvas, and returns the canvas.\n * It is used to convert images to canvases to work around a CORS issue where WebGPU cannot\n * upload an SVGImage to a texture.\n *\n * It uses the CanvasPool to get an optimal canvas and context, and then draws the image onto it.\n * Remember to return this canvas is immediately to the CanvasPool for reuse when you are done with it.\n * (eg upload it to the GPU!)\n * @param image - The image to convert to a canvas.\n * @param resolution - The resolution of the canvas.\n * @internal\n */\nexport function getTemporaryCanvasFromImage(image: ImageLike, resolution: number): CanvasAndContext\n{\n // Get an optimal canvas and context from the CanvasPool, based on the\n // dimensions of the image and the desired resolution.\n const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(\n image.width,\n image.height,\n resolution\n );\n\n // Clear the context of the canvas, and draw the image onto it.\n const { context } = canvasAndContext;\n\n context.clearRect(0, 0, image.width, image.height);\n context.drawImage(image, 0, 0);\n\n // Return the canvas.\n return canvasAndContext;\n}\n\n", "import { type ImageLike } from '../../../environment/ImageLike';\n\n/**\n * This function loads an SVG image into an IImage element.\n * The image can then be uploaded as texture to the GPU.\n * iOS has a bug where embedded fonts are not available immediately after the image loads,\n * so we wait an arbitrary amount of time before resolving the promise.\n * @param image - The image to load the SVG into\n * @param url - The url to load the SVG from\n * @param delay - Whether to delay the load\n * @returns - A promise that resolves when the image has loaded\n * @internal\n */\nexport function loadSVGImage(image: ImageLike, url: string, delay: boolean)\n{\n return new Promise<void>(async (resolve) =>\n {\n // Safari has a known bug where embedded fonts are not available\n // immediately after the image loads, to compensate we wait an\n // arbitrary amount of time\n // @see https://bugs.webkit.org/show_bug.cgi?id=219770\n if (delay)\n {\n await new Promise<void>((resolve) => setTimeout(resolve, 100));\n }\n\n image.onload = () =>\n {\n resolve();\n };\n\n image.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(url)}`;\n image.crossOrigin = 'anonymous';\n });\n}\n", "/* eslint-disable no-restricted-globals */\nimport { HTMLTextRenderData } from '../HTMLTextRenderData';\n\nimport type { Size } from '../../../maths/misc/Size';\nimport type { HTMLTextStyle } from '../HTMLTextStyle';\n\nlet tempHTMLTextRenderData: HTMLTextRenderData;\n\n/**\n * Measures the HTML text without actually generating an image.\n * This is used to calculate the size of the text.\n * @param text - The text to measure\n * @param style - The style to use\n * @param fontStyleCSS - The font css to use\n * @param htmlTextRenderData - The HTMLTextRenderData to write the SVG to\n * @returns - The size of the text\n * @internal\n */\nexport function measureHtmlText(\n text: string,\n style: HTMLTextStyle,\n fontStyleCSS?: string,\n htmlTextRenderData?: HTMLTextRenderData\n): Size\n{\n htmlTextRenderData ||= tempHTMLTextRenderData || (tempHTMLTextRenderData = new HTMLTextRenderData());\n\n const { domElement, styleElement, svgRoot } = htmlTextRenderData;\n\n domElement.innerHTML = `<style>${style.cssStyle};</style><div style='padding:0'>${text}</div>`;\n\n domElement.setAttribute('style', 'transform-origin: top left; display: inline-block');\n\n if (fontStyleCSS)\n {\n styleElement.textContent = fontStyleCSS;\n }\n\n // Measure the contents using the shadow DOM\n document.body.appendChild(svgRoot);\n\n const contentBounds = domElement.getBoundingClientRect();\n\n svgRoot.remove();\n\n // padding is included in the CSS calculation, so we need to remove it here\n const doublePadding = style.padding * 2;\n\n return {\n width: contentBounds.width - doublePadding,\n height: contentBounds.height - doublePadding,\n };\n}\n", "import { type ImageLike } from '../../environment/ImageLike';\nimport { ExtensionType } from '../../extensions/Extensions';\nimport { type CanvasAndContext, CanvasPool } from '../../rendering/renderers/shared/texture/CanvasPool';\nimport { TexturePool } from '../../rendering/renderers/shared/texture/TexturePool';\nimport { type TextureStyle } from '../../rendering/renderers/shared/texture/TextureStyle';\nimport { type Renderer, RendererType } from '../../rendering/renderers/types';\nimport { isSafari } from '../../utils/browser/isSafari';\nimport { warn } from '../../utils/logging/warn';\nimport { BigPool } from '../../utils/pool/PoolGroup';\nimport { getPo2TextureFromSource } from '../text/utils/getPo2TextureFromSource';\nimport { HTMLTextRenderData } from './HTMLTextRenderData';\nimport { type HTMLTextStyle } from './HTMLTextStyle';\nimport { extractFontFamilies } from './utils/extractFontFamilies';\nimport { getFontCss } from './utils/getFontCss';\nimport { getSVGUrl } from './utils/getSVGUrl';\nimport { getTemporaryCanvasFromImage } from './utils/getTemporaryCanvasFromImage';\nimport { loadSVGImage } from './utils/loadSVGImage';\nimport { measureHtmlText } from './utils/measureHtmlText';\n\nimport type { System } from '../../rendering/renderers/shared/system/System';\nimport type { Texture } from '../../rendering/renderers/shared/texture/Texture';\nimport type { PoolItem } from '../../utils/pool/Pool';\nimport type { HTMLText, HTMLTextOptions } from './HTMLText';\n\n/**\n * System plugin to the renderer to manage HTMLText\n * @category rendering\n * @advanced\n */\nexport class HTMLTextSystem implements System\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLSystem,\n ExtensionType.WebGPUSystem,\n ExtensionType.CanvasSystem,\n ],\n name: 'htmlText',\n } as const;\n\n /**\n * WebGPU has a cors issue when uploading an image that is an SVGImage\n * To get around this we need to create a canvas draw the image to it and upload that instead.\n * Bit of a shame.. but no other work around just yet!\n */\n private readonly _createCanvas: boolean;\n private readonly _renderer: Renderer;\n\n private readonly _activeTextures: Record<string, {\n texture: Texture,\n usageCount: number,\n promise: Promise<Texture>,\n }> = {};\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n this._createCanvas = renderer.type === RendererType.WEBGPU;\n }\n\n /**\n * @param options\n * @deprecated Use getTexturePromise instead\n */\n public getTexture(options: HTMLTextOptions): Promise<Texture>\n {\n return this.getTexturePromise(options);\n }\n\n /**\n * Increases the reference count for a texture.\n * @param text - The HTMLText instance associated with the texture.\n */\n public getManagedTexture(text: HTMLText): Promise<Texture>\n {\n const textKey = text.styleKey;\n\n if (this._activeTextures[textKey])\n {\n this._increaseReferenceCount(textKey);\n\n return this._activeTextures[textKey].promise;\n }\n\n const promise = this._buildTexturePromise(text)\n .then((texture) =>\n {\n this._activeTextures[textKey].texture = texture;\n\n return texture;\n });\n\n this._activeTextures[textKey] = {\n texture: null,\n promise,\n usageCount: 1,\n };\n\n return promise;\n }\n\n /**\n * Gets the current reference count for a texture associated with a text key.\n * @param textKey - The unique key identifying the text style configuration\n * @returns The number of Text instances currently using this texture\n */\n public getReferenceCount(textKey: string)\n {\n return this._activeTextures[textKey]?.usageCount ?? null;\n }\n\n private _increaseReferenceCount(textKey: string)\n {\n this._activeTextures[textKey].usageCount++;\n }\n\n /**\n * Decreases the reference count for a texture.\n * If the count reaches zero, the texture is cleaned up.\n * @param textKey - The key associated with the HTMLText instance.\n */\n public decreaseReferenceCount(textKey: string)\n {\n const activeTexture = this._activeTextures[textKey];\n\n if (!activeTexture) return;\n\n activeTexture.usageCount--;\n\n if (activeTexture.usageCount === 0)\n {\n if (activeTexture.texture)\n {\n this._cleanUp(activeTexture.texture);\n }\n else\n {\n // we did not resolve...\n activeTexture.promise.then((texture) =>\n {\n activeTexture.texture = texture;\n\n this._cleanUp(activeTexture.texture);\n }).catch(() =>\n {\n // #if _DEBUG\n warn('HTMLTextSystem: Failed to clean texture');\n // #endif\n });\n }\n\n this._activeTextures[textKey] = null;\n }\n }\n\n /**\n * Returns a promise that resolves to a texture for the given HTMLText options.\n * @param options - The options for the HTMLText.\n * @returns A promise that resolves to a Texture.\n */\n public getTexturePromise(options: HTMLTextOptions): Promise<Texture>\n {\n return this._buildTexturePromise(options);\n }\n\n private async _buildTexturePromise(options: HTMLTextOptions)\n {\n const { text, style, resolution, textureStyle } = options as {\n text: string,\n style: HTMLTextStyle,\n resolution: number,\n textureStyle?: TextureStyle,\n };\n\n const htmlTextData = BigPool.get(HTMLTextRenderData);\n const fontFamilies = extractFontFamilies(text, style);\n const fontCSS = await getFontCss(fontFamilies);\n const measured = measureHtmlText(text, style, fontCSS, htmlTextData);\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 image = htmlTextData.image;\n\n // this off set will ensure we don't get any UV bleeding!\n const uvSafeOffset = 2;\n\n image.width = (width | 0) + uvSafeOffset;\n image.height = (height | 0) + uvSafeOffset;\n\n const svgURL = getSVGUrl(text, style, resolution, fontCSS, htmlTextData);\n\n await loadSVGImage(image, svgURL, isSafari() && fontFamilies.length > 0);\n\n const resource: ImageLike | HTMLCanvasElement = image;\n let canvasAndContext: CanvasAndContext;\n\n if (this._createCanvas)\n {\n // silly webGPU workaround..\n canvasAndContext = getTemporaryCanvasFromImage(image, resolution);\n }\n\n const texture = getPo2TextureFromSource(canvasAndContext ? canvasAndContext.canvas : resource,\n image.width - uvSafeOffset,\n image.height - uvSafeOffset,\n resolution\n );\n\n if (textureStyle) texture.source.style = textureStyle;\n\n if (this._createCanvas)\n {\n this._renderer.texture.initSource(texture.source);\n CanvasPool.returnCanvasAndContext(canvasAndContext);\n }\n\n BigPool.return(htmlTextData as PoolItem);\n\n return texture;\n }\n\n public returnTexturePromise(texturePromise: Promise<Texture>)\n {\n texturePromise.then((texture) =>\n {\n this._cleanUp(texture);\n }).catch(() =>\n {\n // #if _DEBUG\n warn('HTMLTextSystem: Failed to clean texture');\n // #endif\n });\n }\n\n private _cleanUp(texture: Texture)\n {\n TexturePool.returnTexture(texture, true);\n texture.source.resource = null;\n texture.source.uploadMethodId = 'unknown';\n }\n\n public destroy()\n {\n // BOOM!\n (this._renderer as null) = null;\n for (const key in this._activeTextures)\n {\n if (this._activeTextures[key]) this.returnTexturePromise(this._activeTextures[key].promise);\n }\n (this._activeTextures as null) = null;\n }\n}\n", "import { Buffer } from '../../../rendering/renderers/shared/buffer/Buffer';\nimport { BufferUsage } from '../../../rendering/renderers/shared/buffer/const';\nimport { Geometry } from '../../../rendering/renderers/shared/geometry/Geometry';\nimport { deprecation, v8_0_0 } from '../../../utils/logging/deprecation';\n\nimport type { Topology } from '../../../rendering/renderers/shared/geometry/const';\nimport type { BatchMode } from '../../graphics/shared/GraphicsContext';\n\n/**\n * Options for the mesh geometry.\n * @category scene\n * @advanced\n */\nexport interface MeshGeometryOptions\n{\n /** The positions of the mesh. */\n positions?: Float32Array;\n /** The UVs of the mesh. If not provided, they will be filled with 0 and match the size of the positions. */\n uvs?: Float32Array;\n /** The indices of the mesh. */\n indices?: Uint32Array;\n /** The topology of the mesh. */\n topology?: Topology;\n /** Whether to shrink the buffers to fit the data. */\n shrinkBuffersToFit?: boolean;\n}\n\n/**\n * A geometry used to batch multiple meshes with the same texture.\n * @category scene\n * @advanced\n */\nexport class MeshGeometry extends Geometry\n{\n public static defaultOptions: MeshGeometryOptions = {\n topology: 'triangle-list',\n shrinkBuffersToFit: false,\n };\n\n public batchMode: BatchMode = 'auto';\n\n /**\n * @param {MeshGeometryOptions} options - The options of the mesh geometry.\n */\n constructor(options: MeshGeometryOptions);\n /** @deprecated since 8.0.0 */\n constructor(positions: Float32Array, uvs: Float32Array, indices: Uint32Array);\n constructor(...args: [MeshGeometryOptions] | [Float32Array, Float32Array, Uint32Array])\n {\n let options = args[0] ?? {};\n\n if (options instanceof Float32Array)\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'use new MeshGeometry({ positions, uvs, indices }) instead');\n // #endif\n\n options = {\n positions: options,\n uvs: args[1],\n indices: args[2],\n };\n }\n\n options = { ...MeshGeometry.defaultOptions, ...options };\n\n const positions = options.positions || new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);\n\n let uvs = options.uvs;\n\n if (!uvs)\n {\n if (options.positions)\n {\n uvs = new Float32Array(positions.length);\n }\n else\n {\n uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);\n }\n }\n\n const indices = options.indices || new Uint32Array([0, 1, 2, 0, 2, 3]);\n\n const shrinkToFit = options.shrinkBuffersToFit;\n\n const positionBuffer = new Buffer({\n data: positions,\n label: 'attribute-mesh-positions',\n shrinkToFit,\n usage: BufferUsage.VERTEX | BufferUsage.COPY_DST,\n });\n\n const uvBuffer = new Buffer({\n data: uvs,\n label: 'attribute-mesh-uvs',\n shrinkToFit,\n usage: BufferUsage.VERTEX | BufferUsage.COPY_DST,\n });\n\n const indexBuffer = new Buffer({\n data: indices,\n label: 'index-mesh-buffer',\n shrinkToFit,\n usage: BufferUsage.INDEX | BufferUsage.COPY_DST,\n });\n\n super({\n attributes: {\n aPosition: {\n buffer: positionBuffer,\n format: 'float32x2',\n stride: 2 * 4,\n offset: 0,\n },\n aUV: {\n buffer: uvBuffer,\n format: 'float32x2',\n stride: 2 * 4,\n offset: 0,\n },\n },\n indexBuffer,\n topology: options.topology,\n });\n }\n\n /** The positions of the mesh. */\n get positions(): Float32Array\n {\n return this.attributes.aPosition.buffer.data as Float32Array;\n }\n\n /**\n * Set the positions of the mesh.\n * When setting the positions, its important that the uvs array is at least as long as the positions array.\n * otherwise the geometry will not be valid.\n * @param {Float32Array} value - The positions of the mesh.\n */\n set positions(value: Float32Array)\n {\n this.attributes.aPosition.buffer.data = value;\n }\n\n /** The UVs of the mesh. */\n get uvs(): Float32Array\n {\n return this.attributes.aUV.buffer.data as Float32Array;\n }\n\n /**\n * Set the UVs of the mesh.\n * Its important that the uvs array you set is at least as long as the positions array.\n * otherwise the geometry will not be valid.\n * @param {Float32Array} value - The UVs of the mesh.\n */\n set uvs(value: Float32Array)\n {\n this.attributes.aUV.buffer.data = value;\n }\n\n /** The indices of the mesh. */\n get indices(): Uint32Array\n {\n return this.indexBuffer.data as Uint32Array;\n }\n\n set indices(value: Uint32Array)\n {\n this.indexBuffer.data = value;\n }\n}\n", "/** @internal */\nexport const tilingBit = {\n name: 'tiling-bit',\n vertex: {\n header: /* wgsl */`\n struct TilingUniforms {\n uMapCoord:mat3x3<f32>,\n uClampFrame:vec4<f32>,\n uClampOffset:vec2<f32>,\n uTextureTransform:mat3x3<f32>,\n uSizeAnchor:vec4<f32>\n };\n\n @group(2) @binding(0) var<uniform> tilingUniforms: TilingUniforms;\n @group(2) @binding(1) var uTexture: texture_2d<f32>;\n @group(2) @binding(2) var uSampler: sampler;\n `,\n main: /* wgsl */`\n uv = (tilingUniforms.uTextureTransform * vec3(uv, 1.0)).xy;\n\n position = (position - tilingUniforms.uSizeAnchor.zw) * tilingUniforms.uSizeAnchor.xy;\n `\n\n },\n fragment: {\n header: /* wgsl */`\n struct TilingUniforms {\n uMapCoord:mat3x3<f32>,\n uClampFrame:vec4<f32>,\n uClampOffset:vec2<f32>,\n uTextureTransform:mat3x3<f32>,\n uSizeAnchor:vec4<f32>\n };\n\n @group(2) @binding(0) var<uniform> tilingUniforms: TilingUniforms;\n @group(2) @binding(1) var uTexture: texture_2d<f32>;\n @group(2) @binding(2) var uSampler: sampler;\n `,\n main: /* wgsl */`\n\n var coord = vUV + ceil(tilingUniforms.uClampOffset - vUV);\n coord = (tilingUniforms.uMapCoord * vec3(coord, 1.0)).xy;\n var unclamped = coord;\n coord = clamp(coord, tilingUniforms.uClampFrame.xy, tilingUniforms.uClampFrame.zw);\n\n var bias = 0.;\n\n if(unclamped.x == coord.x && unclamped.y == coord.y)\n {\n bias = -32.;\n }\n\n outColor = textureSampleBias(uTexture, uSampler, coord, bias);\n `\n }\n\n};\n\n/** @internal */\nexport const tilingBitGl = {\n name: 'tiling-bit',\n vertex: {\n header: /* glsl */`\n uniform mat3 uTextureTransform;\n uniform vec4 uSizeAnchor;\n\n `,\n main: /* glsl */`\n uv = (uTextureTransform * vec3(aUV, 1.0)).xy;\n\n position = (position - uSizeAnchor.zw) * uSizeAnchor.xy;\n `\n\n },\n fragment: {\n header: /* glsl */`\n uniform sampler2D uTexture;\n uniform mat3 uMapCoord;\n uniform vec4 uClampFrame;\n uniform vec2 uClampOffset;\n `,\n main: /* glsl */`\n\n vec2 coord = vUV + ceil(uClampOffset - vUV);\n coord = (uMapCoord * vec3(coord, 1.0)).xy;\n vec2 unclamped = coord;\n coord = clamp(coord, uClampFrame.xy, uClampFrame.zw);\n\n outColor = texture(uTexture, coord, unclamped == coord ? 0.0 : -32.0);// lod-bias very negative to force lod 0\n\n `\n }\n\n};\n", "import { Matrix } from '../../../maths/matrix/Matrix';\nimport {\n compileHighShaderGlProgram,\n compileHighShaderGpuProgram\n} from '../../../rendering/high-shader/compileHighShaderToProgram';\nimport { localUniformBit, localUniformBitGl } from '../../../rendering/high-shader/shader-bits/localUniformBit';\nimport { roundPixelsBit, roundPixelsBitGl } from '../../../rendering/high-shader/shader-bits/roundPixelsBit';\nimport { Shader } from '../../../rendering/renderers/shared/shader/Shader';\nimport { UniformGroup } from '../../../rendering/renderers/shared/shader/UniformGroup';\nimport { Texture } from '../../../rendering/renderers/shared/texture/Texture';\nimport { tilingBit, tilingBitGl } from './tilingBit';\n\nimport type { GlProgram } from '../../../rendering/renderers/gl/shader/GlProgram';\nimport type { GpuProgram } from '../../../rendering/renderers/gpu/shader/GpuProgram';\n\nlet gpuProgram: GpuProgram;\nlet glProgram: GlProgram;\n\n/**\n * The shader used by the TilingSprite.\n * @internal\n */\nexport class TilingSpriteShader extends Shader\n{\n constructor()\n {\n gpuProgram ??= compileHighShaderGpuProgram({\n name: 'tiling-sprite-shader',\n bits: [\n localUniformBit,\n tilingBit,\n roundPixelsBit,\n ],\n });\n\n glProgram ??= compileHighShaderGlProgram({\n name: 'tiling-sprite-shader',\n bits: [\n localUniformBitGl,\n tilingBitGl,\n roundPixelsBitGl,\n ]\n });\n\n const tilingUniforms = new UniformGroup({\n uMapCoord: { value: new Matrix(), type: 'mat3x3<f32>' },\n uClampFrame: { value: new Float32Array([0, 0, 1, 1]), type: 'vec4<f32>' },\n uClampOffset: { value: new Float32Array([0, 0]), type: 'vec2<f32>' },\n uTextureTransform: { value: new Matrix(), type: 'mat3x3<f32>' },\n uSizeAnchor: { value: new Float32Array([100, 100, 0.5, 0.5]), type: 'vec4<f32>' },\n });\n\n super({\n glProgram,\n gpuProgram,\n resources: {\n localUniforms: new UniformGroup({\n uTransformMatrix: { value: new Matrix(), type: 'mat3x3<f32>' },\n uColor: { value: new Float32Array([1, 1, 1, 1]), type: 'vec4<f32>' },\n uRound: { value: 0, type: 'f32' },\n }),\n tilingUniforms,\n uTexture: Texture.EMPTY.source,\n uSampler: Texture.EMPTY.source.style,\n }\n });\n }\n\n public updateUniforms(\n width: number, height: number,\n matrix: Matrix,\n anchorX: number, anchorY: number,\n texture: Texture\n ): void\n {\n const tilingUniforms = this.resources.tilingUniforms;\n\n const textureWidth = texture.width;\n const textureHeight = texture.height;\n const textureMatrix = texture.textureMatrix;\n\n const uTextureTransform = tilingUniforms.uniforms.uTextureTransform;\n\n uTextureTransform.set(\n matrix.a * textureWidth / width,\n matrix.b * textureWidth / height,\n matrix.c * textureHeight / width,\n matrix.d * textureHeight / height,\n matrix.tx / width,\n matrix.ty / height);\n\n uTextureTransform.invert();\n\n tilingUniforms.uniforms.uMapCoord = textureMatrix.mapCoord;\n tilingUniforms.uniforms.uClampFrame = textureMatrix.uClampFrame;\n tilingUniforms.uniforms.uClampOffset = textureMatrix.uClampOffset;\n tilingUniforms.uniforms.uTextureTransform = uTextureTransform;\n tilingUniforms.uniforms.uSizeAnchor[0] = width;\n tilingUniforms.uniforms.uSizeAnchor[1] = height;\n tilingUniforms.uniforms.uSizeAnchor[2] = anchorX;\n tilingUniforms.uniforms.uSizeAnchor[3] = anchorY;\n\n if (texture)\n {\n this.resources.uTexture = texture.source;\n this.resources.uSampler = texture.source.style;\n }\n }\n}\n", "import { MeshGeometry } from '../../mesh/shared/MeshGeometry';\n\n/** @internal */\nexport class QuadGeometry extends MeshGeometry\n{\n constructor()\n {\n super({\n positions: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]),\n uvs: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]),\n indices: new Uint32Array([0, 1, 2, 0, 2, 3]),\n });\n }\n}\n", "import type { TilingSprite } from '../TilingSprite';\n\n/**\n * @param tilingSprite\n * @param positions\n * @internal\n */\nexport function setPositions(tilingSprite: TilingSprite, positions: Float32Array)\n{\n const anchorX = tilingSprite.anchor.x;\n const anchorY = tilingSprite.anchor.y;\n\n positions[0] = -anchorX * tilingSprite.width;\n positions[1] = -anchorY * tilingSprite.height;\n positions[2] = (1 - anchorX) * tilingSprite.width;\n positions[3] = -anchorY * tilingSprite.height;\n positions[4] = (1 - anchorX) * tilingSprite.width;\n positions[5] = (1 - anchorY) * tilingSprite.height;\n positions[6] = -anchorX * tilingSprite.width;\n positions[7] = (1 - anchorY) * tilingSprite.height;\n}\n", "import type { Matrix } from '../../../maths/matrix/Matrix';\nimport type { TypedArray } from '../../../rendering/renderers/shared/buffer/Buffer';\n\n/**\n * @param array\n * @param stride\n * @param offset\n * @param matrix\n * @internal\n */\nexport function applyMatrix(array: TypedArray, stride: number, offset: number, matrix: Matrix)\n{\n let index = 0;\n const size = array.length / (stride || 2);\n\n const a = matrix.a;\n const b = matrix.b;\n const c = matrix.c;\n const d = matrix.d;\n const tx = matrix.tx;\n const ty = matrix.ty;\n\n offset *= stride;\n\n while (index < size)\n {\n const x = array[offset];\n const y = array[offset + 1];\n\n array[offset] = (a * x) + (c * y) + tx;\n array[offset + 1] = (b * x) + (d * y) + ty;\n\n offset += stride;\n\n index++;\n }\n}\n", "import { Matrix } from '../../../maths/matrix/Matrix';\nimport { applyMatrix } from './applyMatrix';\n\nimport type { TilingSprite } from '../TilingSprite';\n\n/**\n * @param tilingSprite\n * @param uvs\n * @internal\n */\nexport function setUvs(tilingSprite: TilingSprite, uvs: Float32Array)\n{\n const texture = tilingSprite.texture;\n\n const width = texture.frame.width;\n const height = texture.frame.height;\n\n let anchorX = 0;\n let anchorY = 0;\n\n if (tilingSprite.applyAnchorToTexture)\n {\n anchorX = tilingSprite.anchor.x;\n anchorY = tilingSprite.anchor.y;\n }\n\n uvs[0] = uvs[6] = -anchorX;\n uvs[2] = uvs[4] = 1 - anchorX;\n uvs[1] = uvs[3] = -anchorY;\n uvs[5] = uvs[7] = 1 - anchorY;\n\n const textureMatrix = Matrix.shared;\n\n textureMatrix.copyFrom(tilingSprite._tileTransform.matrix);\n\n textureMatrix.tx /= tilingSprite.width;\n textureMatrix.ty /= tilingSprite.height;\n\n textureMatrix.invert();\n\n textureMatrix.scale(tilingSprite.width / width, tilingSprite.height / height);\n\n applyMatrix(uvs, 2, 0, textureMatrix);\n}\n", "import { ExtensionType } from '../../extensions/Extensions';\nimport { getAdjustedBlendModeBlend } from '../../rendering/renderers/shared/state/getAdjustedBlendModeBlend';\nimport { State } from '../../rendering/renderers/shared/state/State';\nimport { type Renderer, RendererType } from '../../rendering/renderers/types';\nimport { color32BitToUniform } from '../graphics/gpu/colorToUniform';\nimport { BatchableMesh } from '../mesh/shared/BatchableMesh';\nimport { MeshGeometry } from '../mesh/shared/MeshGeometry';\nimport { TilingSpriteShader } from './shader/TilingSpriteShader';\nimport { QuadGeometry } from './utils/QuadGeometry';\nimport { setPositions } from './utils/setPositions';\nimport { setUvs } from './utils/setUvs';\n\nimport type { WebGLRenderer } from '../../rendering/renderers/gl/WebGLRenderer';\nimport type { InstructionSet } from '../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { TilingSprite } from './TilingSprite';\n\nconst sharedQuad = new QuadGeometry();\n\n/** @internal */\nexport class TilingSpriteGpuData\n{\n public canBatch: boolean = true;\n public renderable: TilingSprite;\n public batchableMesh?: BatchableMesh;\n public geometry?: MeshGeometry;\n public shader?: TilingSpriteShader;\n\n constructor()\n {\n this.geometry = new MeshGeometry({\n indices: sharedQuad.indices.slice(),\n positions: sharedQuad.positions.slice(),\n uvs: sharedQuad.uvs.slice(),\n });\n }\n\n public destroy()\n {\n this.geometry.destroy();\n this.shader?.destroy();\n }\n}\n\n/**\n * The TilingSpritePipe is a render pipe for rendering TilingSprites.\n * It handles the batching and rendering of TilingSprites using a shader.\n * @internal\n */\nexport class TilingSpritePipe implements RenderPipe<TilingSprite>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'tilingSprite',\n } as const;\n\n private _renderer: Renderer;\n private readonly _state: State = State.default2d;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n }\n\n public validateRenderable(renderable: TilingSprite): boolean\n {\n const tilingSpriteData = this._getTilingSpriteData(renderable);\n\n const couldBatch = tilingSpriteData.canBatch;\n\n this._updateCanBatch(renderable);\n\n const canBatch = tilingSpriteData.canBatch;\n\n if (canBatch && canBatch === couldBatch)\n {\n const { batchableMesh } = tilingSpriteData;\n\n return !batchableMesh._batcher.checkAndUpdateTexture(\n batchableMesh,\n renderable.texture\n );\n }\n\n return (couldBatch !== canBatch);\n\n // // TODO - only update if required?\n // // only texture\n // // only uvs\n // // only positions?\n }\n\n public addRenderable(tilingSprite: TilingSprite, instructionSet: InstructionSet)\n {\n const batcher = this._renderer.renderPipes.batch;\n\n // init\n this._updateCanBatch(tilingSprite);\n\n const tilingSpriteData = this._getTilingSpriteData(tilingSprite);\n\n const { geometry, canBatch } = tilingSpriteData;\n\n if (canBatch)\n {\n tilingSpriteData.batchableMesh ||= new BatchableMesh();\n\n const batchableMesh = tilingSpriteData.batchableMesh;\n\n if (tilingSprite.didViewUpdate)\n {\n this._updateBatchableMesh(tilingSprite);\n\n batchableMesh.geometry = geometry;\n batchableMesh.renderable = tilingSprite;\n batchableMesh.transform = tilingSprite.groupTransform;\n batchableMesh.setTexture(tilingSprite._texture);\n }\n\n batchableMesh.roundPixels = (this._renderer._roundPixels | tilingSprite._roundPixels) as 0 | 1;\n\n batcher.addToBatch(batchableMesh, instructionSet);\n }\n else\n {\n batcher.break(instructionSet);\n\n tilingSpriteData.shader ||= new TilingSpriteShader();\n\n this.updateRenderable(tilingSprite);\n\n instructionSet.add(tilingSprite);\n }\n }\n\n public execute(tilingSprite: TilingSprite)\n {\n const { shader } = this._getTilingSpriteData(tilingSprite);\n\n shader.groups[0] = this._renderer.globalUniforms.bindGroup;\n\n // deal with local uniforms...\n const localUniforms = shader.resources.localUniforms.uniforms;\n\n localUniforms.uTransformMatrix = tilingSprite.groupTransform;\n localUniforms.uRound = this._renderer._roundPixels | tilingSprite._roundPixels;\n\n color32BitToUniform(\n tilingSprite.groupColorAlpha,\n localUniforms.uColor,\n 0\n );\n\n this._state.blendMode = getAdjustedBlendModeBlend(tilingSprite.groupBlendMode, tilingSprite.texture._source);\n\n this._renderer.encoder.draw({\n geometry: sharedQuad,\n shader,\n state: this._state,\n });\n }\n\n public updateRenderable(tilingSprite: TilingSprite)\n {\n const tilingSpriteData = this._getTilingSpriteData(tilingSprite);\n\n const { canBatch } = tilingSpriteData;\n\n if (canBatch)\n {\n const { batchableMesh } = tilingSpriteData;\n\n if (tilingSprite.didViewUpdate) this._updateBatchableMesh(tilingSprite);\n\n batchableMesh._batcher.updateElement(batchableMesh);\n }\n else if (tilingSprite.didViewUpdate)\n {\n const { shader } = tilingSpriteData;\n // now update uniforms...\n\n shader.updateUniforms(\n tilingSprite.width,\n tilingSprite.height,\n tilingSprite._tileTransform.matrix,\n tilingSprite.anchor.x,\n tilingSprite.anchor.y,\n tilingSprite.texture,\n );\n }\n }\n\n private _getTilingSpriteData(renderable: TilingSprite): TilingSpriteGpuData\n {\n return renderable._gpuData[this._renderer.uid] || this._initTilingSpriteData(renderable);\n }\n\n private _initTilingSpriteData(tilingSprite: TilingSprite): TilingSpriteGpuData\n {\n const gpuData = new TilingSpriteGpuData();\n\n gpuData.renderable = tilingSprite;\n tilingSprite._gpuData[this._renderer.uid] = gpuData;\n\n return gpuData;\n }\n\n private _updateBatchableMesh(tilingSprite: TilingSprite)\n {\n const renderableData = this._getTilingSpriteData(tilingSprite);\n\n const { geometry } = renderableData;\n\n const style = tilingSprite.texture.source.style;\n\n if (style.addressMode !== 'repeat')\n {\n style.addressMode = 'repeat';\n style.update();\n }\n\n setUvs(tilingSprite, geometry.uvs);\n setPositions(tilingSprite, geometry.positions);\n }\n\n public destroy()\n {\n this._renderer = null;\n }\n\n private _updateCanBatch(tilingSprite: TilingSprite)\n {\n const renderableData = this._getTilingSpriteData(tilingSprite);\n const texture = tilingSprite.texture;\n\n let _nonPowOf2wrapping = true;\n\n if (this._renderer.type === RendererType.WEBGL)\n {\n _nonPowOf2wrapping = (this._renderer as WebGLRenderer).context.supports.nonPowOf2wrapping;\n }\n\n renderableData.canBatch = texture.textureMatrix.isSimple && (_nonPowOf2wrapping || texture.source.isPowerOfTwo);\n\n return renderableData.canBatch;\n }\n}\n\n", "import { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\nimport { MeshGeometry } from '../mesh/shared/MeshGeometry';\n\nimport type { MeshGeometryOptions } from '../mesh/shared/MeshGeometry';\n\n/**\n * Constructor options used for `PlaneGeometry` instances.\n * ```js\n * const planeGeometry = new PlaneGeometry({\n * width: 100,\n * height: 100,\n * verticesX: 10,\n * verticesY: 10,\n * });\n * ```\n * @see {@link PlaneGeometry}\n * @category scene\n * @advanced\n */\nexport interface PlaneGeometryOptions\n{\n /** Width of plane */\n width?: number;\n /** Height of plane */\n height?: number;\n /** Number of vertices on x-axis */\n verticesX?: number;\n /** Number of vertices on y-axis */\n verticesY?: number;\n}\n\n/**\n * The PlaneGeometry allows you to draw a 2d plane\n * @category scene\n * @advanced\n */\nexport class PlaneGeometry extends MeshGeometry\n{\n public static defaultOptions: PlaneGeometryOptions & MeshGeometryOptions = {\n width: 100,\n height: 100,\n verticesX: 10,\n verticesY: 10,\n };\n\n /** The number of vertices on x-axis */\n public verticesX: number;\n /** The number of vertices on y-axis */\n public verticesY: number;\n /** The width of plane */\n public width: number;\n /** The height of plane */\n public height: number;\n\n /**\n * @param {PlaneGeometryOptions} options - Options to be applied to plane geometry\n */\n constructor(options: PlaneGeometryOptions);\n /** @deprecated since 8.0.0 */\n constructor(width?: number, height?: number, verticesX?: number, verticesY?: number);\n constructor(...args: [PlaneGeometryOptions?] | [number?, number?, number?, number?])\n {\n super({});\n\n let options = args[0] ?? {};\n\n if (typeof options === 'number')\n {\n // #if _DEBUG\n // eslint-disable-next-line max-len\n deprecation(v8_0_0, 'PlaneGeometry constructor changed please use { width, height, verticesX, verticesY } instead');\n // #endif\n\n options = {\n width: options,\n height: args[1],\n verticesX: args[2],\n verticesY: args[3],\n };\n }\n\n this.build(options);\n }\n\n /**\n * Refreshes plane coordinates\n * @param options - Options to be applied to plane geometry\n */\n public build(options: PlaneGeometryOptions): void\n {\n options = { ...PlaneGeometry.defaultOptions, ...options };\n\n this.verticesX = this.verticesX ?? options.verticesX;\n this.verticesY = this.verticesY ?? options.verticesY;\n\n this.width = this.width ?? options.width;\n this.height = this.height ?? options.height;\n\n const total = this.verticesX * this.verticesY;\n const verts = [];\n const uvs = [];\n const indices = [];\n\n const verticesX = this.verticesX - 1;\n const verticesY = this.verticesY - 1;\n\n const sizeX = (this.width) / verticesX;\n const sizeY = (this.height) / verticesY;\n\n for (let i = 0; i < total; i++)\n {\n const x = (i % this.verticesX);\n const y = ((i / this.verticesX) | 0);\n\n verts.push(x * sizeX, y * sizeY);\n uvs.push(x / verticesX, y / verticesY);\n }\n\n const totalSub = verticesX * verticesY;\n\n for (let i = 0; i < totalSub; i++)\n {\n const xpos = i % verticesX;\n const ypos = (i / verticesX) | 0;\n\n const value = (ypos * this.verticesX) + xpos;\n const value2 = (ypos * this.verticesX) + xpos + 1;\n const value3 = ((ypos + 1) * this.verticesX) + xpos;\n const value4 = ((ypos + 1) * this.verticesX) + xpos + 1;\n\n indices.push(value, value2, value3,\n value2, value4, value3);\n }\n\n this.buffers[0].data = new Float32Array(verts);\n this.buffers[1].data = new Float32Array(uvs);\n this.indexBuffer.data = new Uint32Array(indices);\n\n // ensure that the changes are uploaded\n this.buffers[0].update();\n this.buffers[1].update();\n this.indexBuffer.update();\n }\n}\n", "import { type PointData } from '../../maths/point/PointData';\nimport { PlaneGeometry } from '../mesh-plane/PlaneGeometry';\n\n/**\n * Options for the NineSliceGeometry.\n * @category scene\n * @advanced\n */\nexport interface NineSliceGeometryOptions\n{\n\n /** The width of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane. */\n width?: number\n /** The height of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane. */\n height?: number\n /** The original width of the texture */\n originalWidth?: number\n /** The original height of the texture */\n originalHeight?: number\n /** The width of the left column. */\n leftWidth?: number\n /** The height of the top row. */\n topHeight?: number\n /** The width of the right column. */\n rightWidth?: number\n /** The height of the bottom row. */\n bottomHeight?: number\n\n /** The anchor point of the NineSliceSprite. */\n anchor?: PointData\n}\n\n/**\n * The NineSliceGeometry class allows you to create a NineSlicePlane object.\n * @category scene\n * @advanced\n */\nexport class NineSliceGeometry extends PlaneGeometry\n{\n /** The default options for the NineSliceGeometry. */\n public static defaultOptions: NineSliceGeometryOptions = {\n /** The width of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane. */\n width: 100,\n /** The height of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane. */\n height: 100,\n /** The width of the left column. */\n leftWidth: 10,\n /** The height of the top row. */\n topHeight: 10,\n /** The width of the right column. */\n rightWidth: 10,\n /** The height of the bottom row. */\n bottomHeight: 10,\n\n /** The original width of the texture */\n originalWidth: 100,\n /** The original height of the texture */\n originalHeight: 100,\n };\n\n /** @internal */\n public _leftWidth: number;\n /** @internal */\n public _rightWidth: number;\n /** @internal */\n public _topHeight: number;\n /** @internal */\n public _bottomHeight: number;\n\n private _originalWidth: number;\n private _originalHeight: number;\n private _anchorX: any;\n private _anchorY: number;\n\n constructor(options: NineSliceGeometryOptions = {})\n {\n options = { ...NineSliceGeometry.defaultOptions, ...options };\n\n super({\n width: options.width,\n height: options.height,\n verticesX: 4,\n verticesY: 4,\n });\n\n this.update(options);\n }\n\n /**\n * Updates the NineSliceGeometry with the options.\n * @param options - The options of the NineSliceGeometry.\n */\n public update(options: NineSliceGeometryOptions)\n {\n this.width = options.width ?? this.width;\n this.height = options.height ?? this.height;\n this._originalWidth = options.originalWidth ?? this._originalWidth;\n this._originalHeight = options.originalHeight ?? this._originalHeight;\n this._leftWidth = options.leftWidth ?? this._leftWidth;\n this._rightWidth = options.rightWidth ?? this._rightWidth;\n this._topHeight = options.topHeight ?? this._topHeight;\n this._bottomHeight = options.bottomHeight ?? this._bottomHeight;\n\n this._anchorX = options.anchor?.x;\n this._anchorY = options.anchor?.y;\n\n this.updateUvs();\n this.updatePositions();\n }\n\n /** Updates the positions of the vertices. */\n public updatePositions()\n {\n const p = this.positions;\n const {\n width,\n height,\n _leftWidth,\n _rightWidth,\n _topHeight,\n _bottomHeight,\n _anchorX,\n _anchorY,\n } = this;\n\n const w = _leftWidth + _rightWidth;\n const scaleW = width > w ? 1.0 : width / w;\n\n const h = _topHeight + _bottomHeight;\n const scaleH = height > h ? 1.0 : height / h;\n\n const scale = Math.min(scaleW, scaleH);\n\n const anchorOffsetX = _anchorX * width;\n const anchorOffsetY = _anchorY * height;\n\n p[0] = p[8] = p[16] = p[24] = -anchorOffsetX;\n p[2] = p[10] = p[18] = p[26] = (_leftWidth * scale) - anchorOffsetX;\n p[4] = p[12] = p[20] = p[28] = width - (_rightWidth * scale) - anchorOffsetX;\n p[6] = p[14] = p[22] = p[30] = width - anchorOffsetX;\n\n p[1] = p[3] = p[5] = p[7] = -anchorOffsetY;\n p[9] = p[11] = p[13] = p[15] = (_topHeight * scale) - anchorOffsetY;\n p[17] = p[19] = p[21] = p[23] = height - (_bottomHeight * scale) - anchorOffsetY;\n p[25] = p[27] = p[29] = p[31] = height - anchorOffsetY;\n\n this.getBuffer('aPosition').update();\n }\n\n /** Updates the UVs of the vertices. */\n public updateUvs()\n {\n const uvs = this.uvs;\n\n uvs[0] = uvs[8] = uvs[16] = uvs[24] = 0;\n uvs[1] = uvs[3] = uvs[5] = uvs[7] = 0;\n\n uvs[6] = uvs[14] = uvs[22] = uvs[30] = 1;\n uvs[25] = uvs[27] = uvs[29] = uvs[31] = 1;\n\n const _uvw = 1.0 / this._originalWidth;\n const _uvh = 1.0 / this._originalHeight;\n\n uvs[2] = uvs[10] = uvs[18] = uvs[26] = _uvw * this._leftWidth;\n uvs[9] = uvs[11] = uvs[13] = uvs[15] = _uvh * this._topHeight;\n\n uvs[4] = uvs[12] = uvs[20] = uvs[28] = 1 - (_uvw * this._rightWidth);\n uvs[17] = uvs[19] = uvs[21] = uvs[23] = 1 - (_uvh * this._bottomHeight);\n\n this.getBuffer('aUV').update();\n }\n}\n\n", "import { ExtensionType } from '../../extensions/Extensions';\nimport { BatchableMesh } from '../mesh/shared/BatchableMesh';\nimport { NineSliceGeometry } from './NineSliceGeometry';\n\nimport type { InstructionSet } from '../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderer } from '../../rendering/renderers/types';\nimport type { NineSliceSprite } from './NineSliceSprite';\n\n/**\n * GPU data for NineSliceSprite.\n * @internal\n */\nexport class NineSliceSpriteGpuData extends BatchableMesh\n{\n constructor()\n {\n super();\n this.geometry = new NineSliceGeometry();\n }\n\n public destroy()\n {\n this.geometry.destroy();\n }\n}\n\n/**\n * The NineSliceSpritePipe is a render pipe for rendering NineSliceSprites.\n * @internal\n */\nexport class NineSliceSpritePipe implements RenderPipe<NineSliceSprite>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'nineSliceSprite',\n } as const;\n\n private readonly _renderer: Renderer;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n }\n\n public addRenderable(sprite: NineSliceSprite, instructionSet: InstructionSet)\n {\n const gpuSprite = this._getGpuSprite(sprite);\n\n if (sprite.didViewUpdate) this._updateBatchableSprite(sprite, gpuSprite);\n\n this._renderer.renderPipes.batch.addToBatch(gpuSprite, instructionSet);\n }\n\n public updateRenderable(sprite: NineSliceSprite)\n {\n const gpuSprite = this._getGpuSprite(sprite);\n\n if (sprite.didViewUpdate) this._updateBatchableSprite(sprite, gpuSprite);\n\n gpuSprite._batcher.updateElement(gpuSprite);\n }\n\n public validateRenderable(sprite: NineSliceSprite): boolean\n {\n const gpuSprite = this._getGpuSprite(sprite);\n\n return !gpuSprite._batcher.checkAndUpdateTexture(\n gpuSprite,\n sprite._texture\n );\n }\n\n private _updateBatchableSprite(sprite: NineSliceSprite, batchableSprite: BatchableMesh)\n {\n (batchableSprite.geometry as NineSliceGeometry)\n .update(sprite);\n\n // = sprite.bounds;\n batchableSprite.setTexture(sprite._texture);\n }\n\n private _getGpuSprite(sprite: NineSliceSprite): NineSliceSpriteGpuData\n {\n return sprite._gpuData[this._renderer.uid] || this._initGPUSprite(sprite);\n }\n\n private _initGPUSprite(sprite: NineSliceSprite): NineSliceSpriteGpuData\n {\n const gpuData = sprite._gpuData[this._renderer.uid] = new NineSliceSpriteGpuData();\n\n const batchableMesh = gpuData;\n\n batchableMesh.renderable = sprite;\n batchableMesh.transform = sprite.groupTransform;\n batchableMesh.texture = sprite._texture;\n batchableMesh.roundPixels = (this._renderer._roundPixels | sprite._roundPixels) as 0 | 1;\n\n // if the sprite has not been updated by the view, we need to update the batchable mesh now.\n if (!sprite.didViewUpdate)\n {\n this._updateBatchableSprite(sprite, batchableMesh);\n }\n\n return gpuData;\n }\n\n public destroy()\n {\n (this._renderer as null) = null;\n }\n}\n", "import { ExtensionType } from '../extensions/Extensions';\n\nimport type { InstructionSet } from '../rendering/renderers/shared/instructions/InstructionSet';\nimport type { InstructionPipe } from '../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderer } from '../rendering/renderers/types';\nimport type { Container } from '../scene/container/Container';\nimport type { Effect } from '../scene/container/Effect';\nimport type { FilterInstruction } from './FilterSystem';\n\n/** @internal */\nexport class FilterPipe implements InstructionPipe<FilterInstruction>\n{\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'filter',\n } as const;\n\n private _renderer: Renderer;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n }\n\n public push(filterEffect: Effect, container: Container, instructionSet: InstructionSet): void\n {\n const renderPipes = this._renderer.renderPipes;\n\n renderPipes.batch.break(instructionSet);\n\n instructionSet.add({\n renderPipeId: 'filter',\n canBundle: false,\n action: 'pushFilter',\n container,\n filterEffect,\n } as FilterInstruction);\n }\n\n public pop(_filterEffect: Effect, _container: Container, instructionSet: InstructionSet): void\n {\n this._renderer.renderPipes.batch.break(instructionSet);\n\n instructionSet.add({\n renderPipeId: 'filter',\n action: 'popFilter',\n canBundle: false,\n });\n }\n\n public execute(instruction: FilterInstruction)\n {\n if (instruction.action === 'pushFilter')\n {\n this._renderer.filter.push(instruction);\n }\n else if (instruction.action === 'popFilter')\n {\n this._renderer.filter.pop();\n }\n }\n\n public destroy(): void\n {\n this._renderer = null;\n }\n}\n", "var vertex = \"in vec2 aPosition;\\nout vec2 vTextureCoord;\\n\\nuniform vec4 uInputSize;\\nuniform vec4 uOutputFrame;\\nuniform vec4 uOutputTexture;\\n\\nvec4 filterVertexPosition( void )\\n{\\n vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;\\n \\n position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;\\n position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;\\n\\n return vec4(position, 0.0, 1.0);\\n}\\n\\nvec2 filterTextureCoord( void )\\n{\\n return aPosition * (uOutputFrame.zw * uInputSize.zw);\\n}\\n\\nvoid main(void)\\n{\\n gl_Position = filterVertexPosition();\\n vTextureCoord = filterTextureCoord();\\n}\\n\";\n\nexport { vertex as default };\n//# sourceMappingURL=defaultFilter.vert.mjs.map\n", "var fragment = \"in vec2 vTextureCoord;\\nout vec4 finalColor;\\nuniform sampler2D uTexture;\\nvoid main() {\\n finalColor = texture(uTexture, vTextureCoord);\\n}\\n\";\n\nexport { fragment as default };\n//# sourceMappingURL=passthrough.frag.mjs.map\n", "var source = \"struct GlobalFilterUniforms {\\n uInputSize: vec4<f32>,\\n uInputPixel: vec4<f32>,\\n uInputClamp: vec4<f32>,\\n uOutputFrame: vec4<f32>,\\n uGlobalFrame: vec4<f32>,\\n uOutputTexture: vec4<f32>,\\n};\\n\\n@group(0) @binding(0) var <uniform> gfu: GlobalFilterUniforms;\\n@group(0) @binding(1) var uTexture: texture_2d<f32>;\\n@group(0) @binding(2) var uSampler: sampler;\\n\\nstruct VSOutput {\\n @builtin(position) position: vec4<f32>,\\n @location(0) uv: vec2<f32>\\n};\\n\\nfn filterVertexPosition(aPosition: vec2<f32>) -> vec4<f32>\\n{\\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\\n\\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\\n position.y = position.y * (2.0 * gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\\n\\n return vec4(position, 0.0, 1.0);\\n}\\n\\nfn filterTextureCoord(aPosition: vec2<f32>) -> vec2<f32>\\n{\\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\\n}\\n\\n@vertex\\nfn mainVertex(\\n @location(0) aPosition: vec2<f32>,\\n) -> VSOutput {\\n return VSOutput(\\n filterVertexPosition(aPosition),\\n filterTextureCoord(aPosition)\\n );\\n}\\n\\n@fragment\\nfn mainFragment(\\n @location(0) uv: vec2<f32>,\\n) -> @location(0) vec4<f32> {\\n return textureSample(uTexture, uSampler, uv);\\n}\\n\";\n\nexport { source as default };\n//# sourceMappingURL=passthrough.wgsl.mjs.map\n", "import { GlProgram } from '../../../rendering/renderers/gl/shader/GlProgram';\nimport { GpuProgram } from '../../../rendering/renderers/gpu/shader/GpuProgram';\nimport { Filter } from '../../Filter';\nimport vertex from '../defaultFilter.vert';\nimport fragment from './passthrough.frag';\nimport source from './passthrough.wgsl';\n\n/**\n * The PassthroughFilter passes the input data through without altering it.\n * It serves as a basic filter, performing no graphical alterations.\n * @category filters\n * @internal\n */\nexport class PassthroughFilter extends Filter\n{\n constructor()\n {\n const gpuProgram = GpuProgram.from({\n vertex: { source, entryPoint: 'mainVertex' },\n fragment: { source, entryPoint: 'mainFragment' },\n name: 'passthrough-filter'\n });\n\n const glProgram = GlProgram.from({\n vertex,\n fragment,\n name: 'passthrough-filter'\n });\n\n super({\n gpuProgram,\n glProgram,\n });\n }\n}\n", "import { Matrix } from '../../../maths';\n\nimport type { Renderable } from '../../../rendering/renderers/shared/Renderable';\nimport type { Bounds } from './Bounds';\n\n/**\n * This matrix is used for calculations of the bounds for renderables placed inside cacheAsTexture render groups.\n * @ignore\n * @internal\n */\nconst tempProjectionMatrix: Matrix = new Matrix();\n\n/**\n * @param renderables\n * @param bounds\n * @internal\n */\nexport function getGlobalRenderableBounds(renderables: Renderable[], bounds: Bounds): Bounds\n{\n bounds.clear();\n\n // instead of copying the matrix each time we are assigning it in bounds\n // this is a performance hack :D\n // so we need to restore the matrix after we are done\n\n const actualMatrix = bounds.matrix;\n\n for (let i = 0; i < renderables.length; i++)\n {\n const renderable = renderables[i];\n\n if (renderable.globalDisplayStatus < 0b111)\n {\n continue;\n }\n\n const renderGroup = renderable.renderGroup ?? renderable.parentRenderGroup;\n\n if (renderGroup?.isCachedAsTexture)\n {\n bounds.matrix = tempProjectionMatrix.copyFrom(renderGroup.textureOffsetInverseTransform)\n .append(renderable.worldTransform);\n }\n else if (renderGroup?._parentCacheAsTextureRenderGroup)\n {\n bounds.matrix = tempProjectionMatrix\n .copyFrom(renderGroup._parentCacheAsTextureRenderGroup.inverseWorldTransform)\n .append(renderable.groupTransform);\n }\n else\n {\n bounds.matrix = renderable.worldTransform;\n }\n\n bounds.addBounds(renderable.bounds);\n }\n\n bounds.matrix = actualMatrix;\n\n return bounds;\n}\n", "import { ExtensionType } from '../extensions/Extensions';\nimport { PassthroughFilter } from '../filters/defaults/passthrough/PassthroughFilter';\nimport { Matrix } from '../maths/matrix/Matrix';\nimport { type Rectangle } from '../maths/shapes/Rectangle';\nimport { BindGroup } from '../rendering/renderers/gpu/shader/BindGroup';\nimport { Geometry } from '../rendering/renderers/shared/geometry/Geometry';\nimport { UniformGroup } from '../rendering/renderers/shared/shader/UniformGroup';\nimport { Texture } from '../rendering/renderers/shared/texture/Texture';\nimport { TexturePool } from '../rendering/renderers/shared/texture/TexturePool';\nimport { type Renderer, RendererType } from '../rendering/renderers/types';\nimport { Bounds } from '../scene/container/bounds/Bounds';\nimport { getGlobalRenderableBounds } from '../scene/container/bounds/getRenderableBounds';\nimport { warn } from '../utils/logging/warn';\n\nimport type { WebGLRenderer } from '../rendering/renderers/gl/WebGLRenderer';\nimport type { WebGPURenderer } from '../rendering/renderers/gpu/WebGPURenderer';\nimport type { Instruction } from '../rendering/renderers/shared/instructions/Instruction';\nimport type { Renderable } from '../rendering/renderers/shared/Renderable';\nimport type { RenderTarget } from '../rendering/renderers/shared/renderTarget/RenderTarget';\nimport type { RenderSurface } from '../rendering/renderers/shared/renderTarget/RenderTargetSystem';\nimport type { System } from '../rendering/renderers/shared/system/System';\nimport type { Container } from '../scene/container/Container';\nimport type { Sprite } from '../scene/sprite/Sprite';\nimport type { Filter } from './Filter';\nimport type { FilterEffect } from './FilterEffect';\n\nconst quadGeometry = new Geometry({\n attributes: {\n aPosition: {\n buffer: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]),\n format: 'float32x2',\n stride: 2 * 4,\n offset: 0,\n },\n },\n indexBuffer: new Uint32Array([0, 1, 2, 0, 2, 3]),\n});\n\n/**\n * The filter pipeline is responsible for applying filters scene items!\n *\n * KNOWN BUGS:\n * 1. Global bounds calculation is incorrect if it is used when flip flopping filters. The maths can be found below\n * eg: filters [noiseFilter, blurFilter] noiseFilter will calculate the global bounds incorrectly.\n *\n * 2. RenderGroups do not work with filters. This is because the renderGroup matrix is not currently taken into account.\n *\n * Implementation notes:\n * 1. Gotcha - nesting filters that require blending will not work correctly. This creates a chicken and egg problem\n * the complexity and performance required to do this is not worth it i feel.. but lets see if others agree!\n *\n * 2. Filters are designed to be changed on the fly, this is means that changing filter information each frame will\n * not trigger an instruction rebuild. If you are constantly turning a filter on and off.. its therefore better to set\n * enabled to true or false on the filter. Or setting an empty array.\n *\n * 3. Need to look at perhaps aliasing when flip flopping filters. Really we should only need to antialias the FIRST\n * Texture we render too. The rest can be non aliased. This might help performance.\n * Currently we flip flop with an antialiased texture if antialiasing is enabled on the filter.\n * @internal\n */\nexport interface FilterInstruction extends Instruction\n{\n renderPipeId: 'filter',\n action: 'pushFilter' | 'popFilter',\n container?: Container,\n renderables?: Renderable[],\n filterEffect: FilterEffect,\n}\n\n/**\n * Class representing the data required for applying filters.\n * This class holds various properties that are used during the filter application process.\n * @internal\n */\nclass FilterData\n{\n /**\n * Indicates whether the filter should be skipped.\n * @type {boolean}\n */\n public skip = false;\n\n /**\n * The texture to which the filter is applied.\n * @type {Texture}\n */\n public inputTexture: Texture = null;\n\n /**\n * The back texture used for blending, if required.\n * @type {Texture | null}\n */\n public backTexture?: Texture = null;\n\n /**\n * The list of filters to be applied.\n * @type {Filter[]}\n */\n public filters: Filter[] = null;\n\n /**\n * The bounds of the filter area.\n * @type {Bounds}\n */\n public bounds = new Bounds();\n\n /**\n * The container to which the filter is applied.\n * @type {Container}\n */\n public container: Container = null;\n\n /**\n * Indicates whether blending is required for the filter.\n * @type {boolean}\n */\n public blendRequired: boolean = false;\n\n /**\n * The render surface where the output of the filter is rendered.\n * @type {RenderSurface}\n */\n public outputRenderSurface: RenderSurface = null;\n\n /**\n * The global frame of the filter area.\n * @type {{ x: number, y: number, width: number, height: number }}\n */\n public globalFrame = { x: 0, y: 0, width: 0, height: 0 };\n\n /**\n * Indicates whether antialiasing is enabled for the filter.\n * @type {boolean}\n */\n public antialias: boolean;\n\n /**\n * The resolution of the filter.\n * @type {number}\n */\n public resolution: number;\n\n /** The first enabled filter index in the current filter list. */\n public firstEnabledIndex = -1;\n\n /** The last enabled filter index in the current filter list. */\n public lastEnabledIndex = -1;\n}\n\n/**\n * System that manages the filter pipeline\n * @category rendering\n * @advanced\n */\nexport class FilterSystem implements System\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLSystem,\n ExtensionType.WebGPUSystem,\n ],\n name: 'filter',\n } as const;\n\n public readonly renderer: Renderer;\n\n private _filterStackIndex = 0;\n private _filterStack: FilterData[] = [];\n\n private readonly _filterGlobalUniforms = new UniformGroup({\n uInputSize: { value: new Float32Array(4), type: 'vec4<f32>' },\n uInputPixel: { value: new Float32Array(4), type: 'vec4<f32>' },\n uInputClamp: { value: new Float32Array(4), type: 'vec4<f32>' },\n uOutputFrame: { value: new Float32Array(4), type: 'vec4<f32>' },\n uGlobalFrame: { value: new Float32Array(4), type: 'vec4<f32>' },\n uOutputTexture: { value: new Float32Array(4), type: 'vec4<f32>' },\n });\n\n private readonly _globalFilterBindGroup: BindGroup = new BindGroup({});\n private _activeFilterData: FilterData;\n private _passthroughFilter: Filter;\n\n constructor(renderer: Renderer)\n {\n this.renderer = renderer;\n }\n\n /**\n * The back texture of the currently active filter. Requires the filter to have `blendRequired` set to true.\n * @readonly\n */\n public get activeBackTexture(): Texture | undefined\n {\n return this._activeFilterData?.backTexture;\n }\n\n /**\n * Pushes a filter instruction onto the filter stack.\n * @param instruction - The instruction containing the filter effect and container.\n * @internal\n */\n public push(instruction: FilterInstruction)\n {\n const renderer = this.renderer;\n\n const filters = instruction.filterEffect.filters;\n\n // get a filter data from the stack. They can be reused multiple times each frame,\n // so we don't need to worry about overwriting them in a single pass.\n const filterData = this._pushFilterData();\n\n filterData.skip = false;\n\n filterData.filters = filters as Filter[];\n filterData.container = instruction.container;\n filterData.outputRenderSurface = renderer.renderTarget.renderSurface;\n\n const colorTextureSource = renderer.renderTarget.renderTarget.colorTexture.source;\n\n const rootResolution = colorTextureSource.resolution;\n const rootAntialias = colorTextureSource.antialias;\n\n // if there are no filters, or all of them disabled, we skip the pass\n if (filters.every((filter) => !filter.enabled))\n {\n filterData.skip = true;\n\n return;\n }\n\n const bounds = filterData.bounds;\n\n this._calculateFilterArea(instruction, bounds);\n\n this._calculateFilterBounds(filterData, renderer.renderTarget.rootViewPort, rootAntialias, rootResolution, 1);\n\n if (filterData.skip)\n {\n return;\n }\n\n const previousFilterData = this._getPreviousFilterData();\n\n const globalResolution = this._findFilterResolution(rootResolution);\n let offsetX = 0;\n let offsetY = 0;\n\n if (previousFilterData)\n {\n offsetX = previousFilterData.bounds.minX;\n offsetY = previousFilterData.bounds.minY;\n }\n\n this._calculateGlobalFrame(\n filterData,\n offsetX, offsetY,\n globalResolution,\n colorTextureSource.width,\n colorTextureSource.height\n );\n\n // set all the filter data\n\n this._setupFilterTextures(filterData, bounds, renderer, previousFilterData);\n }\n\n /**\n * Applies filters to a texture.\n *\n * This method takes a texture and a list of filters, applies the filters to the texture,\n * and returns the resulting texture.\n * @param {object} params - The parameters for applying filters.\n * @param {Texture} params.texture - The texture to apply filters to.\n * @param {Filter[]} params.filters - The filters to apply.\n * @returns {Texture} The resulting texture after all filters have been applied.\n * @example\n *\n * ```ts\n * // Create a texture and a list of filters\n * const texture = new Texture(...);\n * const filters = [new BlurFilter(), new ColorMatrixFilter()];\n *\n * // Apply the filters to the texture\n * const resultTexture = filterSystem.applyToTexture({ texture, filters });\n *\n * // Use the resulting texture\n * sprite.texture = resultTexture;\n * ```\n *\n * Key Points:\n * 1. padding is not currently supported here - so clipping may occur with filters that use padding.\n * 2. If all filters are disabled or skipped, the original texture is returned.\n */\n public generateFilteredTexture({ texture, filters }: {texture: Texture, filters: Filter[]}): Texture\n {\n // get a filter data from the stack. They can be reused multiple times each frame,\n // so we don't need to worry about overwriting them in a single pass.\n const filterData = this._pushFilterData();\n\n this._activeFilterData = filterData;\n filterData.skip = false;\n\n filterData.filters = filters;\n\n const colorTextureSource = texture.source;\n\n const rootResolution = colorTextureSource.resolution;\n const rootAntialias = colorTextureSource.antialias;\n\n // if there are no filters, or all of them disabled, we skip the pass\n if (filters.every((filter) => !filter.enabled))\n {\n filterData.skip = true;\n\n return texture;\n }\n\n const bounds = filterData.bounds;\n\n // this path is used by the blend modes mostly!\n // they collect all renderables and push them into a list.\n // this list is then used to calculate the bounds of the filter area\n\n bounds.addRect(texture.frame);\n\n this._calculateFilterBounds(filterData, bounds.rectangle, rootAntialias, rootResolution, 0);\n\n if (filterData.skip)\n {\n return texture;\n }\n\n const globalResolution = rootResolution;\n const offsetX = 0;\n const offsetY = 0;\n\n this._calculateGlobalFrame(\n filterData,\n offsetX, offsetY,\n globalResolution,\n colorTextureSource.width,\n colorTextureSource.height\n );\n\n /// /////////\n\n // set all the filter data\n // get a P02 texture from our pool...\n filterData.outputRenderSurface = TexturePool.getOptimalTexture(\n bounds.width,\n bounds.height,\n filterData.resolution,\n filterData.antialias,\n );\n\n filterData.backTexture = Texture.EMPTY;\n\n /// ///\n // bind...\n // TODO this might need looking at for padding!\n filterData.inputTexture = texture;\n\n /// ////////////// PART 2 POP //////////////////////\n\n const renderer = this.renderer;\n\n // TODO required? check with AA\n renderer.renderTarget.finishRenderPass();\n\n // get a BufferResource from the uniformBatch.\n // this will batch the shader uniform data and give us a buffer resource we can\n // set on our globalUniform Bind Group\n this._applyFiltersToTexture(filterData, true);\n\n const outputTexture = filterData.outputRenderSurface as Texture;\n\n outputTexture.source.alphaMode = 'premultiplied-alpha';\n\n return outputTexture;\n }\n\n /** @internal */\n public pop()\n {\n const renderer = this.renderer;\n\n const filterData = this._popFilterData();\n\n // if we are skipping this filter then we just do nothing :D\n if (filterData.skip)\n {\n return;\n }\n\n renderer.globalUniforms.pop();\n\n renderer.renderTarget.finishRenderPass();\n\n this._activeFilterData = filterData;\n\n this._applyFiltersToTexture(filterData, false);\n\n // if we made a background texture, lets return that also\n if (filterData.blendRequired)\n {\n TexturePool.returnTexture(filterData.backTexture);\n }\n\n // return the texture to the pool so we can reuse the next frame\n TexturePool.returnTexture(filterData.inputTexture);\n }\n\n /**\n * Copies the last render surface to a texture.\n * @param lastRenderSurface - The last render surface to copy from.\n * @param bounds - The bounds of the area to copy.\n * @param previousBounds - The previous bounds to use for offsetting the copy.\n */\n public getBackTexture(lastRenderSurface: RenderTarget, bounds: Bounds, previousBounds?: Bounds)\n {\n const backgroundResolution = lastRenderSurface.colorTexture.source._resolution;\n\n const backTexture = TexturePool.getOptimalTexture(\n bounds.width,\n bounds.height,\n backgroundResolution,\n false,\n );\n\n let x = bounds.minX;\n let y = bounds.minY;\n\n if (previousBounds)\n {\n x -= previousBounds.minX;\n y -= previousBounds.minY;\n }\n\n x = Math.floor(x * backgroundResolution);\n y = Math.floor(y * backgroundResolution);\n\n const width = Math.ceil(bounds.width * backgroundResolution);\n const height = Math.ceil(bounds.height * backgroundResolution);\n\n this.renderer.renderTarget.copyToTexture(\n lastRenderSurface,\n backTexture,\n { x, y },\n { width, height },\n { x: 0, y: 0 }\n );\n\n return backTexture;\n }\n\n /**\n * Applies a filter to a texture.\n * @param filter - The filter to apply.\n * @param input - The input texture.\n * @param output - The output render surface.\n * @param clear - Whether to clear the output surface before applying the filter.\n */\n public applyFilter(filter: Filter, input: Texture, output: RenderSurface, clear: boolean)\n {\n const renderer = this.renderer;\n\n const filterData = this._activeFilterData;\n\n const outputRenderSurface = filterData.outputRenderSurface;\n\n const isFinalTarget = outputRenderSurface === output;\n\n // Find the correct resolution by looking back through the filter stack\n const rootResolution = renderer.renderTarget.rootRenderTarget.colorTexture.source._resolution;\n const resolution = this._findFilterResolution(rootResolution);\n\n // Calculate the offset for both outputFrame and globalFrame\n let offsetX = 0;\n let offsetY = 0;\n\n if (isFinalTarget)\n {\n const offset = this._findPreviousFilterOffset();\n\n offsetX = offset.x;\n offsetY = offset.y;\n }\n\n this._updateFilterUniforms(input, output, filterData, offsetX, offsetY, resolution, isFinalTarget, clear);\n\n // If the filter is disabled, we still need to write something into the output surface.\n // Render a pass-through (copy) so the pipeline remains intact.\n const filterToApply = filter.enabled\n ? filter\n : this._getPassthroughFilter();\n\n this._setupBindGroupsAndRender(filterToApply, input, renderer);\n }\n\n /**\n * Multiply _input normalized coordinates_ to this matrix to get _sprite texture normalized coordinates_.\n *\n * Use `outputMatrix * vTextureCoord` in the shader.\n * @param outputMatrix - The matrix to output to.\n * @param {Sprite} sprite - The sprite to map to.\n * @returns The mapped matrix.\n */\n public calculateSpriteMatrix(outputMatrix: Matrix, sprite: Sprite): Matrix\n {\n const data = this._activeFilterData;\n\n const mappedMatrix = outputMatrix.set(\n data.inputTexture._source.width,\n 0, 0,\n data.inputTexture._source.height,\n data.bounds.minX, data.bounds.minY\n );\n\n const worldTransform = sprite.worldTransform.copyTo(Matrix.shared);\n\n const renderGroup = sprite.renderGroup || sprite.parentRenderGroup;\n\n if (renderGroup && renderGroup.cacheToLocalTransform)\n {\n // get the matrix relative to the render group..\n worldTransform.prepend(renderGroup.cacheToLocalTransform);\n }\n\n worldTransform.invert();\n mappedMatrix.prepend(worldTransform);\n mappedMatrix.scale(\n 1.0 / sprite.texture.orig.width,\n 1.0 / sprite.texture.orig.height\n );\n\n mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y);\n\n return mappedMatrix;\n }\n\n public destroy(): void\n {\n this._passthroughFilter?.destroy(true);\n (this._passthroughFilter as null) = null;\n }\n\n private _getPassthroughFilter(): Filter\n {\n this._passthroughFilter ??= new PassthroughFilter();\n\n return this._passthroughFilter;\n }\n\n /**\n * Sets up the bind groups and renders the filter.\n * @param filter - The filter to apply\n * @param input - The input texture\n * @param renderer - The renderer instance\n */\n private _setupBindGroupsAndRender(filter: Filter, input: Texture, renderer: Renderer): void\n {\n // TODO - should prolly use a adaptor...\n if ((renderer as WebGPURenderer).renderPipes.uniformBatch)\n {\n const batchUniforms = (renderer as WebGPURenderer).renderPipes.uniformBatch\n .getUboResource(this._filterGlobalUniforms);\n\n this._globalFilterBindGroup.setResource(batchUniforms, 0);\n }\n else\n {\n this._globalFilterBindGroup.setResource(this._filterGlobalUniforms, 0);\n }\n\n // now lets update the output texture...\n\n // set bind group..\n this._globalFilterBindGroup.setResource(input.source, 1);\n this._globalFilterBindGroup.setResource(input.source.style, 2);\n\n filter.groups[0] = this._globalFilterBindGroup;\n\n renderer.encoder.draw({\n geometry: quadGeometry,\n shader: filter,\n state: filter._state,\n topology: 'triangle-list'\n });\n\n // WebGPU blit's automatically, but WebGL does not!\n if (renderer.type === RendererType.WEBGL)\n {\n renderer.renderTarget.finishRenderPass();\n }\n }\n\n /**\n * Sets up the filter textures including input texture and back texture if needed.\n * @param filterData - The filter data to update\n * @param bounds - The bounds for the texture\n * @param renderer - The renderer instance\n * @param previousFilterData - The previous filter data for back texture calculation\n */\n private _setupFilterTextures(\n filterData: FilterData,\n bounds: Bounds,\n renderer: Renderer,\n previousFilterData: FilterData | null\n ): void\n {\n // set all the filter data\n filterData.backTexture = Texture.EMPTY;\n\n /// ///\n // bind...\n // get a P02 texture from our pool...\n filterData.inputTexture = TexturePool.getOptimalTexture(\n bounds.width,\n bounds.height,\n filterData.resolution,\n filterData.antialias,\n );\n\n // Very cryptic, but important(!) moment.\n //\n // If we try to pull texture from the pool for backTexture before inputTexture,\n // it will be unbounded later by startRenderPass. It happens because in such a case - the current backTexture\n // is actually inputTexture from the previous filter application (check `pop` method).\n //\n // So maintaining the order (inputTexture -> backTexture) helps us to prevent unwanted texture unbinding.\n if (filterData.blendRequired)\n {\n renderer.renderTarget.finishRenderPass();\n // this actually forces the current commandQueue to render everything so far.\n // if we don't do this, we won't be able to copy pixels for the background\n const renderTarget = renderer.renderTarget.getRenderTarget(filterData.outputRenderSurface);\n\n filterData.backTexture = this.getBackTexture(renderTarget, bounds, previousFilterData?.bounds);\n }\n\n renderer.renderTarget.bind(filterData.inputTexture, true);\n\n // set the global uniforms to take into account the bounds offset required\n renderer.globalUniforms.push({\n offset: bounds,\n });\n }\n\n /**\n * Calculates and sets the global frame for the filter.\n * @param filterData - The filter data to update\n * @param offsetX - The X offset\n * @param offsetY - The Y offset\n * @param globalResolution - The global resolution\n * @param sourceWidth - The source texture width\n * @param sourceHeight - The source texture height\n */\n private _calculateGlobalFrame(\n filterData: FilterData,\n offsetX: number,\n offsetY: number,\n globalResolution: number,\n sourceWidth: number,\n sourceHeight: number\n ): void\n {\n const globalFrame = filterData.globalFrame;\n\n globalFrame.x = offsetX * globalResolution;\n globalFrame.y = offsetY * globalResolution;\n globalFrame.width = sourceWidth * globalResolution;\n globalFrame.height = sourceHeight * globalResolution;\n }\n\n /**\n * Updates the filter uniforms with the current filter state.\n * @param input - The input texture\n * @param output - The output render surface\n * @param filterData - The current filter data\n * @param offsetX - The X offset for positioning\n * @param offsetY - The Y offset for positioning\n * @param resolution - The current resolution\n * @param isFinalTarget - Whether this is the final render target\n * @param clear - Whether to clear the output surface\n */\n private _updateFilterUniforms(\n input: Texture,\n output: RenderSurface,\n filterData: FilterData,\n offsetX: number,\n offsetY: number,\n resolution: number,\n isFinalTarget: boolean,\n clear: boolean\n ): void\n {\n const uniforms = this._filterGlobalUniforms.uniforms;\n const outputFrame = uniforms.uOutputFrame;\n const inputSize = uniforms.uInputSize;\n const inputPixel = uniforms.uInputPixel;\n const inputClamp = uniforms.uInputClamp;\n const globalFrame = uniforms.uGlobalFrame;\n const outputTexture = uniforms.uOutputTexture;\n\n // are we rendering back to the original surface?\n if (isFinalTarget)\n {\n outputFrame[0] = filterData.bounds.minX - offsetX;\n outputFrame[1] = filterData.bounds.minY - offsetY;\n }\n else\n {\n outputFrame[0] = 0;\n outputFrame[1] = 0;\n }\n\n outputFrame[2] = input.frame.width;\n outputFrame[3] = input.frame.height;\n\n inputSize[0] = input.source.width;\n inputSize[1] = input.source.height;\n inputSize[2] = 1 / inputSize[0];\n inputSize[3] = 1 / inputSize[1];\n\n inputPixel[0] = input.source.pixelWidth;\n inputPixel[1] = input.source.pixelHeight;\n inputPixel[2] = 1.0 / inputPixel[0];\n inputPixel[3] = 1.0 / inputPixel[1];\n\n inputClamp[0] = 0.5 * inputPixel[2];\n inputClamp[1] = 0.5 * inputPixel[3];\n inputClamp[2] = (input.frame.width * inputSize[2]) - (0.5 * inputPixel[2]);\n inputClamp[3] = (input.frame.height * inputSize[3]) - (0.5 * inputPixel[3]);\n\n const rootTexture = this.renderer.renderTarget.rootRenderTarget.colorTexture;\n\n globalFrame[0] = offsetX * resolution;\n globalFrame[1] = offsetY * resolution;\n globalFrame[2] = rootTexture.source.width * resolution;\n globalFrame[3] = rootTexture.source.height * resolution;\n\n // we are going to overwrite resource we can set it to null!\n if (output instanceof Texture) output.source.resource = null;\n\n // set the output texture - this is where we are going to render to\n const renderTarget = this.renderer.renderTarget.getRenderTarget(output);\n\n this.renderer.renderTarget.bind(output, !!clear);\n\n if (output instanceof Texture)\n {\n outputTexture[0] = output.frame.width;\n outputTexture[1] = output.frame.height;\n }\n else\n {\n // this means a renderTarget was passed directly\n outputTexture[0] = renderTarget.width;\n outputTexture[1] = renderTarget.height;\n }\n\n outputTexture[2] = renderTarget.isRoot ? -1 : 1;\n\n this._filterGlobalUniforms.update();\n }\n\n /**\n * Finds the correct resolution by looking back through the filter stack.\n * @param rootResolution - The fallback root resolution to use\n * @returns The resolution from the previous filter or root resolution\n */\n private _findFilterResolution(rootResolution: number): number\n {\n let currentIndex = this._filterStackIndex - 1;\n\n while (currentIndex > 0 && this._filterStack[currentIndex].skip)\n {\n --currentIndex;\n }\n\n return currentIndex > 0 && this._filterStack[currentIndex].inputTexture\n ? this._filterStack[currentIndex].inputTexture.source._resolution\n : rootResolution;\n }\n\n /**\n * Finds the offset from the previous non-skipped filter in the stack.\n * @returns The offset coordinates from the previous filter\n */\n private _findPreviousFilterOffset(): { x: number, y: number }\n {\n let offsetX = 0;\n let offsetY = 0;\n let lastIndex = this._filterStackIndex;\n\n while (lastIndex > 0)\n {\n lastIndex--;\n const prevFilterData = this._filterStack[lastIndex];\n\n if (!prevFilterData.skip)\n {\n offsetX = prevFilterData.bounds.minX;\n offsetY = prevFilterData.bounds.minY;\n break;\n }\n }\n\n return { x: offsetX, y: offsetY };\n }\n\n /**\n * Calculates the filter area bounds based on the instruction type.\n * @param instruction - The filter instruction\n * @param bounds - The bounds object to populate\n */\n private _calculateFilterArea(instruction: FilterInstruction, bounds: Bounds): void\n {\n // this path is used by the blend modes mostly!\n // they collect all renderables and push them into a list.\n // this list is then used to calculate the bounds of the filter area\n if (instruction.renderables)\n {\n getGlobalRenderableBounds(instruction.renderables, bounds);\n }\n // if a filterArea is provided, we save our selves some measuring and just use that area supplied\n else if (instruction.filterEffect.filterArea)\n {\n bounds.clear();\n\n // transform the filterArea into global space..\n bounds.addRect(instruction.filterEffect.filterArea);\n\n // new for v8, we transform the bounds into the space of the container\n bounds.applyMatrix(instruction.container.worldTransform);\n }\n // classic filter path, we get the bounds of the container and use it by recursively\n // measuring.\n else\n {\n // we want to factor render layers to get the real visual bounds of this container.\n // so the last param is true..\n instruction.container.getFastGlobalBounds(true, bounds);\n }\n\n if (instruction.container)\n {\n // When a container is cached as a texture, its filters need to be applied relative to its\n // cached parent's coordinate space rather than world space. This transform adjustment ensures\n // filters are applied in the correct coordinate system.\n const renderGroup = instruction.container.renderGroup || instruction.container.parentRenderGroup;\n const filterFrameTransform = renderGroup.cacheToLocalTransform;\n\n if (filterFrameTransform)\n {\n bounds.applyMatrix(filterFrameTransform);\n }\n }\n }\n\n private _applyFiltersToTexture(filterData: FilterData, clear: boolean)\n {\n const inputTexture = filterData.inputTexture;\n\n const bounds = filterData.bounds;\n\n const filters = filterData.filters;\n const firstEnabled = filterData.firstEnabledIndex;\n const lastEnabled = filterData.lastEnabledIndex;\n\n // get a BufferResource from the uniformBatch.\n // this will batch the shader uniform data and give us a buffer resource we can\n // set on our globalUniform Bind Group\n // update the resources on the bind group...\n this._globalFilterBindGroup.setResource(inputTexture.source.style, 2);\n this._globalFilterBindGroup.setResource(filterData.backTexture.source, 3);\n\n if (firstEnabled === lastEnabled)\n {\n // render a single filter...\n filters[firstEnabled].apply(this, inputTexture, filterData.outputRenderSurface, clear);\n }\n else\n {\n let flip = filterData.inputTexture;\n\n const tempTexture = TexturePool.getOptimalTexture(\n bounds.width,\n bounds.height,\n flip.source._resolution,\n false\n );\n\n // get another texture that we will render the next filter too\n let flop = tempTexture;\n\n // loop and apply the filters, omitting the last one as we will render that to the final target\n for (let i = firstEnabled; i < lastEnabled; i++)\n {\n const filter = filters[i];\n\n if (!filter.enabled) continue;\n\n filter.apply(this, flip, flop, true);\n const t = flip;\n\n flip = flop;\n flop = t;\n }\n // apply the last enabled filter to the output\n filters[lastEnabled].apply(this, flip, filterData.outputRenderSurface, clear);\n\n // return those textures for later!\n TexturePool.returnTexture(tempTexture);\n }\n }\n\n private _calculateFilterBounds(\n filterData: FilterData,\n viewPort: Rectangle,\n rootAntialias: boolean,\n rootResolution: number,\n // a multiplier padding for the bounds calculation\n // this prop is used when applying filters to textures\n // as the should have padding applied to them already (until we fix padding when applying them to textures)\n // set to 0 to remove padding from the bounds calculation\n paddingMultiplier: number\n )\n {\n const renderer = this.renderer;\n\n const bounds = filterData.bounds;\n const filters = filterData.filters;\n\n // get GLOBAL bounds of the item we are going to apply the filter to\n\n // next we get the settings for the filter\n // we need to find the LOWEST resolution for the filter list\n let resolution = Infinity;\n // Padding is additive to add padding to our padding\n let padding = 0;\n // if this is true for all filter, it should be true, and otherwise false\n let antialias = true;\n // true if any filter requires the previous render target\n let blendRequired = false;\n // true if any filter in the list is enabled\n let enabled = false;\n // false if any filter in the list has false\n let clipToViewport = true;\n // cache first/last enabled indices for later passes\n let firstEnabledIndex = -1;\n let lastEnabledIndex = -1;\n\n for (let i = 0; i < filters.length; i++)\n {\n const filter = filters[i];\n\n // Only enabled filters should influence pipeline characteristics\n if (!filter.enabled) continue;\n\n if (firstEnabledIndex === -1) firstEnabledIndex = i;\n lastEnabledIndex = i;\n resolution = Math.min(resolution, filter.resolution === 'inherit'\n ? rootResolution : filter.resolution);\n padding += filter.padding;\n\n if (filter.antialias === 'off')\n {\n antialias = false;\n }\n else if (filter.antialias === 'inherit')\n {\n antialias &&= rootAntialias;\n }\n\n if (!filter.clipToViewport)\n {\n clipToViewport = false;\n }\n\n const isCompatible = !!(filter.compatibleRenderers & renderer.type);\n\n if (!isCompatible)\n {\n enabled = false;\n break;\n }\n\n if (filter.blendRequired && !((renderer as WebGLRenderer).backBuffer?.useBackBuffer ?? true))\n {\n // #if _DEBUG\n // eslint-disable-next-line max-len\n warn('Blend filter requires backBuffer on WebGL renderer to be enabled. Set `useBackBuffer: true` in the renderer options.');\n // #endif\n\n enabled = false;\n break;\n }\n\n enabled = true;\n blendRequired ||= filter.blendRequired;\n }\n\n // if no filters are enabled lets skip!\n if (!enabled)\n {\n filterData.skip = true;\n\n return;\n }\n\n // here we constrain the bounds to the viewport we will render too\n // this should not take into account the x, y offset of the viewport - as this is\n // handled by the viewport on the gpu.\n if (clipToViewport)\n {\n bounds.fitBounds(0, viewPort.width / rootResolution, 0, viewPort.height / rootResolution);\n }\n\n // round the bounds to the nearest pixel\n bounds\n .scale(resolution)\n .ceil()\n .scale(1 / resolution)\n .pad((padding | 0) * paddingMultiplier);\n\n // skip if the bounds are negative or zero as this means they are\n // not visible on the screen\n if (!bounds.isPositive)\n {\n filterData.skip = true;\n\n return;\n }\n\n // set the global frame to the root texture\n\n // get previous bounds.. we must take into account skipped filters also..\n\n // // to find the previous resolution we need to account for the skipped filters\n // // the following will find the last non skipped filter...\n\n // store the values that will be used to apply the filters\n filterData.antialias = antialias;\n filterData.resolution = resolution;\n filterData.blendRequired = blendRequired;\n filterData.firstEnabledIndex = firstEnabledIndex;\n filterData.lastEnabledIndex = lastEnabledIndex;\n }\n\n private _popFilterData(): FilterData\n {\n this._filterStackIndex--;\n\n return this._filterStack[this._filterStackIndex];\n }\n\n private _getPreviousFilterData(): FilterData | null\n {\n let previousFilterData: FilterData;\n\n let index = this._filterStackIndex - 1;\n\n while (index > 0)\n {\n index--;\n previousFilterData = this._filterStack[index];\n\n if (!previousFilterData.skip)\n {\n break;\n }\n }\n\n return previousFilterData;\n }\n\n private _pushFilterData(): FilterData\n {\n let filterData = this._filterStack[this._filterStackIndex];\n\n if (!filterData)\n {\n filterData = this._filterStack[this._filterStackIndex] = new FilterData();\n }\n\n this._filterStackIndex++;\n\n return filterData;\n }\n}\n"],
5
+ "mappings": "6mBAAA,IAAAA,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CACAA,GAAO,QAAUC,GAOjB,IAAIC,GAAS,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,EAOpEC,GAAU,mCAWd,SAASF,GAAMG,EAAM,CACpB,IAAIC,EAAO,CAAC,EACZ,OAAAD,EAAK,QAAQD,GAAS,SAASG,EAAGC,EAASC,EAAK,CAC/C,IAAIC,EAAOF,EAAQ,YAAY,EAU/B,IATAC,EAAOE,GAAYF,CAAI,EAGnBC,GAAQ,KAAOD,EAAK,OAAS,IAChCH,EAAK,KAAK,CAACE,CAAO,EAAE,OAAOC,EAAK,OAAO,EAAG,CAAC,CAAC,CAAC,EAC7CC,EAAO,IACPF,EAAUA,GAAW,IAAM,IAAM,OAGrB,CACZ,GAAIC,EAAK,QAAUN,GAAOO,CAAI,EAC7B,OAAAD,EAAK,QAAQD,CAAO,EACbF,EAAK,KAAKG,CAAI,EAEtB,GAAIA,EAAK,OAASN,GAAOO,CAAI,EAAG,MAAM,IAAI,MAAM,qBAAqB,EACrEJ,EAAK,KAAK,CAACE,CAAO,EAAE,OAAOC,EAAK,OAAO,EAAGN,GAAOO,CAAI,CAAC,CAAC,CAAC,CACzD,CACD,CAAC,EACMJ,CACR,CAEA,IAAIM,GAAS,oCAEb,SAASD,GAAYF,EAAM,CAC1B,IAAII,EAAUJ,EAAK,MAAMG,EAAM,EAC/B,OAAOC,EAAUA,EAAQ,IAAI,MAAM,EAAI,CAAC,CACzC,IC7CY,IAAAC,IAAAA,IAGRA,EAAAA,EAAA,IAAM,CAAN,EAAA,MAEAA,EAAAA,EAAA,OAAS,CAAT,EAAA,SAEAA,EAAAA,EAAA,KAAO,CAAP,EAAA,OAPQA,IAAAA,IAAA,CAAA,CAAA,ECTZ,SAASC,GAAWC,EACpB,CACQ,GAAA,OAAOA,GAAS,SAEhB,MAAM,IAAI,UAAU,mCAAmC,KAAK,UAAUA,CAAI,CAAC,EAAE,CAErF,CAEA,SAASC,GAAgBC,EACzB,CAGI,OAFWA,EAAI,MAAM,GAAG,EAAE,CAAC,EAEjB,MAAM,GAAG,EAAE,CAAC,CAC1B,CAEA,SAASC,GAAaC,EACtB,CACW,OAAAA,EAAO,QAAQ,sBAAuB,MAAM,CACvD,CAEA,SAASC,GAAWC,EAAaC,EAAcC,EAC/C,CACW,OAAAF,EAAI,QAAQ,IAAI,OAAOH,GAAaI,CAAI,EAAG,GAAG,EAAGC,CAAO,CACnE,CAGA,SAASC,GAAqBT,EAAcU,EAC5C,CACI,IAAIC,EAAM,GACNC,EAAoB,EACpBC,EAAY,GACZC,EAAO,EACPC,EAAO,GAEX,QAASC,EAAI,EAAGA,GAAKhB,EAAK,OAAQ,EAAEgB,EACpC,CACQ,GAAAA,EAAIhB,EAAK,OAEFA,EAAAA,EAAK,WAAWgB,CAAC,MAC5B,IACSD,IAAS,GAEd,MAIOA,EAAA,GAEX,GAAIA,IAAS,GACb,CACI,GAAI,EAAAF,IAAcG,EAAI,GAAKF,IAAS,GAI3B,GAAAD,IAAcG,EAAI,GAAKF,IAAS,EACzC,CACI,GACIH,EAAI,OAAS,GACVC,IAAsB,GACtBD,EAAI,WAAWA,EAAI,OAAS,CAAC,IAAM,IACnCA,EAAI,WAAWA,EAAI,OAAS,CAAC,IAAM,IAGlC,GAAAA,EAAI,OAAS,EACjB,CACU,IAAAM,EAAiBN,EAAI,YAAY,GAAG,EAEtC,GAAAM,IAAmBN,EAAI,OAAS,EACpC,CACQM,IAAmB,IAEbN,EAAA,GACcC,EAAA,IAIdD,EAAAA,EAAI,MAAM,EAAGM,CAAc,EACjCL,EAAoBD,EAAI,OAAS,EAAIA,EAAI,YAAY,GAAG,GAEhDE,EAAAG,EACLF,EAAA,EACP,QAAA,CACJ,SAEKH,EAAI,SAAW,GAAKA,EAAI,SAAW,EAC5C,CACUA,EAAA,GACcC,EAAA,EACRC,EAAAG,EACLF,EAAA,EACP,QAAA,EAGJJ,IAEIC,EAAI,OAAS,EACRA,GAAA,MAEDA,EAAA,KACYC,EAAA,EACxB,MAIID,EAAI,OAAS,EAEbA,GAAO,IAAIX,EAAK,MAAMa,EAAY,EAAGG,CAAC,CAAC,GAIvCL,EAAMX,EAAK,MAAMa,EAAY,EAAGG,CAAC,EAErCJ,EAAoBI,EAAIH,EAAY,EAE5BA,EAAAG,EACLF,EAAA,CAAA,MAEFC,IAAS,IAAMD,IAAS,GAE3B,EAAAA,EAIKA,EAAA,EACX,CAGG,OAAAH,CACX,CAuIO,IAAMX,GAAa,CAWtB,QAAQA,EAAc,CAAS,OAAAK,GAAWL,EAAM,KAAM,GAAG,CAAA,EAazD,MAAMA,EAAc,CAAE,MAAQ,WAAY,KAAK,KAAK,QAAQA,CAAI,CAAC,CAAA,EAWjE,UAAUA,EACV,CAEY,MAAA,yIACH,KAAKA,CAAI,CAAA,EAYlB,UAAUA,EACV,CAEWA,OAAAA,EAAK,WAAW,OAAO,CAAA,EAelC,YAAYA,EAAc,CAAE,MAAQ,WAAY,KAAK,KAAK,QAAQA,CAAI,CAAC,CAAA,EAcvE,YAAYA,EACZ,CACID,GAAWC,CAAI,EACfA,EAAO,KAAK,QAAQA,CAAI,EAElB,IAAAkB,EAAa,eAAgB,KAAKlB,CAAI,EAE5C,GAAIkB,EAEA,OAAOA,EAAU,CAAC,EAGhB,IAAAC,EAAiB,kBAAmB,KAAKnB,CAAI,EAEnD,OAAImB,EAEOA,EAAc,CAAC,EAGnB,EAAA,EAkBX,WAAWjB,EAAakB,EAAwBC,EAChD,CAGI,GAFAtB,GAAWG,CAAG,EAEV,KAAK,UAAUA,CAAG,GAAK,KAAK,UAAUA,CAAG,EAAU,OAAAA,EAEjD,IAAAoB,EAAUrB,GAAgB,KAAK,QAAQmB,GAAiBG,EAAW,IAAI,EAAE,WAAW,CAAC,CAAC,EACtFC,EAAUvB,GAAgB,KAAK,QAAQoB,GAAiB,KAAK,SAASC,CAAO,CAAC,CAAC,EAKjF,OAHEpB,EAAA,KAAK,QAAQA,CAAG,EAGlBA,EAAI,WAAW,GAAG,EAEXF,GAAK,KAAKwB,EAAStB,EAAI,MAAM,CAAC,CAAC,EAGrB,KAAK,WAAWA,CAAG,EAAIA,EAAM,KAAK,KAAKoB,EAASpB,CAAG,CAEjE,EAgBX,UAAUF,EACV,CAGI,GAFAD,GAAWC,CAAI,EAEXA,EAAK,SAAW,EAAU,MAAA,IAC9B,GAAI,KAAK,UAAUA,CAAI,GAAK,KAAK,UAAUA,CAAI,EAAUA,OAAAA,EAEzDA,EAAO,KAAK,QAAQA,CAAI,EAExB,IAAIyB,EAAW,GACTC,EAAa1B,EAAK,WAAW,GAAG,EAElC,KAAK,YAAYA,CAAI,IAEVyB,EAAA,KAAK,SAASzB,CAAI,EAC7BA,EAAOA,EAAK,MAAMyB,EAAS,MAAM,GAG/B,IAAAE,EAAoB3B,EAAK,SAAS,GAAG,EAMvC,OAHJA,EAAOS,GAAqBT,EAAM,EAAK,EAEnCA,EAAK,OAAS,GAAK2B,IAAmB3B,GAAQ,KAC9C0B,EAAmB,IAAI1B,CAAI,GAExByB,EAAWzB,CAAA,EAgBtB,WAAWA,EACX,CAIQ,OAHJD,GAAWC,CAAI,EACfA,EAAO,KAAK,QAAQA,CAAI,EAEpB,KAAK,YAAYA,CAAI,EAAU,GAE5BA,EAAK,WAAW,GAAG,CAAA,EAiB9B,QAAQ4B,EACR,CACQ,GAAAA,EAAS,SAAW,EACf,MAAA,IACL,IAAAC,EAEJ,QAASb,EAAI,EAAGA,EAAIY,EAAS,OAAQ,EAAEZ,EACvC,CACU,IAAAc,EAAMF,EAASZ,CAAC,EAGlB,GADJjB,GAAW+B,CAAG,EACVA,EAAI,OAAS,EAEb,GAAID,IAAW,OAAoBA,EAAAC,MAEnC,CACI,IAAMC,EAAUH,EAASZ,EAAI,CAAC,GAAK,GAE/B,KAAK,eAAe,SAAS,KAAK,QAAQe,CAAO,EAAE,YAAY,CAAC,EAEhEF,GAAU,OAAOC,CAAG,GAIpBD,GAAU,IAAIC,CAAG,EACrB,CAER,CAEJ,OAAID,IAAW,OAAoB,IAE5B,KAAK,UAAUA,CAAM,CAAA,EAgBhC,QAAQ7B,EACR,CAEI,GADAD,GAAWC,CAAI,EACXA,EAAK,SAAW,EAAU,MAAA,IAC9BA,EAAO,KAAK,QAAQA,CAAI,EACpB,IAAAe,EAAOf,EAAK,WAAW,CAAC,EACtBgC,EAAUjB,IAAS,GACrBkB,EAAM,GACNC,EAAe,GAEbC,EAAQ,KAAK,YAAYnC,CAAI,EAC7BoC,EAAWpC,EAEjBA,EAAOA,EAAK,MAAMmC,EAAM,MAAM,EAE9B,QAASnB,EAAIhB,EAAK,OAAS,EAAGgB,GAAK,EAAG,EAAEA,EAGpC,GADOhB,EAAAA,EAAK,WAAWgB,CAAC,EACpBD,IAAS,IAET,GAAI,CAACmB,EACL,CACUD,EAAAjB,EACN,KAAA,OAMWkB,EAAA,GAMvB,OAAID,IAAQ,GAAWD,EAAU,IAAM,KAAK,MAAMI,CAAQ,EAAID,EAAQnC,EAAOmC,EACzEH,GAAWC,IAAQ,EAAU,KAE1BE,EAAQnC,EAAK,MAAM,EAAGiC,CAAG,CAAA,EAgBpC,SAASjC,EACT,CACID,GAAWC,CAAI,EACfA,EAAO,KAAK,QAAQA,CAAI,EAExB,IAAIqC,EAAO,GAQP,GANArC,EAAK,WAAW,GAAG,EAAUqC,EAAA,IAGtBA,EAAA,KAAK,YAAYrC,CAAI,EAG5B,KAAK,MAAMA,CAAI,EACnB,CAEI,IAAMsC,EAAQtC,EAAK,QAAQ,IAAKqC,EAAK,MAAM,EAEvCC,IAAU,GAEHtC,EAAAA,EAAK,MAAM,EAAGsC,CAAK,EAElBtC,EAAAA,EAEPqC,EAAK,SAAS,GAAG,IAAWA,GAAA,IAAA,CAG9B,OAAAA,CAAA,EAiBX,SAASrC,EAAcuC,EACvB,CACIxC,GAAWC,CAAI,EACXuC,GAAKxC,GAAWwC,CAAG,EAEvBvC,EAAOC,GAAgB,KAAK,QAAQD,CAAI,CAAC,EAEzC,IAAIwC,EAAQ,EACRP,EAAM,GACNC,EAAe,GACf,EAEA,GAAAK,IAAQ,QAAaA,EAAI,OAAS,GAAKA,EAAI,QAAUvC,EAAK,OAC9D,CACI,GAAIuC,EAAI,SAAWvC,EAAK,QAAUuC,IAAQvC,EAAa,MAAA,GACnD,IAAAyC,EAASF,EAAI,OAAS,EACtBG,EAAmB,GAEvB,IAAK,EAAI1C,EAAK,OAAS,EAAG,GAAK,EAAG,EAAE,EACpC,CACU,IAAAe,EAAOf,EAAK,WAAW,CAAC,EAE9B,GAAIe,IAAS,IAIT,GAAI,CAACmB,EACL,CACIM,EAAQ,EAAI,EACZ,KAAA,OAKAE,IAAqB,KAINR,EAAA,GACfQ,EAAmB,EAAI,GAEvBD,GAAU,IAGN1B,IAASwB,EAAI,WAAWE,CAAM,EAE1B,EAAEA,IAAW,KAIPR,EAAA,IAODQ,EAAA,GACHR,EAAAS,GAGlB,CAGJ,OAAIF,IAAUP,EAAWA,EAAAS,EAA2BT,IAAQ,KAAIA,EAAMjC,EAAK,QAEpEA,EAAK,MAAMwC,EAAOP,CAAG,CAAA,CAEhC,IAAK,EAAIjC,EAAK,OAAS,EAAG,GAAK,EAAG,EAAE,EAEhC,GAAIA,EAAK,WAAW,CAAC,IAAM,IAIvB,GAAI,CAACkC,EACL,CACIM,EAAQ,EAAI,EACZ,KAAA,OAGCP,IAAQ,KAIEC,EAAA,GACfD,EAAM,EAAI,GAIlB,OAAIA,IAAQ,GAAW,GAEhBjC,EAAK,MAAMwC,EAAOP,CAAG,CAAA,EAkBhC,QAAQjC,EACR,CACID,GAAWC,CAAI,EACfA,EAAOC,GAAgB,KAAK,QAAQD,CAAI,CAAC,EAEzC,IAAI2C,EAAW,GACXC,EAAY,EACZX,EAAM,GACNC,EAAe,GAGfW,EAAc,EAElB,QAAS7B,EAAIhB,EAAK,OAAS,EAAGgB,GAAK,EAAG,EAAEA,EACxC,CACU,IAAAD,EAAOf,EAAK,WAAWgB,CAAC,EAE9B,GAAID,IAAS,GACb,CAGI,GAAI,CAACmB,EACL,CACIU,EAAY5B,EAAI,EAChB,KAAA,CAEJ,QAAA,CAEAiB,IAAQ,KAIOC,EAAA,GACfD,EAAMjB,EAAI,GAEVD,IAAS,GAGL4B,IAAa,GAAeA,EAAA3B,EACvB6B,IAAgB,IAAiBA,EAAA,GAErCF,IAAa,KAIJE,EAAA,GAClB,CAGJ,OACIF,IAAa,IAAMV,IAAQ,IAExBY,IAAgB,GAGhBA,IAAgB,GAAKF,IAAaV,EAAM,GAAKU,IAAaC,EAAY,EAGlE,GAGJ5C,EAAK,MAAM2C,EAAUV,CAAG,CAAA,EA4BnC,MAAMjC,EACN,CACID,GAAWC,CAAI,EAET,IAAA8C,EAAM,CAAE,KAAM,GAAI,IAAK,GAAI,KAAM,GAAI,IAAK,GAAI,KAAM,EAAG,EAE7D,GAAI9C,EAAK,SAAW,EAAU,OAAA8C,EAC9B9C,EAAOC,GAAgB,KAAK,QAAQD,CAAI,CAAC,EAErC,IAAAe,EAAOf,EAAK,WAAW,CAAC,EACtB0B,EAAa,KAAK,WAAW1B,CAAI,EACnCwC,EACEf,EAAW,GAEbqB,EAAA,KAAO,KAAK,SAAS9C,CAAI,EAEzB0B,GAAc,KAAK,YAAY1B,CAAI,EAE3BwC,EAAA,EAIAA,EAAA,EAEZ,IAAIG,EAAW,GACXC,EAAY,EACZX,EAAM,GACNC,EAAe,GACflB,EAAIhB,EAAK,OAAS,EAIlB6C,EAAc,EAGX,KAAA7B,GAAKwB,EAAO,EAAExB,EACrB,CAEI,GADOhB,EAAAA,EAAK,WAAWgB,CAAC,EACpBD,IAAS,GACb,CAGI,GAAI,CAACmB,EACL,CACIU,EAAY5B,EAAI,EAChB,KAAA,CAEJ,QAAA,CAEAiB,IAAQ,KAIOC,EAAA,GACfD,EAAMjB,EAAI,GAEVD,IAAS,GAGL4B,IAAa,GAAeA,EAAA3B,EACvB6B,IAAgB,IAAiBA,EAAA,GAErCF,IAAa,KAIJE,EAAA,GAClB,CAGJ,OACIF,IAAa,IAAMV,IAAQ,IAExBY,IAAgB,GAGhBA,IAAgB,GAAKF,IAAaV,EAAM,GAAKU,IAAaC,EAAY,EAGrEX,IAAQ,KAEJW,IAAc,GAAKlB,EAAYoB,EAAI,KAAOA,EAAI,KAAO9C,EAAK,MAAM,EAAGiC,CAAG,EACrEa,EAAI,KAAOA,EAAI,KAAO9C,EAAK,MAAM4C,EAAWX,CAAG,IAKpDW,IAAc,GAAKlB,GAEnBoB,EAAI,KAAO9C,EAAK,MAAM,EAAG2C,CAAQ,EACjCG,EAAI,KAAO9C,EAAK,MAAM,EAAGiC,CAAG,IAI5Ba,EAAI,KAAO9C,EAAK,MAAM4C,EAAWD,CAAQ,EACzCG,EAAI,KAAO9C,EAAK,MAAM4C,EAAWX,CAAG,GAExCa,EAAI,IAAM9C,EAAK,MAAM2C,EAAUV,CAAG,GAGlCa,EAAA,IAAM,KAAK,QAAQ9C,CAAI,EACvByB,IAAcqB,EAAA,IAAMrB,EAAWqB,EAAI,KAEhCA,CAAA,EAGX,IAAK,IACL,UAAW,IACX,eAAgB,CAAC,OAAO,CAC5B,ECp6BO,IAAMC,GAAgB,CACzBC,EACAC,EACAC,EAAiB,MAGZ,MAAM,QAAQF,CAAK,IAEpBA,EAAQ,CAACA,CAAU,GAGlBC,EAKGD,EAAyB,IAAKG,GAE9B,OAAOA,GAAS,UAAYD,EAErBD,EAAUE,CAAc,EAG5BA,CACV,EAXUH,GCnBf,SAASI,GAASC,EAAcC,EAAiBC,EAAeC,EAAkBC,EAClF,CACU,IAAAC,EAAKJ,EAAIC,CAAK,EAEpB,QAASI,EAAI,EAAGA,EAAID,EAAG,OAAQC,IAC/B,CACU,IAAAC,EAAQF,EAAGC,CAAC,EAEdJ,EAAQD,EAAI,OAAS,EAEZF,GAAAC,EAAK,QAAQG,EAAOD,CAAK,EAAGK,CAAK,EAAGN,EAAKC,EAAQ,EAAGC,EAAQC,CAAI,EAIzEA,EAAK,KAAKJ,EAAK,QAAQG,EAAOD,CAAK,EAAGK,CAAK,CAAC,CAChD,CAER,CAUO,SAASC,GAAuBC,EACvC,CACI,IAAMC,EAAQ,aAERP,EAASM,EAAO,MAAMC,CAAK,EAE3BN,EAAiB,CAAA,EAEvB,GAAID,EACJ,CACI,IAAMF,EAAkB,CAAA,EAEjBE,EAAA,QAASQ,GAChB,CAEU,IAAAC,EAAQD,EAAK,UAAU,EAAGA,EAAK,OAAS,CAAC,EAAE,MAAM,GAAG,EAE1DV,EAAI,KAAKW,CAAK,CAAA,CACjB,EAEDb,GAASU,EAAQR,EAAK,EAAGE,EAAQC,CAAI,CAAA,MAIrCA,EAAK,KAAKK,CAAM,EAGb,OAAAL,CACX,CClDO,IAAMS,GAAgBC,GAA4B,CAAC,MAAM,QAAQA,CAAI,ECwErE,IAAMC,GAAN,KACP,CADO,aAAA,CASH,KAAiB,gCAAqE,CAClF,UAAW,IACX,oBAAqB,CAACC,EAAUC,IAC5B,GAAGD,CAAQ,GAAG,KAAK,kBAAkB,GAAGC,CAAO,GACnD,yBAA0B,CAACD,EAAUE,IACjCA,EAAc,QAAQ,GAAGF,CAAQ,GAAG,KAAK,kBAAkB,GAAI,EAAE,CAAA,EAIjE,KAAA,mBAAqB,KAAK,gCAAgC,UAQ1D,KAAA,qBAGM,KAAK,gCAAgC,oBAQ3C,KAAA,0BAGM,KAAK,gCAAgC,yBAEnD,KAAQ,UAA6C,CAAA,EACrD,KAAQ,gBAAiC,CAAA,EACzC,KAAiB,SAA+B,CAAA,EAEhD,KAAQ,cAA+C,CAAA,EAIvD,KAAQ,SAAqC,CAAA,CAAC,CAQvC,oBAAoBG,EAC3B,CAKQ,GAJC,KAAA,mBAAqBA,EAAiB,WAAa,KAAK,mBACxD,KAAA,qBAAuBA,EAAiB,qBAAuB,KAAK,qBACpE,KAAA,0BAA4BA,EAAiB,0BAA4B,KAAK,0BAE/E,KAAK,0BAA0B,MAAO,KAAK,qBAAqB,MAAO,KAAK,CAAC,IAAM,MAE7E,MAAA,IAAI,MAAM,4DAA4D,CAChF,CAmBG,UAAUC,EACjB,CACiBA,EAAA,QAASC,GACtB,CACS,KAAA,gBAAgB,KAAKA,CAAM,EAE3BA,EAAO,WAGRA,EAAO,SAAW,OAAO,KAAKA,EAAO,MAAM,EAC/C,CACH,EAED,KAAK,cAAgB,CAAA,CAAC,CAW1B,IAAW,SAASC,EACpB,CACI,KAAK,UAAYA,CAAA,CAGrB,IAAW,UACX,CACI,OAAO,KAAK,SAAA,CAchB,IAAW,SAASC,EACpB,CACI,KAAK,UAAYA,CAAA,CAGrB,IAAW,UACX,CACI,OAAO,KAAK,SAAA,CAwChB,IAAW,SACX,CACI,OAAO,KAAK,QAAA,CAIT,OACP,CACS,KAAA,oBAAoB,KAAK,+BAA+B,EAE7D,KAAK,UAAY,CAAA,EACjB,KAAK,gBAAkB,CAAA,EAGvB,KAAK,cAAgB,CAAA,EACrB,KAAK,UAAY,KACjB,KAAK,UAAY,KACjB,KAAK,UAAY,KACjB,KAAK,SAAW,CAAA,EAChB,KAAK,qBAAuB,IAAA,CAOzB,uBAAuBC,EAC9B,CACQ,GAAA,OAAOA,GAAiB,SAExB,KAAK,qBAAuBA,MAGhC,CACI,IAAMC,EAAcD,EAEf,KAAA,qBAAuB,OAAO,KAAKC,CAAW,EAC9C,IAAKC,GAAQ,GAAG,mBAAmBA,CAAG,CAAC,IAAI,mBAAmBD,EAAYC,CAAG,CAAC,CAAC,EAAE,EACjF,KAAK,GAAG,CAAA,CACjB,CAOG,SAASC,EAChB,CACU,GAAA,CAAE,MAAAC,EAAO,IAAAC,CAAA,EAAQF,EAahB,OAZcG,GACjBF,GAASC,EAAME,GAEP,OAAOA,GAAU,SAAiBA,EAElC,MAAM,QAAQA,CAAK,EAAUA,EAAM,IAAKC,GAAOA,GAAmB,KAAOA,CAAC,EAE1ED,GAAO,IAAYA,EAAM,IAEtBA,EACR,EAAA,CAEA,CAQJ,YAAYE,EACnB,CACQ,KAAK,WAGLC,EAAK,8DAA8D,EAIvE,KAAK,UAAYD,EAERA,EAAA,QAAQ,QAASE,GAC1B,CACI,KAAK,UAAUA,EAAO,KAAMA,EAAO,MAAM,CAAA,CAC5C,CAAA,CAuBE,UAAUnB,EAAkBoB,EACnC,CACI,IAAMC,EAAuB,CAAA,EACzBC,EAAqCF,EAEpC,MAAM,QAAQA,CAAM,IAGHE,EAAA,OAAO,QAAQF,CAAM,EAAE,IAAI,CAAC,CAACR,EAAOC,CAAG,IAEjD,OAAOA,GAAQ,UAAY,MAAM,QAAQA,CAAG,EAErC,CAAE,MAAAD,EAAO,IAAAC,CAAI,EAGjB,CAAE,MAAAD,EAAO,GAAGC,CAAI,CAC1B,GAQWS,EAAA,QAASX,GACzB,CACI,IAAMY,EAAOZ,EAAM,IACba,EAAUb,EAAM,MAClBc,EAEA,GAAA,OAAOD,GAAY,SACvB,CACI,IAAME,EAAgB,KAAK,qBAAqB1B,EAAUwB,CAAO,EAEjEH,EAAW,KAAKK,CAAa,EACvBD,EAAA,CAACD,EAASE,CAAa,CAAA,KAGjC,CACU,IAAAC,EAAYH,EAAQ,IAAKI,GAAS,KAAK,qBAAqB5B,EAAU4B,CAAI,CAAC,EAEtEP,EAAA,KAAK,GAAGM,CAAS,EAC5BF,EAAM,CAAC,GAAGD,EAAS,GAAGG,CAAS,CAAA,CAGnC,KAAK,IAAI,CACL,GAAGhB,EAEC,MAAOc,EACP,IAAKF,CACT,CACH,CAAA,CACJ,EAEI,KAAA,SAASvB,CAAQ,EAAIqB,CAAA,CA8BvB,IACHG,EAEJ,CACI,IAAMJ,EAA4B,CAAA,EAE9B,MAAM,QAAQI,CAAO,EAEdJ,EAAA,KAAK,GAAII,CAA6B,EAI7CJ,EAAO,KAAKI,CAA0B,EAGtC,IAAAK,EAIJA,EAAYnB,GACZ,CACQ,KAAK,OAAOA,CAAG,GAGVQ,EAAA,+BAA+BR,CAAG,cAAc,CAEzD,EAIeI,GAAcM,CAAM,EAG5B,QAAST,GACpB,CACU,GAAA,CAAE,IAAAE,CAAA,EAAQF,EACZ,CACA,KAAAmB,EACA,OAAAC,EACA,WAAYC,EACZ,OAAQC,CAAA,EACRtB,EAKEuB,EAAwCpB,GAAwBD,CAAG,EAAE,IAAKA,GAExE,OAAOA,GAAQ,SACVsB,GAAuBtB,CAAG,EAE5B,MAAM,QAAQA,CAAG,EAAIA,EAAM,CAACA,CAAG,CACzC,EAEKuB,EAAe,KAAK,SAASzB,CAAK,EAGlC,MAAA,QAAQyB,CAAY,EAAIA,EAAa,QAAQP,CAAQ,EAAIA,EAASO,CAAY,EAIpF,IAAMC,EAAkC,CAAA,EAGlCC,EAAYC,IAIP,CACH,GAHW,KAAK,SAAS,KAAMC,GAAMA,EAAE,KAAKD,CAAG,CAAC,GAGrC,MAAMA,CAAG,EACpB,IAAKA,CAAA,GAIHL,EAAA,QAASX,GACnB,CACSA,EAAA,QAASV,GACd,CACI,IAAI4B,EAAiB,CAAA,EAwBrB,GAtBI,OAAO5B,GAAQ,SAGf4B,EAAiBH,EAASzB,CAAG,GAI7BiB,EAAOjB,EAAI,MAAQiB,EACnBC,EAASlB,EAAI,QAAUkB,GACnBlB,EAAI,YAAcA,EAAI,UAEtBmB,EAAwBnB,EAAI,YAAcmB,EAC1CC,EAAoBpB,EAAI,QAAUoB,GAGrBQ,EAAA,CACb,GAAGH,EAASzB,EAAI,GAAG,EACnB,GAAGA,CAAA,GAKP,CAACuB,EAED,MAAM,IAAI,MAAM,iDAAiDK,EAAe,GAAG,EAAE,EAGxEA,EAAA,KAAK,oBAAoBA,EAAgB,CACtD,QAASL,EACT,KAAAN,EACA,OAAAC,EACA,WAAYC,EACZ,OAAQC,EACR,aAActB,EAAM,YAAA,CACvB,EAED0B,EAAe,KAAKI,CAAc,CAAA,CACrC,CAAA,CACJ,EAEYL,EAAA,QAASxB,GACtB,CACS,KAAA,UAAUA,CAAK,EAAIyB,CAAA,CAC3B,CAAA,CACJ,CAAA,CA6CE,cAAcV,EAErB,CACU,IAAAe,EAAcC,GAAahB,CAAS,EAE1CA,EAAYb,GAAsBa,CAAS,EAE3C,IAAMiB,EAAqD,CAAA,EAEjD,OAAAjB,EAAA,QAAS3B,GACnB,CACU,IAAAqB,EAAa,KAAK,SAASrB,CAAQ,EAEzC,GAAIqB,EACJ,CACU,IAAAwB,EAAU,KAAK,QAAQxB,CAAU,EAEjCD,EAAwC,CAAA,EAE9C,QAAWV,KAAOmC,EAClB,CACU,IAAAlC,EAAQkC,EAAQnC,CAAG,EAEzBU,EAAO,KAAK,0BAA0BpB,EAAUU,CAAG,CAAC,EAAIC,CAAA,CAG5DiC,EAAI5C,CAAQ,EAAIoB,CAAA,CACpB,CACH,EAEMsB,EAAcE,EAAIjB,EAAU,CAAC,CAAC,EAAIiB,CAAA,CAQtC,WAAWlC,EAClB,CACU,IAAAoC,EAAS,KAAK,QAAQpC,CAAa,EAErC,GAAA,OAAOA,GAAQ,SACnB,CACI,IAAMkC,EAA8B,CAAA,EAEpC,QAAWG,KAAKD,EAEZF,EAAIG,CAAC,EAAKD,EAAyCC,CAAC,EAAE,IAGnD,OAAAH,CAAA,CAGX,OAAQE,EAAyB,GAAA,CAoB9B,QAAQE,EACf,CACU,IAAAN,EAAcC,GAAaK,CAAI,EAErCA,EAAOlC,GAAsBkC,CAAI,EAEjC,IAAMF,EAAwC,CAAA,EAEzC,OAAAE,EAAA,QAAStC,GACd,CACI,GAAI,CAAC,KAAK,cAAcA,CAAG,EAEnB,GAAA,KAAK,UAAUA,CAAG,EACtB,CACQ,IAAAU,EAAS,KAAK,UAAUV,CAAG,EACzBuC,EAAiB,KAAK,mBAAmB7B,CAAM,EAErC6B,GAAA,SAAS,QAASC,GAClC,CACID,EAAe,OAAOC,CAAW,EAAE,QAASnC,GAC5C,CACI,IAAMoC,EAAiB/B,EAAO,OAAQT,GAE9BA,EAAMuC,CAAkC,EAEjCvC,EAAMuC,CAAkC,IAAMnC,EAGlD,EACV,EAEGoC,EAAe,SAEN/B,EAAA+B,EACb,CACH,CAAA,CACJ,EAED,KAAK,cAAczC,CAAG,EAAIU,EAAO,CAAC,CAAA,MAIlC,KAAK,cAAcV,CAAG,EAAI,KAAK,oBAAoB,CAC/C,MAAO,CAACA,CAAG,EACX,IAAKA,CAAA,EACN,CAAA,CAAE,EAIboC,EAAOpC,CAAG,EAAI,KAAK,cAAcA,CAAG,CAAA,CACvC,EAEMgC,EAAcI,EAAOE,EAAK,CAAC,CAAC,EAAIF,CAAA,CAOpC,OAAOpC,EACd,CACI,MAAO,CAAC,CAAC,KAAK,UAAUA,CAAG,CAAA,CAOxB,UAAUA,EACjB,CACI,MAAO,CAAC,CAAC,KAAK,SAASA,CAAG,CAAA,CAOtB,mBAAmBU,EAC3B,CACI,QAAS2B,EAAI,EAAGA,EAAI3B,EAAO,OAAQ2B,IACnC,CACU,IAAApC,EAAQS,EAAO2B,CAAC,EAEhBK,EAAY,KAAK,gBAAgB,KAAMC,GACzCA,EAAW,OAAO,OAAO,SAAS1C,EAAM,MAAM,CAAC,EAEnD,GAAIyC,EAEO,OAAAA,CACX,CAGG,OAAA,KAAK,gBAAgB,CAAC,CAAA,CAQzB,2BAA2Bb,EACnC,CACI,GAAI,CAAC,KAAK,qBAA6B,OAAAA,EAEvC,IAAMe,EAAkB,KAAM,KAAKf,CAAG,EAAI,IAAM,IAEhD,MAAO,GAAGA,CAAG,GAAGe,CAAc,GAAG,KAAK,oBAAoB,EAAA,CAGtD,oBAAoBb,EAA+BX,EAQ3D,CACU,GAAA,CAAE,QAAAN,EAAS,KAAM+B,EAAW,WAAAC,EAAY,OAAAC,EAAQ,OAAA1B,EAAQ,aAAA2B,CAAA,EAAiB5B,EAE3E,OAAA,KAAK,WAAa,KAAK,aAERW,EAAA,IAAMkB,GAAK,WAAWlB,EAAe,IAAK,KAAK,UAAW,KAAK,SAAS,GAG3FA,EAAe,MAAQjB,GAAWiB,EAAe,OAAS,CAACA,EAAe,GAAG,EAC7EA,EAAe,IAAM,KAAK,2BAA2BA,EAAe,GAAG,EACxDA,EAAA,KAAO,CAAE,GAAGc,GAAa,CAAA,EAAI,GAAGd,EAAe,IAAK,EACpDA,EAAA,WAAae,GAAcf,EAAe,WAC1CA,EAAA,OAASgB,GAAUhB,EAAe,OACjDA,EAAe,OAASV,GAAUU,EAAe,QAAUmB,GAAgBnB,EAAe,GAAG,EACzFiB,IAAiB,SAEjBjB,EAAe,aAAeiB,GAG3BjB,CAAA,CAEf,EA7uBa1C,GAOK,cAAgB,eA4uB3B,SAAS6D,GAAgBrB,EAChC,CACI,OAAOA,EAAI,MAAM,GAAG,EAAE,IAAA,EAAM,MAAM,GAAG,EAAE,MAAM,EACxC,MAAM,GAAG,EACT,MAAM,CACf,CC9zBa,IAAAsB,GAAmB,CAACC,EAAmBC,IACpD,CACI,IAAMC,EAAeD,EAAU,MAAM,GAAG,EAAE,CAAC,EAE3C,OAAIC,IAEAF,GAAa,IAAIE,CAAY,IAG1BF,CACX,ECqMO,IAAMG,GAAN,MAAMA,EACb,CAiFI,YAAYC,EAA2DC,EACvE,CA1EA,KAAO,aAAiC,CAAA,EA2EpC,IAAIC,EAAUF,EAETA,GAAsC,kBAAkBG,KAE/CD,EAAA,CACN,QAASF,EACT,KAAMC,CAAA,GAGd,GAAM,CAAE,QAAAG,EAAS,KAAAC,EAAM,YAAAC,EAAc,EAAA,EAAOJ,EAE5C,KAAK,YAAcI,EACd,KAAA,SAAWF,aAAmBG,EAAUH,EAAU,KACvD,KAAK,cAAgBA,EAAQ,OAC7B,KAAK,SAAW,CAAA,EAChB,KAAK,WAAa,CAAA,EAClB,KAAK,KAAOC,EAEZ,IAAMG,EAAiB,WAAWH,EAAK,KAAK,KAAe,EAEvDG,GAEA,KAAK,WAAaA,EACVJ,EAAA,OAAO,WAAa,KAAK,YAI5B,KAAA,WAAaA,EAAQ,OAAO,YAGhC,KAAA,QAAU,KAAK,KAAK,OACzB,KAAK,WAAa,OAAO,KAAK,KAAK,OAAO,EAC1C,KAAK,YAAc,EACnB,KAAK,UAAY,IAAA,CAOd,OACP,CACW,OAAA,IAAI,QAASK,GACpB,CACI,KAAK,UAAYA,EACjB,KAAK,YAAc,EAEf,KAAK,WAAW,QAAUV,GAAY,YAEtC,KAAK,eAAe,CAAC,EACrB,KAAK,mBAAmB,EACxB,KAAK,eAAe,GAIpB,KAAK,WAAW,CACpB,CACH,CAAA,CAOG,eAAeW,EACvB,CACI,IAAIC,EAAaD,EACXE,EAAYb,GAAY,WAE9B,KAAOY,EAAaD,EAAoBE,GAAaD,EAAa,KAAK,WAAW,QAClF,CACU,IAAAE,EAAI,KAAK,WAAWF,CAAU,EAC9BN,EAAO,KAAK,QAAQQ,CAAC,EACrBC,EAAOT,EAAK,MAElB,GAAIS,EACJ,CACI,IAAIC,EAAQ,KACRC,EAAO,KACLC,EAAaZ,EAAK,UAAY,IAASA,EAAK,WAC5CA,EAAK,WAAaA,EAAK,MAEvBa,EAAO,IAAIC,EACb,EACA,EACA,KAAK,MAAMF,EAAW,CAAC,EAAI,KAAK,WAChC,KAAK,MAAMA,EAAW,CAAC,EAAI,KAAK,UAAA,EAGhCZ,EAAK,QAELU,EAAQ,IAAII,EACR,KAAK,MAAML,EAAK,CAAC,EAAI,KAAK,WAC1B,KAAK,MAAMA,EAAK,CAAC,EAAI,KAAK,WAC1B,KAAK,MAAMA,EAAK,CAAC,EAAI,KAAK,WAC1B,KAAK,MAAMA,EAAK,CAAC,EAAI,KAAK,UAAA,EAK9BC,EAAQ,IAAII,EACR,KAAK,MAAML,EAAK,CAAC,EAAI,KAAK,WAC1B,KAAK,MAAMA,EAAK,CAAC,EAAI,KAAK,WAC1B,KAAK,MAAMA,EAAK,CAAC,EAAI,KAAK,WAC1B,KAAK,MAAMA,EAAK,CAAC,EAAI,KAAK,UAAA,EAK9BT,EAAK,UAAY,IAASA,EAAK,mBAE/BW,EAAO,IAAIG,EACP,KAAK,MAAMd,EAAK,iBAAiB,CAAC,EAAI,KAAK,WAC3C,KAAK,MAAMA,EAAK,iBAAiB,CAAC,EAAI,KAAK,WAC3C,KAAK,MAAMS,EAAK,CAAC,EAAI,KAAK,WAC1B,KAAK,MAAMA,EAAK,CAAC,EAAI,KAAK,UAAA,GAIlC,KAAK,SAASD,CAAC,EAAI,IAAIN,EAAQ,CAC3B,OAAQ,KAAK,cAEb,MAAAQ,EACA,KAAAG,EACA,KAAAF,EACA,OAAQX,EAAK,QAAU,EAAI,EAC3B,cAAeA,EAAK,OACpB,eAAgBA,EAAK,QAErB,MAAOQ,EAAE,SAAS,CAAA,CACrB,CAAA,CAGLF,GAAA,CACJ,CAII,oBACR,CACI,IAAMS,EAAa,KAAK,KAAK,YAAc,CAAA,EAE3C,QAAWC,KAAYD,EACvB,CACS,KAAA,WAAWC,CAAiC,EAAI,CAAA,EACrD,QAASR,EAAI,EAAGA,EAAIO,EAAWC,CAAQ,EAAE,OAAQR,IACjD,CACI,IAAMS,EAAYF,EAAWC,CAAQ,EAAER,CAAC,EAExC,KAAK,WAAWQ,CAAQ,EAAE,KAAK,KAAK,SAASC,CAAS,CAAC,CAAA,CAC3D,CACJ,CAII,gBACR,CACI,IAAMC,EAAW,KAAK,UAEtB,KAAK,UAAY,KACjB,KAAK,YAAc,EACVA,EAAA,KAAK,KAAM,KAAK,QAAQ,CAAA,CAI7B,YACR,CACI,KAAK,eAAe,KAAK,YAAcxB,GAAY,UAAU,EACxD,KAAA,cACL,WAAW,IACX,CACQ,KAAK,YAAcA,GAAY,WAAa,KAAK,WAAW,OAE5D,KAAK,WAAW,GAIhB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACxB,EACD,CAAC,CAAA,CAOD,QAAQyB,EAAc,GAC7B,CACe,QAAAX,KAAK,KAAK,SAEZ,KAAA,SAASA,CAAC,EAAE,QAAQ,EAE7B,KAAK,QAAU,KACf,KAAK,WAAa,KAClB,KAAK,KAAO,KACZ,KAAK,SAAW,KACZW,IAEA,KAAK,UAAU,QAAQ,EACvB,KAAK,cAAc,QAAQ,GAE/B,KAAK,SAAW,KAChB,KAAK,cAAgB,KACrB,KAAK,aAAe,CAAA,CAAC,CAE7B,EAlSazB,GAMc,WAAa,IANjC,IAAM0B,GAAN1B,GCtLP,IAAM2B,GAAc,CAAC,MAAO,MAAO,OAAQ,OAAQ,OAC/C,QAAS,OAAQ,MAAO,OAAQ,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAM,EAEpF,SAASC,GAAmBC,EAAgBC,EAAoBC,EAChE,CACI,IAAMC,EAA2B,CAAA,EAYjC,GAVKH,EAAA,QAASI,GACd,CACID,EAAIC,CAAG,EAAIH,CAAA,CACd,EAED,OAAO,KAAKA,EAAM,QAAQ,EAAE,QAASG,GACrC,CACQD,EAAA,GAAGF,EAAM,WAAW,GAAGG,CAAG,EAAE,EAAIH,EAAM,SAASG,CAAG,CAAA,CACzD,EAEG,CAACF,EACL,CACI,IAAMG,EAAWC,GAAK,QAAQN,EAAK,CAAC,CAAC,EAErCC,EAAM,aAAa,QAAQ,CAACM,EAAmBC,IAC/C,CACI,IAAMC,EAAOV,GAAmB,CAAC,GAAGM,CAAQ,IAAIJ,EAAM,KAAK,KAAK,oBAAoBO,CAAC,CAAC,EAAE,EAAGD,EAAM,EAAI,EAE9F,OAAA,OAAOJ,EAAKM,CAAI,CAAA,CAC1B,CAAA,CAGE,OAAAN,CACX,CAqBO,IAAMO,GAAmB,CAC5B,UAAWC,EAAc,MAEzB,MAAO,CACH,KAAOV,GAAuBA,aAAiBW,GAC/C,mBAAoB,CAACZ,EAAgBC,IAAuBF,GAAmBC,EAAMC,EAAO,EAAK,CAAA,EAGrG,SAAU,CACN,UAAW,CACP,KAAMU,EAAc,cACpB,KAAM,oBAAA,EAEV,KAAOE,GACP,CAEU,IAAAC,EADUD,EAAM,MAAM,GAAG,EAAE,CAAC,EACZ,MAAM,GAAG,EACzBE,EAAYD,EAAM,IAAI,EACtBE,EAASF,EAAM,IAAI,EAEzB,OAAOC,IAAc,QAAUjB,GAAY,SAASkB,CAAM,CAAA,EAE9D,MAAQH,GACR,CACU,IAAAC,EAAQD,EAAM,MAAM,GAAG,EAEtB,MAAA,CACH,WAAY,WAAWI,GAAS,cAAc,KAAKJ,CAAK,IAAI,CAAC,GAAK,GAAG,EACrE,OAAQC,EAAMA,EAAM,OAAS,CAAC,EAC9B,IAAKD,CAAA,CACT,CACJ,EAQJ,OAAQ,CAEJ,KAAM,oBACN,GAAI,cAEJ,UAAW,CACP,KAAMF,EAAc,WACpB,SAAUO,GAAqB,OAC/B,KAAM,mBAAA,EAGV,MAAM,UAAUjB,EAAwBkB,EACxC,CACY,OAAAb,GAAK,QAAQa,EAAQ,GAAG,EAAE,YAAA,IAAkB,SAAW,CAAC,CAAClB,EAAM,MAAA,EAG3E,MAAM,MACFA,EACAkB,EAOAC,EAEJ,CACU,GAAA,CACF,QAASC,EACT,cAAAC,EACA,eAAAC,EACA,YAAAC,CAAA,EACAL,GAAS,MAAQ,CAAA,EAEjBd,EAAWC,GAAK,QAAQa,EAAQ,GAAG,EAEnCd,GAAYA,EAAS,YAAY,GAAG,IAAOA,EAAS,OAAS,IAEjDA,GAAA,KAGZ,IAAAoB,EAEJ,GAAIJ,aAAwBK,EAEdD,EAAAJ,MAGd,CACU,IAAAM,EAAYC,GAAiBvB,GAAYiB,GAAiBrB,EAAM,KAAK,OAAQkB,EAAQ,GAAG,EAI9FM,GAFe,MAAML,EAAO,KAAc,CAAC,CAAE,IAAKO,EAAW,KAAMJ,CAAe,CAAC,CAAC,GAEnEI,CAAS,CAAA,CAGxB,IAAAE,EAAc,IAAIjB,GAAY,CAChC,QAASa,EAAQ,OACjB,KAAMxB,EACN,YAAAuB,CAAA,CACH,EAED,MAAMK,EAAY,MAAM,EAIlB,IAAAC,EAAa7B,GAAO,MAAM,oBAE5B,GAAA,MAAM,QAAQ6B,CAAU,EAC5B,CACI,IAAMC,EAAoD,CAAA,EAE1D,QAAWxB,KAAQuB,EACnB,CACQ,GAAA,OAAOvB,GAAS,SAEhB,SAGJ,IAAIyB,EAAU3B,EAAWE,EAGrBY,EAAQ,MAAM,kBAKRa,EAAAJ,GAAiBI,EAASb,EAAQ,GAAG,EAEtCY,EAAA,KAAKX,EAAO,KAAmC,CACpD,IAAKY,EACL,KAAM,CACF,eAAAT,EACA,gBAAiB,EAAA,CACrB,CACH,CAAC,EAAA,CAGN,IAAMU,EAAM,MAAM,QAAQ,IAAIF,CAAQ,EAEtCF,EAAY,aAAeI,EACvBA,EAAA,QAAS1B,GACb,CACIA,EAAK,aAAe,CAACsB,CAAW,EAAE,OAAOA,EAAY,aAAa,OAAQK,GAAQA,IAAO3B,CAAK,CAAC,CAAA,CAClG,CAAA,CAGE,OAAAsB,CAAA,EAGX,MAAM,OAAOA,EAA0BM,EAAgBf,EACvD,CACI,MAAMA,EAAO,OAAOS,EAAY,cAAc,aAAa,EAE3DA,EAAY,QAAQ,EAAK,CAAA,CAC7B,CAER,EC7OAO,GAAW,IAAIC,EAAgB,ECE/B,IAAMC,GAAa,IAAIC,GAQP,SAAAC,GAAcC,EAAiBC,EAAgBC,EAC/D,CACI,IAAMC,EAAeN,GAErBG,EAAK,WAAa,GAEFI,GAAAJ,EAAME,EAAqBC,CAAY,EAEvDF,EAAO,cAAcE,CAAY,EAEjCH,EAAK,WAAa,EACtB,CCVgB,SAAAK,GAAmBC,EAAiBC,EAAgBC,EACpE,CACU,IAAAC,EAAeC,GAAW,IAAI,EAEpCJ,EAAK,WAAa,GAElB,IAAMK,EAAaC,GAAW,IAAI,EAAE,SAAS,EAEvCC,EAAeC,GAA0BR,EAAME,EAAWG,CAAU,EAE3DI,GAAAT,EAAMG,EAAcI,CAAY,EAE/CP,EAAK,WAAa,GAElBC,EAAO,cAAcE,CAAY,EAEjCG,GAAW,OAAOD,CAAU,EAC5BD,GAAW,OAAOD,CAAY,CAClC,CAEA,SAASK,GAA0BE,EAAmBC,EAAiBC,EACvE,CACI,OAAKF,GAUDA,IAAWC,IAEeH,GAAAE,EAAO,OAAQC,EAAMC,CAAM,EAErDF,EAAO,qBAAqB,EAErBE,EAAA,OAAOF,EAAO,cAAc,GAGhCE,IAfHC,EAAK,0DAA0D,EAGxDD,EAaf,CCrCO,IAAME,GAAN,KACP,CASI,YAAYC,EACZ,CAPA,KAAO,SAAW,EAElB,KAAO,QAAmB,GAC1B,KAAO,KAAO,YAKNA,GAAS,MAEJ,KAAA,KAAKA,EAAQ,IAAI,CAC1B,CAGG,KAAKC,EACZ,CACI,KAAK,KAAOA,EAIP,KAAA,oBAAsB,EAAEA,aAAgBC,IAExC,KAAA,KAAK,WAAa,KAAK,oBACvB,KAAA,KAAK,eAAiB,CAAC,KAAK,oBAEjC,KAAK,KAAK,WAAa,EAAA,CAGpB,OACP,CACQ,KAAK,OAAS,OAClB,KAAK,KAAK,WAAa,GACvB,KAAK,KAAO,KAAA,CAGT,UAAUC,EAAgBC,EACjC,CACS,KAAK,SAEQC,GAAA,KAAK,KAAMF,EAAQC,CAAmB,CACxD,CAGG,eAAeD,EAAgBG,EACtC,CACuBC,GAAA,KAAK,KAAMJ,EAAQG,CAAS,CAAA,CAG5C,cAAcE,EAAcC,EACnC,CACI,IAAMR,EAAO,KAAK,KAGX,OAAAQ,EAAUR,EAAMO,CAAK,CAAA,CAGzB,SACP,CACI,KAAK,MAAM,CAAA,CAGf,OAAc,KAAKP,EACnB,CACI,OAAOA,aAAgBC,EAAA,CAE/B,EArEaH,GAEK,UAA+BW,EAAc,WCRxD,IAAMC,GAAN,KACP,CAOI,YAAYC,EACZ,CALA,KAAO,SAAW,EAElB,KAAO,KAAO,YAINA,GAAS,MAEJ,KAAA,KAAKA,EAAQ,IAAI,CAC1B,CAGG,KAAKC,EACZ,CACI,KAAK,KAAOA,CAAA,CAGT,SACP,CAAA,CAIA,OAAc,KAAKA,EACnB,CACI,OAAO,OAAOA,GAAS,QAAA,CAE/B,EA9BaF,GAEK,UAA+BG,EAAc,WCIxD,IAAMC,GAAN,KACP,CAOI,YAAYC,EACZ,CALA,KAAO,SAAW,EAElB,KAAO,KAAO,cAINA,GAAS,MAEJ,KAAA,KAAKA,EAAQ,IAAI,CAC1B,CAGG,KAAKC,EACZ,CACI,KAAK,KAAOA,EACZ,KAAK,KAAK,eAAiB,GAC3B,KAAK,KAAK,WAAa,EAAA,CAGpB,OACP,CACQ,KAAK,OAAS,OAClB,KAAK,KAAK,WAAa,GACvB,KAAK,KAAK,eAAiB,GAC3B,KAAK,KAAO,KAAA,CAGT,UAAUC,EAAgBC,EACjC,CACkBC,GAAA,KAAK,KAAMF,EAAQC,CAAmB,CAAA,CAGjD,eAAeD,EAAgBG,EACtC,CACuBC,GAAA,KAAK,KAAMJ,EAAQG,CAAS,CAAA,CAG5C,cAAcE,EAAcC,EACnC,CACI,IAAMP,EAAO,KAAK,KAGX,OAAAO,EAAUP,EAAMM,CAAK,CAAA,CAGzB,SACP,CACI,KAAK,MAAM,CAAA,CAGf,OAAc,KAAKN,EACnB,CACI,OAAOA,aAAgBQ,EAAA,CAE/B,EA1DaV,GAEK,UAA+BW,EAAc,WCcxD,IAAMC,GAAN,cAA0BC,EACjC,CAII,YAAYC,EACZ,CACI,MAAMA,CAAO,EAJjB,KAAO,eAAiB,QAMpB,KAAK,mBAAqB,EAAA,CAG9B,OAAc,KAAKC,EACnB,CACY,OAAA,WAAW,kBAAoBA,aAAoB,kBACvD,OAAO,YAAgB,KAAeA,aAAoB,aAC1D,WAAW,YAAcA,aAAoB,UAAA,CAEzD,EAlBaH,GAEK,UAA+BI,EAAc,cChC/D,IAAIC,GAeJ,eAAsBC,IACtB,CACI,OAAAD,KAAAA,IAAa,SACb,CAEU,IAAAE,EADSC,EAAW,IAAA,EAAM,aAAa,EAAG,CAAC,EAC/B,WAAW,OAAO,EAEpC,GAAI,CAACD,EAEM,MAAA,8BAGX,IAAME,EAAQ,MAAM,IAAI,QAAkCC,GAC1D,CACUD,IAAAA,EAAQ,SAAS,cAAc,OAAO,EAE5CA,EAAM,aAAe,IAAMC,EAAQD,CAAK,EACxCA,EAAM,QAAU,IAAMC,EAAQ,IAAI,EAClCD,EAAM,SAAW,GACjBA,EAAM,YAAc,YACpBA,EAAM,QAAU,OAEhBA,EAAM,IAAM,0sBACZA,EAAM,KAAK,CAAA,CACd,EAED,GAAI,CAACA,EAEM,MAAA,8BAGL,IAAAE,EAAUJ,EAAG,cAAc,EAE9BA,EAAA,YAAYA,EAAG,WAAYI,CAAO,EAE/B,IAAAC,EAAcL,EAAG,kBAAkB,EAEtCA,EAAA,gBAAgBA,EAAG,YAAaK,CAAW,EAC3CL,EAAA,qBACCA,EAAG,YACHA,EAAG,kBACHA,EAAG,WACHI,EACA,CAAA,EAGDJ,EAAA,YAAYA,EAAG,+BAAgC,EAAK,EACvDA,EAAG,YAAYA,EAAG,mCAAoCA,EAAG,IAAI,EAC1DA,EAAA,WAAWA,EAAG,WAAY,EAAGA,EAAG,KAAMA,EAAG,KAAMA,EAAG,cAAeE,CAAK,EAEnE,IAAAI,EAAQ,IAAI,WAAW,CAAC,EAE3B,OAAAN,EAAA,WAAW,EAAG,EAAG,EAAG,EAAGA,EAAG,KAAMA,EAAG,cAAeM,CAAK,EAE1DN,EAAG,kBAAkBK,CAAW,EAChCL,EAAG,cAAcI,CAAO,EACrBJ,EAAA,aAAa,oBAAoB,GAAG,YAAY,EAE5CM,EAAM,CAAC,GAAKA,EAAM,CAAC,EAAI,sBAAwB,6BAAA,GACvD,GAEIR,EACX,CCxBO,IAAMS,GAAN,MAAMA,WAAoBC,EACjC,CAmEI,YACIC,EAEJ,CACI,MAAMA,CAAO,EA7CjB,KAAO,QAAU,GAEjB,KAAO,eAAiB,QA8CVA,EAAA,CACN,GAAGF,GAAY,eACf,GAAGE,CAAA,EAGP,KAAK,YAAc,GACnB,KAAK,qBAAuB,GACvB,KAAA,WAAaA,EAAQ,WAAa,EACvC,KAAK,gBAAkB,EAClB,KAAA,SAAWA,EAAQ,WAAa,GAChC,KAAA,UAAYA,EAAQ,WAAa,8BAGtC,KAAK,2BAA6B,KAAK,2BAA2B,KAAK,IAAI,EAC3E,KAAK,iCAAmC,KAExC,KAAK,MAAQ,KACb,KAAK,SAAW,KAChB,KAAK,QAAU,KAGf,KAAK,WAAa,KAAK,WAAW,KAAK,IAAI,EAC3C,KAAK,kBAAoB,KAAK,kBAAkB,KAAK,IAAI,EACzD,KAAK,SAAW,KAAK,SAAS,KAAK,IAAI,EACvC,KAAK,aAAe,KAAK,aAAa,KAAK,IAAI,EAC/C,KAAK,YAAc,KAAK,YAAY,KAAK,IAAI,EAC7C,KAAK,UAAY,KAAK,UAAU,KAAK,IAAI,EAErCA,EAAQ,WAAa,IAEhB,KAAK,KAAK,CACnB,CAIM,aACV,CACI,GAAI,MAAK,UAKT,IAAI,KAAK,WACT,CAEI,IAAMC,EAAYC,GAAO,OAAO,UAAY,KAAK,SAAS,aAE1D,KAAK,gBAAkB,KAAK,MAAM,KAAK,gBAAkBD,CAAS,CAAA,EAGlE,CAAC,KAAK,YAAc,KAAK,iBAAmB,KAEvC,KAAA,gBAAkB,KAAK,WAAa,KAAK,MAAM,IAAO,KAAK,UAAU,EAAI,GAG9E,KAAK,SAEL,KAAK,OAAO,EAChB,CAII,4BACR,CACI,KAAK,YAAY,EAEb,KAAK,UAEL,KAAK,iCAAmC,KAInC,KAAA,iCAAmC,KAAK,SAAS,0BAClD,KAAK,0BAAA,CAEb,CAOJ,IAAW,SACX,CACW,MAAA,CAAC,CAAC,KAAK,SAAS,YAAc,CAAC,CAAC,KAAK,SAAS,WAAA,CAOzD,MAAa,MACb,CACI,GAAI,KAAK,MAEL,OAAO,KAAK,MAGhB,IAAME,EAAS,KAAK,SACdH,EAAU,KAAK,QAGhB,OAAAG,EAAO,aAAeA,EAAO,kBAAoBA,EAAO,aAAeA,EAAO,mBAC5EA,EAAO,OAASA,EAAO,SAEzBA,EAAe,SAAW,IAIxBA,EAAA,iBAAiB,OAAQ,KAAK,YAAY,EAC1CA,EAAA,iBAAiB,QAAS,KAAK,WAAW,EAC1CA,EAAA,iBAAiB,SAAU,KAAK,SAAS,EAG3C,KAAK,eAAA,EAaN,KAAK,YAAY,GAXZH,EAAQ,SAGFG,EAAA,iBAAiB,UAAW,KAAK,UAAU,EAE/CA,EAAA,iBAAiB,iBAAkB,KAAK,iBAAiB,EAChEA,EAAO,iBAAiB,QAAS,KAAK,SAAU,EAAI,GAQnD,KAAA,UAAY,MAAMC,GAAqB,EAG5C,KAAK,MAAQ,IAAI,QAAQ,CAACC,EAASC,IACnC,CACQ,KAAK,QAELD,EAAQ,IAAI,GAIZ,KAAK,SAAWA,EAChB,KAAK,QAAUC,EAEXN,EAAQ,mBAAqB,SAExB,KAAA,gBAAkB,WAAW,IAClC,CACI,KAAK,SAAS,IAAI,WAAW,+BAA+BA,EAAQ,gBAAgB,IAAI,CAAC,CAAA,CAC5F,GAELG,EAAO,KAAK,EAChB,CACH,EAEM,KAAK,KAAA,CAOR,SAASI,EACjB,CACI,KAAK,SAAS,oBAAoB,QAAS,KAAK,SAAU,EAAI,EACzD,KAAA,KAAK,QAASA,CAAK,EAEpB,KAAK,UAEL,KAAK,QAAQA,CAAK,EAClB,KAAK,QAAU,KACf,KAAK,SAAW,KACpB,CAOI,kBACR,CACI,IAAMJ,EAAS,KAAK,SAEpB,MAAQ,CAACA,EAAO,QAAU,CAACA,EAAO,KAAA,CAO9B,gBACR,CAGI,OAFe,KAAK,SAEN,WAAa,CAAA,CAIvB,cACR,CAES,KAAK,SAEN,KAAK,YAAY,EAGrB,KAAK,qBAAqB,CAAA,CAItB,aACR,CACI,KAAK,qBAAqB,CAAA,CAItB,WACR,CACQ,KAAK,aAAe,CAAC,KAAK,iBAAA,IAE1B,KAAK,gBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,gBAAkB,EAC3B,CAGI,YACR,CACmB,KAAK,SAGb,oBAAoB,UAAW,KAAK,UAAU,EAErD,KAAK,YAAY,CAAA,CAGb,mBACR,CACmB,KAAK,SAGb,oBAAoB,iBAAkB,KAAK,UAAU,EAExD,KAAK,kBAEL,aAAa,KAAK,eAAe,EACjC,KAAK,gBAAkB,QAG3B,KAAK,YAAY,CAAA,CAIb,aACR,CACI,IAAMA,EAAS,KAAK,SAEhB,KAAK,UAEL,KAAK,QAAU,GACf,KAAK,OAAOA,EAAO,WAAYA,EAAO,WAAW,GAIrD,KAAK,gBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,gBAAkB,EAGnB,KAAK,WAEL,KAAK,SAAS,IAAI,EAClB,KAAK,SAAW,KAChB,KAAK,QAAU,MAIf,KAAK,iBAAA,EAEL,KAAK,aAAa,EAEb,KAAK,UAEL,KAAK,SAAS,KAAK,CAC5B,CAIG,SACP,CACI,KAAK,qBAAqB,EAE1B,IAAMA,EAAS,KAAK,SAEhBA,IAGOA,EAAA,oBAAoB,OAAQ,KAAK,YAAY,EAC7CA,EAAA,oBAAoB,QAAS,KAAK,WAAW,EAC7CA,EAAA,oBAAoB,SAAU,KAAK,SAAS,EAC5CA,EAAA,oBAAoB,UAAW,KAAK,UAAU,EAC9CA,EAAA,oBAAoB,iBAAkB,KAAK,iBAAiB,EACnEA,EAAO,oBAAoB,QAAS,KAAK,SAAU,EAAI,EAGvDA,EAAO,MAAM,EACbA,EAAO,IAAM,GACbA,EAAO,KAAK,GAGhB,MAAM,QAAQ,CAAA,CAIlB,IAAI,YACJ,CACI,OAAO,KAAK,WAAA,CAGhB,IAAI,WAAWK,EACf,CACQA,IAAU,KAAK,cAEf,KAAK,YAAcA,EACnB,KAAK,qBAAqB,EAC9B,CAQJ,IAAI,WACJ,CACI,OAAO,KAAK,UAAA,CAGhB,IAAI,UAAUA,EACd,CACQA,IAAU,KAAK,aAEf,KAAK,WAAaA,EAClB,KAAK,qBAAqB,EAC9B,CAeI,sBACR,CAEQ,KAAK,aAAe,KAAK,iBAAA,EAGrB,CAAC,KAAK,YAAc,KAAK,SAAS,2BAG9B,KAAK,uBAELN,GAAO,OAAO,OAAO,KAAK,YAAa,IAAI,EAC3C,KAAK,qBAAuB,GAE5B,KAAK,gBAAkB,GAIvB,KAAK,mCAAqC,OAErC,KAAA,iCAAmC,KAAK,SAAS,0BAClD,KAAK,0BAAA,KAOT,KAAK,mCAAqC,OAErC,KAAA,SAAS,yBAAyB,KAAK,gCAAgC,EAC5E,KAAK,iCAAmC,MAIvC,KAAK,uBAENA,GAAO,OAAO,IAAI,KAAK,YAAa,IAAI,EACxC,KAAK,qBAAuB,GAE5B,KAAK,gBAAkB,KAS3B,KAAK,mCAAqC,OAErC,KAAA,SAAS,yBAAyB,KAAK,gCAAgC,EAC5E,KAAK,iCAAmC,MAIxC,KAAK,uBAELA,GAAO,OAAO,OAAO,KAAK,YAAa,IAAI,EAC3C,KAAK,qBAAuB,GAE5B,KAAK,gBAAkB,GAE/B,CAcJ,OAAc,KAAKO,EACnB,CACY,OAAA,WAAW,kBAAoBA,aAAoB,gBAAA,CAEnE,EAngBaX,GAEK,UAA+BY,EAAc,cAFlDZ,GAKK,eAAqC,CAC/C,GAAGC,GAAc,eAEjB,SAAU,GAEV,SAAU,GAEV,UAAW,EAEX,YAAa,GAEb,KAAM,GAEN,MAAO,GAEP,YAAa,GAEb,QAAS,EACb,EAvBSD,GAwfK,WACR,CACE,IAAK,YACL,IAAK,kBACL,IAAK,WACT,EA7fD,IAAMa,GAANb,GCpDP,IAAMc,GAAN,KACA,CADA,aAAA,CAEI,KAAiB,SAA0B,CAAA,EAE1B,KAAA,OAAA,IAA4B,IAC5B,KAAA,UAAA,IAGR,GAAI,CAGN,OACP,CACI,KAAK,UAAU,MAAM,EACrB,KAAK,OAAO,MAAM,CAAA,CAOf,IAAIC,EACX,CACW,OAAA,KAAK,OAAO,IAAIA,CAAG,CAAA,CAOvB,IAAaA,EACpB,CACI,IAAMC,EAAS,KAAK,OAAO,IAAID,CAAG,EAElC,OAAKC,GAGIC,EAAA,qBAAqBF,CAAG,6BAA6B,EAIvDC,CAAA,CAQJ,IAAaD,EAAkBG,EACtC,CACU,IAAAC,EAAOC,GAAsBL,CAAG,EAElCM,EAEJ,QAASC,EAAI,EAAGA,EAAI,KAAK,QAAQ,OAAQA,IACzC,CACU,IAAAC,EAAS,KAAK,QAAQD,CAAC,EAEzB,GAAAC,EAAO,KAAKL,CAAK,EACrB,CACsBG,EAAAE,EAAO,mBAAmBJ,EAAMD,CAAK,EAEvD,KAAA,CACJ,CAIE,IAAAM,EAAe,IAAI,IAAI,OAAO,QAAQH,GAAmB,CAAA,CAAE,CAAC,EAE7DA,GAEIF,EAAA,QAASJ,GACd,CACiBS,EAAA,IAAIT,EAAKG,CAAK,CAAA,CAC9B,EAGL,IAAMO,EAAY,CAAC,GAAGD,EAAa,KAAA,CAAM,EAEnCE,EAAe,CACjB,UAAAD,EACA,KAAAN,CAAA,EAICA,EAAA,QAASJ,GACd,CACS,KAAA,UAAU,IAAIA,EAAKW,CAAmB,CAAA,CAC9C,EAESD,EAAA,QAASV,GACnB,CACI,IAAMY,EAAMN,EAAkBA,EAAgBN,CAAG,EAAIG,EAEjD,KAAK,OAAO,IAAIH,CAAG,GAAK,KAAK,OAAO,IAAIA,CAAG,IAAMY,GAGjDV,EAAK,2BAA4BF,CAAG,EAIxC,KAAK,OAAO,IAAIA,EAAKS,EAAa,IAAIT,CAAG,CAAC,CAAA,CAC7C,CAAA,CASE,OAAOA,EACd,CACI,GAAI,CAAC,KAAK,UAAU,IAAIA,CAAG,EAC3B,CAESE,EAAA,qBAAqBF,CAAG,6BAA6B,EAG1D,MAAA,CAGJ,IAAMa,EAAW,KAAK,UAAU,IAAIb,CAAG,EAErBa,EAAS,UAEjB,QAASb,GACnB,CACS,KAAA,OAAO,OAAOA,CAAG,CAAA,CACzB,EAEQa,EAAA,KAAK,QAASb,GACvB,CACS,KAAA,UAAU,OAAOA,CAAG,CAAA,CAC5B,CAAA,CAOL,IAAW,SACX,CACI,OAAO,KAAK,QAAA,CAEpB,EAoDac,EAAQ,IAAIf,GCzLzB,IAAMgB,GAAsC,CAAA,EAE5CC,GAAW,aAAaC,EAAc,cAAeF,EAAO,EA8B5D,SAASG,GAAkBC,EAAoC,CAAA,EAC/D,CACU,IAAAC,EAAcD,GAAYA,EAAiC,SAC3DE,EAAMD,EAAeD,EAAiC,SAAWA,EACjEG,EAAOF,EAAcD,EAAkC,CAAE,SAAUA,CAAQ,EAEjF,QAASI,EAAI,EAAGA,EAAIC,GAAQ,OAAQD,IACpC,CACU,IAAAE,EAASD,GAAQD,CAAC,EAEpB,GAAAE,EAAO,KAAKJ,CAAG,EAER,OAAA,IAAII,EAAOH,CAAI,CAC1B,CAGJ,MAAM,IAAI,MAAM,8CAA8CA,EAAK,QAAQ,EAAE,CACjF,CAOO,SAASI,GACZP,EAAoC,CAAA,EACpCQ,EAAY,GAEhB,CACU,IAAAP,EAAcD,GAAYA,EAAiC,SAC3DS,EAAWR,EAAeD,EAAiC,SAAWA,EACtEG,EAAOF,EAAcD,EAAkC,CAAE,SAAUA,CAAQ,EAEjF,GAAI,CAACQ,GAAaE,EAAM,IAAID,CAAQ,EAEzB,OAAAC,EAAM,IAAID,CAAQ,EAGvB,IAAAE,EAAU,IAAIC,EAAQ,CAAE,OAAQb,GAAkBI,CAAI,CAAA,CAAG,EAEvD,OAAAQ,EAAA,GAAG,UAAW,IACtB,CACQD,EAAM,IAAID,CAAQ,GAElBC,EAAM,OAAOD,CAAQ,CACzB,CACH,EAEID,GAEKE,EAAA,IAAID,EAAUE,CAAO,EAGxBA,CACX,CAWgB,SAAAE,GAAYC,EAAuBN,EAAY,GAC/D,CACQ,OAAA,OAAOM,GAAO,SAEPJ,EAAM,IAAII,CAAE,EAEdA,aAAcC,GAEZ,IAAIH,EAAQ,CAAE,OAAQE,CAAA,CAAI,EAI9BP,GAAkBO,EAAIN,CAAS,CAC1C,CAEAI,EAAQ,KAAOC,GACfE,GAAc,KAAOhB,GCzHrBiB,GAAW,IAAIC,GAAWC,GAAWC,GAAaC,GAAaC,GAAaC,GAAcC,EAAiB,EC4DpG,IAAMC,GAAN,KACP,CAyBI,OAAc,KAAKC,EACnB,CACW,OAAA,eAAe,KAAM,WACxB,CACI,aAAc,GACd,IAAIC,EACJ,CACe,WAAA,oBAAoB,SAAU,KAAK,WAAW,EACzD,KAAK,UAAYA,EACbA,IAEW,WAAA,iBAAiB,SAAU,KAAK,WAAW,EACtD,KAAK,OAAO,EAChB,EAEJ,KACA,CACI,OAAO,KAAK,SAAA,CAChB,CACJ,EAEJ,KAAK,YAAc,IACnB,CACS,KAAK,YAKV,KAAK,cAAc,EAGnB,KAAK,UAAY,sBAAsB,IAAM,KAAK,OAAA,CAAQ,EAAA,EAG9D,KAAK,cAAgB,IACrB,CACQ,KAAK,YAEL,qBAAqB,KAAK,SAAS,EACnC,KAAK,UAAY,KACrB,EAGJ,KAAK,OAAS,IACd,CACQ,GAAA,CAAC,KAAK,UAEN,OAIJ,KAAK,cAAc,EAEf,IAAAC,EACAC,EAGA,GAAA,KAAK,YAAc,WAAW,OAE9BD,EAAQ,WAAW,WACnBC,EAAS,WAAW,gBAIxB,CACI,GAAM,CAAE,YAAAC,EAAa,aAAAC,CAAa,EAAI,KAAK,UAEnCH,EAAAE,EACCD,EAAAE,CAAA,CAGR,KAAA,SAAS,OAAOH,EAAOC,CAAM,EAClC,KAAK,OAAO,CAAA,EAIhB,KAAK,UAAY,KACjB,KAAK,UAAY,KACZ,KAAA,SAAWH,EAAQ,UAAY,IAAA,CAOxC,OAAc,SACd,CACe,WAAA,oBAAoB,SAAU,KAAK,WAAW,EACzD,KAAK,cAAc,EACnB,KAAK,cAAgB,KACrB,KAAK,YAAc,KACnB,KAAK,SAAW,KAChB,KAAK,OAAS,IAAA,CAEtB,EAxHaD,GAGK,UAA+BO,EAAc,YCgExD,IAAMC,GAAN,KACP,CAkBI,OAAc,KAAKC,EACnB,CAEIA,EAAU,OAAO,OAAO,CACpB,UAAW,GACX,aAAc,EAAA,EACfA,CAAO,EAGH,OAAA,eAAe,KAAM,SACxB,CACI,aAAc,GACd,IAAIC,EACJ,CACQ,KAAK,SAEL,KAAK,QAAQ,OAAO,KAAK,OAAQ,IAAI,EAEzC,KAAK,QAAUA,EACXA,GAEAA,EAAO,IAAI,KAAK,OAAQ,KAAMC,GAAgB,GAAG,CACrD,EAEJ,KACA,CACI,OAAO,KAAK,OAAA,CAChB,CACJ,EAEJ,KAAK,KAAO,IACZ,CACI,KAAK,QAAQ,KAAK,CAAA,EAGtB,KAAK,MAAQ,IACb,CACI,KAAK,QAAQ,MAAM,CAAA,EAGvB,KAAK,QAAU,KACf,KAAK,OAASF,EAAQ,aAAeG,GAAO,OAAS,IAAIA,GAGrDH,EAAQ,WAER,KAAK,MAAM,CACf,CAOJ,OAAc,SACd,CACI,GAAI,KAAK,QACT,CACI,IAAMI,EAAY,KAAK,QAEvB,KAAK,OAAS,KACdA,EAAU,QAAQ,CAAA,CACtB,CAER,EAnFaL,GAGK,UAA+BM,EAAc,YC9H/C,SAAAC,GACZC,EACAC,EACAC,EAEAC,EACAC,EACAC,EAEAC,EACAC,EAAiB,KAErB,CACI,IAAIC,EAAQ,EAEMN,GAAAD,EACLG,GAAAC,EAEb,IAAMI,EAAIF,EAAO,EACXG,EAAIH,EAAO,EACXI,EAAIJ,EAAO,EACXK,EAAIL,EAAO,EACXM,EAAKN,EAAO,GACZO,EAAKP,EAAO,GAElB,KAAOC,EAAQF,GACf,CACU,IAAAS,EAAIf,EAASE,CAAc,EAC3Bc,EAAIhB,EAASE,EAAiB,CAAC,EAErCC,EAAIC,CAAS,EAAKK,EAAIM,EAAMJ,EAAIK,EAAKH,EACrCV,EAAIC,EAAY,CAAC,EAAKM,EAAIK,EAAMH,EAAII,EAAKF,EAE5BV,GAAAC,EAEKH,GAAAD,EAElBO,GAAA,CAER,CAQO,SAASS,GACZd,EACAC,EACAC,EACAC,EAEJ,CACI,IAAIE,EAAQ,EAIZ,IAFaJ,GAAAC,EAENG,EAAQF,GAEXH,EAAIC,CAAS,EAAI,EACbD,EAAAC,EAAY,CAAC,EAAI,EAERA,GAAAC,EAEbG,GAER,CCtEO,SAASU,GAAkBC,EAAoBC,EAAWC,EAAiBC,EAAiBC,EACnG,CACI,IAAMC,EAAIJ,EAAE,EACNK,EAAIL,EAAE,EACNM,EAAIN,EAAE,EACNO,EAAIP,EAAE,EACNQ,EAAKR,EAAE,GACPS,EAAKT,EAAE,GAEFC,IAAAA,EAAA,GACAC,IAAAA,EAAA,GACDC,IAAAA,EAAAJ,EAAS,OAASG,EAAUD,GAEtC,IAAIS,EAAQT,EAASC,EAErB,QAASS,EAAI,EAAGA,EAAIR,EAAMQ,IAC1B,CACU,IAAAC,EAAIb,EAASW,CAAK,EAClBG,EAAId,EAASW,EAAQ,CAAC,EAE5BX,EAASW,CAAK,EAAKN,EAAIQ,EAAMN,EAAIO,EAAKL,EACtCT,EAASW,EAAQ,CAAC,EAAKL,EAAIO,EAAML,EAAIM,EAAKJ,EAEjCC,GAAAR,CAAA,CAEjB,CC5BA,IAAMY,GAAiB,IAAIC,EAMdC,GAAN,KACP,CADO,aAAA,CAEH,KAAgB,WAAa,GAC7B,KAAO,YAAc,UAIrB,KAAO,SAAqB,gBAQ5B,KAAO,eAAiB,GACxB,KAAO,YAAqB,EAK5B,KAAO,SAAoB,KAC3B,KAAO,OAAgB,IAAA,CAIvB,IAAI,KACJ,CACI,OAAO,KAAK,aAAa,GAAA,CAG7B,IAAI,WACJ,CACI,OAAO,KAAK,aAAa,QAAA,CAG7B,IAAI,SACJ,CACI,OAAO,KAAK,aAAa,OAAA,CAG7B,IAAI,WACJ,CACQ,OAAA,KAAK,YAAc,KAAK,eAEjB,KAAK,WAAW,eAGpB,QAAA,CAGX,IAAI,OACJ,CACI,IAAMC,EAAM,KAAK,UACXC,EAAOD,GAAO,GAAOA,EAAM,OAAYA,EAAM,MAAS,GACtDE,EAAa,KAAK,WAExB,OAAIA,EAEOC,GAAkBF,EAAKC,EAAW,UAAU,GAC/C,KAAK,MAAQA,EAAW,WAAa,KAAQ,IAG9CD,GAAQ,KAAK,MAAQ,KAAQ,GAAA,CAGxC,IAAI,WACJ,CACW,OAAA,KAAK,YAAY,gBAAkBJ,EAAA,CAGvC,OAAOO,EACd,CACIA,EAAU,YAAc,KAAK,YAC7BA,EAAU,UAAY,KAAK,UAE3BA,EAAU,gBAAkB,KAAK,gBACjCA,EAAU,cAAgB,KAAK,cAE/BA,EAAU,UAAY,KAAK,UAC3BA,EAAU,MAAQ,KAAK,MAEvBA,EAAU,QAAU,KAAK,QACzBA,EAAU,aAAe,KAAK,aAE9BA,EAAU,SAAW,KAAK,QAAA,CAGvB,OACP,CACI,KAAK,eAAiB,GACtB,KAAK,WAAa,KAClB,KAAK,SAAW,eAAA,CAGb,SACP,CACI,KAAK,WAAa,KAClB,KAAK,QAAU,KACf,KAAK,aAAe,KACpB,KAAK,SAAW,KAChB,KAAK,OAAS,IAAA,CAEtB,ECtGO,IAAMC,GAA+C,CACxD,UAAW,CACP,KAAMC,EAAc,aACpB,KAAM,QAAA,EAGV,MAAMC,EAAqBC,EAC3B,CACQ,IAAAC,EACAC,EACAC,EACAC,EAEAC,EACAC,EAEA,GAAAP,EAAM,OAAS,SACnB,CACI,IAAMQ,EAASR,EAGf,GADAM,EAAKC,EAAKC,EAAO,OACbF,GAAM,EAEC,MAAA,GAEXJ,EAAIM,EAAO,EACXL,EAAIK,EAAO,EACXJ,EAAKC,EAAK,CAAA,SAGLL,EAAM,OAAS,UACxB,CACI,IAAMS,EAAUT,EAIZ,GAFJM,EAAKG,EAAQ,UACbF,EAAKE,EAAQ,WACTH,GAAM,GAAKC,GAAM,EAEV,MAAA,GAEXL,EAAIO,EAAQ,EACZN,EAAIM,EAAQ,EACZL,EAAKC,EAAK,CAAA,KAGd,CACI,IAAMK,EAAcV,EACdW,EAAYD,EAAY,MAAQ,EAChCE,EAAaF,EAAY,OAAS,EAExCR,EAAIQ,EAAY,EAAIC,EACpBR,EAAIO,EAAY,EAAIE,EACpBN,EAAKC,EAAK,KAAK,IAAI,EAAG,KAAK,IAAIG,EAAY,OAAQ,KAAK,IAAIC,EAAWC,CAAU,CAAC,CAAC,EACnFR,EAAKO,EAAYL,EACjBD,EAAKO,EAAaL,CAAA,CAGlB,GAAAH,EAAK,GAAKC,EAAK,EAER,MAAA,GAIL,IAAAQ,EAAI,KAAK,KAAK,IAAM,KAAK,KAAKP,EAAKC,CAAE,CAAC,EACtCO,EAAKD,EAAI,GAAMT,EAAK,EAAI,IAAMC,EAAK,EAAI,GAE7C,GAAIS,IAAM,EAEC,MAAA,GAGX,GAAID,IAAM,EAEN,OAAAZ,EAAO,CAAC,EAAIA,EAAO,CAAC,EAAIC,EAAIE,EAC5BH,EAAO,CAAC,EAAIA,EAAO,CAAC,EAAIE,EAAIE,EAC5BJ,EAAO,CAAC,EAAIA,EAAO,CAAC,EAAIC,EAAIE,EAC5BH,EAAO,CAAC,EAAIA,EAAO,CAAC,EAAIE,EAAIE,EAErB,GAGX,IAAIU,EAAK,EACLC,EAAMH,EAAI,GAAMT,EAAK,EAAI,GAAK,EAC9Ba,EAAKD,EACLE,EAAKJ,EAELK,EAAKf,EAAKE,EACVc,EAAKf,EACLgB,EAAKnB,EAAIiB,EACTG,EAAKpB,EAAIiB,EACTI,EAAKpB,EAAIiB,EAOb,GALAnB,EAAOc,GAAI,EAAIM,EACfpB,EAAOc,GAAI,EAAIQ,EACRtB,EAAA,EAAEe,CAAE,EAAIO,EACRtB,EAAA,EAAEe,CAAE,EAAIM,EAEXjB,EACJ,CACI,IAAMmB,EAAKrB,EAAIiB,EAEfnB,EAAOgB,GAAI,EAAIK,EACfrB,EAAOgB,GAAI,EAAIO,EACRvB,EAAA,EAAEiB,CAAE,EAAIM,EACRvB,EAAA,EAAEiB,CAAE,EAAIG,CAAA,CAGnB,QAASI,EAAI,EAAGA,EAAIZ,EAAGY,IACvB,CACI,IAAMC,EAAI,KAAK,GAAK,GAAKD,EAAIZ,GACvBM,EAAKf,EAAM,KAAK,IAAIsB,CAAC,EAAIpB,EACzBc,EAAKf,EAAM,KAAK,IAAIqB,CAAC,EAAInB,EACzBc,EAAKnB,EAAIiB,EACTG,EAAKpB,EAAIiB,EACTI,EAAKpB,EAAIiB,EACTI,EAAKrB,EAAIiB,EAEfnB,EAAOc,GAAI,EAAIM,EACfpB,EAAOc,GAAI,EAAIQ,EACRtB,EAAA,EAAEe,CAAE,EAAIO,EACRtB,EAAA,EAAEe,CAAE,EAAIM,EACfrB,EAAOgB,GAAI,EAAIK,EACfrB,EAAOgB,GAAI,EAAIO,EACRvB,EAAA,EAAEiB,CAAE,EAAIM,EACRvB,EAAA,EAAEiB,CAAE,EAAIG,CAAA,CAGdF,EAAAf,EACLgB,EAAKf,EAAKE,EACVc,EAAKnB,EAAIiB,EACTG,EAAKpB,EAAIiB,EACTI,EAAKpB,EAAIiB,EACT,IAAMI,EAAKrB,EAAIiB,EAEf,OAAAnB,EAAOc,GAAI,EAAIM,EACfpB,EAAOc,GAAI,EAAIQ,EACRtB,EAAA,EAAEiB,CAAE,EAAIM,EACRvB,EAAA,EAAEiB,CAAE,EAAIG,EAEXjB,IAEAH,EAAOc,GAAI,EAAIO,EACfrB,EAAOc,GAAI,EAAIQ,EACRtB,EAAA,EAAEiB,CAAE,EAAIM,EACRvB,EAAA,EAAEiB,CAAE,EAAII,GAGZ,EAAA,EAGX,YAAYrB,EAAQ0B,EAAUC,EAAgBC,EAAgBC,EAASC,EACvE,CACQ,GAAA9B,EAAO,SAAW,EAElB,OAIJ,IAAI+B,EAAU,EACVC,EAAU,EAEd,QAASR,EAAI,EAAGA,EAAIxB,EAAO,OAAQwB,GAAK,EAEpCO,GAAW/B,EAAOwB,CAAC,EACRQ,GAAAhC,EAAOwB,EAAI,CAAC,EAE3BO,GAAY/B,EAAO,OAAS,EAC5BgC,GAAYhC,EAAO,OAAS,EAG5B,IAAIiC,EAAQL,EAEHF,EAAAO,EAAQN,CAAc,EAAII,EACzBL,EAAAO,EAAQN,EAAkB,CAAC,EAAIK,EACzC,IAAME,EAAcD,IAGpB,QAAST,EAAI,EAAGA,EAAIxB,EAAO,OAAQwB,GAAK,EAEpCE,EAASO,EAAQN,CAAc,EAAI3B,EAAOwB,CAAC,EAC3CE,EAAUO,EAAQN,EAAkB,CAAC,EAAI3B,EAAOwB,EAAI,CAAC,EAEjDA,EAAI,IAEJK,EAAQC,GAAe,EAAIG,EAC3BJ,EAAQC,GAAe,EAAII,EACnBL,EAAAC,GAAe,EAAIG,EAAQ,GAEvCA,IAIIJ,EAAAC,GAAe,EAAII,EAAc,EACzCL,EAAQC,GAAe,EAAII,EACnBL,EAAAC,GAAe,EAAIG,EAAQ,CAAA,CAG3C,EAGaE,GAAe,CAAE,GAAGtC,GAAa,UAAW,CAAE,GAAGA,GAAY,UAAW,KAAM,SAAA,CAAY,EAE1FuC,GAAwB,CAAE,GAAGvC,GAAa,UAAW,CAAE,GAAGA,GAAY,UAAW,KAAM,kBAAA,CAAqB,ECtNlH,SAASwC,GAAuBC,EACvC,CACI,IAAMC,EAAID,EAAO,OAEjB,GAAIC,EAAI,EAEG,MAAA,GAGX,IAAIC,EAAO,EAEX,QAASC,EAAI,EAAGC,EAAKJ,EAAOC,EAAI,CAAC,EAAGI,EAAKL,EAAOC,EAAI,CAAC,EAAGE,EAAIF,EAAGE,GAAK,EACpE,CACU,IAAAG,EAAKN,EAAOG,CAAC,EACbI,EAAKP,EAAOG,EAAI,CAAC,EAEdD,IAAAI,EAAKF,IAAOG,EAAKF,GAErBD,EAAAE,EACAD,EAAAE,CAAA,CAGT,OAAIL,EAAO,EAEA,GAGJ,CACX,CCVA,SAASM,GACLC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAEJ,CACU,IAAAC,EAAKR,EAAKE,EAAKE,EACfK,EAAKR,EAAKE,EAAKC,EACfM,EAAKV,EAAKE,EAAKG,EACfM,EAAKV,EAAKE,EAAKE,EAGjBO,EACAC,EAEAP,GAEMM,EAAAT,EACNU,EAAM,CAACX,IAIPU,EAAM,CAACT,EACDU,EAAAX,GAIV,IAAMY,EAAMN,EAAKI,EACXG,EAAMN,EAAKI,EACXG,EAAMN,EAAKE,EACXK,EAAMN,EAAKE,EAGX,OAAAN,EAAA,KAAKO,EAAKC,CAAG,EACbR,EAAA,KAAKS,EAAKC,CAAG,EAEZ,CACX,CAkBA,SAASC,GACLC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAjB,EACAD,EAEJ,CACI,IAAMmB,EAASJ,EAAKF,EACdO,EAASJ,EAAKF,EAEhBO,EAAS,KAAK,MAAMF,EAAQC,CAAM,EAClCE,EAAS,KAAK,MAAML,EAAKJ,EAAIK,EAAKJ,CAAE,EAEpCd,GAAaqB,EAASC,EAEtBD,GAAU,KAAK,GAAK,EAEf,CAACrB,GAAaqB,EAASC,IAE5BA,GAAU,KAAK,GAAK,GAGxB,IAAIC,EAAaF,EACXG,EAAYF,EAASD,EACrBI,EAAe,KAAK,IAAID,CAAS,EAEjCE,EAAS,KAAK,KAAMP,EAASA,EAAWC,EAASA,CAAO,EACxDO,GAAa,GAAKF,EAAe,KAAK,KAAKC,CAAM,EAAI,KAAK,IAAO,GAAK,EACtEE,EAAWJ,EAAYG,EAI7B,GAFcJ,GAAAK,EAEV5B,EACJ,CACUC,EAAA,KAAKY,EAAIC,CAAE,EACXb,EAAA,KAAKc,EAAIC,CAAE,EAER,QAAAa,EAAI,EAAGC,EAAQP,EAAYM,EAAIF,EAAUE,IAAKC,GAASF,EAEtD3B,EAAA,KAAKY,EAAIC,CAAE,EACXb,EAAA,KAAKY,EAAO,KAAK,IAAIiB,CAAK,EAAIJ,EAChCZ,EAAO,KAAK,IAAIgB,CAAK,EAAIJ,CAAA,EAG3BzB,EAAA,KAAKY,EAAIC,CAAE,EACXb,EAAA,KAAKgB,EAAIC,CAAE,CAAA,KAGrB,CACUjB,EAAA,KAAKc,EAAIC,CAAE,EACXf,EAAA,KAAKY,EAAIC,CAAE,EAER,QAAAe,EAAI,EAAGC,EAAQP,EAAYM,EAAIF,EAAUE,IAAKC,GAASF,EAEtD3B,EAAA,KAAKY,EAAO,KAAK,IAAIiB,CAAK,EAAIJ,EAChCZ,EAAO,KAAK,IAAIgB,CAAK,EAAIJ,CAAA,EACvBzB,EAAA,KAAKY,EAAIC,CAAE,EAGfb,EAAA,KAAKgB,EAAIC,CAAE,EACXjB,EAAA,KAAKY,EAAIC,CAAE,CAAA,CAGrB,OAAOa,EAAW,CACtB,CAYO,SAASI,GACZC,EACAC,EACAC,EACAC,EACAC,EACAC,EAEJ,CAGI,IAAMC,EAAM,KAER,GAAAN,EAAO,SAAW,EAElB,OAGJ,IAAMO,EAAQN,EAEVO,EAAYD,EAAM,UAElB,GAAAN,EAAU,YAAc,GAC5B,CAEQ,IAAAQ,EAAcC,GAAuBV,CAAM,EAE3CE,IAA6BO,GAAA,IAEnBD,GAAAA,EAAY,IAAOC,EAAe,EAAA,CAI9C,IAAAE,EAAa,IAAIC,GAAMZ,EAAO,CAAC,EAAGA,EAAO,CAAC,CAAC,EAC3Ca,EAAY,IAAID,GAAMZ,EAAOA,EAAO,OAAS,CAAC,EAAGA,EAAOA,EAAO,OAAS,CAAC,CAAC,EAC1Ec,EAAcX,EACdY,EAAa,KAAK,IAAIJ,EAAW,EAAIE,EAAU,CAAC,EAAIP,GACnD,KAAK,IAAIK,EAAW,EAAIE,EAAU,CAAC,EAAIP,EAG9C,GAAIQ,EACJ,CAEId,EAASA,EAAO,MAAM,EAElBe,IAEAf,EAAO,IAAI,EACXA,EAAO,IAAI,EACDa,EAAA,IAAIb,EAAOA,EAAO,OAAS,CAAC,EAAGA,EAAOA,EAAO,OAAS,CAAC,CAAC,GAGtE,IAAMgB,GAAaL,EAAW,EAAIE,EAAU,GAAK,GAC3CI,IAAaJ,EAAU,EAAIF,EAAW,GAAK,GAE1CX,EAAA,QAAQgB,EAAWC,EAAS,EAC5BjB,EAAA,KAAKgB,EAAWC,EAAS,CAAA,CAGpC,IAAMhD,EAAQmC,EAERc,EAASlB,EAAO,OAAS,EAC3BmB,EAAanB,EAAO,OAClBoB,EAAanD,EAAM,OAAS,EAG5BoD,EAAQd,EAAM,MAAQ,EACtBe,EAAeD,EAAQA,EACvBE,EAAoBhB,EAAM,WAAaA,EAAM,WAG/CiB,EAAKxB,EAAO,CAAC,EACbyB,EAAKzB,EAAO,CAAC,EACb0B,EAAK1B,EAAO,CAAC,EACb2B,EAAK3B,EAAO,CAAC,EACb4B,EAAK,EACLC,EAAK,EAGLC,EAAQ,EAAEL,EAAKE,GACfI,EAAQP,EAAKE,EACbM,EAAS,EACTC,EAAS,EAETC,EAAO,KAAK,KAAMJ,EAAQA,EAAUC,EAAQA,CAAM,EAE7CD,GAAAI,EACAH,GAAAG,EACAJ,GAAAT,EACAU,GAAAV,EAET,IAAMc,GAAQ3B,EACR1C,GAAe,EAAIqE,IAAS,EAC5BpE,EAAcoE,GAAQ,EAEvBrB,IAEGP,EAAM,MAAQ,QAEAY,GAAAvC,GACV4C,EAAMM,GAAShE,EAAcC,GAAe,GAC5C0D,EAAMM,GAASjE,EAAcC,GAAe,GAC5CyD,EAAMM,EAAQhE,EACd2D,EAAMM,EAAQjE,EACd0D,EAAMM,EAAQ/D,EACd0D,EAAMM,EAAQhE,EACdE,EACA,EAAA,EACA,EAECsC,EAAM,MAAQ,WAELY,GAAA1D,GAAO+D,EAAIC,EAAIK,EAAOC,EAAOjE,EAAaC,EAAa,GAAME,CAAK,IAKlFA,EAAA,KACFuD,EAAMM,EAAQhE,EACd2D,EAAMM,EAAQjE,CAAA,EACZG,EAAA,KACFuD,EAAMM,EAAQ/D,EACd0D,EAAMM,EAAQhE,CAAA,EAElB,QAAS8B,EAAI,EAAGA,EAAIqB,EAAS,EAAG,EAAErB,EAClC,CACS2B,EAAAxB,GAAQH,EAAI,GAAK,CAAC,EACvB4B,EAAKzB,GAASH,EAAI,GAAK,EAAK,CAAC,EAExB6B,EAAA1B,EAAOH,EAAI,CAAC,EACZ8B,EAAA3B,EAAQH,EAAI,EAAK,CAAC,EAElB+B,EAAA5B,GAAQH,EAAI,GAAK,CAAC,EACvBgC,EAAK7B,GAASH,EAAI,GAAK,EAAK,CAAC,EAE7BiC,EAAQ,EAAEL,EAAKE,GACfI,EAAQP,EAAKE,EAEbQ,EAAO,KAAK,KAAMJ,EAAQA,EAAUC,EAAQA,CAAM,EACzCD,GAAAI,EACAH,GAAAG,EACAJ,GAAAT,EACAU,GAAAV,EAETW,EAAS,EAAEL,EAAKE,GAChBI,EAASP,EAAKE,EAEdM,EAAO,KAAK,KAAMF,EAASA,EAAWC,EAASA,CAAO,EAC5CD,GAAAE,EACAD,GAAAC,EACAF,GAAAX,EACAY,GAAAZ,EAGV,IAAMe,GAAMV,EAAKF,EACXa,GAAMZ,EAAKE,EACXW,GAAMZ,EAAKE,EACXW,GAAMV,EAAKF,EAGXa,GAAOJ,GAAME,GAAQD,GAAME,GAE3BE,GAASJ,GAAMC,GAAQC,GAAMH,GAC7BpE,GAAayE,GAAQ,EAIvB,GAAA,KAAK,IAAIA,EAAK,EAAI,KAAQ,KAAK,IAAID,EAAG,EAC1C,CACUvE,EAAA,KACFyD,EAAMI,EAAQhE,EACd6D,EAAMI,EAAQjE,CAAA,EACZG,EAAA,KACFyD,EAAMI,EAAQ/D,EACd4D,EAAMI,EAAQhE,CAAA,EAGdyE,IAAO,IAEHjC,EAAM,OAAS,QAEDY,GAAAvC,GACV8C,EAAIC,EACJD,EAAMI,EAAQhE,EAAc6D,EAAMI,EAAQjE,EAC1C4D,EAAMM,EAASlE,EAAc6D,EAAMM,EAASnE,EAC5CG,EAAO,EAAA,EAAS,EAINkD,GAAA,EAGZlD,EAAA,KACFyD,EAAMM,EAASjE,EACf4D,EAAMM,EAASlE,CAAA,EACbE,EAAA,KACFyD,EAAMM,EAASlE,EACf6D,EAAMM,EAASnE,CAAA,GAGvB,QAAA,CAIE,IAAA4E,IAAO,CAACZ,EAAQN,IAAO,CAACO,EAAQJ,IAAS,CAACG,EAAQJ,IAAO,CAACK,EAAQN,GAClEkB,IAAO,CAACX,EAASJ,IAAO,CAACK,EAASN,IAAS,CAACK,EAASN,IAAO,CAACO,EAASJ,GACtEe,IAAOR,GAAMO,GAAOL,GAAMI,IAAOD,GACjCI,IAAON,GAAMG,GAAOL,GAAMM,IAAOF,GACjCK,IAAUF,GAAKlB,IAAOkB,GAAKlB,IAASmB,GAAKlB,IAAOkB,GAAKlB,GAGrDoB,GAAMrB,GAAOkB,GAAKlB,GAAM5D,EACxBkF,GAAMrB,GAAOkB,GAAKlB,GAAM7D,EAExBmF,GAAMvB,GAAOkB,GAAKlB,GAAM3D,EACxBmF,GAAMvB,GAAOkB,GAAKlB,GAAM5D,EAGxBoF,GAAyB,KAAK,IAAKf,GAAMA,GAAQC,GAAMA,GAAOC,GAAMA,GAAQC,GAAMA,EAAI,EACtFa,GAAepF,GAAYF,EAAcC,EACzCsF,GAA0BF,GAA0BC,GAAeA,GAAe9B,EAClEwB,IAASO,GAIvB9C,EAAM,OAAS,SAAWuC,GAAQxB,EAAeC,GAE7CvD,IAEMC,EAAA,KAAK8E,GAAKC,EAAG,EACnB/E,EAAM,KAAKyD,EAAMI,EAAQ/D,EAAc4D,EAAMI,EAAQhE,CAAY,EAC3DE,EAAA,KAAK8E,GAAKC,EAAG,EACnB/E,EAAM,KAAKyD,EAAMM,EAASjE,EAAc4D,EAAMM,EAASlE,CAAY,IAInEE,EAAM,KAAKyD,EAAMI,EAAQhE,EAAc6D,EAAMI,EAAQjE,CAAY,EAC3DG,EAAA,KAAKgF,GAAKC,EAAG,EACnBjF,EAAM,KAAKyD,EAAMM,EAASlE,EAAc6D,EAAMM,EAASnE,CAAY,EAC7DG,EAAA,KAAKgF,GAAKC,EAAG,GAGT/B,GAAA,GAETZ,EAAM,OAAS,QAEhBvC,IAEMC,EAAA,KAAK8E,GAAKC,EAAG,EACnB/E,EAAM,KAAKyD,EAAMI,EAAQ/D,EAAc4D,EAAMI,EAAQhE,CAAY,EAEnDoD,GAAAvC,GACV8C,EAAIC,EACJD,EAAMI,EAAQ/D,EAAc4D,EAAMI,EAAQhE,EAC1C2D,EAAMM,EAASjE,EAAc4D,EAAMM,EAASlE,EAC5CE,EAAO,EAAA,EACP,EAEEA,EAAA,KAAK8E,GAAKC,EAAG,EACnB/E,EAAM,KAAKyD,EAAMM,EAASjE,EAAc4D,EAAMM,EAASlE,CAAY,IAInEE,EAAM,KAAKyD,EAAMI,EAAQhE,EAAc6D,EAAMI,EAAQjE,CAAY,EAC3DG,EAAA,KAAKgF,GAAKC,EAAG,EAEL/B,GAAAvC,GACV8C,EAAIC,EACJD,EAAMI,EAAQhE,EAAc6D,EAAMI,EAAQjE,EAC1C4D,EAAMM,EAASlE,EAAc6D,EAAMM,EAASnE,EAC5CG,EAAO,EAAA,EACP,EAEJA,EAAM,KAAKyD,EAAMM,EAASlE,EAAc6D,EAAMM,EAASnE,CAAY,EAC7DG,EAAA,KAAKgF,GAAKC,EAAG,IAKjBjF,EAAA,KAAK8E,GAAKC,EAAG,EACb/E,EAAA,KAAKgF,GAAKC,EAAG,IAKvBjF,EAAM,KAAKyD,EAAMI,EAAQhE,EAAc6D,EAAMI,EAAQjE,CAAY,EACjEG,EAAM,KAAKyD,EAAMI,EAAQ/D,EAAc4D,EAAMI,EAAQhE,CAAY,EAC7DwC,EAAM,OAAS,QAEXvC,GAEcmD,GAAAvC,GACV8C,EAAIC,EACJD,EAAMI,EAAQ/D,EAAc4D,EAAMI,EAAQhE,EAC1C2D,EAAMM,EAASjE,EAAc4D,EAAMM,EAASlE,EAC5CE,EAAO,EAAA,EACP,EAIUkD,GAAAvC,GACV8C,EAAIC,EACJD,EAAMI,EAAQhE,EAAc6D,EAAMI,EAAQjE,EAC1C4D,EAAMM,EAASlE,EAAc6D,EAAMM,EAASnE,EAC5CG,EAAO,EAAA,EACP,EAGHsC,EAAM,OAAS,SAAWuC,GAAQxB,GAAgBC,IAEnDvD,IAEMC,EAAA,KAAKgF,GAAKC,EAAG,EACbjF,EAAA,KAAKgF,GAAKC,EAAG,IAIbjF,EAAA,KAAK8E,GAAKC,EAAG,EACb/E,EAAA,KAAK8E,GAAKC,EAAG,GAET7B,GAAA,GAElBlD,EAAM,KAAKyD,EAAMM,EAASlE,EAAc6D,EAAMM,EAASnE,CAAY,EACnEG,EAAM,KAAKyD,EAAMM,EAASjE,EAAc4D,EAAMM,EAASlE,CAAY,EACrDoD,GAAA,EAClB,CAGCK,EAAAxB,GAAQkB,EAAS,GAAK,CAAC,EAC5BO,EAAKzB,GAASkB,EAAS,GAAK,EAAK,CAAC,EAE7BQ,EAAA1B,GAAQkB,EAAS,GAAK,CAAC,EAC5BS,EAAK3B,GAASkB,EAAS,GAAK,EAAK,CAAC,EAElCY,EAAQ,EAAEL,EAAKE,GACfI,EAAQP,EAAKE,EAEbQ,EAAO,KAAK,KAAMJ,EAAQA,EAAUC,EAAQA,CAAM,EACzCD,GAAAI,EACAH,GAAAG,EACAJ,GAAAT,EACAU,GAAAV,EAETpD,EAAM,KAAKyD,EAAMI,EAAQhE,EAAc6D,EAAMI,EAAQjE,CAAY,EACjEG,EAAM,KAAKyD,EAAMI,EAAQ/D,EAAc4D,EAAMI,EAAQhE,CAAY,EAE5D+C,IAEGP,EAAM,MAAQ,QAEAY,GAAAvC,GACV8C,EAAMI,GAAShE,EAAcC,GAAe,GAC5C4D,EAAMI,GAASjE,EAAcC,GAAe,GAC5C2D,EAAMI,EAAQhE,EACd6D,EAAMI,EAAQjE,EACd4D,EAAMI,EAAQ/D,EACd4D,EAAMI,EAAQhE,EACdE,EACA,EAAA,EACA,EAECsC,EAAM,MAAQ,WAELY,GAAA1D,GAAOiE,EAAIC,EAAIG,EAAOC,EAAOjE,EAAaC,EAAa,GAAOE,CAAK,IAKzF,IAAMqF,GAAO,KAAW,KAGxB,QAASzD,EAAIuB,EAAYvB,EAAIsB,EAAaC,EAAa,EAAG,EAAEvB,EAEnD2B,EAAAvD,EAAO4B,EAAI,CAAE,EACb4B,EAAAxD,EAAO4B,EAAI,EAAK,CAAC,EAEjB6B,EAAAzD,GAAO4B,EAAI,GAAK,CAAC,EACtB8B,EAAK1D,GAAQ4B,EAAI,GAAK,EAAK,CAAC,EAEvB+B,EAAA3D,GAAO4B,EAAI,GAAK,CAAC,EACtBgC,EAAK5D,GAAQ4B,EAAI,GAAK,EAAK,CAAC,EAGxB,OAAK,IAAK2B,GAAMG,EAAKE,GAAQH,GAAMG,EAAKJ,GAAQG,GAAMH,EAAKE,EAAI,EAAI2B,KAKvEjD,EAAQ,KAAKR,EAAGA,EAAI,EAAGA,EAAI,CAAC,CAEpC,CC9hBO,SAAS0D,GACZC,EACAC,EACAC,EACAC,EAEJ,CACI,IAAMC,EAAM,KAER,GAAAJ,EAAO,SAAW,EAElB,OAKE,IAAAK,EAAKL,EAAO,CAAC,EACbM,EAAKN,EAAO,CAAC,EAEbO,EAAKP,EAAOA,EAAO,OAAS,CAAC,EAE7BQ,EAAKR,EAAOA,EAAO,OAAS,CAAC,EAE7BS,EAAYR,GAAW,KAAK,IAAII,EAAKE,CAAE,EAAIH,GAAO,KAAK,IAAIE,EAAKE,CAAE,EAAIJ,EAEtEM,EAAQR,EAERS,EAASX,EAAO,OAAS,EACzBY,EAAaF,EAAM,OAAS,EAElC,QAASG,EAAI,EAAGA,EAAIF,EAAQE,IAExBH,EAAM,KAAKV,EAAQa,EAAI,CAAE,CAAC,EAC1BH,EAAM,KAAKV,EAAQa,EAAI,EAAK,CAAC,CAAC,EAGlC,QAASA,EAAI,EAAGA,EAAIF,EAAS,EAAGE,IAE5BV,EAAQ,KAAKS,EAAaC,EAAGD,EAAaC,EAAI,CAAC,EAG/CJ,GAEAN,EAAQ,KAAKS,EAAaD,EAAS,EAAGC,CAAU,CAExD,CC3CO,SAASE,GACZC,EACAC,EACAC,EACAC,EACAC,EAEAC,EACAC,EAEJ,CACI,IAAMC,EAAYC,GAAOR,EAAQC,EAAO,CAAC,EAEzC,GAAI,CAACM,EAED,OAGJ,QAASE,EAAI,EAAGA,EAAIF,EAAU,OAAQE,GAAK,EAEvCJ,EAAQC,GAAe,EAAKC,EAAUE,CAAC,EAAIL,EAC3CC,EAAQC,GAAe,EAAKC,EAAUE,EAAI,CAAC,EAAIL,EAC/CC,EAAQC,GAAe,EAAKC,EAAUE,EAAI,CAAC,EAAIL,EAGnD,IAAIM,EAAQN,EAAiBD,EAE7B,QAASM,EAAI,EAAGA,EAAIT,EAAO,OAAQS,GAAK,EAE3BP,EAAAQ,CAAK,EAAIV,EAAOS,CAAC,EAC1BP,EAASQ,EAAQ,CAAC,EAAIV,EAAOS,EAAI,CAAC,EAEzBC,GAAAP,CAEjB,CCxCA,IAAMQ,GAAuB,CAAA,EAShBC,GAA2C,CACpD,UAAW,CACP,KAAMC,EAAc,aACpB,KAAM,SAAA,EAGV,MAAMC,EAAgBC,EACtB,CACI,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAO,OAAQE,IAErCD,EAAOC,CAAC,EAAIF,EAAM,OAAOE,CAAC,EAGvB,MAAA,EAAA,EAGX,YACID,EAEAE,EACAC,EACAC,EAEAC,EACAC,EAEJ,CACIC,GAAqBP,EAAQJ,GAAYM,EAAUC,EAAgBC,EAAgBC,EAASC,CAAa,CAAA,CAGjH,ECjCO,IAAME,GAA+C,CACxD,UAAW,CACP,KAAMC,EAAc,aACpB,KAAM,WAAA,EAGV,MAAMC,EAAkBC,EACxB,CACI,IAAMC,EAAWF,EACXG,EAAID,EAAS,EACbE,EAAIF,EAAS,EACbG,EAAQH,EAAS,MACjBI,EAASJ,EAAS,OAExB,OAAMG,EAAQ,GAAKC,EAAS,GAK5BL,EAAO,CAAC,EAAIE,EACZF,EAAO,CAAC,EAAIG,EACLH,EAAA,CAAC,EAAIE,EAAIE,EAChBJ,EAAO,CAAC,EAAIG,EACLH,EAAA,CAAC,EAAIE,EAAIE,EACTJ,EAAA,CAAC,EAAIG,EAAIE,EAChBL,EAAO,CAAC,EAAIE,EACLF,EAAA,CAAC,EAAIG,EAAIE,EAET,IAZI,EAYJ,EAGX,YACIL,EAEAM,EACAC,EACAC,EAEAC,EACAC,EAEJ,CACI,IAAIC,EAAQ,EAEMH,GAAAD,EAElBD,EAASE,EAAiBG,CAAK,EAAIX,EAAO,CAAC,EAC3CM,EAASE,EAAiBG,EAAQ,CAAC,EAAIX,EAAO,CAAC,EAEtCW,GAAAJ,EAETD,EAASE,EAAiBG,CAAK,EAAIX,EAAO,CAAC,EAC3CM,EAASE,EAAiBG,EAAQ,CAAC,EAAIX,EAAO,CAAC,EAEtCW,GAAAJ,EAETD,EAASE,EAAiBG,CAAK,EAAIX,EAAO,CAAC,EAC3CM,EAASE,EAAiBG,EAAQ,CAAC,EAAIX,EAAO,CAAC,EAEtCW,GAAAJ,EAETD,EAASE,EAAiBG,CAAK,EAAIX,EAAO,CAAC,EAC3CM,EAASE,EAAiBG,EAAQ,CAAC,EAAIX,EAAO,CAAC,EAEtCW,GAAAJ,EAET,IAAMK,EAAgBJ,EAAiBD,EAGvCE,EAAQC,GAAe,EAAIE,EACnBH,EAAAC,GAAe,EAAIE,EAAgB,EACnCH,EAAAC,GAAe,EAAIE,EAAgB,EAGnCH,EAAAC,GAAe,EAAIE,EAAgB,EACnCH,EAAAC,GAAe,EAAIE,EAAgB,EACnCH,EAAAC,GAAe,EAAIE,EAAgB,CAAA,CAEnD,EC9EO,IAAMC,GAA6C,CACtD,UAAW,CACP,KAAMC,EAAc,aACpB,KAAM,UAAA,EAGV,MAAMC,EAAiBC,EACvB,CACW,OAAAA,EAAA,CAAC,EAAID,EAAM,EACXC,EAAA,CAAC,EAAID,EAAM,EACXC,EAAA,CAAC,EAAID,EAAM,GACXC,EAAA,CAAC,EAAID,EAAM,GACXC,EAAA,CAAC,EAAID,EAAM,GACXC,EAAA,CAAC,EAAID,EAAM,GAEX,EAAA,EAGX,YACIC,EAEAC,EACAC,EACAC,EAEAC,EACAC,EAEJ,CACI,IAAIC,EAAQ,EAEMH,GAAAD,EAElBD,EAASE,EAAiBG,CAAK,EAAIN,EAAO,CAAC,EAC3CC,EAASE,EAAiBG,EAAQ,CAAC,EAAIN,EAAO,CAAC,EAEtCM,GAAAJ,EAETD,EAASE,EAAiBG,CAAK,EAAIN,EAAO,CAAC,EAC3CC,EAASE,EAAiBG,EAAQ,CAAC,EAAIN,EAAO,CAAC,EAEtCM,GAAAJ,EAETD,EAASE,EAAiBG,CAAK,EAAIN,EAAO,CAAC,EAC3CC,EAASE,EAAiBG,EAAQ,CAAC,EAAIN,EAAO,CAAC,EAE/C,IAAMO,EAAgBJ,EAAiBD,EAGvCE,EAAQC,GAAe,EAAIE,EACnBH,EAAAC,GAAe,EAAIE,EAAgB,EACnCH,EAAAC,GAAe,EAAIE,EAAgB,CAAA,CAEnD,EC2DA,IAAMC,GAAuD,CAAC,CAAE,OAAQ,EAAG,MAAO,OAAQ,EAAG,CAAE,OAAQ,EAAG,MAAO,OAAA,CAAS,EAkF7GC,GAAN,MAAMA,EACb,CA0FI,eAAeC,EACf,CA9DgB,KAAA,IAAcC,GAAI,cAAc,EAMhD,KAAO,MAAgB,EAEvB,KAAgB,KAAqB,SAOrC,KAAO,WAAuD,CAAA,EAgDtD,IAAAC,EAAUC,GAAsBH,CAAI,EAIxCE,EAAU,CAAE,GAFKA,EAAQ,OAAS,SAAWH,GAAa,qBAAuBA,GAAa,qBAErE,GAAGK,GAAaF,CAAO,CAAE,EAElD,KAAK,aAAeA,EAAQ,YAC5B,KAAK,UAAYA,EAAQ,SAErBA,EAAQ,OAAS,UAEjB,KAAK,OAASA,EAAQ,OACjB,KAAA,YAAcA,EAAQ,aAAe,KAAK,OAC/C,KAAK,YAAcA,EAAQ,YAC3B,KAAK,YAAcA,EAAQ,YAC3B,KAAK,MAAQA,EAAQ,MACrB,KAAK,SAAWA,EAAQ,WAIxB,KAAK,MAAQA,EAAQ,MACrB,KAAK,IAAMA,EAAQ,KAGvB,KAAK,aAAeA,EAAQ,aAE5B,KAAK,KAAOA,EAAQ,KACZA,EAAA,WAAW,QAASG,GAC5B,CACI,KAAK,aAAaA,EAAK,OAAQA,EAAK,KAAK,CAAA,CAC5C,CAAA,CASE,aAAaC,EAAgBC,EACpC,CACI,YAAK,WAAW,KAAK,CAAE,OAAAD,EAAQ,MAAOE,EAAM,OAAO,SAASD,CAAK,EAAE,OAAO,CAAA,CAAG,EAEtE,IAAA,CAQJ,qBACP,CACI,GAAI,KAAK,QAAS,OAElB,GAAI,CAAE,EAAGE,EAAI,EAAGC,CAAA,EAAO,KAAK,MACxB,CAAE,EAAGC,EAAI,EAAGC,CAAA,EAAO,KAAK,IAExBC,EAAKF,EAAKF,EACVK,EAAKF,EAAKF,EAGRK,EAAOF,EAAK,GAAKC,EAAK,EAExB,GAAA,KAAK,YAAc,gBACvB,CACI,GAAID,EAAK,EACT,CACI,IAAMG,EAAOP,EAERA,EAAAE,EACAA,EAAAK,EACCH,GAAA,EAAA,CAEV,GAAIC,EAAK,EACT,CACI,IAAME,EAAON,EAERA,EAAAE,EACAA,EAAAI,EACCF,GAAA,EAAA,CACV,CAGJ,IAAMG,EAAa,KAAK,WAAW,OAAS,KAAK,WAAanB,GAExDoB,EAAc,KAAK,aAEnB,CAAE,OAAAC,EAAQ,QAAAC,CAAA,EAAYC,GAAUH,EAAa,CAAC,EAE9CI,EAAYP,EAEZK,EAAQ,qBAAqB,KAAK,aAAc,EAAG,EAAG,CAAC,EADvDA,EAAQ,qBAAqB,EAAG,EAAG,KAAK,aAAc,CAAC,EAG7DG,GAAcD,EAAUL,CAAU,EAElCG,EAAQ,UAAYE,EACpBF,EAAQ,SAAS,EAAG,EAAGF,EAAa,CAAC,EAEhC,KAAA,QAAU,IAAIM,EAAQ,CACvB,OAAQ,IAAIC,GAAY,CACpB,SAAUN,EACV,YAAa,KAAK,SAAA,CACrB,CAAA,CACJ,EAID,IAAMO,EAAO,KAAK,KAAMb,EAAKA,EAAOC,EAAKA,CAAG,EACtCa,EAAQ,KAAK,MAAMb,EAAID,CAAE,EAKzB,EAAI,IAAIe,EAEZ,EAAA,MAAOF,EAAOR,EAAc,CAAC,EAC/B,EAAE,OAAOS,CAAK,EACZ,EAAA,UAAUlB,EAAIC,CAAE,EAEd,KAAK,eAAiB,SAEpB,EAAA,MAAMQ,EAAaA,CAAW,EAEpC,KAAK,UAAY,CAAA,CAQd,eACP,CACS,KAAK,SAAc,KAAA,QACpB,KAAK,OAAS,SAEd,KAAK,oBAAoB,EAIzB,KAAK,oBAAoB,CAC7B,CAQG,qBACP,CACI,GAAI,KAAK,QAAS,OAElB,IAAMD,EAAa,KAAK,WAAW,OAAS,KAAK,WAAanB,GAExDoB,EAAc,KAAK,aACnB,CAAE,OAAAC,EAAQ,QAAAC,CAAA,EAAYC,GAAUH,EAAaA,CAAW,EAExD,CAAE,EAAGT,EAAI,EAAGC,CAAA,EAAO,KAAK,OACxB,CAAE,EAAGC,EAAI,EAAGC,CAAA,EAAO,KAAK,YAExBiB,EAAK,KAAK,YACVC,EAAK,KAAK,YAEVC,EAAKpB,EAAKmB,EACVE,EAAKpB,EAAKkB,EAEVG,EAAQf,GAAeY,EAAK,GAE5BI,GAAMzB,EAAKsB,GAAME,EACjBE,GAAMzB,EAAKsB,GAAMC,EAEjBX,EAAWF,EAAQ,qBACrBc,EACAC,EACAN,EAAKI,GACJtB,EAAKoB,GAAME,GACXrB,EAAKoB,GAAMC,EACZH,EAAKG,CAAA,EAGTV,GAAcD,EAAUL,CAAU,EAElCG,EAAQ,UAAYH,EAAWA,EAAW,OAAS,CAAC,EAAE,MACtDG,EAAQ,SAAS,EAAG,EAAGF,EAAaA,CAAW,EAE/CE,EAAQ,UAAYE,EAGZF,EAAA,UAAUc,EAAIC,CAAE,EAGhBf,EAAA,OAAO,KAAK,QAAQ,EAGpBA,EAAA,MAAM,EAAG,KAAK,KAAK,EAG3BA,EAAQ,UAAU,CAACc,EAAI,CAACC,CAAE,EAE1Bf,EAAQ,SAAS,EAAG,EAAGF,EAAaA,CAAW,EAE1C,KAAA,QAAU,IAAIM,EAAQ,CACvB,OAAQ,IAAIC,GAAY,CACpB,SAAUN,EACV,YAAa,KAAK,SAAA,CACrB,CAAA,CACJ,EAEK,IAAAiB,EAAI,IAAIR,EAGdQ,EAAE,MAAM,EAAIH,EAAO,EAAIA,CAAK,EAC1BG,EAAA,UAAUL,EAAIC,CAAE,EAEd,KAAK,eAAiB,SAEpBI,EAAA,MAAMlB,EAAaA,CAAW,EAGpC,KAAK,UAAYkB,CAAA,CAId,SACP,CACS,KAAA,SAAS,QAAQ,EAAI,EAC1B,KAAK,QAAU,KACf,KAAK,UAAY,KACjB,KAAK,WAAa,CAAA,EAClB,KAAK,MAAQ,KACb,KAAK,IAAM,KACX,KAAK,OAAS,KACd,KAAK,YAAc,IAAA,CAQvB,IAAW,UACX,CACI,MAAO,iBAAiB,KAAK,GAAG,IAAI,KAAK,KAAK,EAAA,CAEtD,EAnVarC,GAGc,qBAA8C,CACjE,MAAO,CAAE,EAAG,EAAG,EAAG,CAAE,EACpB,IAAK,CAAE,EAAG,EAAG,EAAG,CAAE,EAClB,WAAY,CAAA,EACZ,aAAc,QACd,KAAM,SACN,YAAa,IACb,SAAU,eACd,EAXSA,GAcc,qBAA8C,CACjE,OAAQ,CAAE,EAAG,GAAK,EAAG,EAAI,EACzB,YAAa,EACb,YAAa,GACb,WAAY,CAAA,EACZ,MAAO,EACP,aAAc,QACd,KAAM,SACN,YAAa,IACb,SAAU,eACd,EAxBG,IAAMsC,EAANtC,GAqVP,SAASwB,GAAcD,EAA0BL,EACjD,CACI,QAASqB,EAAI,EAAGA,EAAIrB,EAAW,OAAQqB,IACvC,CACU,IAAAjC,EAAOY,EAAWqB,CAAC,EAEzBhB,EAAS,aAAajB,EAAK,OAAQA,EAAK,KAAK,CAAA,CAErD,CAEA,SAASgB,GAAUkB,EAAeC,EAClC,CACI,IAAMrB,EAASsB,EAAW,IAAA,EAAM,aAAaF,EAAOC,CAAM,EACpDpB,EAAUD,EAAO,WAAW,IAAI,EAE/B,MAAA,CAAE,OAAAA,EAAQ,QAAAC,CAAQ,CAC7B,CAmBA,SAASjB,GACLH,EAEJ,CACI,IAAIE,EAAWF,EAAK,CAAC,GAAK,CAAA,EAG1B,OAAI,OAAOE,GAAY,UAAYF,EAAK,CAAC,KAGrC0C,EAAY,QAAS,4BAA4B,EAGvCxC,EAAA,CACN,KAAM,SACN,MAAO,CAAE,EAAGF,EAAK,CAAC,EAAG,EAAGA,EAAK,CAAC,CAAE,EAChC,IAAK,CAAE,EAAGA,EAAK,CAAC,EAAG,EAAGA,EAAK,CAAC,CAAE,EAC9B,aAAcA,EAAK,CAAC,EACpB,YAAaA,EAAK,CAAC,GAAKqC,EAAa,qBAAqB,WAAA,GAI3DnC,CACX,CCllBA,IAAMyC,GAAoB,IAAIC,EAMxBC,GAAW,IAAIC,EAqBd,SAASC,GAAsBC,EAAaC,EAAgCC,EAAuBC,EAC1G,CAEU,IAAAC,EAAgBH,EAAM,OACtBD,EAAI,SAASC,EAAM,MAAM,EAAE,OAAA,EAC3BD,EAAI,SAAS,EAEf,GAAAC,EAAM,eAAiB,QAC3B,CAEU,IAAAI,EAASH,EAAM,UAAUL,EAAQ,EAElCI,EAAsB,OAEhBI,EAAA,IAAKJ,EAAsB,KAAK,EAG3C,GAAM,CAAE,EAAGK,EAAI,EAAGC,CAAA,EAAOF,EACnBG,EAAK,EAAIH,EAAO,MAChBI,EAAK,EAAIJ,EAAO,OAEhBK,EAAM,CAACJ,EAAKE,EACZG,EAAM,CAACJ,EAAKE,EAEZG,EAAKR,EAAc,EACnBS,EAAKT,EAAc,EACnBU,EAAKV,EAAc,EACnBW,EAAKX,EAAc,EAEzBA,EAAc,GAAKI,EACnBJ,EAAc,GAAKI,EACnBJ,EAAc,GAAKK,EACnBL,EAAc,GAAKK,EAEnBL,EAAc,GAAMM,EAAME,EAAOD,EAAMG,EAAMV,EAAc,GAC3DA,EAAc,GAAMM,EAAMG,EAAOF,EAAMI,EAAMX,EAAc,EAAA,MAK7CA,EAAA,UAAUH,EAAM,QAAQ,MAAM,EAAGA,EAAM,QAAQ,MAAM,CAAC,EACtDG,EAAA,MAAM,EAAKH,EAAM,QAAQ,OAAO,MAAQ,EAAKA,EAAM,QAAQ,OAAO,MAAO,EAGrF,IAAAe,EAAcf,EAAM,QAAQ,OAAO,MAGzC,MAAI,EAAEA,EAAM,gBAAgBgB,IAAiBD,EAAY,cAAgB,kBAErEA,EAAY,YAAc,SAC1BA,EAAY,OAAO,GAInBb,GAEAC,EAAc,OAAOT,GAAkB,SAASQ,CAAM,EAAE,OAAA,CAAQ,EAG7DC,CACX,CCpEO,IAAMc,GAAmD,CAAA,EAEhEC,GAAW,YAAYC,EAAc,aAAcF,EAAa,EAChEC,GAAW,IAAIE,GAAgBC,GAAcC,GAAeC,GAAaC,GAAcC,EAAqB,EAE5G,IAAMC,GAAW,IAAIC,EACfC,GAAoB,IAAIC,EAOd,SAAAC,GAAoBC,EAA0BC,EAC9D,CACU,GAAA,CAAE,aAAAC,EAAc,QAAAC,CAAA,EAAYF,EAGlCE,EAAQ,OAAS,EACjBD,EAAa,QAAQ,OAAS,EAC9BA,EAAa,SAAS,OAAS,EAC/BA,EAAa,IAAI,OAAS,EAE1B,QAASE,EAAI,EAAGA,EAAIJ,EAAQ,aAAa,OAAQI,IACjD,CACU,IAAAC,EAAcL,EAAQ,aAAaI,CAAC,EAEtC,GAAAC,EAAY,SAAW,UAGEC,GAAAD,EAAY,KAAMF,EAASD,CAAY,UAE3DG,EAAY,SAAW,QAAUA,EAAY,SAAW,SACjE,CACU,IAAAE,EAAWF,EAAY,SAAW,SAGlCG,EAAYH,EAAY,KAAK,KAAK,UAElCI,EAAQJ,EAAY,KAAK,MAEzBK,EAAOL,EAAY,KAAK,KAE1BE,GAAYG,GAEZC,GAA2BD,EAAK,UAAWD,EAAO,GAAMN,EAASD,CAAY,EAG7EQ,IAGUF,EAAA,gBAAgBA,EAAU,gBAAgB,OAAS,CAAC,EAAE,MAAQE,EAAK,UAAU,iBAG3FC,GAA2BH,EAAWC,EAAOF,EAAUJ,EAASD,CAAY,CAAA,CAChF,CAER,CAEA,SAASI,GACLM,EACAT,EACAD,EAMJ,CACI,IAAMW,EAAmB,CAAA,EAEnBC,EAAQ5B,GAAc,UAEtB6B,EAAOpB,GAEboB,EAAK,EAAIH,EAAK,GACdG,EAAK,EAAIH,EAAK,GACdG,EAAK,MAAQH,EAAK,GAClBG,EAAK,OAASH,EAAK,GAEnB,IAAMI,EAASJ,EAAK,UAGpB,GAAI,CAACE,EAAM,MAAMC,EAAMF,CAAM,EAEzB,OAGJ,GAAM,CAAE,SAAAI,EAAU,IAAAC,EAAK,QAAAC,CAAA,EAAYjB,EAE7BkB,EAAcD,EAAQ,OACtBE,EAAaJ,EAAS,OAAS,EAEjCD,GAEAM,GAAkBT,EAAQG,CAAM,EAGpCF,EAAM,YAAYD,EAAQI,EAAU,EAAGI,EAAYF,EAASC,CAAW,EAEvE,IAAMG,EAAUX,EAAK,MACfY,EAAaD,EAAQ,IAEvBL,EAAA,KACAM,EAAW,GAAIA,EAAW,GAC1BA,EAAW,GAAIA,EAAW,GAC1BA,EAAW,GAAIA,EAAW,GAC1BA,EAAW,GAAIA,EAAW,EAAA,EAGxB,IAAAC,EAAgBC,EAAQ,IAAIC,EAAiB,EAEnDF,EAAc,YAAcL,EACdK,EAAA,UAAYN,EAAQ,OAASC,EAE3CK,EAAc,gBAAkBJ,EAClBI,EAAA,cAAiBR,EAAS,OAAS,EAAKI,EAEtDI,EAAc,UAAYb,EAAK,MAC/Ba,EAAc,MAAQb,EAAK,MAE3Ba,EAAc,QAAUF,EACxBE,EAAc,aAAevB,EAE7BC,EAAQ,KAAKsB,CAAa,CAC9B,CAEA,SAASd,GACLH,EACAC,EACAF,EACAJ,EACAD,EAMJ,CACI,GAAM,CAAE,SAAAe,EAAU,IAAAC,EAAK,QAAAC,CAAA,EAAYjB,EAEzBM,EAAA,gBAAgB,QAAQ,CAAC,CAAE,MAAAoB,EAAO,UAAWZ,EAAQ,MAAAa,CAAA,IAC/D,CACI,IAAMhB,EAAmB,CAAA,EACnBC,EAAQ5B,GAAc0C,EAAM,IAAI,EAMtC,GAAI,CAACd,EAAM,MAAMc,EAAOf,CAAM,EAE1B,OAGJ,IAAMO,EAAcD,EAAQ,OACtBE,EAAaJ,EAAS,OAAS,EACjCa,EAAqB,gBAOzB,GALId,GAEAM,GAAkBT,EAAQG,CAAM,EAG/BT,EAwBL,CACU,IAAAwB,EAASH,EAAkB,WAAa,GACxCI,EAAYvB,EAEbuB,EAAU,WAMIC,GAAApB,EAAQkB,EAAOd,EAAUE,CAAO,EACpCW,EAAA,aALXI,GAAUrB,EAAQmB,EAAW,GAAOD,EAAOd,EAAUE,CAAO,CAMhE,SAlCIU,EACJ,CACI,IAAMM,EAAwB,CAAA,EAExBC,EAAcvB,EAAO,MAAM,EAEdwB,GAAcR,CAAK,EAE3B,QAASS,GACpB,CACgBH,EAAA,KAAKC,EAAY,OAAS,CAAC,EAC3BA,EAAA,KAAK,GAAGE,CAAU,CAAA,CACjC,EAEDC,GAAqBH,EAAaD,EAAalB,EAAU,EAAGI,EAAYF,EAASC,CAAW,CAAA,MAI5FN,EAAM,YAAYD,EAAQI,EAAU,EAAGI,EAAYF,EAASC,CAAW,EAmBzE,IAAAoB,EAAYtB,EAAI,OAAS,EAEzBK,EAAUd,EAAM,QAElB,GAAAc,IAAYkB,EAAQ,MACxB,CACI,IAAMC,EAAgBC,GAA0B9C,GAAmBY,EAAOmB,EAAOZ,CAAM,EAE9E4B,GAAA3B,EAAU,EAAGI,EAAYH,EAAKsB,EAAW,EAAIvB,EAAS,OAAS,EAAKI,EAAYqB,CAAa,CAAA,MAItGG,GAAe3B,EAAKsB,EAAW,EAAIvB,EAAS,OAAS,EAAKI,CAAU,EAGlE,IAAAI,EAAgBC,EAAQ,IAAIC,EAAiB,EAEnDF,EAAc,YAAcL,EACdK,EAAA,UAAYN,EAAQ,OAASC,EAE3CK,EAAc,gBAAkBJ,EAClBI,EAAA,cAAiBR,EAAS,OAAS,EAAKI,EAEtDI,EAAc,UAAYhB,EAAM,MAChCgB,EAAc,MAAQhB,EAAM,MAE5BgB,EAAc,QAAUF,EACxBE,EAAc,aAAevB,EAC7BuB,EAAc,SAAWK,EAEzB3B,EAAQ,KAAKsB,CAAa,CAAA,CAC7B,CACL,CAEA,SAASY,GAAcS,EACvB,CACI,IAAMC,EAAa,CAAA,EAEnB,QAASC,EAAI,EAAGA,EAAIF,EAAe,OAAQE,IAC3C,CACU,IAAAC,EAAgBH,EAAeE,CAAC,EAAE,MAGlCV,EAAuB,CAAA,EAETpD,GAAc+D,EAAc,IAAI,EAEpC,MAAMA,EAAeX,CAAU,GAE3CS,EAAW,KAAKT,CAAU,CAC9B,CAGG,OAAAS,CACX,CCpQO,IAAMG,GAAN,KACP,CADO,aAAA,CAKH,KAAO,QAA+B,CAAA,EACtC,KAAO,aAA6B,CAChC,SAAU,CAAA,EACV,IAAK,CAAA,EACL,QAAS,CAAA,CAAC,CACd,CAEJ,EAOaC,GAAN,KACP,CADO,aAAA,CAGI,KAAA,aAAe,IAAIC,EAAe,CAElC,KAAKC,EACZ,CACI,IAAMC,EAAcD,EAAQ,YAE5B,KAAK,QAAU,KAAK,QAAQ,mBAAmBC,CAAW,EAAI,KAAK,QAAU,IAAIC,GAAe,CAAE,YAAAD,CAAA,CAAa,EAC/G,KAAK,aAAa,MAAM,CAAA,CAQ5B,IAAI,UACJ,CAEI,OAAAE,EAAYC,GAAQ,wFAAwF,EAGrG,KAAK,QAAQ,QAAA,CAGjB,SACP,CACI,KAAK,QAAQ,QAAQ,EACrB,KAAK,aAAa,QAAQ,EAE1B,KAAK,QAAU,KACf,KAAK,aAAe,IAAA,CAE5B,EAkBaC,GAAN,MAAMA,EACb,CA2BI,YAAYC,EACZ,CANA,KAAQ,gBAAsD,CAAA,EAEtD,KAAA,yBAA6E,OAAA,OAAO,IAAI,EAK5F,KAAK,UAAYA,EACRA,EAAA,aAAa,eAAe,KAAM,iBAAiB,EACnDA,EAAA,aAAa,eAAe,KAAM,0BAA0B,CAAA,CAOlE,KAAKN,EACZ,CACIK,GAAsB,eAAe,iBAAmBL,GAAS,kBAC1DK,GAAsB,eAAe,gBAAA,CAQzC,qBAAqBE,EAC5B,CACI,OAAO,KAAK,yBAAyBA,EAAQ,GAAG,GAAK,KAAK,uBAAuBA,CAAO,CAAA,CAUrF,iBAAiBA,EACxB,CACQ,IAAAC,EAAiC,KAAK,gBAAgBD,EAAQ,GAAG,GAE9D,KAAK,aAAaA,CAAO,EAEhC,GAAIA,EAAQ,MACZ,CACQC,EAEA,KAAK,0BAA0BD,CAAO,EAIzBC,EAAA,KAAK,aAAaD,CAAO,EAG1CE,GAAoBF,EAASC,CAAU,EAEvC,IAAME,EAAYH,EAAQ,UAEtBA,EAAQ,cAAgBG,IAAc,WAEtCF,EAAW,YAAc,GAEpBE,IAAc,OAEnBF,EAAW,YAAeA,EAAW,aAAa,SAAS,OAAS,IAIpEA,EAAW,YAAc,GAG7BD,EAAQ,MAAQ,EAAA,CAGb,OAAAC,CAAA,CAUJ,cAAcD,EACrB,CACI,OAAO,KAAK,gBAAgBA,EAAQ,GAAG,GAAK,KAAK,aAAaA,CAAO,CAAA,CAGjE,uBAAuBA,EAC/B,CACU,IAAAI,EAA0CC,EAAQ,IAAId,GAA2B,CACnF,YAAa,KAAK,UAAU,OAAO,oBAAA,CACtC,EAEK,CAAE,QAAAe,EAAS,aAAAC,CAAA,EAAiB,KAAK,gBAAgBP,EAAQ,GAAG,EAE5DQ,EAAaD,EAAa,SAAS,OACnCE,EAAYF,EAAa,QAAQ,OAEvC,QAASG,EAAI,EAAGA,EAAIJ,EAAQ,OAAQI,IAExBJ,EAAAI,CAAC,EAAE,eAAiB,GAGhC,IAAMC,EAAUP,EAAa,QAG7BO,EAAQ,sBAAsBH,CAAU,EACxCG,EAAQ,kBAAkBF,CAAS,EAEnCE,EAAQ,MAAM,EAEd,QAASD,EAAI,EAAGA,EAAIJ,EAAQ,OAAQI,IACpC,CACU,IAAAE,EAAQN,EAAQI,CAAC,EAEvBC,EAAQ,IAAIC,CAAK,CAAA,CAGbD,EAAA,OAAOP,EAAa,YAAY,EAExC,IAAMS,EAAWF,EAAQ,SAKzBE,EAAS,YAAY,gBAAgBF,EAAQ,YAAaA,EAAQ,UAAW,EAAI,EACxEE,EAAA,QAAQ,CAAC,EAAE,gBAAgBF,EAAQ,gBAAgB,YAAaA,EAAQ,cAAe,EAAI,EAEpG,IAAMG,EAAcH,EAAQ,QAE5B,QAASD,EAAI,EAAGA,EAAII,EAAY,OAAQJ,IACxC,CACU,IAAAE,EAAQE,EAAYJ,CAAC,EAE3BE,EAAM,UAAYG,GACdH,EAAM,SAAS,SACfA,EAAM,SAAS,MACf,KAAK,UAAU,OAAO,oBAAA,CAC1B,CAGC,YAAA,yBAAyBZ,EAAQ,GAAG,EAAII,EAEtCA,CAAA,CAGH,aAAaJ,EACrB,CACU,IAAAC,EAAa,IAAIX,GAEvB,OAAAW,EAAW,QAAUD,EAEhB,KAAA,gBAAgBA,EAAQ,GAAG,EAAIC,EAEpCD,EAAQ,GAAG,UAAW,KAAK,yBAA0B,IAAI,EAElD,KAAK,gBAAgBA,EAAQ,GAAG,CAAA,CAGjC,yBAAyBA,EACnC,CACI,KAAK,0BAA0BA,CAAO,EAEtCA,EAAQ,IAAI,UAAW,KAAK,yBAA0B,IAAI,EAErD,KAAA,gBAAgBA,EAAQ,GAAG,EAAI,IAAA,CAGhC,0BAA0BA,EAClC,CACI,IAAMC,EAAiC,KAAK,gBAAgBD,EAAQ,GAAG,EAElEC,EAAW,aAER,KAAK,yBAAyBD,EAAQ,GAAG,IAEzCK,EAAQ,OAAO,KAAK,qBAAqBL,CAAO,CAAa,EAGxD,KAAA,yBAAyBA,EAAQ,GAAG,EAAI,MAIjDC,EAAW,SAEAA,EAAA,QAAQ,QAASW,GAC5B,CACIP,EAAQ,OAAOO,CAAiB,CAAA,CACnC,CACL,CAGG,SACP,CAEe,QAAAF,KAAK,KAAK,gBAEb,KAAK,gBAAgBA,CAAC,GAEtB,KAAK,yBAAyB,KAAK,gBAAgBA,CAAC,EAAE,OAAO,EAIrE,KAAK,gBAAkB,CAAA,EACvB,KAAK,yBAA2B,CAAA,EAC/B,KAAK,UAAqB,IAAA,CAEnC,EA1OaZ,GAGK,UAAY,CACtB,KAAM,CACFkB,EAAc,YACdA,EAAc,aACdA,EAAc,YAAA,EAElB,KAAM,iBACV,EAVSlB,GAac,eAA+C,CAKlE,iBAAkB,EACtB,EAnBG,IAAMmB,GAANnB,GC3EA,IAAMoB,GAAN,KACP,CADO,aAAA,CAEH,KAAO,QAA+B,CAAA,EACtC,KAAO,QAAU,EAAA,CACV,SACP,CACS,KAAA,QAAQ,QAASC,GACtB,CACIC,EAAQ,OAAOD,CAAiB,CAAA,CACnC,EAED,KAAK,QAAQ,OAAS,CAAA,CAE9B,EAGaE,GAAN,KACP,CAgBI,YAAYC,EAAoBC,EAChC,CALO,KAAA,MAAeC,GAAM,MAAM,EAM9B,KAAK,SAAWF,EAEhB,KAAK,SAAWC,EAEhB,KAAK,SAAS,QAAQ,cAAc,IAAI,IAAI,CAAA,CAGzC,eACP,CACS,KAAA,SAAS,cAAc,KAAK,QAAQ,CAAA,CAGtC,mBAAmBE,EAC1B,CAEI,IAAMC,EAAUD,EAAS,QAEnBE,EAAa,CAAC,CAACF,EAAS,SAExBG,EAAa,KAAK,SAAS,gBAAgB,iBAAiBF,CAAO,EAEzE,MAAI,GAAAE,EAAW,aAAeD,IAAeC,EAAW,YAMjD,CAGJ,cAAcH,EAAoBI,EACzC,CACI,IAAMD,EAAa,KAAK,SAAS,gBAAgB,iBAAiBH,EAAS,OAAO,EAI9EA,EAAS,eAET,KAAK,SAASA,CAAQ,EAGtBG,EAAW,YAEN,KAAA,cAAcH,EAAUI,CAAc,GAI3C,KAAK,SAAS,YAAY,MAAM,MAAMA,CAAc,EACpDA,EAAe,IAAIJ,CAAQ,EAC/B,CAGG,iBAAiBA,EACxB,CAGI,IAAMK,EAFU,KAAK,yBAAyBL,CAAQ,EAE9B,QAExB,QAASM,EAAI,EAAGA,EAAID,EAAQ,OAAQC,IACpC,CACU,IAAAZ,EAAQW,EAAQC,CAAC,EAEjBZ,EAAA,SAAS,cAAcA,CAAK,CAAA,CACtC,CAGG,QAAQM,EACf,CACI,GAAI,CAACA,EAAS,aAAc,OAE5B,IAAMH,EAAW,KAAK,SAChBI,EAAUD,EAAS,QAIzB,GAAI,CAHkBH,EAAS,gBAGZ,cAAcI,CAAO,EAAE,QAAQ,OAChD,OAEF,IAAMM,EAASN,EAAQ,cAAgB,KAAK,SAAS,OAEhD,KAAA,MAAM,UAAYD,EAAS,eAE1B,IAAAQ,EAAgBD,EAAO,UAAU,cAAc,SAErDC,EAAc,iBAAmBR,EAAS,eAC5BQ,EAAA,OAASX,EAAS,aAAeG,EAAS,aAExDS,GACIT,EAAS,gBACTQ,EAAc,OACd,CAAA,EAGC,KAAA,SAAS,QAAQ,KAAMR,CAAQ,CAAA,CAGhC,SAASA,EACjB,CACU,IAAAU,EAAU,KAAK,yBAAyBV,CAAQ,EAEhDG,EAAa,KAAK,SAAS,gBAAgB,iBAAiBH,EAAS,OAAO,EAGlFU,EAAQ,QAAQ,EAEZP,EAAW,aAEN,KAAA,4BAA4BH,EAAUU,CAAO,CACtD,CAGI,cAAcV,EAAoBI,EAC1C,CACU,IAAAO,EAAY,KAAK,SAAS,YAAY,MAEtCN,EAAU,KAAK,yBAAyBL,CAAQ,EAAE,QAExD,QAAS,EAAI,EAAG,EAAIK,EAAQ,OAAQ,IACpC,CACU,IAAAX,EAAQW,EAAQ,CAAC,EAEbM,EAAA,WAAWjB,EAAOU,CAAc,CAAA,CAC9C,CAGI,yBAAyBJ,EACjC,CACW,OAAAA,EAAS,SAAS,KAAK,SAAS,GAAG,GAAK,KAAK,0BAA0BA,CAAQ,CAAA,CAGlF,0BAA0BA,EAClC,CACU,IAAAU,EAAU,IAAIjB,GAEpB,OAAAO,EAAS,SAAS,KAAK,SAAS,GAAG,EAAIU,EAEhCA,CAAA,CAGH,4BAA4BV,EAAoBU,EACxD,CACI,IAAMT,EAAUD,EAAS,QAEnBG,EAAiC,KAAK,SAAS,gBAAgB,cAAcF,CAAO,EAEpFW,EAAe,KAAK,SAAS,aAAeZ,EAAS,aAE3DU,EAAQ,QAAUP,EAAW,QAAQ,IAAKT,GAC1C,CACU,IAAAmB,EAAalB,EAAQ,IAAImB,EAAiB,EAEhD,OAAApB,EAAM,OAAOmB,CAAU,EAEvBA,EAAW,WAAab,EAExBa,EAAW,YAAcD,EAElBC,CAAA,CACV,CAAA,CAGE,SACP,CACI,KAAK,SAAW,KAEhB,KAAK,SAAS,QAAQ,EACtB,KAAK,SAAW,KAChB,KAAK,MAAQ,IAAA,CAErB,EA5LajB,GAGK,UAAY,CACtB,KAAM,CACFmB,EAAc,WACdA,EAAc,YACdA,EAAc,WAAA,EAElB,KAAM,UACV,ECtCG,IAAMC,GAAN,KACP,CADO,aAAA,CAEH,KAAO,YAAc,UAIrB,KAAgB,WAAa,GAK7B,KAAO,YAAc,EACrB,KAAO,gBAAkB,EAKzB,KAAO,YAAqB,EAG5B,KAAO,SAAoB,KAC3B,KAAO,OAAgB,KAGvB,KAAO,uBAAiC,GAGxC,KAAQ,YAAsB,EAAA,CAE9B,IAAI,WAAY,CAAE,OAAO,KAAK,WAAW,cAAA,CAEzC,IAAI,UAAW,CAAS,OAAA,KAAK,WAAa,KAAK,SAAS,QAAA,CACxD,IAAI,SAASC,EAAiB,CAAE,KAAK,UAAYA,CAAA,CAE1C,OACP,CACI,KAAK,WAAa,KAClB,KAAK,QAAU,KACf,KAAK,SAAW,KAChB,KAAK,OAAS,KACd,KAAK,SAAW,KAChB,KAAK,YAAc,GACnB,KAAK,uBAAyB,EAAA,CAS3B,WAAWA,EAClB,CACQ,KAAK,UAAYA,IAErB,KAAK,QAAUA,EACf,KAAK,uBAAyB,GAAA,CAGlC,IAAI,KACJ,CAGU,IAAAC,EAFW,KAAK,SAEI,UAAU,KAAK,EAEnCC,EAAMD,EAAS,KAEjBE,EAAiBD,EACfE,EAAgB,KAAK,QAAQ,cAE/B,OAACA,EAAc,WAEfD,EAAiB,KAAK,iBAElB,KAAK,yBAA2BC,EAAc,WAAa,KAAK,cAAgBH,EAAS,cAErF,CAACE,GAAkBA,EAAe,OAASD,EAAI,UAE/CC,EAAiB,KAAK,gBAAkB,IAAI,aAAaD,EAAI,MAAM,GAGvE,KAAK,uBAAyBE,EAAc,UAC5C,KAAK,YAAcH,EAAS,UAEdG,EAAA,YAAYF,EAAqBC,CAAc,IAI9DA,CAAA,CAGX,IAAI,WACJ,CACI,OAAO,KAAK,SAAS,SAAA,CAGzB,IAAI,SACJ,CACI,OAAO,KAAK,SAAS,OAAA,CAGzB,IAAI,OACJ,CACI,OAAO,KAAK,WAAW,eAAA,CAG3B,IAAI,gBACJ,CACI,OAAO,KAAK,WAAW,cAAA,CAG3B,IAAI,eACJ,CACW,OAAA,KAAK,SAAS,UAAU,OAAS,CAAA,CAG5C,IAAI,WACJ,CACW,OAAA,KAAK,SAAS,QAAQ,MAAA,CAErC,EC5GO,IAAME,GAAN,KACP,CAIW,SACP,CAAA,CAGJ,EA+BaC,GAAN,KACP,CAyBI,YAAYC,EAAoBC,EAChC,CAfO,KAAA,cAAgB,IAAIC,EAAa,CACpC,iBAAkB,CAAE,MAAO,IAAIC,EAAU,KAAM,aAAc,EAC7D,OAAQ,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,EAAG,KAAM,WAAY,EACnE,OAAQ,CAAE,MAAO,EAAG,KAAM,KAAM,CAAA,CACnC,EAEM,KAAA,uBAAyB,IAAIC,GAAU,CAC1C,EAAG,KAAK,aAAA,CACX,EAQG,KAAK,SAAWJ,EAChB,KAAK,SAAWC,EAEhB,KAAK,SAAS,KAAK,CAAA,CAGhB,mBAAmBI,EAC1B,CACU,IAAAC,EAAW,KAAK,aAAaD,CAAI,EAEjCE,EAAaD,EAAS,QAEtBE,EAAYH,EAAK,QAIvB,GAFAC,EAAS,QAAUE,EAEfD,IAAeC,EAER,MAAA,GAAA,GAEFA,EACT,CACI,IAAMC,EAAWJ,EAAK,UAGlB,GAAAI,EAAS,QAAQ,SAAWH,EAAS,WAC9BG,EAAS,UAAU,SAAWH,EAAS,WAErC,OAAAA,EAAA,UAAYG,EAAS,QAAQ,OAC7BH,EAAA,WAAaG,EAAS,UAAU,OAElC,GAGL,IAAAC,EAAgB,KAAK,kBAAkBL,CAAI,EAEjD,OAAIK,EAAc,QAAQ,MAAQL,EAAK,SAAS,MAE5CK,EAAc,uBAAyB,IAGpC,CAACA,EAAc,SAAS,sBAC3BA,EACAL,EAAK,QAAA,CACT,CAGG,MAAA,EAAA,CAGJ,cAAcA,EAAYM,EACjC,CACU,IAAAC,EAAU,KAAK,SAAS,YAAY,MAEpCN,EAAW,KAAK,aAAaD,CAAI,EAQvC,GANIA,EAAK,gBAEIC,EAAA,UAAYD,EAAK,UAAU,SAAS,OACpCC,EAAA,WAAaD,EAAK,UAAU,WAAW,QAGhDC,EAAS,QACb,CACU,IAAAO,EAAmB,KAAK,kBAAkBR,CAAI,EAEnCQ,EAAA,WAAWR,EAAK,QAAQ,EACzCQ,EAAiB,SAAWR,EAAK,UAEzBO,EAAA,WAAWC,EAAkBF,CAAc,CAAA,MAInDC,EAAQ,MAAMD,CAAc,EAE5BA,EAAe,IAAIN,CAAI,CAC3B,CAGG,iBAAiBA,EACxB,CACI,GAAIA,EAAK,QACT,CACU,IAAAQ,EAAmB,KAAK,kBAAkBR,CAAI,EAEnCQ,EAAA,WAAWR,EAAK,QAAQ,EAEzCQ,EAAiB,SAAWR,EAAK,UAEhBQ,EAAA,SAAS,cAAcA,CAAgB,CAAA,CAC5D,CAGG,QAAQR,EACf,CACI,GAAI,CAACA,EAAK,aAAc,OAExBA,EAAK,MAAM,UAAYS,GAA0BT,EAAK,eAAgBA,EAAK,QAAQ,OAAO,EAE1F,IAAMU,EAAgB,KAAK,cAEbA,EAAA,SAAS,iBAAmBV,EAAK,eAC/CU,EAAc,SAAS,OAAS,KAAK,SAAS,aAAeV,EAAK,aAClEU,EAAc,OAAO,EAErBC,GACIX,EAAK,gBACLU,EAAc,SAAS,OACvB,CAAA,EAGC,KAAA,SAAS,QAAQ,KAAMV,CAAI,CAAA,CAG5B,aAAaA,EACrB,CA/MJ,IAAAY,EAAAC,EAgNQ,OAAAD,EAAAZ,EAAK,UAALa,EAAc,KAAK,SAAS,GAA5B,IAAAD,EAAAC,CAAA,EAAqC,IAAIpB,IAElCO,EAAK,SAAS,KAAK,SAAS,GAAG,EAAE,UAAY,KAAK,cAAcA,CAAI,CAAA,CAGvE,cAAcA,EACtB,CACI,OAAAA,EAAK,SAAS,KAAK,SAAS,GAAG,EAAE,SAAW,CACxC,QAASA,EAAK,QACd,UAAW,EACX,WAAY,CAAA,EAGTA,EAAK,SAAS,KAAK,SAAS,GAAG,EAAE,QAAA,CAGpC,kBAAkBA,EAC1B,CAjOJ,IAAAY,EAAAC,EAkOQ,OAAAD,EAAAZ,EAAK,UAALa,EAAc,KAAK,SAAS,GAA5B,IAAAD,EAAAC,CAAA,EAAqC,IAAIpB,IAElCO,EAAK,SAAS,KAAK,SAAS,GAAG,EAAE,eAAiB,KAAK,mBAAmBA,CAAI,CAAA,CAGjF,mBAAmBA,EAC3B,CAEU,IAAAc,EAAyB,IAAIC,GAEnC,OAAAD,EAAQ,WAAad,EACbc,EAAA,WAAWd,EAAK,QAAQ,EAChCc,EAAQ,UAAYd,EAAK,eACzBc,EAAQ,YAAe,KAAK,SAAS,aAAed,EAAK,aAEzDA,EAAK,SAAS,KAAK,SAAS,GAAG,EAAE,cAAgBc,EAE1CA,CAAA,CAGJ,SACP,CACI,KAAK,cAAgB,KACrB,KAAK,uBAAyB,KAE9B,KAAK,SAAS,QAAQ,EACtB,KAAK,SAAW,KAEhB,KAAK,SAAW,IAAA,CAExB,EAhMapB,GAGK,UAAY,CACtB,KAAM,CACFsB,EAAc,WACdA,EAAc,YACdA,EAAc,WAAA,EAElB,KAAM,MACV,ECrEG,IAAMC,GAAN,KACP,CACW,QAAQC,EAA8CC,EAC7D,CACI,IAAMC,EAAQF,EAAsB,MAC9BG,EAAWH,EAAsB,SACjCI,EAASH,EAAU,QAAUD,EAAsB,cAElDI,EAAA,UAAU,SAAWH,EAAU,QAAQ,QACvCG,EAAA,UAAU,SAAWJ,EAAsB,cAElD,IAAMK,EAAKF,EAAS,GAEdG,EAASN,EAAsB,WAAWC,CAAS,EAGhDE,EAAA,OAAO,KAAKC,CAAM,EAClBD,EAAA,MAAM,IAAID,CAAK,EACxBC,EAAS,SAAS,KAAKG,EAAO,SAAUF,EAAO,SAAS,EAGxD,IAAMG,EADWD,EAAO,SAAS,YAAY,KAAK,oBACtB,EAAID,EAAG,eAAiBA,EAAG,aAEpDA,EAAA,aAAaA,EAAG,UAAWJ,EAAU,iBAAiB,OAAS,EAAGM,EAAQ,CAAC,CAAA,CAEtF,ECtBgB,SAAAC,GACZC,EACAC,EAA8C,KAElD,CAEI,IAAMC,EAAeF,EAAO,EAYxB,GATAE,EAAe,MAEDD,IAAAA,EAAA,IAAI,YAAYC,CAAY,GAI5BD,IAAAA,EAAA,IAAI,YAAYC,CAAY,GAG1CD,EAAU,SAAWC,EAErB,MAAM,IAAI,MAAM,uCAAuCD,EAAU,MAAM,iBAAiBC,CAAY,EAAE,EAIjG,QAAAC,EAAI,EAAGC,EAAI,EAAGD,EAAID,EAAcC,GAAK,EAAGC,GAAK,EAExCH,EAAAE,EAAI,CAAC,EAAIC,EAAI,EACbH,EAAAE,EAAI,CAAC,EAAIC,EAAI,EACbH,EAAAE,EAAI,CAAC,EAAIC,EAAI,EACbH,EAAAE,EAAI,CAAC,EAAIC,EAAI,EACbH,EAAAE,EAAI,CAAC,EAAIC,EAAI,EACbH,EAAAE,EAAI,CAAC,EAAIC,EAAI,EAGpB,OAAAH,CACX,CC5BO,SAASI,GAA+BC,EAC/C,CACW,MAAA,CACH,cAAeC,GAAuBD,EAAY,EAAI,EACtD,aAAcC,GAAuBD,EAAY,EAAK,CAAA,CAE9D,CAEA,SAASC,GACLD,EACAE,EAEJ,CACI,IAAMC,EAA0B,CAAA,EAEhCA,EAAc,KAAK;;;;;;;;aAQV,EAET,IAAIC,EAAS,EAEb,QAAW,KAAKJ,EAChB,CACU,IAAAK,EAAWL,EAAW,CAAC,EAE7B,GAAIE,IAAYG,EAAS,QAAS,SAEpBF,EAAA,KAAK,oBAAoBC,CAAM,EAAE,EAEjCD,EAAA,KAAKE,EAAS,IAAI,EAE1B,IAAAC,EAAgBC,GAA2BF,EAAS,MAAM,EAEhED,GAAUE,EAAc,OAAS,CAAA,CAGrCH,EAAc,KAAK;;;KAGlB,EAGDA,EAAc,QAAQ;uBACHC,CAAM;KACxB,EAEK,IAAAI,EAAiBL,EAAc,KAAK;CAAI,EAG9C,OAAO,IAAI,SAAS,KAAM,OAAQ,OAAQK,CAAc,CAC5D,CCzCO,IAAMC,GAAN,KACP,CA0BI,YAAYC,EACZ,CATA,KAAQ,MAAQ,EAGhB,KAAiB,6BAGZ,CAAA,EAKD,IAAMC,EAAO,KAAK,MAAQD,EAAQ,MAAQ,IAGpCE,EAAaF,EAAQ,WAGvBG,EAAmB,EACnBC,EAAoB,EAExB,QAAWC,KAAKH,EAChB,CACU,IAAAI,EAAWJ,EAAWG,CAAC,EACvBE,EAAgBC,GAA2BF,EAAS,MAAM,EAE5DA,EAAS,QAGTF,GAAqBG,EAAc,OAKnCJ,GAAoBI,EAAc,MACtC,CAGJ,KAAK,eAAiBH,EAAoB,EAC1C,KAAK,cAAgBD,EAAmB,EAExC,KAAK,sBAAwB,IAAIM,GAAeR,EAAO,EAAIE,CAAgB,EAC3E,KAAK,uBAAyB,IAAIM,GAAeR,EAAO,EAAIG,CAAiB,EAExE,KAAA,YAAcM,GAAsBT,CAAI,EAIvC,IAAAU,EAAW,IAAIC,GAEjBC,EAAgB,EAChBC,EAAe,EAEd,KAAA,cAAgB,IAAIC,GAAO,CAC5B,KAAM,IAAI,aAAa,CAAC,EACxB,MAAO,yBACP,YAAa,GACb,MAAOC,EAAY,OAASA,EAAY,QAAA,CAC3C,EAEI,KAAA,eAAiB,IAAID,GAAO,CAC7B,KAAM,IAAI,aAAa,CAAC,EACxB,MAAO,0BACP,YAAa,GACb,MAAOC,EAAY,OAASA,EAAY,QAAA,CAC3C,EAED,QAAWX,KAAKH,EAChB,CACU,IAAAI,EAAWJ,EAAWG,CAAC,EACvBE,EAAgBC,GAA2BF,EAAS,MAAM,EAE5DA,EAAS,SAEAK,EAAA,aAAaL,EAAS,cAAe,CAC1C,OAAQ,KAAK,eACb,OAAQ,KAAK,eAAiB,EAC9B,OAAQO,EAAgB,EACxB,OAAQP,EAAS,MAAA,CACpB,EACDO,GAAiBN,EAAc,OAItBI,EAAA,aAAaL,EAAS,cAAe,CAC1C,OAAQ,KAAK,cACb,OAAQ,KAAK,cAAgB,EAC7B,OAAQQ,EAAe,EACvB,OAAQR,EAAS,MAAA,CACpB,EACDQ,GAAgBP,EAAc,KAClC,CAGKI,EAAA,SAAS,KAAK,WAAW,EAE5B,IAAAM,EAAiB,KAAK,kBAAkBf,CAAU,EAExD,KAAK,eAAiBe,EAAe,cACrC,KAAK,cAAgBA,EAAe,aAEpC,KAAK,SAAWN,CAAA,CAGb,kBAAkBT,EACzB,CACU,IAAAgB,EAAMC,GAAmBjB,CAAU,EAErC,OAAA,KAAK,6BAA6BgB,CAAG,EAE9B,KAAK,6BAA6BA,CAAG,GAGhD,KAAK,6BAA6BA,CAAG,EAAI,KAAK,uBAAuBhB,CAAU,EAExE,KAAK,6BAA6BgB,CAAG,EAAA,CAGzC,uBAAuBhB,EAC9B,CACI,OAAOkB,GAA+BlB,CAAU,CAAA,CAG7C,OAAOmB,EAAwBC,EACtC,CAGQD,EAAU,OAAS,KAAK,QAETC,EAAA,GAEV,KAAA,MAAQ,KAAK,IAAID,EAAU,OAAS,KAAK,MAAQ,IAAO,CAAC,EAEzD,KAAA,sBAAwB,IAAIZ,GAAe,KAAK,MAAQ,KAAK,cAAgB,EAAI,CAAC,EAClF,KAAA,uBAAyB,IAAIA,GAAe,KAAK,MAAQ,KAAK,eAAiB,EAAI,CAAC,EACpF,KAAA,YAAcC,GAAsB,KAAK,KAAK,EAEnD,KAAK,SAAS,YAAY,gBACtB,KAAK,YAAa,KAAK,YAAY,WAAY,EAAA,GAGvD,IAAMa,EAAyB,KAAK,uBAOpC,GALA,KAAK,eAAeF,EAAWE,EAAuB,YAAaA,EAAuB,UAAU,EAEpG,KAAK,eAAe,gBAChB,KAAK,uBAAuB,YAAaF,EAAU,OAAS,KAAK,eAAiB,EAAG,EAAA,EAErFC,EACJ,CACI,IAAME,EAAwB,KAAK,sBAEnC,KAAK,cAAcH,EAAWG,EAAsB,YAAaA,EAAsB,UAAU,EAEjG,KAAK,cAAc,gBACfA,EAAsB,YAAaH,EAAU,OAAS,KAAK,cAAgB,EAAG,EAAA,CAAI,CAC1F,CAGG,SACP,CACI,KAAK,cAAc,QAAQ,EAC3B,KAAK,eAAe,QAAQ,EAC5B,KAAK,SAAS,QAAQ,CAAA,CAE9B,EAEA,SAASF,GAAmBjB,EAC5B,CACI,IAAMuB,EAAmB,CAAA,EAEzB,QAAWP,KAAOhB,EAClB,CACU,IAAAI,EAAWJ,EAAWgB,CAAG,EAE/BO,EAAO,KAAKP,EAAKZ,EAAS,KAAMA,EAAS,QAAU,IAAM,GAAG,CAAA,CAGzD,OAAAmB,EAAO,KAAK,GAAG,CAC1B,CCnOA,IAAIC,GAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;GCAf,IAAIC,GAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECAb,IAAIC,GAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;GCYJ,IAAMC,GAAN,cAA6BC,EACpC,CACI,aACA,CACU,IAAAC,EAAYC,GAAU,KAAK,CAC7B,OAAAC,GACA,SAAAC,EAAA,CACH,EAEKC,EAAaC,GAAW,KAAK,CAC/B,SAAU,CACN,OAAQC,GACR,WAAY,cAAA,EAEhB,OAAQ,CACJ,OAAQA,GACR,WAAY,YAAA,CAChB,CACH,EAEK,MAAA,CACF,UAAAN,EACA,WAAAI,EACA,UAAW,CAEP,SAAUG,EAAQ,MAAM,OAExB,SAAU,IAAIC,GAAa,CAAA,CAAE,EAE7B,SAAU,CACN,mBAAoB,CAAE,MAAO,IAAIC,EAAU,KAAM,aAAc,EAC/D,OAAQ,CAAE,MAAO,IAAIC,EAAM,QAAQ,EAAG,KAAM,WAAY,EACxD,OAAQ,CAAE,MAAO,EAAG,KAAM,KAAM,EAChC,YAAa,CAAE,MAAO,CAAC,EAAG,CAAC,EAAG,KAAM,WAAY,CAAA,CACpD,CACJ,CACH,CAAA,CAET,ECzBO,IAAMC,GAAN,KACP,CAuBI,YAAYC,EAAoBC,EAChC,CAjBgB,KAAA,MAAQC,GAAM,MAAM,EAKpB,KAAA,cAAgB,IAAIC,EAAa,CAC7C,mBAAoB,CAAE,MAAO,IAAIC,EAAU,KAAM,aAAc,EAC/D,OAAQ,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,KAAM,WAAY,EACxD,OAAQ,CAAE,MAAO,EAAG,KAAM,KAAM,EAChC,YAAa,CAAE,MAAO,CAAC,EAAG,CAAC,EAAG,KAAM,WAAY,CAAA,CACnD,EAQG,KAAK,SAAWJ,EAEhB,KAAK,QAAUC,EAEV,KAAA,cAAgB,IAAII,GAEpB,KAAA,MAAQH,GAAM,MAAM,CAAA,CAGtB,mBAAmBI,EAC1B,CAEW,MAAA,EAAA,CAGJ,cAAcC,EAA+BC,EACpD,CACI,KAAK,SAAS,YAAY,MAAM,MAAMA,CAAc,EACpDA,EAAe,IAAID,CAAU,CAAA,CAG1B,WAAWA,EAClB,CACW,OAAAA,EAAW,SAAS,KAAK,SAAS,GAAG,GAAK,KAAK,YAAYA,CAAU,CAAA,CAGxE,YAAYA,EACpB,CACI,OAAAA,EAAW,SAAS,KAAK,SAAS,GAAG,EAAI,IAAIE,GAAe,CACxD,KAAMF,EAAW,iBAAiB,OAClC,WAAYA,EAAW,WAAA,CAC1B,EAEMA,EAAW,SAAS,KAAK,SAAS,GAAG,CAAA,CAGzC,iBAAiBD,EACxB,CAAA,CAKO,QAAQI,EACf,CACI,IAAMC,EAAWD,EAAU,iBAEvB,GAAAC,EAAS,SAAW,EAEpB,OAGJ,IAAMX,EAAW,KAAK,SAChBY,EAAS,KAAK,WAAWF,CAAS,EAExCA,EAAU,UAAVA,EAAU,QAAYC,EAAS,CAAC,EAAE,SAElC,IAAME,EAAQ,KAAK,MAEZD,EAAA,OAAOD,EAAUD,EAAU,cAAc,EAChDA,EAAU,eAAiB,GAE3BG,EAAM,UAAYC,GAA0BJ,EAAU,UAAWA,EAAU,QAAQ,OAAO,EAEpF,IAAAK,EAAW,KAAK,cAAc,SAE9BC,EAAuBD,EAAS,mBAE5BL,EAAA,eAAe,OAAOM,CAAoB,EAEpDA,EAAqB,QAAQhB,EAAS,eAAe,kBAAkB,gBAAgB,EAE9Ee,EAAA,YAAcf,EAAS,eAAe,kBAAkB,WACxDe,EAAA,OAASf,EAAS,aAAeU,EAAU,aAEpDO,GACIP,EAAU,gBACVK,EAAS,OACT,CAAA,EAGC,KAAA,QAAQ,QAAQ,KAAML,CAAS,CAAA,CAIjC,SACP,CACK,KAAK,SAAoB,KACtB,KAAK,gBAEL,KAAK,cAAc,QAAQ,EAC3B,KAAK,cAAgB,KACzB,CAER,ECrIO,IAAMQ,GAAN,cAAsCC,EAC7C,CASI,YAAYC,EACZ,CACU,MAAAA,EAAU,IAAIC,EAA4B,CAAA,CAExD,EAdaH,GAGK,UAAY,CACtB,KAAM,CACFI,EAAc,UAAA,EAElB,KAAM,UACV,ECdG,IAAMC,GAAN,KACP,CACW,QAAQC,EAA8CC,EAC7D,CACI,IAAMC,EAAWF,EAAsB,SAEjCG,EAASF,EAAU,QAAUD,EAAsB,cAElDG,EAAA,OAAO,CAAC,EAAID,EAAS,YAAY,aAAa,oBAAoBF,EAAsB,cAAe,EAAI,EAElHG,EAAO,OAAO,CAAC,EAAID,EAAS,QAAQ,oBAAoBD,EAAU,OAAO,EAEzE,IAAMG,EAAQJ,EAAsB,MAE9BK,EAASL,EAAsB,WAAWC,CAAS,EAEzDC,EAAS,QAAQ,KAAK,CAClB,SAAUG,EAAO,SACjB,OAAQJ,EAAU,QAAUD,EAAsB,cAClD,MAAAI,EACA,KAAMH,EAAU,iBAAiB,OAAS,CAAA,CAC7C,CAAA,CAET,ECjBO,IAAMK,GAAN,cAAuCC,EAC9C,CASI,YAAYC,EACZ,CACU,MAAAA,EAAU,IAAIC,EAA6B,CAAA,CAEzD,EAdaH,GAGK,UAAY,CACtB,KAAM,CACFI,EAAc,WAAA,EAElB,KAAM,UACV,ECJY,SAAAC,GAAiBC,EAAkCC,EACnE,CACU,GAAA,CAAE,QAAAC,EAAS,OAAAC,CAAA,EAAWH,EACtBI,EAAUH,EAAK,OAAO,iBAAiB,EAQ5BI,GAAAF,EAAQF,EAAK,QAASC,CAAO,EAK9C,IAAMI,EAAgBL,EAAK,QAAQ,GAAKG,EAAU,EAC5CG,EAAiBN,EAAK,QAAQ,GAAKG,EAAU,EAEnDD,EAAO,MAAQC,EAAUE,EACzBH,EAAO,MAAQC,EAAUG,EACzBJ,EAAO,MAAQC,EAAUE,EACzBH,EAAO,MAAQC,EAAUG,CAC7B,CChCO,IAAMC,GAAN,cAA4BC,EACnC,CAII,YAAYC,EACZ,CACU,MAAA,EAIN,KAAK,UAAYA,EAERA,EAAA,QAAQ,iBAAiB,IAAI,IAAI,CAAA,CAGvC,kBACP,CACI,IAAMC,EAAO,KAAK,WAEdA,EAAK,iBAELA,EAAK,aAAa,CACtB,CAGG,SACP,CACU,GAAA,CAAE,WAAAC,CAAW,EAAI,KAAK,UACXA,EAAW,kBAAkB,KAAK,UAAU,EAE9C,EAEAA,EAAA,uBAAuB,KAAK,UAAU,EAE5C,KAAK,SAECA,EAAA,cAAc,KAAK,OAAO,EAGzC,KAAK,UAAU,QAAQ,iBAAiB,OAAO,IAAI,EAClD,KAAK,UAAqB,IAAA,CAEnC,ECvCO,IAAMC,GAAN,KACP,CAaI,YAAYC,EACZ,CACI,KAAK,UAAYA,CAAA,CAGd,mBAAmBC,EAC1B,CACU,IAAAC,EAAU,KAAK,YAAYD,CAAI,EAE/BE,EAASF,EAAK,SAEpB,OAAIC,EAAQ,aAAeC,EAAe,GAEnCF,EAAK,cAAA,CAGT,cAAcA,EAAYG,EACjC,CACU,IAAAC,EAAgB,KAAK,YAAYJ,CAAI,EAE3C,GAAIA,EAAK,eACT,CACI,IAAMK,EAAaL,EAAK,gBAAkB,KAAK,UAAU,WAAaA,EAAK,YAEvEI,EAAc,aAAeJ,EAAK,UAAYA,EAAK,aAAeK,IAGlE,KAAK,eAAeL,CAAI,EAG5BA,EAAK,eAAiB,GAEtBM,GAAiBF,EAAeJ,CAAI,CAAA,CAGxC,KAAK,UAAU,YAAY,MAAM,WAAWI,EAAeD,CAAc,CAAA,CAGtE,iBAAiBH,EACxB,CACU,IAAAI,EAAgB,KAAK,YAAYJ,CAAI,EAE7BI,EAAA,SAAS,cAAcA,CAAa,CAAA,CAG9C,eAAeJ,EACvB,CACU,IAAAI,EAAgB,KAAK,YAAYJ,CAAI,EAEvCI,EAAc,SAEd,KAAK,UAAU,WAAW,uBAAuBA,EAAc,UAAU,EAG7EJ,EAAK,YAAcA,EAAK,gBAAkB,KAAK,UAAU,WAAaA,EAAK,WAE3EI,EAAc,QAAU,KAAK,UAAU,WAAW,kBAAkBJ,CAAI,EACxEI,EAAc,WAAaJ,EAAK,QAAA,CAG5B,YAAYA,EACpB,CACW,OAAAA,EAAK,SAAS,KAAK,UAAU,GAAG,GAAK,KAAK,YAAYA,CAAI,CAAA,CAG9D,YAAYA,EACnB,CACI,IAAMI,EAAgB,IAAIG,GAAc,KAAK,SAAS,EAEtD,OAAAH,EAAc,WAAa,KAC3BA,EAAc,WAAaJ,EAC3BI,EAAc,UAAYJ,EAAK,eACjBI,EAAA,OAAS,CAAE,KAAM,EAAG,KAAM,EAAG,KAAM,EAAG,KAAM,CAAE,EAC5DA,EAAc,YAAe,KAAK,UAAU,aAAeJ,EAAK,aAEhEA,EAAK,SAAS,KAAK,UAAU,GAAG,EAAII,EAE7BA,CAAA,CAGJ,SACP,CACI,KAAK,UAAY,IAAA,CAEzB,EAlGaN,GAGK,UAAY,CACtB,KAAM,CACFU,EAAc,WACdA,EAAc,YACdA,EAAc,WAAA,EAElB,KAAM,MACV,ECFJ,IAAMC,GAAgB,CAClB,OAAQ,CACJ,aAAc,SACd,aAAc,QAAA,EAElB,WAAY,CACR,aAAc,SACd,aAAc,eAAA,EAElB,WAAY,CACR,aAAc,gBACd,aAAc,QAAA,EAElB,YAAa,CACT,aAAc,gBACd,aAAc,eAAA,CAEtB,EAsBaC,GAAN,KACP,CAiBI,YAAYC,EAAkBC,EAC9B,CAbgB,KAAA,IAAcC,GAAI,aAAa,EAM/C,KAAO,MAAgB,EAIhB,KAAA,UAAY,IAAIC,EAInB,KAAK,QAAUH,EAEf,KAAK,UAAU,MACX,EAAIA,EAAQ,MAAM,MAClB,EAAIA,EAAQ,MAAM,MAAA,EAGlBC,IAEAD,EAAQ,OAAO,MAAM,aAAeF,GAAcG,CAAU,EAAE,aAC9DD,EAAQ,OAAO,MAAM,aAAeF,GAAcG,CAAU,EAAE,aAClE,CAQG,aAAaG,EACpB,CACI,IAAMJ,EAAU,KAAK,QAEhB,KAAA,UAAU,SAASI,CAAS,EACjC,KAAK,UAAU,OAAO,EAEtB,KAAK,UAAU,MACX,EAAIJ,EAAQ,MAAM,MAClB,EAAIA,EAAQ,MAAM,MAAA,EAGjB,KAAA,OAAA,CAIT,IAAW,SACX,CACI,OAAO,KAAK,QAAA,CAEhB,IAAW,QAAQK,EACnB,CACQ,KAAK,WAAaA,IAEtB,KAAK,SAAWA,EACX,KAAA,QAAA,CAQT,IAAW,UACX,CACI,MAAO,gBAAgB,KAAK,GAAG,IAAI,KAAK,KAAK,EAAA,CAI1C,SACP,CACS,KAAA,QAAQ,QAAQ,EAAI,EACzB,KAAK,QAAU,IAAA,CAEvB,E,kBC3GgB,SAAAC,GAAaC,EAAiBC,EAC9C,CAEU,IAAAC,KAAW,GAAAC,SAAMH,CAAO,EAGxBI,EAAsB,CAAA,EACxBC,EAAiC,KAGjCC,EAAQ,EACRC,EAAQ,EAGZ,QAASC,EAAI,EAAGA,EAAIN,EAAS,OAAQM,IACrC,CACU,IAAAC,EAAUP,EAASM,CAAC,EACpBE,EAAOD,EAAQ,CAAC,EAChBE,EAAOF,EAEb,OAAQC,EACR,CACI,IAAK,IACDJ,EAAQK,EAAK,CAAC,EACdJ,EAAQI,EAAK,CAAC,EAETV,EAAA,OAAOK,EAAOC,CAAK,EACxB,MACJ,IAAK,IACDD,GAASK,EAAK,CAAC,EACfJ,GAASI,EAAK,CAAC,EAEVV,EAAA,OAAOK,EAAOC,CAAK,EACxB,MACJ,IAAK,IACDD,EAAQK,EAAK,CAAC,EAETV,EAAA,OAAOK,EAAOC,CAAK,EACxB,MACJ,IAAK,IACDD,GAASK,EAAK,CAAC,EAEVV,EAAA,OAAOK,EAAOC,CAAK,EACxB,MACJ,IAAK,IACDA,EAAQI,EAAK,CAAC,EAETV,EAAA,OAAOK,EAAOC,CAAK,EACxB,MACJ,IAAK,IACDA,GAASI,EAAK,CAAC,EAEVV,EAAA,OAAOK,EAAOC,CAAK,EACxB,MACJ,IAAK,IACDD,EAAQK,EAAK,CAAC,EACdJ,EAAQI,EAAK,CAAC,EAETV,EAAA,OAAOK,EAAOC,CAAK,EACxB,MACJ,IAAK,IACDD,GAASK,EAAK,CAAC,EACfJ,GAASI,EAAK,CAAC,EAEVV,EAAA,OAAOK,EAAOC,CAAK,EACxB,MACJ,IAAK,IACDD,EAAQK,EAAK,CAAC,EACdJ,EAAQI,EAAK,CAAC,EAETV,EAAA,cACDU,EAAK,CAAC,EAAGA,EAAK,CAAC,EACfA,EAAK,CAAC,EAAGA,EAAK,CAAC,EACfL,EAAOC,CAAA,EAEX,MACJ,IAAK,IACIN,EAAA,cACDK,EAAQK,EAAK,CAAC,EAAGJ,EAAQI,EAAK,CAAC,EAC/BL,EAAQK,EAAK,CAAC,EAAGJ,EAAQI,EAAK,CAAC,EAC/BL,EAAQK,EAAK,CAAC,EAAGJ,EAAQI,EAAK,CAAC,CAAA,EAGnCL,GAASK,EAAK,CAAC,EACfJ,GAASI,EAAK,CAAC,EACf,MACJ,IAAK,IACDL,EAAQK,EAAK,CAAC,EACdJ,EAAQI,EAAK,CAAC,EAETV,EAAA,mBACDU,EAAK,CAAC,EAAGA,EAAK,CAAC,EACfL,EAAOC,CAAA,EAEX,MACJ,IAAK,IACIN,EAAA,mBACDK,EAAQK,EAAK,CAAC,EAAGJ,EAAQI,EAAK,CAAC,EAC/BL,EAAQK,EAAK,CAAC,EAAGJ,EAAQI,EAAK,CAAC,CAAA,EAGnCL,GAASK,EAAK,CAAC,EACfJ,GAASI,EAAK,CAAC,EACf,MACJ,IAAK,IACDL,EAAQK,EAAK,CAAC,EACdJ,EAAQI,EAAK,CAAC,EAETV,EAAA,iBACDU,EAAK,CAAC,EAAGA,EAAK,CAAC,EACfL,EAAOC,CAAA,EAEX,MACJ,IAAK,IACIN,EAAA,iBACDK,EAAQK,EAAK,CAAC,EAAGJ,EAAQI,EAAK,CAAC,EAC/BL,EAAQK,EAAK,CAAC,EAAGJ,EAAQI,EAAK,CAAC,CAAA,EAGnCL,GAASK,EAAK,CAAC,EACfJ,GAASI,EAAK,CAAC,EACf,MACJ,IAAK,IACDL,EAAQK,EAAK,CAAC,EACdJ,EAAQI,EAAK,CAAC,EAETV,EAAA,sBACDK,EAAOC,CAAA,EAEX,MACJ,IAAK,IACDD,GAASK,EAAK,CAAC,EACfJ,GAASI,EAAK,CAAC,EAEVV,EAAA,sBACDK,EAAOC,CAAA,EAEX,MACJ,IAAK,IACDD,EAAQK,EAAK,CAAC,EACdJ,EAAQI,EAAK,CAAC,EAETV,EAAA,SACDU,EAAK,CAAC,EACNA,EAAK,CAAC,EACNA,EAAK,CAAC,EACNA,EAAK,CAAC,EACNA,EAAK,CAAC,EACNL,EAAOC,CAAA,EAEX,MACJ,IAAK,IACDD,GAASK,EAAK,CAAC,EACfJ,GAASI,EAAK,CAAC,EAEVV,EAAA,SACDU,EAAK,CAAC,EACNA,EAAK,CAAC,EACNA,EAAK,CAAC,EACNA,EAAK,CAAC,EACNA,EAAK,CAAC,EACNL,EAAOC,CAAA,EAEX,MACJ,IAAK,IACL,IAAK,IACDN,EAAK,UAAU,EACXG,EAAS,OAAS,IAGlBC,EAAiBD,EAAS,IAAI,EAC1BC,GAEAC,EAAQD,EAAe,OACvBE,EAAQF,EAAe,SAIfC,EAAA,EACAC,EAAA,IAGCF,EAAA,KACjB,MACJ,QAESO,EAAA,6BAA6BF,CAAI,EAAE,CAAA,CAK5CA,IAAS,KAAOA,IAAS,KAErBL,IAAmB,OAEnBA,EAAiB,CAAE,OAAQC,EAAO,OAAQC,CAAM,EAChDH,EAAS,KAAKC,CAAc,EAEpC,CAGG,OAAAJ,CACX,CC7MO,IAAMY,GAAN,MAAMC,CACb,CA2EI,YAAYC,EAAI,EAAGC,EAAI,EAAGC,EAAS,EACnC,CARA,KAAgB,KAAwB,SASpC,KAAK,EAAIF,EACT,KAAK,EAAIC,EACT,KAAK,OAASC,CAAA,CAuBX,OACP,CACI,OAAO,IAAIH,EAAO,KAAK,EAAG,KAAK,EAAG,KAAK,MAAM,CAAA,CA4B1C,SAASC,EAAWC,EAC3B,CACI,GAAI,KAAK,QAAU,EAAU,MAAA,GAEvB,IAAAE,EAAK,KAAK,OAAS,KAAK,OAC1BC,EAAM,KAAK,EAAIJ,EACfK,EAAM,KAAK,EAAIJ,EAEb,OAAAG,GAAAA,EACAC,GAAAA,EAEED,EAAKC,GAAMF,CAAA,CAwBhB,eAAeH,EAAWC,EAAWK,EAAeC,EAAoB,GAC/E,CACI,GAAI,KAAK,SAAW,EAAU,MAAA,GAExB,IAAAH,EAAM,KAAK,EAAIJ,EACfK,EAAM,KAAK,EAAIJ,EACfC,EAAS,KAAK,OACdM,GAAc,EAAID,GAAaD,EAC/BG,EAAW,KAAK,KAAML,EAAKA,EAAOC,EAAKA,CAAG,EAEhD,OAAQI,GAAYP,EAASM,GAAcC,EAAWP,GAAUI,EAAQE,EAAA,CAqBrE,UAAUE,EACjB,CACI,OAAAA,IAAAA,EAAQ,IAAIC,GAERD,EAAA,EAAI,KAAK,EAAI,KAAK,OAClBA,EAAA,EAAI,KAAK,EAAI,KAAK,OAClBA,EAAA,MAAQ,KAAK,OAAS,EACtBA,EAAA,OAAS,KAAK,OAAS,EAEpBA,CAAA,CAiBJ,SAASE,EAChB,CACI,YAAK,EAAIA,EAAO,EAChB,KAAK,EAAIA,EAAO,EAChB,KAAK,OAASA,EAAO,OAEd,IAAA,CAiBJ,OAAOA,EACd,CACI,OAAAA,EAAO,SAAS,IAAI,EAEbA,CAAA,CAIJ,UACP,CACW,MAAA,0BAA0B,KAAK,CAAC,MAAM,KAAK,CAAC,WAAW,KAAK,MAAM,GAAA,CAGjF,ECtQO,IAAMC,GAAN,MAAMC,CACb,CA0EI,YAAYC,EAAI,EAAGC,EAAI,EAAGC,EAAY,EAAGC,EAAa,EACtD,CATA,KAAgB,KAAO,UAUnB,KAAK,EAAIH,EACT,KAAK,EAAIC,EACT,KAAK,UAAYC,EACjB,KAAK,WAAaC,CAAA,CAwBf,OACP,CACW,OAAA,IAAIJ,EAAQ,KAAK,EAAG,KAAK,EAAG,KAAK,UAAW,KAAK,UAAU,CAAA,CAsB/D,SAASC,EAAWC,EAC3B,CACI,GAAI,KAAK,WAAa,GAAK,KAAK,YAAc,EAEnC,MAAA,GAIX,IAAIG,GAAUJ,EAAI,KAAK,GAAK,KAAK,UAC7BK,GAAUJ,EAAI,KAAK,GAAK,KAAK,WAExB,OAAAG,GAAAA,EACAC,GAAAA,EAEDD,EAAQC,GAAS,CAAA,CA4BtB,eAAeL,EAAWC,EAAWK,EAAqBC,EAAoB,GACrF,CACU,GAAA,CAAE,UAAAL,EAAW,WAAAC,CAAA,EAAe,KAE9B,GAAAD,GAAa,GAAKC,GAAc,EAEzB,MAAA,GAGL,IAAAK,EAAmBF,GAAe,EAAIC,GACtCE,EAAmBH,EAAcE,EAEjCE,EAAkBR,EAAYO,EAC9BE,EAAgBR,EAAaM,EAE7BG,EAAkBV,EAAYM,EAC9BK,EAAgBV,EAAaK,EAE7BM,EAAcd,EAAI,KAAK,EACvBe,EAAcd,EAAI,KAAK,EAEvBe,EAAiBF,EAAcA,GAAgBJ,EAAkBA,GAC/DK,EAAcA,GAAgBJ,EAAgBA,GAEhDM,EAAiBH,EAAcA,GAAgBF,EAAkBA,GAC/DG,EAAcA,GAAgBF,EAAgBA,GAE/C,OAAAG,EAAe,GAAKC,GAAgB,CAAA,CA0BxC,UAAUC,EACjB,CACI,OAAAA,IAAAA,EAAQ,IAAIC,GAERD,EAAA,EAAI,KAAK,EAAI,KAAK,UAClBA,EAAA,EAAI,KAAK,EAAI,KAAK,WAClBA,EAAA,MAAQ,KAAK,UAAY,EACzBA,EAAA,OAAS,KAAK,WAAa,EAExBA,CAAA,CAiBJ,SAASE,EAChB,CACI,YAAK,EAAIA,EAAQ,EACjB,KAAK,EAAIA,EAAQ,EACjB,KAAK,UAAYA,EAAQ,UACzB,KAAK,WAAaA,EAAQ,WAEnB,IAAA,CAiBJ,OAAOA,EACd,CACI,OAAAA,EAAQ,SAAS,IAAI,EAEdA,CAAA,CAIJ,UACP,CACW,MAAA,2BAA2B,KAAK,CAAC,MAAM,KAAK,CAAC,cAAc,KAAK,SAAS,eAAe,KAAK,UAAU,GAAA,CAGtH,EC/SO,SAASC,GACZC,EAAWC,EACXC,EAAYC,EACZC,EAAYC,EAEhB,CACI,IAAMC,EAAIN,EAAIE,EACRK,EAAIN,EAAIE,EACRK,EAAIJ,EAAKF,EACTO,EAAIJ,EAAKF,EAETO,EAAOJ,EAAIE,EAAMD,EAAIE,EACrBE,EAASH,EAAIA,EAAMC,EAAIA,EACzBG,EAAQ,GAERD,IAAU,IAEVC,EAAQF,EAAMC,GAGd,IAAAE,EACAC,EAEAF,EAAQ,GAEHC,EAAAX,EACAY,EAAAX,GAEAS,EAAQ,GAERC,EAAAT,EACAU,EAAAT,IAKLQ,EAAKX,EAAMU,EAAQJ,EACnBM,EAAKX,EAAMS,EAAQH,GAGvB,IAAMM,EAAKf,EAAIa,EACTG,EAAKf,EAAIa,EAEP,OAAAC,EAAKA,EAAOC,EAAKA,CAC7B,CChDA,IAAIC,GACAC,GAkCSC,GAAN,MAAMC,CACb,CAuEI,eAAeC,EACf,CAZA,KAAgB,KAAwB,UAahC,IAAAC,EAAO,MAAM,QAAQD,EAAO,CAAC,CAAC,EAAIA,EAAO,CAAC,EAAIA,EAGlD,GAAI,OAAOC,EAAK,CAAC,GAAM,SACvB,CACI,IAAMC,EAAc,CAAA,EAEpB,QAASC,EAAI,EAAGC,EAAKH,EAAK,OAAQE,EAAIC,EAAID,IAEpCD,EAAA,KAAMD,EAAKE,CAAC,EAAgB,EAAIF,EAAKE,CAAC,EAAgB,CAAC,EAGtDF,EAAAC,CAAA,CAGX,KAAK,OAASD,EAEd,KAAK,UAAY,EAAA,CA0Bd,aACP,CACI,IAAII,EAAO,EACLL,EAAS,KAAK,OACdM,EAASN,EAAO,OAEtB,QAASG,EAAI,EAAGA,EAAIG,EAAQH,GAAK,EACjC,CACU,IAAAI,EAAKP,EAAOG,CAAC,EACbK,EAAKR,EAAOG,EAAI,CAAC,EACjBM,EAAKT,GAAQG,EAAI,GAAKG,CAAM,EAC5BI,EAAKV,GAAQG,EAAI,GAAKG,CAAM,EAEzBD,IAAAI,EAAKF,IAAOG,EAAKF,EAAA,CAG9B,OAAOH,EAAO,CAAA,CAuBX,gBAAgBM,EACvB,CAEU,IAAAC,EAAa,KAAK,UAAUhB,EAAQ,EACpCiB,EAAcF,EAAQ,UAAUd,EAAS,EAE/C,GAAI,CAACe,EAAW,aAAaC,CAAW,EAE7B,MAAA,GAIX,IAAMb,EAASW,EAAQ,OAEvB,QAAS,EAAI,EAAG,EAAIX,EAAO,OAAQ,GAAK,EACxC,CACU,IAAAc,EAAId,EAAO,CAAC,EACZe,EAAIf,EAAO,EAAI,CAAC,EAGtB,GAAI,CAAC,KAAK,SAASc,EAAGC,CAAC,EAEZ,MAAA,EACX,CAGG,MAAA,EAAA,CAmBJ,OACP,CACU,IAAAf,EAAS,KAAK,OAAO,MAAM,EAC3BW,EAAU,IAAIZ,EAAQC,CAAM,EAElC,OAAAW,EAAQ,UAAY,KAAK,UAElBA,CAAA,CAkBJ,SAASG,EAAWC,EAC3B,CACI,IAAIC,EAAS,GAIPV,EAAS,KAAK,OAAO,OAAS,EAE3B,QAAA,EAAI,EAAGW,EAAIX,EAAS,EAAG,EAAIA,EAAQW,EAAI,IAChD,CACI,IAAMC,EAAK,KAAK,OAAO,EAAI,CAAC,EACtBC,EAAK,KAAK,OAAQ,EAAI,EAAK,CAAC,EAC5BC,EAAK,KAAK,OAAOH,EAAI,CAAC,EACtBI,EAAK,KAAK,OAAQJ,EAAI,EAAK,CAAC,EACdE,EAAKJ,GAAQM,EAAKN,GAAQD,GAAMM,EAAKF,KAAQH,EAAII,IAAOE,EAAKF,IAAQD,IAIrFF,EAAS,CAACA,EACd,CAGG,OAAAA,CAAA,CAwBJ,eAAeF,EAAWC,EAAWO,EAAqBC,EAAY,GAC7E,CACI,IAAMC,EAAqBF,EAAcA,EACnCG,EAAoBD,GAAsB,EAAID,GAC9CG,EAAmBF,EAAqBC,EAExC,CAAE,OAAAzB,CAAA,EAAW,KACb2B,EAAkB3B,EAAO,QAAU,KAAK,UAAY,EAAI,GAE9D,QAASG,EAAI,EAAGA,EAAIwB,EAAiBxB,GAAK,EAC1C,CACU,IAAAI,EAAKP,EAAOG,CAAC,EACbK,EAAKR,EAAOG,EAAI,CAAC,EACjBM,EAAKT,GAAQG,EAAI,GAAKH,EAAO,MAAM,EACnCU,EAAKV,GAAQG,EAAI,GAAKH,EAAO,MAAM,EAEnC4B,EAAkBC,GAA6Bf,EAAGC,EAAGR,EAAIC,EAAIC,EAAIC,CAAE,EAEnEoB,EAAO,KAAK,MAAOrB,EAAKF,IAAOQ,EAAIP,IAASE,EAAKF,IAAOM,EAAIP,EAAI,EAEtE,GAAIqB,IAAoBE,EAAO,EAAIJ,EAAmBD,GAE3C,MAAA,EACX,CAGG,MAAA,EAAA,CAqBJ,UAAUM,EACjB,CACIA,IAAAA,EAAQ,IAAIC,GAEZ,IAAMhC,EAAS,KAAK,OAEhBiC,EAAO,IACPC,EAAO,KAEPC,EAAO,IACPC,EAAO,KAEF,QAAAjC,EAAI,EAAGkC,EAAIrC,EAAO,OAAQG,EAAIkC,EAAGlC,GAAK,EAC/C,CACU,IAAAW,EAAId,EAAOG,CAAC,EACZY,EAAIf,EAAOG,EAAI,CAAC,EAEf8B,EAAAnB,EAAImB,EAAOnB,EAAImB,EACfC,EAAApB,EAAIoB,EAAOpB,EAAIoB,EAEfC,EAAApB,EAAIoB,EAAOpB,EAAIoB,EACfC,EAAArB,EAAIqB,EAAOrB,EAAIqB,CAAA,CAG1B,OAAAL,EAAI,EAAIE,EACRF,EAAI,MAAQG,EAAOD,EAEnBF,EAAI,EAAII,EACRJ,EAAI,OAASK,EAAOD,EAEbJ,CAAA,CAiBJ,SAASpB,EAChB,CACS,YAAA,OAASA,EAAQ,OAAO,MAAM,EACnC,KAAK,UAAYA,EAAQ,UAElB,IAAA,CAiBJ,OAAOA,EACd,CACI,OAAAA,EAAQ,SAAS,IAAI,EAEdA,CAAA,CAIJ,UACP,CACI,MAAO,oCACc,KAAK,SAAS,UACnB,KAAK,OAAO,OAAO,CAAC2B,EAAYC,IAAiB,GAAGD,CAAU,KAAKC,CAAY,GAAI,EAAE,CAAC,GAAA,CAiB1G,IAAI,OACJ,CACI,OAAO,KAAK,OAAO,KAAK,OAAO,OAAS,CAAC,CAAA,CAgB7C,IAAI,OACJ,CACI,OAAO,KAAK,OAAO,KAAK,OAAO,OAAS,CAAC,CAAA,CAQ7C,IAAI,GACJ,CAEI,OAAAC,EAAY,SAAU,gEAAgE,EAG/E,KAAK,OAAO,KAAK,OAAO,OAAS,CAAC,CAAA,CAQ7C,IAAI,GACJ,CAEI,OAAAA,EAAY,SAAU,4DAA4D,EAG3E,KAAK,OAAO,KAAK,OAAO,OAAS,CAAC,CAAA,CAe7C,IAAI,QACJ,CACW,OAAA,KAAK,OAAO,CAAC,CAAA,CAgBxB,IAAI,QACJ,CACW,OAAA,KAAK,OAAO,CAAC,CAAA,CAE5B,EC5hBA,IAAMC,GAAuB,CACzBC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,IAEJ,CACI,IAAMC,EAAKP,EAAKE,EACVM,EAAKP,EAAKE,EACVM,EAAW,KAAK,KAAMF,EAAKA,EAAOC,EAAKA,CAAG,EAEhD,OAAOC,GAAYL,EAASC,GAAoBI,GAAYL,EAASE,CACzE,EAwBaI,GAAN,MAAMC,CACb,CAiGI,YAAYC,EAAI,EAAGC,EAAI,EAAGC,EAAQ,EAAGC,EAAS,EAAGX,EAAS,GAC1D,CAVA,KAAgB,KAAwB,mBAWpC,KAAK,EAAIQ,EACT,KAAK,EAAIC,EACT,KAAK,MAAQC,EACb,KAAK,OAASC,EACd,KAAK,OAASX,CAAA,CAwBX,UAAUY,EACjB,CACI,OAAAA,IAAAA,EAAQ,IAAIC,GAEZD,EAAI,EAAI,KAAK,EACbA,EAAI,EAAI,KAAK,EACbA,EAAI,MAAQ,KAAK,MACjBA,EAAI,OAAS,KAAK,OAEXA,CAAA,CAwBJ,OACP,CACW,OAAA,IAAIL,EAAiB,KAAK,EAAG,KAAK,EAAG,KAAK,MAAO,KAAK,OAAQ,KAAK,MAAM,CAAA,CAsB7E,SAASO,EAChB,CACI,YAAK,EAAIA,EAAU,EACnB,KAAK,EAAIA,EAAU,EACnB,KAAK,MAAQA,EAAU,MACvB,KAAK,OAASA,EAAU,OAEjB,IAAA,CAsBJ,OAAOA,EACd,CACI,OAAAA,EAAU,SAAS,IAAI,EAEhBA,CAAA,CAsBJ,SAASN,EAAWC,EAC3B,CACI,GAAI,KAAK,OAAS,GAAK,KAAK,QAAU,EAE3B,MAAA,GAEX,GAAID,GAAK,KAAK,GAAKA,GAAK,KAAK,EAAI,KAAK,OAE9BC,GAAK,KAAK,GAAKA,GAAK,KAAK,EAAI,KAAK,OACtC,CACI,IAAMT,EAAS,KAAK,IAAI,EAAG,KAAK,IAAI,KAAK,OAAQ,KAAK,IAAI,KAAK,MAAO,KAAK,MAAM,EAAI,CAAC,CAAC,EAEvF,GAAKS,GAAK,KAAK,EAAIT,GAAUS,GAAK,KAAK,EAAI,KAAK,OAAST,GACjDQ,GAAK,KAAK,EAAIR,GAAUQ,GAAK,KAAK,EAAI,KAAK,MAAQR,EAEhD,MAAA,GAEP,IAAAG,EAAKK,GAAK,KAAK,EAAIR,GACnBI,EAAKK,GAAK,KAAK,EAAIT,GACjBe,EAAUf,EAASA,EAiBzB,GAfKG,EAAKA,EAAOC,EAAKA,GAAOW,IAI7BZ,EAAKK,GAAK,KAAK,EAAI,KAAK,MAAQR,GAC3BG,EAAKA,EAAOC,EAAKA,GAAOW,KAI7BX,EAAKK,GAAK,KAAK,EAAI,KAAK,OAAST,GAC5BG,EAAKA,EAAOC,EAAKA,GAAOW,KAIxBZ,EAAAK,GAAK,KAAK,EAAIR,GACdG,EAAKA,EAAOC,EAAKA,GAAOW,GAElB,MAAA,EACX,CAID,MAAA,EAAA,CAwBJ,eAAenB,EAAYC,EAAYmB,EAAqBC,EAAoB,GACvF,CACI,GAAM,CAAE,EAAAT,EAAG,EAAAC,EAAG,MAAAC,EAAO,OAAAC,EAAQ,OAAAX,CAAA,EAAW,KAElCE,EAAmBc,GAAe,EAAIC,GACtChB,EAAmBe,EAAcd,EAEjCgB,EAASV,EAAIR,EACbmB,EAASV,EAAIT,EACboB,EAAaV,EAASV,EAAS,EAC/BqB,EAAcV,EAAUX,EAAS,EACjCsB,EAAad,EAAIE,EACjBa,EAAcd,EAAIE,EAWxB,OARMf,GAAMY,EAAIN,GAAoBN,GAAMY,EAAIP,GACtCL,GAAM0B,EAAarB,GAAoBL,GAAM0B,EAAapB,IAC3DL,GAAMsB,GAAUtB,GAAMsB,EAASE,IAMhCxB,GAAMY,EAAIP,GAAoBL,GAAMY,EAAIR,GACtCJ,GAAM0B,EAActB,GAAoBJ,GAAM0B,EAAcrB,IAC7DN,GAAMsB,GAAUtB,GAAMsB,EAASE,EAE3B,GAMNxB,EAAKsB,GAAUrB,EAAKsB,GACdxB,GAAqBC,EAAIC,EAAIqB,EAAQC,EACpCnB,EAAQC,EAAkBC,CAAA,GAE9BN,EAAK0B,EAAatB,GAAUH,EAAKsB,GAC9BxB,GAAqBC,EAAIC,EAAIyB,EAAatB,EAAQmB,EACjDnB,EAAQC,EAAkBC,CAAA,GAE9BN,EAAK0B,EAAatB,GAAUH,EAAK0B,EAAcvB,GAC5CL,GAAqBC,EAAIC,EAAIyB,EAAatB,EAAQuB,EAAcvB,EAC/DA,EAAQC,EAAkBC,CAAA,GAE9BN,EAAKsB,GAAUrB,EAAK0B,EAAcvB,GAC/BL,GAAqBC,EAAIC,EAAIqB,EAAQK,EAAcvB,EAClDA,EAAQC,EAAkBC,CAAA,CAAgB,CAInD,UACP,CACI,MAAO,oCAAoC,KAAK,CAAC,MAAM,KAAK,CAAC,SAC9C,KAAK,KAAK,WAAW,KAAK,MAAM,WAAW,KAAK,MAAM,GAAA,CAG7E,ECnZA,IAAMsB,GAAkB,EAClBC,GAAc,aACdC,GAAwB,EAExBC,GAA6B,IAC7BC,GAAkB,EAClBC,GAAa,EAeH,SAAAC,GACZC,EACAC,EAAYC,EACZC,EAAcC,EACdC,EAAcC,EACdC,EAAYC,EACZC,EAEJ,CAGI,IAAMC,EAAY,KAAK,IACnB,IACA,KAAK,IAAI,EAAGD,GAAcE,GAAsB,eAAe,gBAAgB,CAAA,EAE/EC,GAAqBjB,GAAwBe,GAAa,EAEzC,OAAAE,GAAAA,EACfC,GAAAZ,EAAIC,EAAIC,EAAMC,EAAMC,EAAMC,EAAMC,EAAIC,EAAIR,EAAQY,CAAiB,EAEhEZ,CACX,CAKA,SAASa,GACLZ,EAAYC,EACZC,EAAcC,EACdC,EAAcC,EACdC,EAAYC,EACZR,EACAY,EAEJ,CAGcE,GAAAb,EAAIC,EAAIC,EAAMC,EAAMC,EAAMC,EAAMC,EAAIC,EAAIR,EAAQY,EAAmB,CAAC,EACvEZ,EAAA,KAAKO,EAAIC,CAAE,CACtB,CAGA,SAASM,GACLC,EAAYC,EACZC,EAAYC,EACZC,EAAYC,EACZC,EAAYC,EACZtB,EACAY,EACAW,EACJ,CACI,GAAIA,EAAQ9B,GACV,OAEF,IAAM+B,EAAK,KAAK,GAIVC,GAAOV,EAAKE,GAAM,EAClBS,GAAOV,EAAKE,GAAM,EAClBS,GAAOV,EAAKE,GAAM,EAClBS,GAAOV,EAAKE,GAAM,EAClBS,GAAOV,EAAKE,GAAM,EAClBS,GAAOV,EAAKE,GAAM,EAClBS,GAAQN,EAAME,GAAO,EACrBK,GAAQN,EAAME,GAAO,EACrBK,GAAQN,EAAME,GAAO,EACrBK,GAAQN,EAAME,GAAO,EACrBK,GAASJ,EAAOE,GAAQ,EACxBG,GAASJ,EAAOE,GAAQ,EAE9B,GAAIX,EAAQ,EACZ,CAGI,IAAIc,EAAKhB,EAAKN,EACVuB,EAAKhB,EAAKN,EAERuB,EAAK,KAAK,KAAMtB,EAAKI,GAAMiB,GAAQpB,EAAKI,GAAMe,CAAG,EACjDG,EAAK,KAAK,KAAMrB,EAAKE,GAAMiB,GAAQlB,EAAKE,GAAMe,CAAG,EAEnDI,EAASC,EAET,GAAAH,EAAK7C,IAAe8C,EAAK9C,IAIpB,IAAA6C,EAAKC,IAAOD,EAAKC,IAAO5B,GAAsByB,EAAKA,EAAOC,EAAKA,GACpE,CAII,GAAIzC,GAAkBD,GACtB,CACWI,EAAA,KAAKmC,EAAOC,CAAK,EAExB,MAAA,CAKJ,IAAMO,EAAM,KAAK,MAAMvB,EAAKF,EAAIC,EAAKF,CAAE,EAOnC,GALEwB,EAAA,KAAK,IAAIE,EAAM,KAAK,MAAMzB,EAAKF,EAAIC,EAAKF,CAAE,CAAC,EAC3C2B,EAAA,KAAK,IAAI,KAAK,MAAMpB,EAAKF,EAAIC,EAAKF,CAAE,EAAIwB,CAAG,EAC7CF,GAAOjB,IAAIiB,EAAO,EAAIjB,EAAMiB,GAC5BC,GAAOlB,IAAIkB,EAAO,EAAIlB,EAAMkB,GAE5BD,EAAMC,EAAM7C,GAChB,CAGWG,EAAA,KAAKmC,EAAOC,CAAK,EAExB,MAAA,CAGJ,GAAItC,KAAe,EACnB,CACI,GAAI2C,EAAM3C,GACV,CACWE,EAAA,KAAKiB,EAAIC,CAAE,EAElB,MAAA,CAGJ,GAAIwB,EAAM5C,GACV,CACWE,EAAA,KAAKmB,EAAIC,CAAE,EAElB,MAAA,CACJ,CACJ,UAGCmB,EAAK7C,IAIV,GAAI6C,EAAKA,GAAM3B,GAAsByB,EAAKA,EAAOC,EAAKA,GACtD,CACI,GAAIzC,GAAkBD,GACtB,CACWI,EAAA,KAAKmC,EAAOC,CAAK,EAExB,MAAA,CAQJ,GAHAK,EAAM,KAAK,IAAI,KAAK,MAAMrB,EAAKF,EAAIC,EAAKF,CAAE,EAAI,KAAK,MAAMC,EAAKF,EAAIC,EAAKF,CAAE,CAAC,EACtE0B,GAAOjB,IAAIiB,EAAO,EAAIjB,EAAMiB,GAE5BA,EAAM5C,GACV,CACWG,EAAA,KAAKiB,EAAIC,CAAE,EACXlB,EAAA,KAAKmB,EAAIC,CAAE,EAElB,MAAA,CAGJ,GAAItB,KAAe,GAEX2C,EAAM3C,GACV,CACWE,EAAA,KAAKiB,EAAIC,CAAE,EAElB,MAAA,CAER,UAGCsB,EAAK9C,IAIV,GAAI8C,EAAKA,GAAM5B,GAAsByB,EAAKA,EAAOC,EAAKA,GACtD,CACI,GAAIzC,GAAkBD,GACtB,CACWI,EAAA,KAAKmC,EAAOC,CAAK,EAExB,MAAA,CAQJ,GAHAK,EAAM,KAAK,IAAI,KAAK,MAAMnB,EAAKF,EAAIC,EAAKF,CAAE,EAAI,KAAK,MAAMC,EAAKF,EAAIC,EAAKF,CAAE,CAAC,EACtEwB,GAAOjB,IAAIiB,EAAO,EAAIjB,EAAMiB,GAE5BA,EAAM5C,GACV,CACWG,EAAA,KAAKiB,EAAIC,CAAE,EACXlB,EAAA,KAAKmB,EAAIC,CAAE,EAElB,MAAA,CAGJ,GAAItB,KAAe,GAEX2C,EAAM3C,GACV,CACWE,EAAA,KAAKmB,EAAIC,CAAE,EAElB,MAAA,CAER,UAOCiB,EAAAF,GAAUpB,EAAKM,GAAM,EACrBiB,EAAAF,GAAUpB,EAAKM,GAAM,EACrBe,EAAKA,EAAOC,EAAKA,GAAO1B,EAC7B,CACWZ,EAAA,KAAKmC,EAAOC,CAAK,EAExB,MAAA,CAER,CAKMtB,GAAAC,EAAIC,EAAIS,EAAKC,EAAKK,EAAMC,EAAMG,EAAOC,EAAOpC,EAAQY,EAAmBW,EAAQ,CAAC,EAChFT,GAAAqB,EAAOC,EAAOH,EAAMC,EAAML,EAAKC,EAAKT,EAAIC,EAAItB,EAAQY,EAAmBW,EAAQ,CAAC,CAC9F,CCzPA,IAAMqB,GAAkB,EAClBC,GAAc,aACdC,GAAwB,EAExBC,GAA6B,IAC7BC,GAAkB,EAaR,SAAAC,GACZC,EACAC,EAAYC,EACZC,EAAcC,EACdC,EAAYC,EACZC,EAEJ,CAEI,IAAMC,EAAY,KAAK,IACnB,IACA,KAAK,IAAI,EAAGD,GAAcE,GAAsB,eAAe,gBAAgB,CAAA,EAE/EC,GAAqBd,GAAwBY,GAAa,EAEzC,OAAAE,GAAAA,EACrBC,GAAMV,EAAIC,EAAIC,EAAMC,EAAMC,EAAIC,EAAIN,EAAQU,CAAiB,EAEpDV,CACX,CAKA,SAASW,GACLV,EAAYC,EACZC,EAAcC,EACdC,EAAYC,EACZN,EACAU,EAEJ,CACcE,GAAAZ,EAAQC,EAAIC,EAAIC,EAAMC,EAAMC,EAAIC,EAAII,EAAmB,CAAC,EAE3DV,EAAA,KAAKK,EAAIC,CAAE,CACtB,CAEA,SAASM,GACLZ,EACAa,EAAYC,EACZC,EAAYC,EACZC,EAAYC,EACZR,EACAS,EAEJ,CACI,GAAIA,EAAQzB,GACV,OAEF,IAAM0B,EAAK,KAAK,GAIVC,GAAOR,EAAKE,GAAM,EAClBO,GAAOR,EAAKE,GAAM,EAClBO,GAAOR,EAAKE,GAAM,EAClBO,GAAOR,EAAKE,GAAM,EAClBO,GAAQJ,EAAME,GAAO,EACrBG,GAAQJ,EAAME,GAAO,EAEvBG,EAAKV,EAAKJ,EACVe,EAAKV,EAAKJ,EACRe,EAAI,KAAK,KAAOd,EAAKE,GAAMW,GAAQZ,EAAKE,GAAMS,CAAI,EAExD,GAAIE,EAAIlC,IAIJ,GAAIkC,EAAIA,GAAKnB,GAAsBiB,EAAKA,EAAOC,EAAKA,GACpD,CAII,GAAI9B,GAAkBD,GACtB,CACWG,EAAA,KAAKyB,EAAMC,CAAI,EAEtB,MAAA,CAKJ,IAAII,EAAK,KAAK,IAAI,KAAK,MAAMZ,EAAKF,EAAIC,EAAKF,CAAE,EAAI,KAAK,MAAMC,EAAKF,EAAIC,EAAKF,CAAE,CAAC,EAI7E,GAFIiB,GAAMV,IAAIU,EAAM,EAAIV,EAAMU,GAE1BA,EAAKhC,GACT,CAGWE,EAAA,KAAKyB,EAAMC,CAAI,EAEtB,MAAA,CACJ,UAOCC,EAAAF,GAASZ,EAAKI,GAAM,EACpBW,EAAAF,GAASZ,EAAKI,GAAM,EACpBS,EAAKA,EAAOC,EAAKA,GAAOlB,EAC7B,CACWV,EAAA,KAAKyB,EAAMC,CAAI,EAEtB,MAAA,CAMEd,GAAAZ,EAAQa,EAAIC,EAAIO,EAAKC,EAAKG,EAAMC,EAAMhB,EAAmBS,EAAQ,CAAC,EAClEP,GAAAZ,EAAQyB,EAAMC,EAAMH,EAAKC,EAAKP,EAAIC,EAAIR,EAAmBS,EAAQ,CAAC,CAChF,CC9HgB,SAAAY,GACZC,EACAC,EAAWC,EACXC,EACAC,EACAC,EACAC,EACAC,EAEJ,CAGI,IAAIC,EAAO,KAAK,IAAIJ,EAAQC,CAAG,GAE3B,CAACC,GAAaF,EAAQC,GAIjBC,GAAaD,EAAMD,KAEhBI,EAAA,EAAI,KAAK,GAAMA,GAK3BD,IAAAA,EAAU,KAAK,IAAI,EAAG,KAAK,MAAM,EAAI,KAAK,IAAIJ,EAAQ,EAAI,CAAC,GAAKK,EAAQ,KAAK,GAAI,CAAC,GAG1ED,EAAA,KAAK,IAAIA,EAAO,CAAC,EAEzB,IAAIE,EAAID,EAAQD,EACZG,EAAIN,EAGRK,GAAKH,EAAY,GAAK,EAEtB,QAASK,EAAI,EAAGA,EAAIJ,EAAQ,EAAGI,IAC/B,CACU,IAAAC,EAAK,KAAK,IAAIF,CAAC,EACfG,EAAK,KAAK,IAAIH,CAAC,EAEfI,EAAKb,EAAKW,EAAKT,EACfY,EAAKb,EAAKW,EAAKV,EAEdH,EAAA,KAAKc,EAAIC,CAAE,EAEbL,GAAAD,CAAA,CAEb,CC7CO,SAASO,GACZC,EACAC,EAAYC,EACZC,EAAYC,EACZC,EAEJ,CACI,IAAMC,EAAQN,EAAOA,EAAO,OAAS,CAAC,EAGhCO,EAFQP,EAAOA,EAAO,OAAS,CAAC,EAEnBE,EACbM,EAAKF,EAAQL,EACbQ,EAAKL,EAAKF,EACVQ,EAAKP,EAAKF,EACVU,EAAK,KAAK,IAAKJ,EAAKG,EAAOF,EAAKC,CAAG,EAErC,GAAAE,EAAK,MAAUN,IAAW,EAC9B,EACQL,EAAOA,EAAO,OAAS,CAAC,IAAMC,GAAMD,EAAOA,EAAO,OAAS,CAAC,IAAME,IAE3DF,EAAA,KAAKC,EAAIC,CAAE,EAGtB,MAAA,CAGE,IAAAU,EAAML,EAAKA,EAAOC,EAAKA,EACvBK,EAAMJ,EAAKA,EAAOC,EAAKA,EACvBI,EAAMP,EAAKE,EAAOD,EAAKE,EACvBK,EAAKV,EAAS,KAAK,KAAKO,CAAE,EAAID,EAC9BK,EAAKX,EAAS,KAAK,KAAKQ,CAAE,EAAIF,EAC9BM,EAAKF,EAAKD,EAAKF,EACfM,EAAKF,EAAKF,EAAKD,EACfM,EAAMJ,EAAKL,EAAOM,EAAKR,EACvBY,EAAML,EAAKN,EAAOO,EAAKT,EACvBc,EAAKb,GAAMQ,EAAKC,GAChBK,EAAKf,GAAMS,EAAKC,GAChBM,EAAKb,GAAMK,EAAKG,GAChBM,EAAKf,GAAMM,EAAKG,GAChBO,EAAa,KAAK,MAAMH,EAAKF,EAAIC,EAAKF,CAAE,EACxCO,EAAW,KAAK,MAAMF,EAAKJ,EAAIG,EAAKJ,CAAE,EAE5CQ,GAAS3B,EACJmB,EAAKlB,EACLmB,EAAKlB,EACNG,EACAoB,EACAC,EACAlB,EAAKC,EAAKC,EAAKH,CAAA,CAEvB,CC9DA,IAAMqB,GAAM,KAAK,GAAK,EAEhBC,GAAM,CACR,QAAS,EACT,QAAS,EACT,KAAM,EACN,KAAM,CACV,EAEMC,GAAe,CACjB,CAAE,EAAAC,EAAG,EAAAC,CAAE,EACPC,EAAYC,EACZC,EAAgBC,EAChBC,EAAiBC,EACjBT,IAEJ,CACSE,GAAAE,EACAD,GAAAE,EAEC,IAAAK,EAAMJ,EAASJ,EAAMK,EAASJ,EAC9BQ,EAAMJ,EAASL,EAAMI,EAASH,EAEpCH,OAAAA,EAAI,EAAIU,EAAKF,EACbR,EAAI,EAAIW,EAAKF,EAENT,CACX,EAEA,SAASY,GAAcC,EAAcC,EACrC,CAIU,IAAAC,EAAKD,IAAS,oBAAsB,eAAkB,mBAAQ,KAAK,IAAIA,EAAO,CAAC,EAE/EE,EAAIF,IAAS,mBAAqB,cAAiBC,EAEnDE,EAAK,KAAK,IAAIJ,CAAI,EAClBK,EAAK,KAAK,IAAIL,CAAI,EAClBM,EAAK,KAAK,IAAIN,EAAOC,CAAI,EACzBM,EAAK,KAAK,IAAIP,EAAOC,CAAI,EAExB,MAAA,CACH,CACI,EAAGG,EAAMC,EAAKF,EACd,EAAGE,EAAMD,EAAKD,CAAA,EAElB,CACI,EAAGG,EAAMC,EAAKJ,EACd,EAAGI,EAAMD,EAAKH,CAAA,EAElB,CACI,EAAGG,EACH,EAAGC,CAAA,CACP,CAER,CAEA,IAAMC,GAAc,CAACC,EAAYC,EAAYC,EAAYC,IACzD,CACI,IAAMC,EAASJ,EAAKG,EAAOF,EAAKC,EAAM,EAAK,GAAK,EAE5CG,EAAOL,EAAKE,EAAOD,EAAKE,EAE5B,OAAIE,EAAM,IAEAA,EAAA,GAGNA,EAAM,KAEAA,EAAA,IAGHD,EAAO,KAAK,KAAKC,CAAG,CAC/B,EAEMC,GAAe,CACjBC,EACAC,EACAC,EACAC,EACA5B,EACAC,EACA4B,EACAC,EACA3B,EACAD,EACA6B,EACAC,EACApC,IAQJ,CACI,IAAMqC,EAAO,KAAK,IAAIjC,EAAI,CAAC,EACrBkC,EAAO,KAAK,IAAIjC,EAAI,CAAC,EACrBkC,EAAQ,KAAK,IAAIJ,EAAK,CAAC,EACvBK,EAAQ,KAAK,IAAIJ,EAAK,CAAC,EAEzBK,EAAYJ,EAAOC,EAASD,EAAOG,EAAUF,EAAOC,EAEpDE,EAAW,IAEAA,EAAA,GAGFA,GAAAJ,EAAOG,EAAUF,EAAOC,EACrCE,EAAW,KAAK,KAAKA,CAAQ,GAAKR,IAAiBC,EAAY,GAAK,GAE9D,IAAAQ,EAAWD,EAAWrC,EAAKC,EAAK+B,EAChCO,EAAWF,EAAW,CAACpC,EAAKD,EAAK+B,EAEjC3B,EAAWF,EAASoC,EAAanC,EAASoC,GAAcd,EAAKE,GAAM,EACnEtB,EAAWF,EAASmC,EAAapC,EAASqC,GAAcb,EAAKE,GAAM,EAEnEY,GAAOT,EAAMO,GAAYtC,EACzByC,GAAOT,EAAMO,GAAYtC,EACzByC,GAAO,CAACX,EAAMO,GAAYtC,EAC1B2C,GAAO,CAACX,EAAMO,GAAYtC,EAE1BQ,EAAOQ,GAAY,EAAG,EAAGuB,EAAKC,CAAG,EACnC/B,EAAOO,GAAYuB,EAAKC,EAAKC,EAAKC,CAAG,EAErCb,IAAc,GAAKpB,EAAO,IAElBA,GAAAf,IAGRmC,IAAc,GAAKpB,EAAO,IAElBA,GAAAf,IAGZC,EAAI,QAAUQ,EACdR,EAAI,QAAUS,EACdT,EAAI,KAAOa,EACXb,EAAI,KAAOc,CACf,EAeO,SAASkC,GACZC,EACApB,EACAC,EACAC,EACAC,EACA5B,EACAC,EACA6C,EAAgB,EAChBjB,EAAe,EACfC,EAAY,EAEhB,CACQ,GAAA9B,IAAO,GAAKC,IAAO,EAEnB,OAGJ,IAAME,EAAS,KAAK,IAAI2C,EAAgBnD,GAAM,GAAG,EAC3CO,EAAS,KAAK,IAAI4C,EAAgBnD,GAAM,GAAG,EAE3CoC,EAAO7B,GAAUuB,EAAKE,GAAM,EAAMxB,GAAUuB,EAAKE,GAAM,EACvDI,EAAO,CAAC7B,GAAUsB,EAAKE,GAAM,EAAMzB,GAAUwB,EAAKE,GAAM,EAE1D,GAAAG,IAAQ,GAAKC,IAAQ,EAErB,OAGChC,EAAA,KAAK,IAAIA,CAAE,EACXC,EAAA,KAAK,IAAIA,CAAE,EAEhB,IAAM8C,EAAU,KAAK,IAAIhB,EAAK,CAAC,EAAI,KAAK,IAAI/B,EAAI,CAAC,EAAM,KAAK,IAAIgC,EAAK,CAAC,EAAI,KAAK,IAAI/B,EAAI,CAAC,EAEpF8C,EAAS,IAEH/C,GAAA,KAAK,KAAK+C,CAAM,EAChB9C,GAAA,KAAK,KAAK8C,CAAM,GAG1BvB,GACIC,EACAC,EACAC,EACAC,EACA5B,EACAC,EACA4B,EACAC,EACA3B,EACAD,EACA6B,EACAC,EACApC,EAAA,EAGA,GAAA,CAAE,KAAAa,EAAM,KAAAC,CAAA,EAASd,GACf,CAAE,QAAAQ,EAAS,QAAAC,CAAA,EAAYT,GAMzBoD,EAAQ,KAAK,IAAItC,CAAI,GAAKf,GAAM,GAEhC,KAAK,IAAI,EAAMqD,CAAK,EAAI,OAEhBA,EAAA,GAGZ,IAAMC,EAAW,KAAK,IAAI,KAAK,KAAKD,CAAK,EAAG,CAAC,EAErCtC,GAAAuC,EAER,IAAIC,EAAQL,EAAOA,EAAO,OAAS,CAAC,EAChCM,EAAQN,EAAOA,EAAO,OAAS,CAAC,EAE9BO,EAAgB,CAAE,EAAG,EAAG,EAAG,CAAE,EAEnC,QAASC,EAAI,EAAGA,EAAIJ,EAAUI,IAC9B,CACU,IAAAC,EAAQ9C,GAAcC,EAAMC,CAAI,EAEhC,CAAE,EAAGG,EAAI,EAAGC,CAAA,EAAOjB,GAAayD,EAAM,CAAC,EAAGtD,EAAIC,EAAIC,EAAQC,EAAQC,EAASC,EAAS+C,CAAa,EACjG,CAAE,EAAGrC,EAAI,EAAGC,CAAA,EAAOnB,GAAayD,EAAM,CAAC,EAAGtD,EAAIC,EAAIC,EAAQC,EAAQC,EAASC,EAAS+C,CAAa,EACjG,CAAE,EAAAtD,EAAG,EAAAC,EAAE,EAAIF,GAAayD,EAAM,CAAC,EAAGtD,EAAIC,EAAIC,EAAQC,EAAQC,EAASC,EAAS+C,CAAa,EAE/FG,GACIV,EACAK,EAAOC,EACPtC,EAAIC,EAAIC,EAAIC,EAAIlB,EAAGC,EAAA,EAGfmD,EAAApD,EACAqD,EAAApD,GAEAU,GAAAC,CAAA,CAEhB,CCvPgB,SAAA8C,GACZC,EACAC,EACAC,EAEJ,CACU,IAAAC,EAAU,CAACC,EAAcC,IAC/B,CACU,IAAAC,EAAID,EAAG,EAAID,EAAE,EACbG,EAAIF,EAAG,EAAID,EAAE,EACbI,EAAM,KAAK,KAAMF,EAAIA,EAAMC,EAAIA,CAAE,EACjCE,EAAKH,EAAIE,EACTE,EAAKH,EAAIC,EAER,MAAA,CAAE,IAAAA,EAAK,GAAAC,EAAI,GAAAC,CAAG,CAAA,EAGnBC,EAAc,CAACC,EAAWR,IAChC,CACQQ,IAAM,EAENZ,EAAE,OAAOI,EAAE,EAAGA,EAAE,CAAC,EAIjBJ,EAAE,OAAOI,EAAE,EAAGA,EAAE,CAAC,CACrB,EAGAS,EAAKZ,EAAOA,EAAO,OAAS,CAAC,EAEjC,QAASW,EAAI,EAAGA,EAAIX,EAAO,OAAQW,IACnC,CACI,IAAME,EAAKb,EAAOW,EAAIX,EAAO,MAAM,EAC7Bc,EAAUD,EAAG,QAAUZ,EAE7B,GAAIa,GAAW,EACf,CACIJ,EAAYC,EAAGE,CAAE,EACZD,EAAAC,EACL,QAAA,CAGJ,IAAME,EAAKf,GAAQW,EAAI,GAAKX,EAAO,MAAM,EACnCgB,EAAKd,EAAQW,EAAID,CAAE,EACnBK,EAAKf,EAAQW,EAAIE,CAAE,EAEzB,GAAIC,EAAG,IAAM,MAAQC,EAAG,IAAM,KAC9B,CACIP,EAAYC,EAAGE,CAAE,EACZD,EAAAC,EACL,QAAA,CAGA,IAAAK,EAAQ,KAAK,KAAMF,EAAG,GAAKC,EAAG,GAAOD,EAAG,GAAKC,EAAG,EAAG,EACnDE,EAAe,EACfC,EAAgB,GAEfJ,EAAG,GAAKC,EAAG,GAAOD,EAAG,GAAK,CAACC,EAAG,GAAM,EAEjCC,EAAQ,EAERA,EAAQ,KAAK,GAAKA,GAIlBA,EAAQ,KAAK,GAAKA,EACHC,EAAA,GACCC,EAAA,IAGfF,EAAQ,IAEEC,EAAA,GACCC,EAAA,IAGpB,IAAMC,EAAYH,EAAQ,EAEtBI,EACAC,EAAS,KAAK,IACb,KAAK,IAAIF,CAAS,EAAIP,EAAW,KAAK,IAAIO,CAAS,CAAA,EAGpDE,EAAS,KAAK,IAAIP,EAAG,IAAM,EAAGC,EAAG,IAAM,CAAC,GAExCM,EAAS,KAAK,IAAIP,EAAG,IAAM,EAAGC,EAAG,IAAM,CAAC,EAC9BK,EAAA,KAAK,IAAKC,EAAS,KAAK,IAAIF,CAAS,EAAK,KAAK,IAAIA,CAAS,CAAC,GAI7DC,EAAAR,EAGR,IAAAU,EAAKX,EAAG,EAAKI,EAAG,GAAKM,EAAW,CAACN,EAAG,GAAKK,EAAUH,EACnDM,EAAKZ,EAAG,EAAKI,EAAG,GAAKM,EAAWN,EAAG,GAAKK,EAAUH,EAClDO,EAAa,KAAK,MAAMV,EAAG,GAAIA,EAAG,EAAE,EAAM,KAAK,GAAK,EAAKG,EACzDQ,EAAW,KAAK,MAAMV,EAAG,GAAIA,EAAG,EAAE,EAAM,KAAK,GAAK,EAAKE,EAEzDR,IAAM,GAEJZ,EAAA,OACEyB,EAAM,KAAK,IAAIE,CAAU,EAAIJ,EAC7BG,EAAM,KAAK,IAAIC,CAAU,EAAIJ,CAAA,EAIrCvB,EAAE,IAAIyB,EAAIC,EAAIH,EAASI,EAAYC,EAAUP,CAAa,EAErDR,EAAAC,CAAA,CAEb,CAiBO,SAASe,GACZ7B,EACAC,EACAC,EACA4B,EAEJ,CACI,IAAMC,EAAW,CAAClB,EAAeC,IAC7B,KAAK,MAAOD,EAAG,EAAIC,EAAG,IAAM,GAAOD,EAAG,EAAIC,EAAG,IAAM,CAAE,EAEnDkB,EAAY,CAACnB,EAAeC,EAAemB,KAAe,CAC5D,EAAGpB,EAAG,GAAMC,EAAG,EAAID,EAAG,GAAKoB,EAC3B,EAAGpB,EAAG,GAAMC,EAAG,EAAID,EAAG,GAAKoB,CAAA,GAGzBC,EAAYjC,EAAO,OAEzB,QAASW,EAAI,EAAGA,EAAIsB,EAAWtB,IAC/B,CACI,IAAMuB,EAAYlC,GAAQW,EAAI,GAAKsB,CAAS,EACtCnB,EAAUoB,EAAU,QAAUjC,EAEpC,GAAIa,GAAW,EACf,CACQH,IAAM,EAENZ,EAAE,OAAOmC,EAAU,EAAGA,EAAU,CAAC,EAIjCnC,EAAE,OAAOmC,EAAU,EAAGA,EAAU,CAAC,EAGrC,QAAA,CAGE,IAAAC,EAAYnC,EAAOW,CAAC,EACpByB,EAAYpC,GAAQW,EAAI,GAAKsB,CAAS,EAEtCI,EAAiBP,EAASK,EAAWD,CAAS,EAChDI,EAEJ,GAAID,EAAiB,KAETC,EAAAJ,MAGZ,CACI,IAAMK,EAAqB,KAAK,IAAIF,EAAiB,EAAGvB,CAAO,EAEvDwB,EAAAP,EACJG,EACAC,EACAI,EAAqBF,CAAA,CACzB,CAGE,IAAAG,EAAiBV,EAASM,EAAWF,CAAS,EAChDO,EAEJ,GAAID,EAAiB,KAEXC,EAAAP,MAGV,CACI,IAAMQ,EAAqB,KAAK,IAAIF,EAAiB,EAAG1B,CAAO,EAEzD2B,EAAAV,EACFG,EACAE,EACAM,EAAqBF,CAAA,CACzB,CAGA7B,IAAM,EAENZ,EAAE,OAAOuC,EAAM,EAAGA,EAAM,CAAC,EAIzBvC,EAAE,OAAOuC,EAAM,EAAGA,EAAM,CAAC,EAE3BvC,EAAA,iBAAiBmC,EAAU,EAAGA,EAAU,EAAGO,EAAI,EAAGA,EAAI,EAAGZ,CAAU,CAAA,CAE7E,CC3MA,IAAMc,GAAgB,IAAIC,EAwBbC,GAAN,KACP,CAQI,YAAYC,EACZ,CAPA,KAAO,gBAA6C,CAAA,EACpD,KAAQ,aAA+B,KAEtB,KAAA,QAAU,IAAIC,GAK3B,KAAK,gBAAkBD,EACvB,KAAK,OAASA,EAAe,aAAA,CAS1B,OAAOE,EAAWC,EACzB,CACS,YAAA,UAAUD,EAAGC,CAAC,EAEZ,IAAA,CASJ,OAAOD,EAAWC,EACzB,CACI,KAAK,YAAY,EAEX,IAAAC,EAAS,KAAK,aAAa,OAE3BC,EAAQD,EAAOA,EAAO,OAAS,CAAC,EAChCE,EAAQF,EAAOA,EAAO,OAAS,CAAC,EAElC,OAAAC,IAAUH,GAAKI,IAAUH,IAElBC,EAAA,KAAKF,EAAGC,CAAC,EAGb,IAAA,CAcJ,IAAID,EAAWC,EAAWI,EAAgBC,EAAoBC,EAAkBC,EACvF,CAGI,KAAK,YAAY,EAAK,EAEhB,IAAAN,EAAS,KAAK,aAAa,OAEjC,OAAAO,GAASP,EAAQF,EAAGC,EAAGI,EAAQC,EAAYC,EAAUC,CAAgB,EAE9D,IAAA,CAaJ,MAAME,EAAYC,EAAYC,EAAYC,EAAYR,EAC7D,CACI,KAAK,YAAY,EAEX,IAAAH,EAAS,KAAK,aAAa,OAEjC,OAAAY,GAAWZ,EAAQQ,EAAIC,EAAIC,EAAIC,EAAIR,CAAM,EAElC,IAAA,CAeJ,SACHU,EAAYC,EACZC,EAAuBC,EAAsBC,EAC7CnB,EAAWC,EAEf,CACU,IAAAC,EAAS,KAAK,aAAa,OAGjC,OAAAkB,GACIlB,EACA,KAAK,aAAa,MAClB,KAAK,aAAa,MAClBF,EACAC,EACAc,EACAC,EACAC,EACAC,EACAC,CAAA,EAGG,IAAA,CAgBJ,cACHE,EAAcC,EAAcC,EAAcC,EAC1CxB,EAAWC,EACXwB,EAEJ,CACI,KAAK,YAAY,EAEjB,IAAMC,EAAc,KAAK,aAKzB,OAAAC,GACI,KAAK,aAAa,OAClBD,EAAY,MAAOA,EAAY,MAC/BL,EAAMC,EAAMC,EAAMC,EAAMxB,EAAGC,EAC3BwB,CAAA,EAGG,IAAA,CAaJ,iBAAiBJ,EAAcC,EAActB,EAAWC,EAAW2B,EAC1E,CACI,KAAK,YAAY,EAEjB,IAAMF,EAAc,KAAK,aAKzB,OAAAG,GACI,KAAK,aAAa,OAClBH,EAAY,MAAOA,EAAY,MAC/BL,EAAMC,EAAMtB,EAAGC,EACf2B,CAAA,EAGG,IAAA,CAQJ,WACP,CACI,YAAK,QAAQ,EAAI,EAEV,IAAA,CASJ,QAAQE,EAAoBC,EACnC,CACI,KAAK,QAAQ,EAGTA,GAAa,CAACA,EAAU,WAAA,IAEjBD,EAAAA,EAAK,MAAM,EAAI,EACtBA,EAAK,UAAUC,CAAS,GAG5B,IAAMC,EAAkB,KAAK,gBACvBC,EAAQD,EAAgB,OAE9B,QAAS,EAAI,EAAG,EAAIF,EAAK,aAAa,OAAQ,IAC9C,CACU,IAAAI,EAAcJ,EAAK,aAAa,CAAC,EAEvC,KAAKI,EAAY,MAAM,EAAE,GAAIA,EAAY,IAA0D,CAAA,CAOvG,GAAIJ,EAAK,eAAiBE,EAAgB,OAASC,EAAQ,EAC3D,CACI,IAAIE,EAAY,KAGhB,QAASC,EAAIH,EAAOG,EAAIJ,EAAgB,OAAQI,IAChD,CACU,IAAAC,EAAiBL,EAAgBI,CAAC,EAEpC,GAAAC,EAAe,MAAM,OAAS,UAClC,CACI,IAAMC,EAAUD,EAAe,MACzBE,EAAcJ,GAAW,MAE3BI,GAAeA,EAAY,gBAAgBD,CAAO,GAGxCH,EAAA,QAAVA,EAAU,MAAU,CAAA,GACVA,EAAA,MAAM,KAAKE,CAAc,EAGnBL,EAAA,WAAWI,EAAGA,EAAI,CAAC,EACnBJ,EAAA,SAChBI,KAIYD,EAAAE,CAChB,CACJ,CACJ,CAGG,OAAA,IAAA,CAOJ,OAAOG,EAAY,GAC1B,CACI,KAAK,QAAQA,CAAS,CAAA,CAYnB,KAAKxC,EAAWC,EAAWwC,EAAWC,EAAWX,EACxD,CACS,YAAA,UAAU,IAAInC,EAAUI,EAAGC,EAAGwC,EAAGC,CAAC,EAAGX,CAAS,EAE5C,IAAA,CAWJ,OAAO/B,EAAWC,EAAWI,EAAgB0B,EACpD,CACI,YAAK,UAAU,IAAIY,GAAO3C,EAAGC,EAAGI,CAAM,EAAG0B,CAAS,EAE3C,IAAA,CAWJ,KAAK7B,EAAgC0C,EAAiBb,EAC7D,CACU,IAAAO,EAAU,IAAIO,GAAQ3C,CAAM,EAElC,OAAAoC,EAAQ,UAAYM,EAEf,KAAA,UAAUN,EAASP,CAAS,EAE1B,IAAA,CAaJ,YAAY/B,EAAWC,EAAWI,EAAgByC,EAAeC,EAAW,EAAGhB,EACtF,CACIe,EAAQ,KAAK,IAAIA,EAAQ,EAAG,CAAC,EAC7B,IAAMxC,EAAc,GAAK,KAAK,GAAK,EAAKyC,EAClCC,EAAS,KAAK,GAAK,EAAKF,EACxBR,EAAU,CAAA,EAEhB,QAASF,EAAI,EAAGA,EAAIU,EAAOV,IAC3B,CACU,IAAAa,EAAQ3C,EAAc8B,EAAIY,EAExBV,EAAA,KACJtC,EAAKK,EAAS,KAAK,IAAI4C,CAAK,EAC5BhD,EAAKI,EAAS,KAAK,IAAI4C,CAAK,CAAA,CAChC,CAGC,YAAA,KAAKX,EAAS,GAAMP,CAAS,EAE3B,IAAA,CAeJ,UACH/B,EAAWC,EACXI,EACAyC,EAAeI,EACfH,EAAW,EACXtB,EAEJ,CAGI,GAFAqB,EAAQ,KAAK,IAAKA,EAAQ,EAAI,CAAC,EAE3BI,GAAU,EAEV,OAAO,KAAK,YAAYlD,EAAGC,EAAGI,EAAQyC,EAAOC,CAAQ,EAGzD,IAAMI,EAAc9C,EAAS,KAAK,IAAI,KAAK,GAAKyC,CAAK,EAAK,KAEjDI,EAAA,KAAK,IAAIA,EAAQC,CAAU,EAEpC,IAAM7C,EAAc,GAAK,KAAK,GAAK,EAAKyC,EAClCC,EAAS,KAAK,GAAK,EAAKF,EACxBM,GAAkBN,EAAQ,GAAK,KAAK,GAAMA,EAAQ,EAExD,QAASV,EAAI,EAAGA,EAAIU,EAAOV,IAC3B,CACU,IAAAa,EAASb,EAAIY,EAAS1C,EACtB+C,EAAKrD,EAAKK,EAAS,KAAK,IAAI4C,CAAK,EACjCK,EAAKrD,EAAKI,EAAS,KAAK,IAAI4C,CAAK,EACjCM,EAAKN,EAAS,KAAK,GAAMG,EACzBI,EAAKP,EAAS,KAAK,GAAMG,EACzB1C,EAAK2C,EAAMH,EAAS,KAAK,IAAIK,CAAE,EAC/B5C,EAAK2C,EAAMJ,EAAS,KAAK,IAAIK,CAAE,EAC/BE,EAAKJ,EAAMH,EAAS,KAAK,IAAIM,CAAE,EAC/BE,EAAKJ,EAAMJ,EAAS,KAAK,IAAIM,CAAE,EAEjCpB,IAAM,EAED,KAAA,OAAO1B,EAAIC,CAAE,EAIb,KAAA,OAAOD,EAAIC,CAAE,EAEtB,KAAK,iBAAiB0C,EAAIC,EAAIG,EAAIC,EAAIjC,CAAU,CAAA,CAGpD,OAAO,KAAK,UAAU,CAAA,CAgBnB,WAAWvB,EAAwBG,EAAgBsD,EAAe,GAAOlC,EAChF,CACQ,OAAAvB,EAAO,OAAS,EAET,MAGPyD,EAE2BC,GAAA,KAAM1D,EAAQG,EAAQoB,CAAU,EAI3CoC,GAAA,KAAM3D,EAAQG,CAAM,EAGjC,KAAK,UAAU,EAAA,CAYnB,WAAWL,EAAWC,EAAW6D,EAAeC,EAAgBC,EACvE,CACI,GAAIA,IAAW,EAEX,OAAO,KAAK,KAAKhE,EAAGC,EAAG6D,EAAOC,CAAM,EAGxC,IAAME,EAAY,KAAK,IAAIH,EAAOC,CAAM,EAAI,EACtCG,EAAQ,KAAK,IAAID,EAAW,KAAK,IAAI,CAACA,EAAWD,CAAM,CAAC,EACxDG,EAAQnE,EAAI8D,EACZM,EAASnE,EAAI8D,EACbM,EAAMH,EAAQ,EAAI,CAACA,EAAQ,EAC3BI,EAAO,KAAK,IAAIJ,CAAK,EAE3B,OAAO,KACF,OAAOlE,EAAGC,EAAIqE,CAAI,EAClB,MAAMtE,EAAIqE,EAAKpE,EAAIoE,EAAKrE,EAAIsE,EAAMrE,EAAGqE,CAAI,EACzC,OAAOH,EAAQG,EAAMrE,CAAC,EACtB,MAAMkE,EAAQE,EAAKpE,EAAIoE,EAAKF,EAAOlE,EAAIqE,EAAMA,CAAI,EACjD,OAAOH,EAAOC,EAASE,CAAI,EAC3B,MAAMH,EAAQE,EAAKD,EAASC,EAAKrE,EAAI8D,EAAQQ,EAAMF,EAAQE,CAAI,EAC/D,OAAOtE,EAAIsE,EAAMF,CAAM,EACvB,MAAMpE,EAAIqE,EAAKD,EAASC,EAAKrE,EAAGoE,EAASE,EAAMA,CAAI,EACnD,UAAU,CAAA,CAYZ,YAAYtE,EAAWC,EAAW6D,EAAeC,EAAgBQ,EAAiBxC,EACzF,CACI,GAAIwC,GAAW,EAEX,OAAO,KAAK,KAAKvE,EAAGC,EAAG6D,EAAOC,CAAM,EAGlC,IAAAG,EAAQ,KAAK,IAAIK,EAAS,KAAK,IAAIT,EAAOC,CAAM,EAAI,CAAC,EACrDI,EAAQnE,EAAI8D,EACZM,EAASnE,EAAI8D,EACb7D,EAAS,CACXF,EAAIkE,EAAOjE,EACXkE,EAAQD,EAAOjE,EACfkE,EAAOlE,EAAIiE,EACXC,EAAOC,EAASF,EAChBC,EAAQD,EAAOE,EACfpE,EAAIkE,EAAOE,EACXpE,EAAGoE,EAASF,EACZlE,EAAGC,EAAIiE,CAAA,EAIX,QAAS9B,EAAIlC,EAAO,OAAS,EAAGkC,GAAK,EAAGA,GAAK,EAErClC,EAAOkC,CAAC,IAAMlC,EAAOkC,EAAI,CAAC,GAAKlC,EAAOkC,EAAI,CAAC,IAAMlC,EAAOkC,EAAI,CAAC,GAEtDlC,EAAA,OAAOkC,EAAI,EAAG,CAAC,EAI9B,OAAO,KAAK,KAAKlC,EAAQ,GAAM6B,CAAS,CAAA,CAarC,QAAQ/B,EAAWC,EAAWuE,EAAiBC,EAAiB1C,EACvE,CAGS,YAAA,UAAU,IAAI2C,GAAQ1E,EAAGC,EAAGuE,EAASC,CAAO,EAAG1C,CAAS,EAEtD,IAAA,CAeJ,UAAU/B,EAAWC,EAAWwC,EAAWC,EAAWrC,EAAiB0B,EAC9E,CACS,YAAA,UAAU,IAAI4C,GAAiB3E,EAAGC,EAAGwC,EAAGC,EAAGrC,CAAM,EAAG0B,CAAS,EAE3D,IAAA,CAYJ,UAAU6C,EAAuBC,EACxC,CACI,YAAK,QAAQ,EAEb,KAAK,gBAAgB,KAAK,CAAE,MAAAD,EAAO,UAAWC,CAAA,CAAQ,EAE/C,IAAA,CAUJ,UAAU7E,EAAWC,EAC5B,CACI,IAAIyB,EAAc,KAAK,aAEvB,OAAIA,GAEA,KAAK,QAAQ,EAGjBA,EAAc,IAAImB,GAENnB,EAAA,OAAO,KAAK1B,EAAGC,CAAC,EAE5B,KAAK,aAAeyB,EAEb,IAAA,CAWJ,QAAQc,EAAY,GAC3B,CACI,IAAMoC,EAAQ,KAAK,aAEnB,OAAIA,GAASA,EAAM,OAAO,OAAS,IAE/BA,EAAM,UAAYpC,EAElB,KAAK,gBAAgB,KAAK,CAAE,MAAAoC,CAAA,CAAO,GAGvC,KAAK,aAAe,KAEb,IAAA,CAGH,YAAY3C,EAAQ,GAC5B,CACI,GAAI,MAAK,eAEJ,KAAA,aAAe,IAAIY,GAEpBZ,GACJ,CAEI,IAAM6C,EAAY,KAAK,gBAAgB,KAAK,gBAAgB,OAAS,CAAC,EAEtE,GAAIA,EACJ,CAEQ,IAAAC,EAAKD,EAAU,MAAM,EACrBE,EAAKF,EAAU,MAAM,EAEzB,GAAIA,EAAU,WAAa,CAACA,EAAU,UAAU,WAAA,EAChD,CACI,IAAMG,EAAIH,EAAU,UAEdI,EAAQH,EAEdA,EAAME,EAAE,EAAIF,EAAOE,EAAE,EAAID,EAAMC,EAAE,GACjCD,EAAMC,EAAE,EAAIC,EAAUD,EAAE,EAAID,EAAMC,EAAE,EAAA,CAGxC,KAAK,aAAa,OAAO,KAAKF,EAAIC,CAAE,CAAA,MAIpC,KAAK,aAAa,OAAO,KAAK,EAAG,CAAC,CACtC,CACJ,CAIG,WACP,CACI,IAAMlD,EAAO,KAAK,gBAElB,KAAK,gBAAgB,OAAS,EAC9B,KAAK,aAAe,KAEpB,QAASM,EAAI,EAAGA,EAAIN,EAAK,aAAa,OAAQM,IAC9C,CACU,IAAAF,EAAcJ,EAAK,aAAaM,CAAC,EAGvC,KAAKF,EAAY,MAAM,EAAE,GAAIA,EAAY,IAA0D,CAAA,CAGvG,KAAK,OAAO,CAAA,CAIhB,IAAI,QACJ,CACI,IAAMiD,EAAS,KAAK,QAEpBA,EAAO,MAAM,EAEb,IAAMnD,EAAkB,KAAK,gBAE7B,QAASI,EAAI,EAAGA,EAAIJ,EAAgB,OAAQI,IAC5C,CACU,IAAAC,EAAiBL,EAAgBI,CAAC,EAElCgD,EAAa/C,EAAe,MAAM,UAAU1C,EAAa,EAE3D0C,EAAe,UAER8C,EAAA,QAAQC,EAAY/C,EAAe,SAAS,EAInD8C,EAAO,QAAQC,CAAU,CAC7B,CAGG,OAAAD,CAAA,CAEf,EC9tBO,IAAME,EAAN,MAAMC,CACb,CAkDI,YAAYC,EAA2CC,EAAS,GAChE,CAlDA,KAAO,aAAkC,CAAA,EAGzB,KAAA,IAAcC,GAAI,cAAc,EAEhD,KAAQ,OAAS,GA8Cb,KAAK,cAAgBD,EAEjB,OAAOD,GAAiB,SAExBG,GAAaH,EAAc,IAAI,EAI/B,KAAK,aAAeA,GAAc,MAAM,GAAK,CAAA,CACjD,CAhCJ,IAAI,WACJ,CACQ,OAAC,KAAK,aAED,KAAA,WAAa,IAAII,GAAU,IAAI,GAGpC,KAAK,SAEL,KAAK,OAAS,GACd,KAAK,WAAW,UAAU,GAGvB,KAAK,UAAA,CA4BT,QAAQC,EAAoBC,EACnC,CACI,OAAAD,EAAOA,EAAK,MAAM,EACb,KAAA,aAAa,KAAK,CAAE,OAAQ,UAAW,KAAM,CAACA,EAAMC,CAAS,CAAA,CAAG,EAErE,KAAK,OAAS,GAEP,IAAA,CAeJ,OAAOC,EACd,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,MAAO,KAAMA,CAAA,CAAM,EAEpD,KAAK,OAAS,GAEP,IAAA,CAcJ,SAASA,EAChB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,QAAS,KAAMA,CAAA,CAAM,EAEtD,KAAK,OAAS,GAEP,IAAA,CAiBJ,YAAYA,EACnB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,WAAY,KAAMA,CAAA,CAAM,EAEzD,KAAK,OAAS,GAEP,IAAA,CAqBJ,iBAAiBA,EACxB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,gBAAiB,KAAMA,CAAA,CAAM,EAE9D,KAAK,OAAS,GAEP,IAAA,CAcJ,mBAAmBC,EAAcC,EAAcC,EAAWC,EAAWC,EAC5E,CACI,IAAMC,EAAO,KAAK,aAAa,KAAK,aAAa,OAAS,CAAC,EAErDC,EAAY,KAAK,aAAaC,GAAM,MAAM,EAE5CC,EAAO,EACPC,EAAO,EAEX,GAAI,CAACJ,GAAQA,EAAK,SAAW,gBAEzBG,EAAOF,EAAU,EACjBG,EAAOH,EAAU,MAGrB,CACWE,EAAAH,EAAK,KAAK,CAAC,EACXI,EAAAJ,EAAK,KAAK,CAAC,EAElB,IAAMK,EAAWJ,EAAU,EACrBK,EAAWL,EAAU,EAE3BE,EAAOE,GAAYA,EAAWF,GAC9BC,EAAOE,GAAYA,EAAWF,EAAA,CAGlC,YAAK,aAAa,KAAK,CAAE,OAAQ,gBAAiB,KAAM,CAACD,EAAMC,EAAMT,EAAMC,EAAMC,EAAGC,EAAGC,CAAU,CAAA,CAAG,EAEpG,KAAK,OAAS,GAEP,IAAA,CAQJ,WACP,CACS,YAAA,aAAa,KAAK,CAAE,OAAQ,YAAa,KAAM,CAAA,CAAA,CAAI,EAExD,KAAK,OAAS,GAEP,IAAA,CAcJ,WAAWL,EAClB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,UAAW,KAAMA,CAAA,CAAM,EAIxD,KAAK,OAAS,GAEP,IAAA,CAUJ,UAAUA,EACjB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,SAAU,KAAMA,CAAA,CAAM,EAEvD,KAAK,OAAS,GAEP,IAAA,CAUJ,UAAUA,EACjB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,SAAU,KAAMA,CAAA,CAAM,EAEhD,IAAA,CAcJ,oBAAoBA,EAC3B,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,mBAAoB,KAAMA,CAAA,CAAM,EAEjE,KAAK,OAAS,GAEP,IAAA,CAUJ,sBAAsBG,EAAWC,EAAWC,EACnD,CAEI,IAAMC,EAAO,KAAK,aAAa,KAAK,aAAa,OAAS,CAAC,EAErDC,EAAY,KAAK,aAAaC,GAAM,MAAM,EAE5CK,EAAO,EACPC,EAAO,EAEX,GAAI,CAACR,GAAQA,EAAK,SAAW,mBAEzBO,EAAON,EAAU,EACjBO,EAAOP,EAAU,MAGrB,CACWM,EAAAP,EAAK,KAAK,CAAC,EACXQ,EAAAR,EAAK,KAAK,CAAC,EAElB,IAAMK,EAAWJ,EAAU,EACrBK,EAAWL,EAAU,EAE3BM,EAAOF,GAAYA,EAAWE,GAC9BC,EAAOF,GAAYA,EAAWE,EAAA,CAGlC,YAAK,aAAa,KAAK,CAAE,OAAQ,mBAAoB,KAAM,CAACD,EAAMC,EAAMX,EAAGC,EAAGC,CAAU,CAAA,CAAG,EAE3F,KAAK,OAAS,GAEP,IAAA,CAYJ,KAAKF,EAAWC,EAAWW,EAAWC,EAAWjB,EACxD,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,OAAQ,KAAM,CAACI,EAAGC,EAAGW,EAAGC,EAAGjB,CAAS,CAAA,CAAG,EAExE,KAAK,OAAS,GAEP,IAAA,CAWJ,OAAOI,EAAWC,EAAWa,EAAgBlB,EACpD,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,SAAU,KAAM,CAACI,EAAGC,EAAGa,EAAQlB,CAAS,CAAA,CAAG,EAE5E,KAAK,OAAS,GAEP,IAAA,CAgBJ,aAAaC,EACpB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,YAAa,KAAMA,CAAA,CAAM,EAE1D,KAAK,OAAS,GAEP,IAAA,CAaJ,QAAQA,EACf,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,OAAQ,KAAMA,CAAA,CAAM,EAErD,KAAK,OAAS,GAEP,IAAA,CAcJ,eAAeA,EACtB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,cAAe,KAAMA,CAAA,CAAM,EAE5D,KAAK,OAAS,GAEP,IAAA,CAeJ,aAAaA,EACpB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,YAAa,KAAMA,CAAA,CAAM,EAE1D,KAAK,OAAS,GAEP,IAAA,CAiBJ,cAAcA,EACrB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,aAAc,KAAMA,CAAA,CAAM,EAE3D,KAAK,OAAS,GAEP,IAAA,CAaJ,cAAcA,EACrB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,aAAc,KAAMA,CAAA,CAAM,EAE3D,KAAK,OAAS,GAEP,IAAA,CAaJ,eAAeA,EACtB,CACI,YAAK,aAAa,KAAK,CAAE,OAAQ,cAAe,KAAMA,CAAA,CAAM,EAE5D,KAAK,OAAS,GAEP,IAAA,CAsBJ,KAAKG,EAAWC,EAAWc,EAAgBD,EAAgBE,EAAsBC,EAAmBrB,EAC3G,CACIoB,IAAAA,EAAgBF,EAAS,GAEzB,IAAMI,EAAc,GAAK,KAAK,GAAK,EAAKD,EAClCE,EAAMJ,EAAS,EACfK,EAAS,KAAK,GAAK,EAAKD,EACxBE,EAAU,CAAA,EAEhB,QAASC,EAAI,EAAGA,EAAIH,EAAKG,IACzB,CACU,IAAAC,EAAID,EAAI,EAAIN,EAAcF,EAC1BU,EAASF,EAAIF,EAASF,EAEpBG,EAAA,KACJrB,EAAKuB,EAAI,KAAK,IAAIC,CAAK,EACvBvB,EAAKsB,EAAI,KAAK,IAAIC,CAAK,CAAA,CAC3B,CAGC,YAAA,KAAKH,EAAS,GAAMzB,CAAS,EAE3B,IAAA,CAWJ,MAAM6B,EAAO,GACpB,CACU,IAAAC,EAAoB,IAAIrC,EAI9B,GAFAqC,EAAkB,cAAgB,KAAK,cAEnC,CAACD,EAEiBC,EAAA,aAAe,KAAK,aAAa,MAAM,MAIzD,SAASJ,EAAI,EAAGA,EAAI,KAAK,aAAa,OAAQA,IAC9C,CACU,IAAAK,EAAc,KAAK,aAAaL,CAAC,EAErBI,EAAA,aAAa,KAAK,CAAE,OAAQC,EAAY,OAAQ,KAAMA,EAAY,KAAK,MAAM,CAAA,CAAG,CAAA,CAInG,OAAAD,CAAA,CAGJ,OACP,CACI,YAAK,aAAa,OAAS,EAC3B,KAAK,OAAS,GAEP,IAAA,CAiBJ,UAAUE,EACjB,CACI,GAAIA,EAAO,WAAW,EAAU,OAAA,KAEhC,IAAMC,EAAID,EAAO,EACXE,EAAIF,EAAO,EACXG,EAAIH,EAAO,EACXI,EAAIJ,EAAO,EACXK,EAAKL,EAAO,GACZM,EAAKN,EAAO,GAEd5B,EAAI,EACJC,EAAI,EAEJS,EAAO,EACPC,EAAO,EACPwB,EAAO,EACPC,EAAO,EAEPC,EAAK,EACLC,EAAK,EAET,QAAShB,EAAI,EAAGA,EAAI,KAAK,aAAa,OAAQA,IAC9C,CACU,IAAAK,EAAc,KAAK,aAAaL,CAAC,EACjCiB,EAAOZ,EAAY,KAEzB,OAAQA,EAAY,OACpB,CACI,IAAK,SACL,IAAK,SAED3B,EAAIuC,EAAK,CAAC,EACVtC,EAAIsC,EAAK,CAAC,EAEVA,EAAK,CAAC,EAAKV,EAAI7B,EAAM+B,EAAI9B,EAAKgC,EAC9BM,EAAK,CAAC,EAAKT,EAAI9B,EAAMgC,EAAI/B,EAAKiC,EAC9B,MACJ,IAAK,gBAEDxB,EAAO6B,EAAK,CAAC,EACb5B,EAAO4B,EAAK,CAAC,EACbJ,EAAOI,EAAK,CAAC,EACbH,EAAOG,EAAK,CAAC,EAEbvC,EAAIuC,EAAK,CAAC,EACVtC,EAAIsC,EAAK,CAAC,EAEVA,EAAK,CAAC,EAAKV,EAAInB,EAASqB,EAAIpB,EAAQsB,EACpCM,EAAK,CAAC,EAAKT,EAAIpB,EAASsB,EAAIrB,EAAQuB,EACpCK,EAAK,CAAC,EAAKV,EAAIM,EAASJ,EAAIK,EAAQH,EACpCM,EAAK,CAAC,EAAKT,EAAIK,EAASH,EAAII,EAAQF,EACpCK,EAAK,CAAC,EAAKV,EAAI7B,EAAM+B,EAAI9B,EAAKgC,EAC9BM,EAAK,CAAC,EAAKT,EAAI9B,EAAMgC,EAAI/B,EAAKiC,EAC9B,MAEJ,IAAK,mBAEDxB,EAAO6B,EAAK,CAAC,EACb5B,EAAO4B,EAAK,CAAC,EAEbvC,EAAIuC,EAAK,CAAC,EACVtC,EAAIsC,EAAK,CAAC,EAEVA,EAAK,CAAC,EAAKV,EAAInB,EAASqB,EAAIpB,EAAQsB,EACpCM,EAAK,CAAC,EAAKT,EAAIpB,EAASsB,EAAIrB,EAAQuB,EAEpCK,EAAK,CAAC,EAAKV,EAAI7B,EAAM+B,EAAI9B,EAAKgC,EAC9BM,EAAK,CAAC,EAAKT,EAAI9B,EAAMgC,EAAI/B,EAAKiC,EAE9B,MAEJ,IAAK,WAEDlC,EAAIuC,EAAK,CAAC,EACVtC,EAAIsC,EAAK,CAAC,EAEVF,EAAKE,EAAK,CAAC,EACXD,EAAKC,EAAK,CAAC,EAIXA,EAAK,CAAC,EAAKV,EAAIQ,EAAON,EAAIO,EAC1BC,EAAK,CAAC,EAAKT,EAAIO,EAAOL,EAAIM,EAE1BC,EAAK,CAAC,EAAKV,EAAI7B,EAAM+B,EAAI9B,EAAKgC,EAC9BM,EAAK,CAAC,EAAKT,EAAI9B,EAAMgC,EAAI/B,EAAKiC,EAE9B,MAEJ,IAAK,SACDK,EAAK,CAAC,EAAIC,GAAgBD,EAAK,CAAC,EAAGX,CAAM,EACzC,MACJ,IAAK,OACDW,EAAK,CAAC,EAAIC,GAAgBD,EAAK,CAAC,EAAGX,CAAM,EACzC,MACJ,IAAK,UACDW,EAAK,CAAC,EAAIC,GAAgBD,EAAK,CAAC,EAAGX,CAAM,EACzC,MACJ,IAAK,YACDW,EAAK,CAAC,EAAIC,GAAgBD,EAAK,CAAC,EAAGX,CAAM,EACzC,MACJ,IAAK,UACIW,EAAA,CAAC,EAAE,UAAUX,CAAM,EACxB,MACJ,IAAK,OACDW,EAAK,CAAC,EAAIC,GAAgBD,EAAK,CAAC,EAAGX,CAAM,EACzC,MACJ,QAESa,EAAA,2BAA4Bd,EAAY,MAAM,EAEnD,KAAA,CACR,CAGJ,YAAK,OAAS,GAEP,IAAA,CAGX,IAAI,QACJ,CACI,OAAO,KAAK,UAAU,MAAA,CAiBnB,aAAae,EACpB,CACQ,IAAAC,EAAQ,KAAK,aAAa,OAAS,EAEnCC,EAAkB,KAAK,aAAaD,CAAK,EAE7C,GAAI,CAACC,EAED,OAAAF,EAAI,EAAI,EACRA,EAAI,EAAI,EAEDA,EAGJ,KAAAE,EAAgB,SAAW,aAClC,CAGI,GAFAD,IAEIA,EAAQ,EAER,OAAAD,EAAI,EAAI,EACRA,EAAI,EAAI,EAEDA,EAGOE,EAAA,KAAK,aAAaD,CAAK,CAAA,CAG7C,OAAQC,EAAgB,OACxB,CACI,IAAK,SACL,IAAK,SACGF,EAAA,EAAIE,EAAgB,KAAK,CAAC,EAC1BF,EAAA,EAAIE,EAAgB,KAAK,CAAC,EAC9B,MACJ,IAAK,mBACGF,EAAA,EAAIE,EAAgB,KAAK,CAAC,EAC1BF,EAAA,EAAIE,EAAgB,KAAK,CAAC,EAC9B,MACJ,IAAK,gBACGF,EAAA,EAAIE,EAAgB,KAAK,CAAC,EAC1BF,EAAA,EAAIE,EAAgB,KAAK,CAAC,EAC9B,MACJ,IAAK,MACL,IAAK,WACGF,EAAA,EAAIE,EAAgB,KAAK,CAAC,EAC1BF,EAAA,EAAIE,EAAgB,KAAK,CAAC,EAC9B,MACJ,IAAK,UAEDA,EAAgB,KAAK,CAAC,EAAE,aAAaF,CAAG,EACxC,KAAA,CAGD,OAAAA,CAAA,CAEf,EAEA,SAASF,GAAgBK,EAAwBjD,EACjD,CACI,OAAIiD,EAEOA,EAAc,QAAQjD,CAAS,EAGnCA,EAAU,MAAM,CAC3B,CC/0BgB,SAAAkD,EAAuBC,EAAiBC,EAAYC,EACpE,CACU,IAAAC,EAAQH,EAAI,aAAaC,CAAE,EAE1B,OAAAE,EAAQ,OAAOA,CAAK,EAAID,CACnC,CCLgB,SAAAE,GAAoBC,EAAiBC,EACrD,CAEU,IAAAC,EAAcF,EAAI,iBAAiB,MAAM,EAG/C,QAASG,EAAI,EAAGA,EAAID,EAAY,OAAQC,IACxC,CACU,IAAAC,EAAaF,EAAYC,CAAC,EAGhC,QAASE,EAAI,EAAGA,EAAID,EAAW,SAAS,OAAQC,IAChD,CACU,IAAAC,EAAQF,EAAW,SAASC,CAAC,EAG3B,OAAAC,EAAM,SAAS,YAAA,EACvB,CACI,IAAK,iBAEDL,EAAQ,KAAKK,EAAM,EAAE,EAAIC,GAAoBD,CAAmB,EAChE,MACJ,IAAK,iBACDL,EAAQ,KAAKK,EAAM,EAAE,EAAIE,GAAoBF,CAAmB,EAChE,MACJ,QACI,KAAA,CACR,CACJ,CAER,CAOA,SAASC,GAAoBD,EAC7B,CAEI,IAAMG,EAAKC,EAAuBJ,EAAO,KAAM,CAAC,EAC1CK,EAAKD,EAAuBJ,EAAO,KAAM,CAAC,EAC1CM,EAAKF,EAAuBJ,EAAO,KAAM,CAAC,EAC1CO,EAAKH,EAAuBJ,EAAO,KAAM,CAAC,EAG1CQ,EAAeR,EAAM,aAAa,eAAe,GAAK,oBAGtDS,EAAW,IAAIC,EACjBP,EACAE,EACAC,EACAC,EACAC,IAAiB,oBAAsB,QAAU,QAAA,EAIrD,QAASG,EAAI,EAAGA,EAAIX,EAAM,SAAS,OAAQW,IAC3C,CACU,IAAAC,EAAOZ,EAAM,SAASW,CAAC,EAGvBE,EAAST,EAAuBQ,EAAM,SAAU,CAAC,EACjDE,EAAQC,EAAM,OAAO,SAASH,EAAK,aAAa,YAAY,CAAC,EAAE,SAAS,EAErEH,EAAA,aAAaI,EAAQC,CAAK,CAAA,CAGhC,OAAAL,CACX,CAQA,SAASP,GAAoBc,EAC7B,CAEI,OAAAC,EAAK,qDAAqD,EAGnD,IAAIP,EAAa,EAAG,EAAG,EAAG,CAAC,CACtC,CC7EO,SAASQ,GAAgBC,EAChC,CAEU,IAAAC,EAAQD,EAAI,MAAM,+CAA+C,EAEhE,OAAAC,EAAQA,EAAM,CAAC,EAAI,EAC9B,CCbO,IAAMC,GAAkB,CAE3B,KAAM,CAAE,KAAM,QAAS,QAAS,CAAE,EAClC,eAAgB,CAAE,KAAM,SAAU,QAAS,CAAE,EAG7C,OAAQ,CAAE,KAAM,QAAS,QAAS,CAAE,EACpC,eAAgB,CAAE,KAAM,SAAU,QAAS,CAAE,EAC7C,iBAAkB,CAAE,KAAM,SAAU,QAAS,CAAE,EAC/C,iBAAkB,CAAE,KAAM,SAAU,QAAS,MAAO,EACpD,kBAAmB,CAAE,KAAM,SAAU,QAAS,OAAQ,EACtD,oBAAqB,CAAE,KAAM,SAAU,QAAS,EAAG,EACnD,mBAAoB,CAAE,KAAM,SAAU,QAAS,MAAO,EACtD,oBAAqB,CAAE,KAAM,SAAU,QAAS,CAAE,EAGlD,QAAS,CAAE,KAAM,SAAU,QAAS,CAAE,CAC1C,EAyBgB,SAAAC,GAAcC,EAAiBC,EAC/C,CACU,IAAAC,EAAQF,EAAI,aAAa,OAAO,EAEhCG,EAA2B,CAAA,EAE3BC,EAAuB,CAAA,EAEvBC,EAAsB,CACxB,YAAAF,EACA,UAAAC,EACA,QAAS,GACT,UAAW,EAAA,EAIf,QAAWE,KAAOR,GAClB,CACU,IAAAS,EAAYP,EAAI,aAAaM,CAAG,EAElCC,GAEAC,GAAeP,EAASI,EAAQC,EAAKC,EAAU,KAAA,CAAM,CACzD,CAIJ,GAAIL,EACJ,CACU,IAAAO,EAAaP,EAAM,MAAM,GAAG,EAElC,QAASQ,EAAI,EAAGA,EAAID,EAAW,OAAQC,IACvC,CACI,IAAMC,EAAYF,EAAWC,CAAC,EAAE,KAAK,EAE/B,CAACJ,EAAKM,CAAK,EAAID,EAAU,MAAM,GAAG,EAEpCb,GAAgBQ,CAAmC,GAEnDE,GAAeP,EAASI,EAAQC,EAAKM,EAAM,KAAA,CAAM,CACrD,CACJ,CAGG,MAAA,CACH,YAAaP,EAAO,UAAaF,EAAuC,KACxE,UAAWE,EAAO,QAAWD,EAAmC,KAChE,QAASC,EAAO,QAChB,UAAWA,EAAO,SAAA,CAE1B,CAUA,SAASG,GACLP,EACAI,EACAQ,EACAD,EAEJ,CACI,OAAQC,EACR,CACI,IAAK,SACD,GAAID,IAAU,OACd,CACQ,GAAAA,EAAM,WAAW,MAAM,EAC3B,CAEUC,IAAAA,EAAKC,GAAgBF,CAAK,EAEhCP,EAAO,YAAY,KAAOJ,EAAQ,KAAKY,CAAE,CAAA,MAKzCR,EAAO,YAAY,MAAQU,EAAM,OAAO,SAASH,CAAK,EAAE,SAAS,EAGrEP,EAAO,UAAY,EAAA,CAGvB,MACJ,IAAK,eACMA,EAAA,YAAY,MAAQ,OAAOO,CAAK,EACvC,MACJ,IAAK,OACD,GAAIA,IAAU,OACd,CACQ,GAAAA,EAAM,WAAW,MAAM,EAC3B,CAEUC,IAAAA,EAAKC,GAAgBF,CAAK,EAEhCP,EAAO,UAAU,KAAOJ,EAAQ,KAAKY,CAAE,CAAA,MAKvCR,EAAO,UAAU,MAAQU,EAAM,OAAO,SAASH,CAAK,EAAE,SAAS,EAGnEP,EAAO,QAAU,EAAA,CAErB,MACJ,IAAK,eACMA,EAAA,UAAU,MAAQ,OAAOO,CAAK,EACrC,MACJ,IAAK,iBACMP,EAAA,YAAY,MAAQ,OAAOO,CAAK,EACvC,MACJ,IAAK,UAEMP,EAAA,UAAU,MAAQ,OAAOO,CAAK,EAC9BP,EAAA,YAAY,MAAQ,OAAOO,CAAK,EACvC,KAAA,CAEZ,CCzKO,SAASI,GAAsBC,EACtC,CACQ,GAAAA,EAAiB,QAAU,EAEpB,MAAA,GAGX,IAAMC,EAAQD,EAAiB,IAAKE,GAAMA,EAAE,IAAI,EAAE,KAAK,CAAC,EAAGC,IAAMA,EAAI,CAAC,EAEhE,CAACC,EAAaC,CAAU,EAAIJ,EAC5BK,EAAeL,EAAMA,EAAM,OAAS,CAAC,EAErCM,EAAuBH,EAAcC,EACrCG,EAAwBH,EAAaC,EAKvC,MAAA,EAAAC,EAAuB,GAAKC,EAAwB,EAM5D,CC3BO,SAASC,GAAgBC,EAChC,CAKW,OAHOA,EAAS,MAAM,UAAU,EAChB,OAAQC,GAASA,EAAK,KAAA,EAAO,OAAS,CAAC,CAGlE,CAQO,SAASC,GAAkBF,EAClC,CACU,IAAAG,EAASH,EAAS,MAAM,uBAAuB,EAEjD,GAAA,CAACG,GAAUA,EAAO,OAAS,EAAU,MAAA,GAEnC,IAAAC,EAAUD,EAAO,IAAI,MAAM,EAC3BE,EAAK,CAAA,EACLC,EAAK,CAAA,EAEX,QAASC,EAAI,EAAGA,EAAIH,EAAQ,OAAQG,GAAK,EAEjCA,EAAI,EAAIH,EAAQ,SAEbC,EAAA,KAAKD,EAAQG,CAAC,CAAC,EAClBD,EAAG,KAAKF,EAAQG,EAAI,CAAC,CAAC,GAI9B,GAAIF,EAAG,SAAW,GAAKC,EAAG,SAAW,EAAU,MAAA,GAE/C,IAAME,EAAO,KAAK,IAAI,GAAGH,CAAE,EACrBI,EAAO,KAAK,IAAI,GAAGJ,CAAE,EACrBK,EAAO,KAAK,IAAI,GAAGJ,CAAE,EACrBK,EAAO,KAAK,IAAI,GAAGL,CAAE,EAIpB,OAFOG,EAAOD,IAASG,EAAOD,EAGzC,CAQgB,SAAAE,GAAcZ,EAAkBa,EAChD,CACI,IAAMC,EAAW,IAAIC,EAAaf,EAAU,EAAK,EAEtC,QAAAgB,KAAeF,EAAS,aAElBD,EAAA,aAAa,KAAKG,CAAW,CAElD,CChCgB,SAAAC,GACZC,EACAC,EAEJ,CAEQ,GAAA,OAAOD,GAAQ,SACnB,CAEU,IAAAE,EAAM,SAAS,cAAc,KAAK,EAEpCA,EAAA,UAAYF,EAAI,KAAK,EACnBA,EAAAE,EAAI,cAAc,KAAK,CAAA,CAIjC,IAAMC,EAAU,CACZ,QAASF,EACT,KAAM,CAAA,EACN,KAAM,IAAIG,CAAa,EAI3BC,GAAoBL,EAAKG,CAAO,EAGhC,IAAMG,EAAWN,EAAI,SAEf,CAAE,UAAAO,EAAW,YAAAC,CAAA,EAAgBC,GAAcT,EAAKG,CAAO,EAE7D,QAASO,EAAI,EAAGA,EAAIJ,EAAS,OAAQI,IACrC,CACU,IAAAC,EAAQL,EAASI,CAAC,EAEpBC,EAAM,SAAS,YAAA,IAAkB,QACtBC,GAAAD,EAAOR,EAASI,EAAWC,CAAW,CAAA,CAGlD,OAAAP,CACX,CAUA,SAASW,GAAeZ,EAAiBG,EAAkBI,EAAsBC,EACjF,CACI,IAAMF,EAAWN,EAAI,SAGf,CAAE,UAAWa,EAAI,YAAaC,CAAA,EAAOL,GAAcT,EAAKG,CAAO,EAEjEU,GAAMN,EAENA,EAAY,CAAE,GAAGA,EAAW,GAAGM,CAAG,EAE7BA,IAEON,EAAAM,GAGZC,GAAMN,EAENA,EAAc,CAAE,GAAGA,EAAa,GAAGM,CAAG,EAEjCA,IAESN,EAAAM,GAGZ,IAAAC,EAAU,CAACR,GAAa,CAACC,EAG3BO,IAEYR,EAAA,CAAE,MAAO,CAAE,GAIvB,IAAAS,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGI,OAAAhC,EAAI,SAAS,YAAA,EACrB,CACI,IAAK,OACL,CACQ6B,EAAA7B,EAAI,aAAa,GAAG,EAElB,IAAAiC,EAAWjC,EAAI,aAAa,WAAW,EAEvCkC,EAAWC,GAAgBN,CAAC,EAC5BO,EAAqBH,IAAa,UAClCI,EAAsBH,EAAS,OAAS,EAI9C,GAF2BE,GAAsBC,EAGjD,CACI,IAAMC,EAAmBJ,EAAS,IAAKK,IAAa,CAChD,KAAMA,EACN,KAAMC,GAAkBD,CAAO,CAAA,EACjC,EAOF,GALAD,EAAiB,KAAK,CAACG,EAAGC,IAAMA,EAAE,KAAOD,EAAE,IAAI,EAGdP,EAAS,OAAS,GAAK,CAACS,GAAsBL,CAAgB,EAK3F,QAAS5B,EAAI,EAAGA,EAAI4B,EAAiB,OAAQ5B,IAC7C,CACU,IAAA6B,EAAUD,EAAiB5B,CAAC,EAC5BkC,GAAclC,IAAM,EAE1BP,EAAQ,QAAQ,UAAU,EAC1B,IAAM0C,EAAU,IAAIzC,EAAa,OAAW,EAAI,EAElC0C,GAAAP,EAAQ,KAAMM,CAAO,EAC3B1C,EAAA,QAAQ,KAAK0C,CAAO,EAExBD,IAEIrC,GAAmBJ,EAAA,QAAQ,KAAKI,CAAS,EACzCC,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,GAInDL,EAAQ,QAAQ,IAAI,CACxB,KAMJ,SAASO,EAAI,EAAGA,EAAI4B,EAAiB,OAAQ5B,IAC7C,CACU,IAAA6B,EAAUD,EAAiB5B,CAAC,EAC5BqC,GAASrC,EAAI,IAAM,EAEzBP,EAAQ,QAAQ,UAAU,EAC1B,IAAM0C,EAAU,IAAIzC,EAAa,OAAW,EAAI,EAElC0C,GAAAP,EAAQ,KAAMM,CAAO,EAC3B1C,EAAA,QAAQ,KAAK0C,CAAO,EAExBE,GAEA5C,EAAQ,QAAQ,IAAI,GAIhBI,GAAmBJ,EAAA,QAAQ,KAAKI,CAAS,EACzCC,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,EACvD,CAER,KAGJ,CACU,IAAAwC,EAA4Bf,EAAYA,IAAa,UAAa,GAEzDH,EAAA,IAAI1B,EAAayB,EAAGmB,CAAyB,EACpD7C,EAAA,QAAQ,KAAK2B,CAAY,EAC7BvB,GAAmBJ,EAAA,QAAQ,KAAKI,CAAS,EACzCC,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,CAAA,CAEvD,KAAA,CAGJ,IAAK,SACIc,EAAA2B,EAAuBjD,EAAK,KAAM,CAAC,EACnCuB,EAAA0B,EAAuBjD,EAAK,KAAM,CAAC,EACpCwB,EAAAyB,EAAuBjD,EAAK,IAAK,CAAC,EACtCG,EAAQ,QAAQ,QAAQmB,EAAIC,EAAIC,EAAGA,CAAC,EAChCjB,GAAmBJ,EAAA,QAAQ,KAAKI,CAAS,EACzCC,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,EACnD,MAEJ,IAAK,OACGQ,EAAAiC,EAAuBjD,EAAK,IAAK,CAAC,EAClCiB,EAAAgC,EAAuBjD,EAAK,IAAK,CAAC,EAC9B+B,EAAAkB,EAAuBjD,EAAK,QAAS,CAAC,EACrCgC,EAAAiB,EAAuBjD,EAAK,SAAU,CAAC,EAC3CyB,EAAAwB,EAAuBjD,EAAK,KAAM,CAAC,EACnC0B,EAAAuB,EAAuBjD,EAAK,KAAM,CAAC,EAEpCyB,GAAMC,EAENvB,EAAQ,QAAQ,UAAUa,EAAGC,EAAGc,EAAOC,EAAQP,GAAMC,CAAE,EAIvDvB,EAAQ,QAAQ,KAAKa,EAAGC,EAAGc,EAAOC,CAAM,EAGxCzB,GAAmBJ,EAAA,QAAQ,KAAKI,CAAS,EACzCC,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,EACnD,MAEJ,IAAK,UACIc,EAAA2B,EAAuBjD,EAAK,KAAM,CAAC,EACnCuB,EAAA0B,EAAuBjD,EAAK,KAAM,CAAC,EACnCyB,EAAAwB,EAAuBjD,EAAK,KAAM,CAAC,EACnC0B,EAAAuB,EAAuBjD,EAAK,KAAM,CAAC,EAExCG,EAAQ,QAAQ,UAAU,EAC1BA,EAAQ,QAAQ,QAAQmB,EAAIC,EAAIE,EAAIC,CAAE,EAElCnB,GAAmBJ,EAAA,QAAQ,KAAKI,CAAS,EACzCC,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,EACnD,MAEJ,IAAK,OACIU,EAAA+B,EAAuBjD,EAAK,KAAM,CAAC,EACnCmB,EAAA8B,EAAuBjD,EAAK,KAAM,CAAC,EACnCoB,EAAA6B,EAAuBjD,EAAK,KAAM,CAAC,EACnCqB,EAAA4B,EAAuBjD,EAAK,KAAM,CAAC,EAExCG,EAAQ,QAAQ,UAAU,EAClBA,EAAA,QAAQ,OAAOe,EAAIC,CAAE,EACrBhB,EAAA,QAAQ,OAAOiB,EAAIC,CAAE,EAEzBb,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,EACnD,MAEJ,IAAK,UACcoB,EAAA5B,EAAI,aAAa,QAAQ,EAC/B2B,EAAAC,EAAa,MAAM,MAAM,EAAE,IAAKsB,GAAM,SAASA,EAAG,EAAE,CAAC,EACtD/C,EAAA,QAAQ,KAAKwB,EAAQ,EAAI,EAC7BpB,GAAmBJ,EAAA,QAAQ,KAAKI,CAAS,EACzCC,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,EACnD,MAEJ,IAAK,WACcoB,EAAA5B,EAAI,aAAa,QAAQ,EAC/B2B,EAAAC,EAAa,MAAM,MAAM,EAAE,IAAKsB,GAAM,SAASA,EAAG,EAAE,CAAC,EACtD/C,EAAA,QAAQ,KAAKwB,EAAQ,EAAK,EAC9BnB,GAAqBL,EAAA,QAAQ,OAAOK,CAAW,EACnD,MAGJ,IAAK,IACL,IAAK,MACD,MAEJ,QAAS,CAEA2C,EAAA,iBAAiBnD,EAAI,QAAQ,wBAAwB,EAC1D,KAAA,CACJ,CAGAe,IAEYR,EAAA,MAIhB,QAASG,EAAI,EAAGA,EAAIJ,EAAS,OAAQI,IAEjCE,GAAeN,EAASI,CAAC,EAAiBP,EAASI,EAAWC,CAAW,CAEjF,CClTA,SAAS4C,GAAYC,EACrB,CACW,OAAAC,EAAM,YAAYD,CAAoB,CACjD,CAEA,SAASE,GAAcF,EACvB,CACI,OAAOA,aAAiBG,EAC5B,CAEA,SAASC,GAAeJ,EACxB,CACI,OAAOA,aAAiBK,CAC5B,CAEA,SAASC,GAAUN,EACnB,CACI,OAAOA,aAAiBO,CAC5B,CAYA,SAASC,GACLC,EACAT,EACAU,EAEJ,CACI,IAAMC,EAAOV,EAAM,OAAO,SAASD,GAAS,CAAC,EAExC,OAAAS,EAAA,MAAQE,EAAK,SAAS,EAC3BF,EAAK,MAAQE,EAAK,QAAU,EAAID,EAAa,MAAQC,EAAK,MAC1DF,EAAK,QAAUF,EAAQ,MAEhB,CAAE,GAAGG,EAAc,GAAGD,CAAK,CACtC,CAUA,SAASG,GAAcH,EAAiBT,EAAgBU,EACxD,CACI,OAAAD,EAAK,QAAUT,EAER,CAAE,GAAGU,EAAc,GAAGD,CAAK,CACtC,CAUA,SAASI,GACLJ,EACAT,EACAU,EAEJ,CACI,OAAAD,EAAK,KAAOT,EACZS,EAAK,MAAQ,SACbA,EAAK,QAAUT,EAAM,QACrBS,EAAK,OAAST,EAAM,UAEb,CAAE,GAAGU,EAAc,GAAGD,CAAK,CACtC,CAUA,SAASK,GACLL,EACAT,EACAU,EAEJ,CACI,OAAAV,EAAM,cAAc,EACpBS,EAAK,KAAOT,EACZS,EAAK,MAAQ,SACbA,EAAK,QAAUT,EAAM,QACrBS,EAAK,OAAST,EAAM,UACpBS,EAAK,aAAeT,EAAM,aAEnB,CAAE,GAAGU,EAAc,GAAGD,CAAK,CACtC,CAeA,SAASM,GAAiBf,EAAkBU,EAC5C,CACI,IAAMM,EAAQ,CAAE,GAAGN,EAAc,GAAIV,CAAoB,EAEnDiB,EAAQhB,EAAM,OAAO,SAASe,EAAM,KAAK,EAE/C,OAAAA,EAAM,OAASC,EAAM,MACfD,EAAA,MAAQC,EAAM,SAAS,EAEtBD,CACX,CAWgB,SAAAE,GACZlB,EACAU,EAEJ,CACQ,GAAuBV,GAAU,KAE1B,OAAA,KAGX,IAAMS,EAA2B,CAAA,EAC3BU,EAAcnB,EAEhB,OAAAD,GAAYC,CAAK,EAEVQ,GAAgBC,EAAMT,EAAOU,CAAY,EAE3CJ,GAAUN,CAAK,EAEbY,GAAcH,EAAMT,EAAOU,CAAY,EAEzCR,GAAcF,CAAK,EAEjBa,GAAkBJ,EAAMT,EAAOU,CAAY,EAE7CN,GAAeJ,CAAK,EAElBc,GAAmBL,EAAMT,EAAOU,CAAY,EAE9CS,EAAY,MAAQjB,GAAciB,EAAY,IAAI,EAEhDN,GAAkBM,EAAaA,EAAY,KAAMT,CAAY,EAE/DS,EAAY,MAAQf,GAAee,EAAY,IAAI,EAEjDL,GAAmBK,EAAaA,EAAY,KAAMT,CAAY,EAGlEK,GAAiBI,EAAaT,CAAY,CACrD,CAQgB,SAAAU,GAAcpB,EAAoBU,EAClD,CACU,GAAA,CAAE,MAAAW,EAAO,UAAAC,EAAW,WAAAC,EAAY,IAAAC,EAAK,KAAAC,EAAM,UAAAC,EAAW,GAAGC,CAAA,EAASjB,EAClED,EAAOS,GAAYlB,EAAO2B,CAAI,EAEpC,OAAKlB,EAKE,CACH,MAAAY,EACA,UAAAC,EACA,WAAAC,EACA,IAAAC,EACA,KAAAC,EACA,UAAAC,EACA,GAAGjB,CAAA,EAVI,IAYf,CCzMA,IAAMmB,GAAW,IAAIC,GAkDfC,GAAa,IAAIC,EAWVC,GAAN,MAAMA,WAAwBC,EAIrC,CAJO,aAAA,CAAA,MAAA,GAAA,SAAA,EAqDa,KAAA,IAAcC,GAAI,iBAAiB,EAKnD,KAAO,MAAQ,GAEf,KAAO,UAAuB,OAE9B,KAAO,aAAuC,CAAA,EAOtC,KAAA,YAA4B,IAAIC,EAChC,KAAA,WAAqB,IAAIJ,EAEjC,KAAQ,WAAiC,CAAE,GAAGC,GAAgB,gBAAiB,EAC/E,KAAQ,aAAqC,CAAE,GAAGA,GAAgB,kBAAmB,EACrF,KAAQ,YAAyG,CAAA,EAEjH,KAAQ,MAAQ,EAER,KAAA,QAAU,IAAII,GACtB,KAAQ,aAAe,EAAA,CAOhB,OACP,CACU,IAAAC,EAAQ,IAAIL,GAElB,OAAAK,EAAM,UAAY,KAAK,UACjBA,EAAA,aAAe,KAAK,aAAa,MAAM,EACvCA,EAAA,YAAc,KAAK,YAAY,MAAM,EACrCA,EAAA,WAAa,KAAK,WAAW,MAAM,EACzCA,EAAM,WAAa,CAAE,GAAG,KAAK,UAAW,EACxCA,EAAM,aAAe,CAAE,GAAG,KAAK,YAAa,EACtCA,EAAA,YAAc,KAAK,YAAY,MAAM,EACrCA,EAAA,QAAU,KAAK,QAAQ,MAAM,EACnCA,EAAM,aAAe,GAEdA,CAAA,CAMX,IAAI,WACJ,CACI,OAAO,KAAK,UAAA,CAGhB,IAAI,UAAUC,EACd,CACI,KAAK,WAAaC,GAAYD,EAAON,GAAgB,gBAAgB,CAAA,CAMzE,IAAI,aACJ,CACI,OAAO,KAAK,YAAA,CAGhB,IAAI,YAAYM,EAChB,CACI,KAAK,aAAeE,GAAcF,EAAON,GAAgB,kBAAkB,CAAA,CAUxE,aAAaS,EACpB,CACI,YAAK,WAAaF,GAAYE,EAAOT,GAAgB,gBAAgB,EAE9D,IAAA,CAUJ,eAAeS,EACtB,CACI,YAAK,aAAeF,GAAYE,EAAOT,GAAgB,kBAAkB,EAElE,IAAA,CA2BJ,QAAQU,EAAkBC,EAAoBC,EAAaC,EAAaC,EAAaC,EAC5F,CACI,YAAK,aAAa,KAAK,CACnB,OAAQ,UACR,KAAM,CACF,MAAOL,EAEP,GAAIE,GAAM,EACV,GAAIC,GAAM,EAEV,GAAIC,GAAMJ,EAAQ,MAAM,MACxB,GAAIK,GAAML,EAAQ,MAAM,OAExB,UAAW,KAAK,WAAW,MAAM,EACjC,MAAO,KAAK,WAAW,MACvB,MAAOC,EAAOK,EAAM,OAAO,SAASL,CAAI,EAAE,SAAA,EAAa,QAAA,CAC3D,CACH,EAED,KAAK,SAAS,EAEP,IAAA,CAQJ,WACP,CACS,YAAA,YAAc,IAAIR,EAEhB,IAAA,CAYJ,KAAKM,EAAmBQ,EAC/B,CACQ,IAAAC,EAEEC,EAAkB,KAAK,aAAa,KAAK,aAAa,OAAS,CAAC,EAWtE,OATI,KAAK,QAAU,GAAKA,GAAiB,SAAW,SAEhDD,EAAOC,EAAgB,KAAK,KAIrBD,EAAA,KAAK,YAAY,MAAM,EAG7BA,GAGDT,GAAS,OAELQ,IAAU,QAAa,OAAOR,GAAU,WAGxCW,EAAYC,EAAQ,sGAAsG,EAGlHZ,EAAA,CAAE,MAAOA,EAAO,MAAAQ,CAAM,GAElC,KAAK,WAAaV,GAAYE,EAAOT,GAAgB,gBAAgB,GAIzE,KAAK,aAAa,KAAK,CACnB,OAAQ,OAER,KAAM,CAAE,MAAO,KAAK,UAAW,KAAAkB,CAAK,CAAA,CACvC,EAED,KAAK,SAAS,EAEd,KAAK,sBAAsB,EAC3B,KAAK,MAAQ,EAEN,MA5BW,IA4BX,CAGH,uBACR,CAEU,GAAA,CAAE,EAAAI,EAAG,EAAAC,CAAE,EAAI,KAAK,YAAY,aAAa1B,GAAM,MAAM,EAE3D,KAAK,YAAY,MAAM,EAClB,KAAA,YAAY,OAAOyB,EAAGC,CAAC,CAAA,CASzB,OAAOd,EACd,CACQ,IAAAS,EAEEC,EAAkB,KAAK,aAAa,KAAK,aAAa,OAAS,CAAC,EAWtE,OATI,KAAK,QAAU,GAAKA,GAAiB,SAAW,OAEhDD,EAAOC,EAAgB,KAAK,KAIrBD,EAAA,KAAK,YAAY,MAAM,EAG7BA,GAGDT,GAAS,OAET,KAAK,aAAeD,GAAcC,EAAOT,GAAgB,kBAAkB,GAI/E,KAAK,aAAa,KAAK,CACnB,OAAQ,SAER,KAAM,CAAE,MAAO,KAAK,YAAa,KAAAkB,CAAK,CAAA,CACzC,EAED,KAAK,SAAS,EAEd,KAAK,sBAAsB,EAC3B,KAAK,MAAQ,EAEN,MApBW,IAoBX,CASJ,KACP,CACI,QAASM,EAAI,EAAGA,EAAI,EAAGA,IACvB,CACI,IAAML,EAAkB,KAAK,aAAa,KAAK,aAAa,OAAS,EAAIK,CAAC,EAEpEC,EAAW,KAAK,YAAY,MAAM,EAExC,GAAIN,IAEIA,EAAgB,SAAW,UAAYA,EAAgB,SAAW,QAE9D,GAAAA,EAAgB,KAAK,KAELA,EAAA,KAAK,KAAK,QAAQM,CAAQ,MAG9C,CACIN,EAAgB,KAAK,KAAOM,EAC5B,KAAA,CAGZ,CAGJ,YAAK,sBAAsB,EAEpB,IAAA,CAcJ,IAAIH,EAAWC,EAAWG,EAAgBC,EAAoBC,EAAkBC,EACvF,CACS,KAAA,QAEL,IAAMC,EAAI,KAAK,WAEf,YAAK,YAAY,IACZA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GACzBA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GAC1BJ,EACAC,EACAC,EACAC,CAAA,EAGG,IAAA,CAaJ,MAAME,EAAYC,EAAYC,EAAYC,EAAYR,EAC7D,CACS,KAAA,QAEL,IAAMI,EAAI,KAAK,WAEf,YAAK,YAAY,MACZA,EAAE,EAAIC,EAAOD,EAAE,EAAIE,EAAMF,EAAE,GAC3BA,EAAE,EAAIC,EAAOD,EAAE,EAAIE,EAAMF,EAAE,GAC3BA,EAAE,EAAIG,EAAOH,EAAE,EAAII,EAAMJ,EAAE,GAC3BA,EAAE,EAAIG,EAAOH,EAAE,EAAII,EAAMJ,EAAE,GAC5BJ,CAAA,EAGG,IAAA,CAeJ,SACHS,EAAYC,EACZC,EACAC,EACAC,EACAjB,EAAWC,EAEf,CACS,KAAA,QAEL,IAAMO,EAAI,KAAK,WAEf,YAAK,YAAY,SACbK,EAAIC,EACJC,EACAC,EACAC,EACCT,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GACzBA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,EAAA,EAGvB,IAAA,CAgBJ,cAAcU,EAAcC,EAAcC,EAAcC,EAAcrB,EAAWC,EAAWqB,EACnG,CACS,KAAA,QAGL,IAAMd,EAAI,KAAK,WAEf,YAAK,YAAY,cACZA,EAAE,EAAIU,EAASV,EAAE,EAAIW,EAAQX,EAAE,GAC/BA,EAAE,EAAIU,EAASV,EAAE,EAAIW,EAAQX,EAAE,GAC/BA,EAAE,EAAIY,EAASZ,EAAE,EAAIa,EAAQb,EAAE,GAC/BA,EAAE,EAAIY,EAASZ,EAAE,EAAIa,EAAQb,EAAE,GAC/BA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GACzBA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GAC1Bc,CAAA,EAGG,IAAA,CAQJ,WACP,CACS,YAAA,QAEL,KAAK,aAAa,UAAU,EAErB,IAAA,CAYJ,QAAQtB,EAAWC,EAAWsB,EAAiBC,EACtD,CACS,YAAA,QAEA,KAAA,YAAY,QAAQxB,EAAGC,EAAGsB,EAASC,EAAS,KAAK,WAAW,MAAA,CAAO,EAEjE,IAAA,CAUJ,OAAOxB,EAAWC,EAAWG,EACpC,CACS,YAAA,QAEA,KAAA,YAAY,OAAOJ,EAAGC,EAAGG,EAAQ,KAAK,WAAW,MAAA,CAAO,EAEtD,IAAA,CAQJ,KAAKR,EACZ,CACS,YAAA,QAEL,KAAK,YAAY,QAAQA,EAAM,KAAK,WAAW,MAAA,CAAO,EAE/C,IAAA,CASJ,OAAOI,EAAWC,EACzB,CACS,KAAA,QAEL,IAAMO,EAAI,KAAK,WAEf,YAAK,YAAY,OACZA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GACzBA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,EAAA,EAGvB,IAAA,CASJ,OAAOR,EAAWC,EACzB,CACS,KAAA,QAEL,IAAMO,EAAI,KAAK,WAETiB,EAAe,KAAK,YAAY,aAEhCC,EAAgBlB,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GACzCmB,EAAgBnB,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GAE/C,OAAIiB,EAAa,SAAW,GAAKA,EAAa,CAAC,EAAE,SAAW,UAExDA,EAAa,CAAC,EAAE,KAAK,CAAC,EAAIC,EAC1BD,EAAa,CAAC,EAAE,KAAK,CAAC,EAAIE,EAEnB,OAEX,KAAK,YAAY,OACbD,EACAC,CAAA,EAGG,KAAA,CAaJ,iBAAiBC,EAAaC,EAAa7B,EAAWC,EAAWqB,EACxE,CACS,KAAA,QAEL,IAAMd,EAAI,KAAK,WAEf,YAAK,YAAY,iBACZA,EAAE,EAAIoB,EAAQpB,EAAE,EAAIqB,EAAOrB,EAAE,GAC7BA,EAAE,EAAIoB,EAAQpB,EAAE,EAAIqB,EAAOrB,EAAE,GAC7BA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GACzBA,EAAE,EAAIR,EAAMQ,EAAE,EAAIP,EAAKO,EAAE,GAC1Bc,CAAA,EAGG,IAAA,CAWJ,KAAKtB,EAAWC,EAAW6B,EAAWC,EAC7C,CACS,YAAA,QAEA,KAAA,YAAY,KAAK/B,EAAGC,EAAG6B,EAAGC,EAAG,KAAK,WAAW,MAAA,CAAO,EAElD,IAAA,CAcJ,UAAU/B,EAAWC,EAAW6B,EAAWC,EAAW3B,EAC7D,CACS,YAAA,QAEA,KAAA,YAAY,UAAUJ,EAAGC,EAAG6B,EAAGC,EAAG3B,EAAQ,KAAK,WAAW,MAAA,CAAO,EAE/D,IAAA,CAWJ,KAAK4B,EAAgCC,EAC5C,CACS,YAAA,QAEL,KAAK,YAAY,KAAKD,EAAQC,EAAO,KAAK,WAAW,MAAA,CAAO,EAErD,IAAA,CAaJ,YAAYjC,EAAWC,EAAWG,EAAgB8B,EAAeC,EAAW,EAAGC,EACtF,CACS,YAAA,QACL,KAAK,YAAY,YAAYpC,EAAGC,EAAGG,EAAQ8B,EAAOC,EAAUC,CAAS,EAE9D,IAAA,CAcJ,UAAUpC,EAAWC,EAAWG,EAAgB8B,EAAeG,EAAgBF,EACtF,CACS,YAAA,QACL,KAAK,YAAY,UAAUnC,EAAGC,EAAGG,EAAQ8B,EAAOG,EAAQF,CAAQ,EAEzD,IAAA,CAgBJ,WAAWH,EAAwB5B,EAAgBkC,EAAwBhB,EAClF,CACS,YAAA,QACL,KAAK,YAAY,WAAWU,EAAQ5B,EAAQkC,EAAchB,CAAU,EAE7D,IAAA,CAYJ,WAAWtB,EAAWC,EAAWsC,EAAeC,EAAgBC,EACvE,CACS,YAAA,QACL,KAAK,YAAY,WAAWzC,EAAGC,EAAGsC,EAAOC,EAAQC,CAAM,EAEhD,IAAA,CAYJ,YAAYzC,EAAWC,EAAWsC,EAAeC,EAAgBE,EAAiBN,EACzF,CACS,YAAA,QACL,KAAK,YAAY,YAAYpC,EAAGC,EAAGsC,EAAOC,EAAQE,EAASN,CAAS,EAE7D,IAAA,CAmBJ,KAAKpC,EAAWC,EAAW+B,EAAgB5B,EAAgBuC,EAAc,EAAGR,EAAW,EAC9F,CACS,YAAA,QAEA,KAAA,YAAY,KAAKnC,EAAGC,EAAG+B,EAAQ5B,EAAQuC,EAAaR,EAAU,KAAK,WAAW,MAAA,CAAO,EAEnF,IAAA,CAQJ,IAAIS,EACX,CACS,YAAA,QAELC,GAAUD,EAAK,IAAI,EAEZ,IAAA,CAOJ,SACP,CACU,IAAAE,EAAQ,KAAK,YAAY,IAAI,EAEnC,OAAIA,IAEA,KAAK,WAAaA,EAAM,UACxB,KAAK,WAAaA,EAAM,UACxB,KAAK,aAAeA,EAAM,aAGvB,IAAA,CAIJ,MACP,CACI,YAAK,YAAY,KAAK,CAClB,UAAW,KAAK,WAAW,MAAM,EACjC,UAAW,CAAE,GAAG,KAAK,UAAW,EAChC,YAAa,CAAE,GAAG,KAAK,YAAa,CAAA,CACvC,EAEM,IAAA,CAOJ,cACP,CACI,OAAO,KAAK,UAAA,CAOT,gBACP,CACI,YAAK,WAAW,SAAS,EAElB,IAAA,CAQJ,OAAOC,EACd,CACS,YAAA,WAAW,OAAOA,CAAK,EAErB,IAAA,CASJ,MAAM/C,EAAWC,EAAYD,EACpC,CACS,YAAA,WAAW,MAAMA,EAAGC,CAAC,EAEnB,IAAA,CAsBJ,aAAa+C,EAAoBC,EAAYC,EAAYC,EAAY7D,EAAaC,EACzF,CACI,OAAIyD,aAAavE,GAEb,KAAK,WAAW,IAAIuE,EAAE,EAAGA,EAAE,EAAGA,EAAE,EAAGA,EAAE,EAAGA,EAAE,GAAIA,EAAE,EAAE,EAE3C,OAGX,KAAK,WAAW,IAAIA,EAAGC,EAAGC,EAAGC,EAAG7D,EAAIC,CAAE,EAE/B,KAAA,CAsBJ,UAAUyD,EAAoBC,EAAYC,EAAYC,EAAY7D,EAAaC,EACtF,CACI,OAAIyD,aAAavE,GAER,KAAA,WAAW,OAAOuE,CAAC,EAEjB,OAGXxE,GAAW,IAAIwE,EAAGC,EAAGC,EAAGC,EAAG7D,EAAIC,CAAE,EAC5B,KAAA,WAAW,OAAOf,EAAU,EAE1B,KAAA,CASJ,UAAUwB,EAAWC,EAAYD,EACxC,CACS,YAAA,WAAW,UAAUA,EAAGC,CAAC,EAEvB,IAAA,CAQJ,OACP,CACI,YAAK,YAAY,MAAM,EACvB,KAAK,aAAa,OAAS,EAC3B,KAAK,eAAe,EAEpB,KAAK,SAAS,EAEP,IAAA,CAGD,UACV,CAGI,KAAK,aAAe,GAIhB,MAAK,QACJ,KAAA,KAAK,SAAU,KAAM,EAAI,EAC9B,KAAK,MAAQ,GAAA,CAIjB,IAAI,QACJ,CACI,GAAI,CAAC,KAAK,aAAc,OAAO,KAAK,QAEpC,KAAK,aAAe,GAGpB,IAAMmD,EAAS,KAAK,QAEpBA,EAAO,MAAM,EAEb,QAASlD,EAAI,EAAGA,EAAI,KAAK,aAAa,OAAQA,IAC9C,CACU,IAAAmD,EAAc,KAAK,aAAanD,CAAC,EACjCoD,EAASD,EAAY,OAE3B,GAAIC,IAAW,OACf,CACI,IAAMC,EAAOF,EAAY,KAElBD,EAAA,UAAUG,EAAK,KAAK,MAAM,CAAA,SAE5BD,IAAW,UACpB,CACI,IAAMC,EAAOF,EAAY,KAEzBD,EAAO,SAASG,EAAK,GAAIA,EAAK,GAAIA,EAAK,GAAKA,EAAK,GAAIA,EAAK,GAAKA,EAAK,GAAIA,EAAK,SAAS,CAAA,CAE1F,GAAID,IAAW,SACf,CACI,IAAMC,EAAOF,EAAY,KAEnBG,EAAYD,EAAK,MAAM,UAEvBE,EAAgBF,EAAK,MAAM,OAAS,EAAIC,GAExCE,EAAUH,EAAK,KAAK,OAEnBH,EAAA,SACHM,EAAQ,KAAOD,EACfC,EAAQ,KAAOD,EACfC,EAAQ,KAAOD,EACfC,EAAQ,KAAOD,CAAA,CACnB,CACJ,CAGG,OAAAL,CAAA,CAQJ,cAAcO,EACrB,CAEI,GAAI,CAAC,KAAK,OAAO,cAAcA,EAAM,EAAGA,EAAM,CAAC,EAAU,MAAA,GAEzD,IAAMlC,EAAe,KAAK,aACtBmC,EAAS,GAEb,QAASC,EAAI,EAAGA,EAAIpC,EAAa,OAAQoC,IACzC,CACU,IAAAR,EAAc5B,EAAaoC,CAAC,EAE5BN,EAAOF,EAAY,KACnBzD,EAAO2D,EAAK,KAEd,GAAA,CAACF,EAAY,QAAU,CAACzD,EAAM,SAElC,IAAMT,EAAQoE,EAAK,MACbO,EAASlE,EAAK,UAAU,gBAE9B,QAASM,EAAI,EAAGA,EAAI4D,EAAO,OAAQ5D,IACnC,CACU,IAAA6D,EAAQD,EAAO5D,CAAC,EAAE,MAEpB,GAAA,CAACf,GAAS,CAAC4E,EAAO,SAEhB,IAAA3B,EAAY0B,EAAO5D,CAAC,EAAE,UAEtB8D,EAAmB5B,EAAYA,EAAU,aAAauB,EAAOrF,EAAQ,EAAIqF,EAE3E,GAAAN,EAAY,SAAW,OAEvBO,EAASG,EAAM,SAASC,EAAiB,EAAGA,EAAiB,CAAC,MAGlE,CACI,IAAMC,EAAe9E,EAEZyE,EAAAG,EAAM,eAAeC,EAAiB,EAAGA,EAAiB,EAAGC,EAAY,MAAOA,EAAY,SAAS,CAAA,CAGlH,IAAMC,EAAQX,EAAK,KAEnB,GAAIW,EACJ,CACU,IAAAC,EAAaD,EAAM,WAAW,gBAEpC,GAAIC,EAEA,QAASC,EAAI,EAAGA,EAAID,EAAW,OAAQC,IAE/BD,EAAWC,CAAC,EAAE,MAAM,SAASJ,EAAiB,EAAGA,EAAiB,CAAC,IAE1DJ,EAAA,GAGrB,CAGJ,GAAIA,EAEO,MAAA,EACX,CACJ,CAGG,OAAAA,CAAA,CAYJ,QAAQS,EAA6C,GAC5D,CASI,GARA,KAAK,YAAY,OAAS,EAC1B,KAAK,WAAa,KAEb,KAAA,KAAK,UAAW,IAAI,EACzB,KAAK,mBAAmB,EAED,OAAOA,GAAY,UAAYA,EAAUA,GAAS,QAGzE,CACI,IAAMC,EAAuB,OAAOD,GAAY,UAAYA,EAAUA,GAAS,cAE3E,KAAK,WAAW,UAEhB,KAAK,WAAW,MAAQ,QAAS,KAAK,WAAW,KAC3C,KAAK,WAAW,KAAK,QAAA,EACrB,KAAK,WAAW,QAAQ,QAAQC,CAAoB,GAG1D,KAAK,aAAa,UAElB,KAAK,aAAa,MAAQ,QAAS,KAAK,aAAa,KAC/C,KAAK,aAAa,KAAK,QAAA,EACvB,KAAK,aAAa,QAAQ,QAAQA,CAAoB,EAChE,CAGJ,KAAK,WAAa,KAClB,KAAK,aAAe,KAEpB,KAAK,aAAe,KACpB,KAAK,YAAc,KACnB,KAAK,QAAU,KACf,KAAK,YAAc,KACnB,KAAK,aAAe,KACpB,KAAK,WAAa,IAAA,CAE1B,EAjpCa5F,GAMK,iBAAuC,CAEjD,MAAO,SAEP,MAAO,EAEP,QAAS6F,EAAQ,MAEjB,OAAQ,KAER,KAAM,KAEN,aAAc,OAClB,EAnBS7F,GAsBK,mBAA2C,CAErD,MAAO,EAEP,MAAO,SAEP,MAAO,EAEP,UAAW,GAEX,WAAY,GAEZ,IAAK,OAEL,KAAM,QAEN,QAAS6F,EAAQ,MAEjB,OAAQ,KAER,KAAM,KAEN,aAAc,QAEd,UAAW,EACf,EA/CG,IAAMC,EAAN9F,GC2mBA,IAAM+F,GAAN,MAAMA,WAAkBC,EAG/B,CAmGI,YAAYC,EAAmC,CAAA,EAC/C,CACU,MAAA,EA5EH,KAAA,IAAMC,GAAI,WAAW,EAM5B,KAAO,MAAQ,EAwEXC,GAAmBF,CAAK,EAExB,IAAMG,EAAY,CAAE,GAAGL,GAAU,iBAAkB,GAAGE,CAAM,EAE5D,QAAWI,KAAOD,EAClB,CACI,IAAME,EAAUD,EAEX,KAAAC,CAAO,EAAIF,EAAUC,CAA6B,CAAA,CAG3D,KAAK,OAAO,EACZ,KAAK,MAAQ,CAAA,CAOjB,IAAI,OAAwB,CAAE,OAAO,KAAK,MAAA,CAE1C,IAAI,MAAME,EACV,CACQ,KAAK,SAAWA,IAEpB,KAAK,OAASA,EACd,KAAK,OAAO,EAAA,CAIhB,IAAI,YAAsB,CAAE,OAAO,KAAK,WAAA,CAExC,IAAI,WAAWA,EACf,CACQ,KAAK,cAAgBA,IAEzB,KAAK,YAAcA,EACnB,KAAK,OAAO,EAAA,CAIhB,IAAI,YAA6B,CAAE,OAAO,KAAK,WAAA,CAE/C,IAAI,WAAWA,EACf,CACQ,KAAK,cAAgBA,IAErBA,IAAU,MAAQ,OAAOA,GAAU,SAE9B,KAAA,YAAc,KAAK,aAAa,CAAE,GAAGR,GAAU,kBAAmB,GAAGQ,CAAA,CAAO,EAI5E,KAAA,YAAcA,EAAQ,KAAK,aAAa,CAAE,GAAGR,GAAU,iBAAkB,CAAC,EAAI,KAGvF,KAAK,OAAO,EAAA,CAIhB,IAAI,YAAgC,CAAE,OAAO,KAAK,WAAA,CAElD,IAAI,WAAWQ,EACf,CACQ,KAAK,cAAgBA,IAEzB,KAAK,YAAcA,EACnB,KAAK,OAAO,EAAA,CAIhB,IAAI,UAAmB,CAAE,OAAO,KAAK,SAAA,CAErC,IAAI,SAASA,EACb,CACQ,KAAK,YAAcA,IAEnB,OAAOA,GAAU,SAGZ,KAAA,UAAY,SAASA,EAAiB,EAAE,EAI7C,KAAK,UAAYA,EAErB,KAAK,OAAO,EAAA,CAOhB,IAAI,WAAgC,CAAE,OAAO,KAAK,UAAA,CAElD,IAAI,UAAUA,EACd,CACQ,KAAK,aAAeA,IAEnB,KAAA,WAAaA,EAAM,YAAY,EACpC,KAAK,OAAO,EAAA,CAOhB,IAAI,aAAoC,CAAE,OAAO,KAAK,YAAA,CAEtD,IAAI,YAAYA,EAChB,CACQ,KAAK,eAAiBA,IAE1B,KAAK,aAAeA,EACpB,KAAK,OAAO,EAAA,CAOhB,IAAI,YAAkC,CAAE,OAAO,KAAK,WAAA,CAEpD,IAAI,WAAWA,EACf,CACQ,KAAK,cAAgBA,IAEzB,KAAK,YAAcA,EACnB,KAAK,OAAO,EAAA,CAIhB,IAAI,SAAkB,CAAE,OAAO,KAAK,QAAA,CAEpC,IAAI,QAAQA,EACZ,CACQ,KAAK,WAAaA,IAEtB,KAAK,SAAWA,EAChB,KAAK,OAAO,EAAA,CAIhB,IAAI,eAAwB,CAAE,OAAO,KAAK,cAAA,CAE1C,IAAI,cAAcA,EAClB,CACQ,KAAK,iBAAmBA,IAE5B,KAAK,eAAiBA,EACtB,KAAK,OAAO,EAAA,CAIhB,IAAI,YAAqB,CAAE,OAAO,KAAK,WAAA,CAEvC,IAAI,WAAWA,EACf,CACQ,KAAK,cAAgBA,IAEzB,KAAK,YAAcA,EACnB,KAAK,OAAO,EAAA,CAQhB,IAAI,SAAkB,CAAE,OAAO,KAAK,QAAA,CAEpC,IAAI,QAAQA,EACZ,CACQ,KAAK,WAAaA,IAEtB,KAAK,SAAWA,EAChB,KAAK,OAAO,EAAA,CAShB,IAAI,SAA6B,CAAE,OAAO,KAAK,QAAA,CAE/C,IAAI,QAAQA,EACZ,CACQ,KAAK,WAAaA,IAEjB,KAAA,SAAW,OAAO,OAAOA,CAAK,EACnC,KAAK,OAAO,EAAA,CAShB,IAAI,MAAgB,CAAE,OAAO,KAAK,KAAA,CAElC,IAAI,KAAKA,EACT,CACQ,KAAK,QAAUA,IAEnB,KAAK,MAAQA,EACb,KAAK,OAAO,EAAA,CAOhB,IAAI,cAAsC,CAAE,OAAO,KAAK,aAAA,CAExD,IAAI,aAAaA,EACjB,CACQ,KAAK,gBAAkBA,IAE3B,KAAK,cAAgBA,EACrB,KAAK,OAAO,EAAA,CAchB,IAAI,YAAkC,CAAE,OAAO,KAAK,WAAA,CAEpD,IAAI,WAAWA,EACf,CACQ,KAAK,cAAgBA,IAEzB,KAAK,YAAcA,EACnB,KAAK,OAAO,EAAA,CAIhB,IAAI,UAAoB,CAAE,OAAO,KAAK,SAAA,CAEtC,IAAI,SAASA,EACb,CACQ,KAAK,YAAcA,IAEvB,KAAK,UAAYA,EACjB,KAAK,OAAO,EAAA,CAIhB,IAAI,eAAwB,CAAE,OAAO,KAAK,cAAA,CAE1C,IAAI,cAAcA,EAClB,CACQ,KAAK,iBAAmBA,IAE5B,KAAK,eAAiBA,EACtB,KAAK,OAAO,EAAA,CA4BhB,IAAI,MACJ,CACI,OAAO,KAAK,aAAA,CAGhB,IAAI,KAAKA,EACT,CACQA,IAAU,KAAK,gBAEnB,KAAK,cAAgBA,EAEjB,KAAK,aAAaA,CAAK,IAElB,KAAA,cAAgB,KAAK,aAAa,CAAE,GAAGC,EAAgB,iBAAkB,GAAGD,CAAM,EAAG,IAC1F,CACI,KAAK,MAAQE,GACT,CAAE,GAAG,KAAK,aAA2B,EACrCD,EAAgB,gBAAA,CACpB,CACH,GAGL,KAAK,MAAQC,GACTF,IAAU,EAAM,QAAUA,EAC1BC,EAAgB,gBAAA,EAEpB,KAAK,OAAO,EAAA,CAIhB,IAAI,QACJ,CACI,OAAO,KAAK,eAAA,CAGhB,IAAI,OAAOD,EACX,CACQA,IAAU,KAAK,kBAEnB,KAAK,gBAAkBA,EAEnB,KAAK,aAAaA,CAAK,IAElB,KAAA,gBAAkB,KAAK,aAAa,CAAE,GAAGC,EAAgB,mBAAoB,GAAGD,CAAM,EAAG,IAC9F,CACI,KAAK,QAAUG,GACX,CAAE,GAAG,KAAK,eAA+B,EACzCF,EAAgB,kBAAA,CACpB,CACH,GAGL,KAAK,QAAUE,GAAcH,EAAOC,EAAgB,kBAAkB,EACtE,KAAK,OAAO,EAAA,CAGT,QACP,CACS,KAAA,QACA,KAAA,KAAK,SAAU,IAAI,CAAA,CAIrB,OACP,CACI,IAAMG,EAAeZ,GAAU,iBAE/B,QAAWM,KAAOM,EAET,KAAAN,CAAwB,EAAIM,EAAaN,CAA6B,CAC/E,CAQJ,IAAW,UACX,CACI,MAAO,GAAG,KAAK,GAAG,IAAI,KAAK,KAAK,EAAA,CAO7B,OACP,CACI,OAAO,IAAIN,GAAU,CACjB,MAAO,KAAK,MACZ,WAAY,KAAK,WACjB,WAAY,KAAK,YAAc,CAAE,GAAG,KAAK,WAAA,EAAgB,KACzD,KAAM,KAAK,MACX,WAAY,KAAK,WACjB,SAAU,KAAK,SACf,UAAW,KAAK,UAChB,YAAa,KAAK,YAClB,WAAY,KAAK,WACjB,QAAS,KAAK,QACd,cAAe,KAAK,cACpB,WAAY,KAAK,WACjB,QAAS,KAAK,QACd,OAAQ,KAAK,QACb,aAAc,KAAK,aACnB,WAAY,KAAK,WACjB,SAAU,KAAK,SACf,cAAe,KAAK,cACpB,QAAS,KAAK,SAAW,CAAC,GAAG,KAAK,QAAQ,EAAI,MAAA,CACjD,CAAA,CASE,kBACP,CACI,IAAIa,EAAgB,EAEpB,GAAI,KAAK,SAEL,QAASC,EAAI,EAAGA,EAAI,KAAK,SAAS,OAAQA,IAErBD,GAAA,KAAK,SAASC,CAAC,EAAE,QAI1C,OAAO,KAAK,IAAI,KAAK,SAAUD,CAAa,CAAA,CAYzC,QAAQE,EAA6C,GAC5D,CAKI,GAJA,KAAK,mBAAmB,EAED,OAAOA,GAAY,UAAYA,EAAUA,GAAS,QAGzE,CACI,IAAMC,EAAuB,OAAOD,GAAY,UAAYA,EAAUA,GAAS,cAE3E,KAAK,OAAO,SAEP,KAAA,MAAM,QAAQ,QAAQC,CAAoB,EAG9C,KAAK,eAA6B,SAElC,KAAK,cAA4B,QAAQ,QAAQA,CAAoB,EAGtE,KAAK,SAAS,SAET,KAAA,QAAQ,QAAQ,QAAQA,CAAoB,EAGhD,KAAK,iBAA+B,SAEpC,KAAK,gBAA8B,QAAQ,QAAQA,CAAoB,CAC5E,CAGJ,KAAK,MAAQ,KACb,KAAK,QAAU,KACf,KAAK,WAAa,KAClB,KAAK,gBAAkB,KACvB,KAAK,cAAgB,IAAA,CAGjB,aAA+BR,EAAUS,EACjD,CACW,OAAA,IAAI,MAAST,EAAO,CACvB,IAAK,CAACU,EAAQC,EAAUC,KAEhBF,EAAOC,CAAmB,IAAMC,IAEpCF,EAAOC,CAAmB,EAAIC,EAC9BH,IAAKE,EAAoBC,CAAQ,EACjC,KAAK,OAAO,GAEL,GACX,CACH,CAAA,CAGG,aAAaZ,EACrB,CACa,OAAAA,GAAS,QAAU,MACrB,EAAEa,EAAM,YAAYb,CAAK,GAAKA,aAAiBc,GAAgBd,aAAiBe,GAAA,CAE/F,EAxlBavB,GAeK,kBAAoC,CAC9C,MAAO,EACP,MAAO,KAAK,GAAK,EACjB,KAAM,EACN,MAAO,QACP,SAAU,CACd,EArBSA,GA+CK,iBAAqC,CAC/C,MAAO,OACP,WAAY,GACZ,WAAY,KACZ,KAAM,QACN,WAAY,QACZ,SAAU,GACV,UAAW,SACX,YAAa,SACb,WAAY,SACZ,QAAS,EACT,cAAe,EACf,WAAY,EACZ,QAAS,EACT,OAAQ,KACR,aAAc,aACd,KAAM,GACN,WAAY,MACZ,SAAU,GACV,cAAe,GACnB,EAnEG,IAAMwB,GAANxB,GA0lBP,SAASI,GAAmBF,EAC5B,CACI,IAAMuB,EAAWvB,EAUjB,GAAI,OAAOuB,EAAS,YAAe,WAAaA,EAAS,WACzD,CACI,IAAMC,EAAWF,GAAU,kBAE3BtB,EAAM,WAAa,CACf,MAAOuB,EAAS,iBAAmBC,EAAS,MAC5C,MAAOD,EAAS,iBAAmBC,EAAS,MAC5C,KAAMD,EAAS,gBAAkBC,EAAS,KAC1C,MAAOD,EAAS,iBAAmBC,EAAS,MAC5C,SAAUD,EAAS,oBAAsBC,EAAS,QAAA,CACtD,CAGA,GAAAD,EAAS,kBAAoB,OACjC,CAEIE,EAAYC,EAAQ,yCAAyC,EAG7D,IAAMC,EAAQJ,EAAS,OACnBK,EAAiB,CAAA,EAGjB,GAAAT,EAAM,YAAYQ,CAAoB,EAEtCC,EAAI,MAAQD,UAGPA,aAAiBP,GAAgBO,aAAiBN,GAEvDO,EAAI,KAAOD,UAGN,OAAO,eAAe,KAAKA,EAAO,OAAO,GAAK,OAAO,eAAe,KAAKA,EAAO,MAAM,EAErFC,EAAAD,MAIA,OAAA,IAAI,MAAM,uBAAuB,EAG3C3B,EAAM,OAAS,CACX,GAAG4B,EACH,MAAOL,EAAS,eAAA,CACpB,CAGJ,GAAI,MAAM,QAAQA,EAAS,iBAAiB,EAC5C,CAKQ,GAHJE,EAAYC,EAAQ,8DAA8D,EAG9E,CAAC,MAAM,QAAQH,EAAS,IAAI,GAAKA,EAAS,KAAK,SAAW,EAEpD,MAAA,IAAI,MAAM,oEAAoE,EAGpFA,EAAS,KAAK,SAAWA,EAAS,kBAAkB,QAGpDM,EAAK,yEAAyE,EAI5E,IAAAC,EAAe,IAAIV,EAAa,CAClC,MAAO,CAAE,EAAG,EAAG,EAAG,CAAE,EACpB,IAAK,CAAE,EAAG,EAAG,EAAG,CAAE,EAClB,aAAc,OAAA,CACjB,EAEKW,EAAoBR,EAAS,kBAAkB,MAAM,EACrDS,EAAkBT,EAAS,KAC5B,IAAKI,GAAuBR,EAAM,OAAO,SAASQ,CAAK,EAAE,SAAA,CAAU,EAEtDI,EAAA,QAAQ,CAACE,EAAMC,IACjC,CACIJ,EAAa,aAAaG,EAAMD,EAAME,CAAK,CAAC,CAAA,CAC/C,EAEDlC,EAAM,KAAO,CACT,KAAM8B,CAAA,CACV,CAER,CC/2CA,IAAMK,GAAa,IAAIC,GAYhB,SAASC,GACZC,EACAC,EACAC,EACAC,EAEJ,CACI,IAAMC,EAASP,GAEfO,EAAO,KAAO,EACdA,EAAO,KAAO,EAEPA,EAAA,KAAQJ,EAAM,MAAQG,EAAc,EACpCC,EAAA,KAAQJ,EAAM,OAASG,EAAc,EAE5C,IAAME,EAAUC,EAAY,kBACxBF,EAAO,MACPA,EAAO,OACPD,EACA,EAAA,EAGJ,OAAAE,EAAQ,OAAO,eAAiB,QAChCA,EAAQ,OAAO,SAAWL,EAC1BK,EAAQ,OAAO,UAAY,8BAEnBA,EAAA,MAAM,MAAQJ,EAAQE,EACtBE,EAAA,MAAM,OAASH,EAASC,EAOhCE,EAAQ,OAAO,KAAK,SAAUA,EAAQ,MAAM,EAE5CA,EAAQ,UAAU,EAEXA,CACX,CClDA,IAAIE,GAAkC,KAClCC,GAAqD,KAEzD,SAASC,GAAqBC,EAAeC,EAC7C,CACSJ,KAEDA,GAAkBK,EAAW,IAAA,EAAM,aAAa,IAAK,GAAG,EACxDJ,GAAmBD,GAAgB,WAAW,KAAM,CAAE,mBAAoB,EAAA,CAAM,EAChFC,GAAiB,yBAA2B,OAC5CA,GAAiB,YAAc,IAG/BD,GAAgB,MAAQG,GAASH,GAAgB,OAASI,KAG1CJ,GAAA,MAAQM,GAASH,CAAK,EACtBH,GAAA,OAASM,GAASF,CAAM,EAEhD,CAEA,SAASG,GAASC,EAAyBL,EAAeM,EAC1D,CACa,QAAAC,EAAI,EAAGC,EAAQ,EAAIF,EAAIN,EAAOO,EAAIP,EAAO,EAAEO,EAAGC,GAAS,EAExD,GAAAH,EAAKG,EAAQ,CAAC,IAAM,EAAU,MAAA,GAG/B,MAAA,EACX,CAEA,SAASC,GAAYJ,EAAyBL,EAAeO,EAAWG,EAAaC,EACrF,CACI,IAAMC,EAAS,EAAIZ,EAEnB,QAASM,EAAII,EAAKF,EAASE,EAAME,EAAW,EAAIL,EAAID,GAAKK,EAAQ,EAAEL,EAAGE,GAASI,EAEvE,GAAAP,EAAKG,EAAQ,CAAC,IAAM,EAAU,MAAA,GAG/B,MAAA,EACX,CAmEO,SAASK,MAAwBC,EACxC,CACQ,IAAAC,EAAUD,EAAK,CAAC,EAEfC,EAAQ,SAECA,EAAA,CAAE,OAAQD,EAAK,CAAC,EAAc,WAAYA,EAAK,CAAC,CAAE,GAG1D,GAAA,CAAE,OAAAE,CAAA,EAAWD,EAGbE,EAAa,KAAK,IAAIF,EAAQ,YAAc,EAAG,CAAC,EAChDf,EAAQe,EAAQ,OAASC,EAAO,MAChCf,EAASc,EAAQ,QAAUC,EAAO,OACpCE,EAASH,EAAQ,OAKrB,GAFAhB,GAAqBC,EAAOC,CAAM,EAE9B,CAACH,GAEK,MAAA,IAAI,UAAU,iCAAiC,EAIxCA,GAAA,UACbkB,EACA,EAAG,EACHhB,EAAOC,EACP,EAAG,EACHD,EAAQiB,EAAYhB,EAASgB,CAAA,EAKjC,IAAMZ,EADYP,GAAiB,aAAa,EAAG,EAAGE,EAAOC,CAAM,EAC5C,KAEnBkB,EAAO,EACPT,EAAM,EACNU,EAAQpB,EAAQ,EAChBW,EAASV,EAAS,EAEtB,KAAOS,EAAMT,GAAUG,GAASC,EAAML,EAAOU,CAAG,GAAK,EAAAA,EACrD,GAAIA,IAAQT,EAAQ,OAAOoB,EAAU,MAC9B,KAAAjB,GAASC,EAAML,EAAOW,CAAM,GAAK,EAAAA,EACxC,KAAOF,GAAYJ,EAAML,EAAOmB,EAAMT,EAAKC,CAAM,GAAK,EAAAQ,EACtD,KAAOV,GAAYJ,EAAML,EAAOoB,EAAOV,EAAKC,CAAM,GAAK,EAAAS,EAErD,QAAAA,EACA,EAAAT,EAEFb,GAAiB,yBAA2B,cAE5CA,GAAiB,WAAWqB,EAAMT,EAAKU,EAAQD,EAAMR,EAASD,CAAG,EACjEZ,GAAiB,yBAA2B,OAE5CoB,IAAAA,EAAW,IAAIG,GAERH,EAAA,IAAIC,EAAOF,EAAYP,EAAMO,GAAaG,EAAQD,GAAQF,GAAaN,EAASD,GAAOO,CAAU,EAEjGC,CACX,CCzJA,IAAMI,GAAN,KAAU,CAcT,YAAaC,EAAM,EAAGC,EAAM,EAAGC,EAAW,GAAO,CAChD,KAAK,MAAQ,KACb,KAAK,MAAQ,OAAO,OAAO,IAAI,EAC/B,KAAK,KAAO,KACZ,KAAK,IAAMF,EACX,KAAK,SAAWE,EAChB,KAAK,KAAO,EACZ,KAAK,IAAMD,CACZ,CAaA,OAAS,CACR,YAAK,MAAQ,KACb,KAAK,MAAQ,OAAO,OAAO,IAAI,EAC/B,KAAK,KAAO,KACZ,KAAK,KAAO,EAEL,IACR,CAiBA,OAAQE,EAAK,CACZ,GAAI,KAAK,IAAIA,CAAG,EAAG,CAClB,IAAMC,EAAO,KAAK,MAAMD,CAAG,EAE3B,OAAO,KAAK,MAAMA,CAAG,EACrB,KAAK,OAEDC,EAAK,OAAS,OACjBA,EAAK,KAAK,KAAOA,EAAK,MAGnBA,EAAK,OAAS,OACjBA,EAAK,KAAK,KAAOA,EAAK,MAGnB,KAAK,QAAUA,IAClB,KAAK,MAAQA,EAAK,MAGf,KAAK,OAASA,IACjB,KAAK,KAAOA,EAAK,KAEnB,CAEA,OAAO,IACR,CAkBA,QAASC,EAAO,KAAK,KAAK,EAAG,CAC5B,OAAOA,EAAK,IAAIF,GAAO,CAACA,EAAK,KAAK,IAAIA,CAAG,CAAC,CAAC,CAC5C,CAeA,MAAOG,EAAS,GAAO,CACtB,GAAIA,GAAU,KAAK,KAAO,EAAG,CAC5B,IAAMF,EAAO,KAAK,MAElB,OAAO,KAAK,MAAMA,EAAK,GAAG,EAEtB,EAAE,KAAK,OAAS,GACnB,KAAK,MAAQ,KACb,KAAK,KAAO,OAEZ,KAAK,MAAQA,EAAK,KAClB,KAAK,MAAM,KAAO,KAEpB,CAEA,OAAO,IACR,CAiBA,UAAWD,EAAK,CACf,IAAII,EAEJ,OAAI,KAAK,IAAIJ,CAAG,IACfI,EAAS,KAAK,MAAMJ,CAAG,EAAE,QAGnBI,CACR,CAiBA,IAAKJ,EAAK,CACT,IAAMC,EAAO,KAAK,MAAMD,CAAG,EAE3B,GAAIC,IAAS,OAAW,CAEvB,GAAI,KAAK,IAAM,GACVA,EAAK,QAAU,KAAK,IAAI,EAAG,CAC9B,KAAK,OAAOD,CAAG,EAEf,MACD,CAID,YAAK,UAAUC,CAAI,EAEZA,EAAK,KACb,CAGD,CAiBA,IAAKD,EAAK,CACT,OAAOA,KAAO,KAAK,KACpB,CAaA,UAAWC,EAAM,CAEZ,KAAK,OAASA,IAKdA,EAAK,OAAS,OACjBA,EAAK,KAAK,KAAOA,EAAK,MAGnBA,EAAK,OAAS,OACjBA,EAAK,KAAK,KAAOA,EAAK,MAInB,KAAK,QAAUA,IAClB,KAAK,MAAQA,EAAK,MAInBA,EAAK,KAAO,KAAK,KACjBA,EAAK,KAAO,KAER,KAAK,OAAS,OACjB,KAAK,KAAK,KAAOA,GAGlB,KAAK,KAAOA,EAGR,KAAK,QAAU,OAClB,KAAK,MAAQA,GAEf,CAgBA,MAAQ,CACP,IAAMG,EAAS,CAAC,EACZC,EAAI,KAAK,MAEb,KAAOA,IAAM,MACZD,EAAO,KAAKC,EAAE,GAAG,EACjBA,EAAIA,EAAE,KAGP,OAAOD,CACR,CAmBA,eAAgBJ,EAAKM,EAAOP,EAAW,KAAK,SAAU,CACrD,IAAIQ,EAAU,KAEd,GAAI,KAAK,IAAIP,CAAG,EACf,KAAK,IAAIA,EAAKM,EAAO,GAAMP,CAAQ,MAC7B,CACF,KAAK,IAAM,GAAK,KAAK,OAAS,KAAK,MACtCQ,EAAU,CAAC,GAAG,KAAK,KAAK,EACxB,KAAK,MAAM,EAAI,GAGhB,IAAIN,EAAO,KAAK,MAAMD,CAAG,EAAI,CAC5B,OAAQ,KAAK,IAAM,EAAI,KAAK,IAAI,EAAI,KAAK,IAAM,KAAK,IACpD,IAAKA,EACL,KAAM,KAAK,KACX,KAAM,KACN,MAAAM,CACD,EAEI,EAAE,KAAK,OAAS,EACnB,KAAK,MAAQL,EAEb,KAAK,KAAK,KAAOA,EAGlB,KAAK,KAAOA,CACb,CAEA,OAAOM,CACR,CAoBA,IAAKP,EAAKM,EAAOH,EAAS,GAAOJ,EAAW,KAAK,SAAU,CAC1D,IAAIE,EAAO,KAAK,MAAMD,CAAG,EAEzB,OAAIG,GAAUF,IAAS,QAEtBA,EAAK,MAAQK,EAETH,IAAW,IAASJ,IACvBE,EAAK,OAAS,KAAK,IAAM,EAAI,KAAK,IAAI,EAAI,KAAK,IAAM,KAAK,KAI3D,KAAK,UAAUA,CAAI,IAGf,KAAK,IAAM,GAAK,KAAK,OAAS,KAAK,KACtC,KAAK,MAAM,EAAI,EAGhBA,EAAO,KAAK,MAAMD,CAAG,EAAI,CACxB,OAAQ,KAAK,IAAM,EAAI,KAAK,IAAI,EAAI,KAAK,IAAM,KAAK,IACpD,IAAKA,EACL,KAAM,KAAK,KACX,KAAM,KACN,MAAAM,CACD,EAEI,EAAE,KAAK,OAAS,EACnB,KAAK,MAAQL,EAEb,KAAK,KAAK,KAAOA,EAGlB,KAAK,KAAOA,GAGN,IACR,CAkBA,OAAQC,EAAO,KAAK,KAAK,EAAG,CAC3B,OAAOA,EAAK,IAAIF,GAAO,KAAK,IAAIA,CAAG,CAAC,CACrC,CACD,EA0BA,SAASQ,GAAKX,EAAM,IAAMC,EAAM,EAAGC,EAAW,GAAO,CACpD,GAAI,MAAMF,CAAG,GAAKA,EAAM,EACvB,MAAM,IAAI,UAAU,mBAAmB,EAGxC,GAAI,MAAMC,CAAG,GAAKA,EAAM,EACvB,MAAM,IAAI,UAAU,mBAAmB,EAGxC,GAAI,OAAOC,GAAa,UACvB,MAAM,IAAI,UAAU,wBAAwB,EAG7C,OAAO,IAAIH,GAAIC,EAAKC,EAAKC,CAAQ,CAClC,CC9dA,IAAMU,GAAsB,CACxB,QACA,aACA,YACA,UACA,UACA,WACJ,EAQO,SAASC,GAAwBC,EACxC,CAEU,IAAAC,EAAkB,OAAOD,EAAM,UAAa,SAAY,GAAGA,EAAM,QAAQ,KAAOA,EAAM,SAIxFE,EAAkCF,EAAM,WAEvC,MAAM,QAAQA,EAAM,UAAU,IAEhBE,EAAAF,EAAM,WAAW,MAAM,GAAG,GAG7C,QAASG,EAAID,EAAa,OAAS,EAAGC,GAAK,EAAGA,IAC9C,CAEI,IAAIC,EAAaF,EAAaC,CAAC,EAAE,KAAK,EAGlC,CAAE,qBAAsB,KAAKC,CAAU,GAAK,CAACN,GAAoB,SAASM,CAAU,IAEpFA,EAAa,IAAIA,CAAU,KAE9BF,EAA0BC,CAAC,EAAIC,CAAA,CAIpC,MAAO,GAAGJ,EAAM,SAAS,IAAIA,EAAM,WAAW,IAAIA,EAAM,UAAU,IAAIC,CAAc,IAAKC,EAA0B,KAAK,GAAG,CAAC,EAChI,CCMA,IAAMG,GAAqD,CAEvD,mBAAoB,EACxB,EAiBaC,GAAN,MAAMA,CACb,CAyFI,WAAkB,oCAClB,CACI,IAAIC,EAASD,EAAkB,oCAE/B,GAAIC,IAAW,OACf,CACI,IAAMC,EAAQC,EAAW,IAAI,EAAE,4BAAA,EAA8B,UAE7DF,EACMD,EAAkB,oCAClB,kBAAmBE,GAAS,sBAAuBA,CAAA,CAGtD,OAAAD,CAAA,CAyDX,YAAYG,EAAcC,EAAkBC,EAAeC,EAAgBC,EAAiBC,EACxFC,EAAoBC,EAAsBC,EAC9C,CACI,KAAK,KAAOR,EACZ,KAAK,MAAQC,EACb,KAAK,MAAQC,EACb,KAAK,OAASC,EACd,KAAK,MAAQC,EACb,KAAK,WAAaC,EAClB,KAAK,WAAaC,EAClB,KAAK,aAAeC,EACpB,KAAK,eAAiBC,CAAA,CAW1B,OAAc,YACVR,EAAO,IACPC,EACAQ,EAAkBb,EAAkB,QACpCc,EAAoBT,EAAM,SAE9B,CACI,IAAMU,EAAU,GAAGX,CAAI,IAAIC,EAAM,QAAQ,aAAaS,CAAQ,GAG9D,GAAId,EAAkB,kBAAkB,IAAIe,CAAO,EAExC,OAAAf,EAAkB,kBAAkB,IAAIe,CAAO,EAGpD,IAAAC,EAAOC,GAAwBZ,CAAK,EACpCO,EAAiBZ,EAAkB,YAAYgB,CAAI,EAGrDJ,EAAe,WAAa,IAE5BA,EAAe,SAAWP,EAAM,SAChCO,EAAe,OAASP,EAAM,UAGlC,IAAMa,EAAUlB,EAAkB,UAElCkB,EAAQ,KAAOF,EAGT,IAAAR,GADaM,EAAWd,EAAkB,UAAUI,EAAMC,EAAOQ,CAAM,EAAIT,GACxD,MAAM,gBAAgB,EACzCK,EAAa,IAAI,MAAcD,EAAM,MAAM,EAC7CG,EAAe,EAEnB,QAASQ,EAAI,EAAGA,EAAIX,EAAM,OAAQW,IAClC,CACU,IAAAC,EAAYpB,EAAkB,aAAaQ,EAAMW,CAAC,EAAGd,EAAM,cAAea,CAAO,EAEvFT,EAAWU,CAAC,EAAIC,EACDT,EAAA,KAAK,IAAIA,EAAcS,CAAS,CAAA,CAG7C,IAAAC,EAAchB,EAAM,SAAS,OAAS,EAExCC,EAAQK,EAAeU,EAEvBhB,EAAM,aAENC,GAASD,EAAM,WAAW,UAGxB,IAAAK,EAAaL,EAAM,YAAcO,EAAe,SAElDL,EAAS,KAAK,IAAIG,EAAYE,EAAe,SAAYS,CAAY,GACjEb,EAAM,OAAS,IAAME,EAAaL,EAAM,SAE5CA,EAAM,aAENE,GAAUF,EAAM,WAAW,UAG/B,IAAMiB,EAAe,IAAItB,EACrBI,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAAaL,EAAM,QACnBM,EACAC,CAAA,EAIc,OAAAZ,EAAA,kBAAkB,IAAIe,EAASO,CAAY,EAEtDA,CAAA,CAGX,OAAe,aACXlB,EACAmB,EACAL,EAEJ,CACI,IAAIM,EAA+B,GAE/BxB,EAAkB,qCAEdA,EAAkB,2BAEVkB,EAAA,cAAgB,GAAGK,CAAa,KAChCL,EAAA,kBAAoB,GAAGK,CAAa,KACbC,EAAA,KAI/BN,EAAQ,cAAgB,MACxBA,EAAQ,kBAAoB,QAI9B,IAAAO,EAAUP,EAAQ,YAAYd,CAAI,EACpCsB,EAAcD,EAAQ,MACpBE,EAAwB,CAACF,EAAQ,sBAEnCG,EAD2BH,EAAQ,uBACIE,EAE3C,GAAID,EAAc,EAEd,GAAIF,EAEeE,GAAAH,EACAK,GAAAL,MAGnB,CACI,IAAMM,GAAO7B,EAAkB,kBAAkBI,CAAI,EAAE,OAAS,GAAKmB,EAEtDG,GAAAG,EACAD,GAAAC,CAAA,CAMhB,OAAA,KAAK,IAAIH,EAAaE,CAAW,CAAA,CAW5C,OAAe,UACXxB,EACAC,EACAQ,EAAkBb,EAAkB,QAExC,CACI,IAAMkB,EAAUL,EAAO,WAAW,KAAMd,EAAe,EAEnDO,EAAQ,EACRwB,EAAO,GACPtB,EAAQ,GAENuB,EAAoC,OAAA,OAAO,IAAI,EAC/C,CAAE,cAAAR,EAAe,WAAAS,CAAA,EAAe3B,EAGhC4B,EAAiBjC,EAAkB,gBAAgBgC,CAAU,EAC7DE,EAAmBlC,EAAkB,kBAAkBgC,CAAU,EAGnEG,EAAmB,CAACF,EAQlBG,EAAgB/B,EAAM,cAAgBkB,EAGtCc,EAASrC,EAAkB,UAAUI,CAAI,EAE/C,QAASe,EAAI,EAAGA,EAAIkB,EAAO,OAAQlB,IACnC,CAEQ,IAAAmB,EAAQD,EAAOlB,CAAC,EAGhB,GAAAnB,EAAkB,WAAWsC,CAAK,EACtC,CAEI,GAAI,CAACJ,EACL,CACa1B,GAAAR,EAAkB,SAAS8B,CAAI,EACxCK,EAAmB,CAACF,EACbH,EAAA,GACCxB,EAAA,EACR,QAAA,CAKIgC,EAAA,GAAA,CAIZ,GAAIL,EACJ,CAEU,IAAAM,EAAsBvC,EAAkB,gBAAgBsC,CAAK,EAC7DE,EAAsBxC,EAAkB,gBAAgB8B,EAAKA,EAAK,OAAS,CAAC,CAAC,EAEnF,GAAIS,GAAuBC,EAEvB,QACJ,CAIJ,IAAMC,EAAazC,EAAkB,cAAcsC,EAAOf,EAAeQ,EAAOb,CAAO,EAGvF,GAAIuB,EAAaL,EAYb,GATIN,IAAS,KAGAtB,GAAAR,EAAkB,SAAS8B,CAAI,EACjCA,EAAA,GACCxB,EAAA,GAIRN,EAAkB,cAAcsC,EAAOjC,EAAM,UAAU,EAC3D,CAEU,IAAAqC,EAAa1C,EAAkB,cAAcsC,CAAK,EAGxD,QAASK,EAAI,EAAGA,EAAID,EAAW,OAAQC,IACvC,CACQ,IAAAC,EAAOF,EAAWC,CAAC,EACnBE,EAAWD,EAEXE,EAAI,EAGD,KAAAJ,EAAWC,EAAIG,CAAC,GACvB,CACU,IAAAC,EAAWL,EAAWC,EAAIG,CAAC,EAG7B,GAAA,CAAC9C,EAAkB,cAAc6C,EAAUE,EAAUT,EAAOK,EAAGtC,EAAM,UAAU,EAGvEuC,GAAAG,MAIR,OAGOF,EAAAE,EACXD,GAAA,CAGJH,GAAKG,EAAI,EAET,IAAME,EAAiBhD,EAAkB,cAAc4C,EAAMrB,EAAeQ,EAAOb,CAAO,EAEtF8B,EAAiB1C,EAAQ8B,IAEhB5B,GAAAR,EAAkB,SAAS8B,CAAI,EACrBK,EAAA,GACZL,EAAA,GACCxB,EAAA,GAGJwB,GAAAc,EACCtC,GAAA0C,CAAA,CACb,KAKJ,CAGQlB,EAAK,OAAS,IAELtB,GAAAR,EAAkB,SAAS8B,CAAI,EACjCA,EAAA,GACCxB,EAAA,GAGN,IAAA2C,EAAc9B,IAAMkB,EAAO,OAAS,EAG1C7B,GAASR,EAAkB,SAASsC,EAAO,CAACW,CAAW,EACpCd,EAAA,GACZL,EAAA,GACCxB,EAAA,CAAA,MASRmC,EAAanC,EAAQ8B,IAGFD,EAAA,GAGV3B,GAAAR,EAAkB,SAAS8B,CAAI,EAGjCA,EAAA,GACCxB,EAAA,IAIRwB,EAAK,OAAS,GAAK,CAAC9B,EAAkB,gBAAgBsC,CAAK,GAAKH,KAGxDL,GAAAQ,EAGChC,GAAAmC,EAEjB,CAGK,OAAAjC,GAAAR,EAAkB,SAAS8B,EAAM,EAAK,EAExCtB,CAAA,CASX,OAAe,SAASsB,EAAcoB,EAAU,GAChD,CACW,OAAApB,EAAA9B,EAAkB,WAAW8B,CAAI,EAEhCA,EAAAoB,EAAW,GAAGpB,CAAI;EAAOA,EAE1BA,CAAA,CAWX,OAAe,cAAcqB,EAAa5B,EAAuBQ,EAC7Db,EACJ,CACQ,IAAAZ,EAAQyB,EAAMoB,CAAG,EAEjB,OAAA,OAAO7C,GAAU,WAEjBA,EAAQN,EAAkB,aAAamD,EAAK5B,EAAeL,CAAO,EAAIK,EACtEQ,EAAMoB,CAAG,EAAI7C,GAGVA,CAAA,CAQX,OAAe,gBAAgB0B,EAC/B,CACY,OAAAA,IAAe,UAAYA,IAAe,UAAA,CAQtD,OAAe,kBAAkBA,EACjC,CACI,OAAQA,IAAe,QAAA,CAQ3B,OAAe,WAAW5B,EAC1B,CACQ,GAAA,OAAOA,GAAS,SAET,MAAA,GAGX,QAASe,EAAIf,EAAK,OAAS,EAAGe,GAAK,EAAGA,IACtC,CACU,IAAAyB,EAAOxC,EAAKe,CAAC,EAEnB,GAAI,CAACnB,EAAkB,gBAAgB4C,CAAI,EAEvC,MAGGxC,EAAAA,EAAK,MAAM,EAAG,EAAE,CAAA,CAGpB,OAAAA,CAAA,CAQX,OAAe,WAAWwC,EAC1B,CACQ,OAAA,OAAOA,GAAS,SAET,GAGJ5C,EAAkB,UAAU,SAAS4C,EAAK,WAAW,CAAC,CAAC,CAAA,CAalE,OAAc,gBAAgBA,EAAcQ,EAC5C,CACQ,OAAA,OAAOR,GAAS,SAET,GAGJ5C,EAAkB,gBAAgB,SAAS4C,EAAK,WAAW,CAAC,CAAC,CAAA,CAQxE,OAAe,UAAUxC,EACzB,CACI,IAAMiC,EAAmB,CAAA,EACrBC,EAAQ,GAER,GAAA,OAAOlC,GAAS,SAET,OAAAiC,EAGX,QAASlB,EAAI,EAAGA,EAAIf,EAAK,OAAQe,IACjC,CACU,IAAAyB,EAAOxC,EAAKe,CAAC,EACb4B,EAAW3C,EAAKe,EAAI,CAAC,EAEvB,GAAAnB,EAAkB,gBAAgB4C,EAAMG,CAAQ,GAAK/C,EAAkB,WAAW4C,CAAI,EAC1F,CACQN,IAAU,KAEVD,EAAO,KAAKC,CAAK,EACTA,EAAA,IAIRM,IAAS,MAAQG,IAAa;GAE9BV,EAAO,KAAK;CAAM,EAClBlB,KAIAkB,EAAO,KAAKO,CAAI,EAGpB,QAAA,CAGKN,GAAAM,CAAA,CAGb,OAAIN,IAAU,IAEVD,EAAO,KAAKC,CAAK,EAGdD,CAAA,CAaX,OAAc,cAAcgB,EAAgBC,EAC5C,CACW,OAAAA,CAAA,CAiBX,OAAc,cAAcC,EAAeH,EAAmBC,EAAgBG,EAC1EC,EACJ,CACW,MAAA,EAAA,CAaX,OAAc,cAAcnB,EAC5B,CACW,OAAAtC,EAAkB,kBAAkBsC,CAAK,CAAA,CAQpD,OAAc,YAAYtB,EAC1B,CAEQ,GAAAhB,EAAkB,OAAOgB,CAAI,EAEtB,OAAAhB,EAAkB,OAAOgB,CAAI,EAGxC,IAAME,EAAUlB,EAAkB,SAElCkB,EAAQ,KAAOF,EACf,IAAMS,EAAUP,EAAQ,YAAYlB,EAAkB,eAAiBA,EAAkB,eAAe,EAElG0D,EAAa,CACf,OAAQjC,EAAQ,wBAChB,QAASA,EAAQ,yBACjB,SAAUA,EAAQ,wBAA0BA,EAAQ,wBAAA,EAGtC,OAAAzB,EAAA,OAAOgB,CAAI,EAAI0C,EAE1BA,CAAA,CAOX,OAAc,aAAa1C,EAAO,GAClC,CACQA,EAEO,OAAAhB,EAAkB,OAAOgB,CAAI,EAIpChB,EAAkB,OAAS,CAAA,CAC/B,CAQJ,WAAkB,SAClB,CACQ,GAAA,CAACA,EAAkB,SACvB,CACQ,IAAAa,EAGJ,GAAA,CAEI,IAAM8C,EAAI,IAAI,gBAAgB,EAAG,CAAC,EAGlC,GAFgBA,EAAE,WAAW,KAAM5D,EAAe,GAErC,YAET,OAAAC,EAAkB,SAAW2D,EAEtBA,EAGF9C,EAAAV,EAAW,IAAI,EAAE,aAAa,CAAA,MAG3C,CACaU,EAAAV,EAAW,IAAI,EAAE,aAAa,CAAA,CAEpCU,EAAA,MAAQA,EAAO,OAAS,GAC/Bb,EAAkB,SAAWa,CAAA,CAGjC,OAAOb,EAAkB,QAAA,CAO7B,WAAkB,UAClB,CACQ,OAACA,EAAkB,YAEnBA,EAAkB,UAAYA,EAAkB,QAAQ,WAAW,KAAMD,EAAe,GAGrFC,EAAkB,SAAA,CAEjC,EA5zBaA,GAiCK,eAAiB,aAjCtBA,GAoCK,gBAAkB,IApCvBA,GAuCK,oBAAsB,IAvC3BA,GA0CK,kBAAoB,EA1CzBA,GAuDK,mBAA8C,IAC5D,CACQ,GAAA,OAAQ,MAAgB,WAAc,WAC1C,CACU,IAAA4D,EAAY,IAAK,KAAe,UAEtC,OAAQC,GACR,CACU,IAAAC,EAAWF,EAAU,QAAQC,CAAC,EAC9B5D,EAAS,CAAA,EAEXkB,EAAI,EAER,QAAW4C,KAAWD,EAEX7D,EAAAkB,GAAG,EAAK4C,EAAQ,QAGpB,OAAA9D,CAAA,CACX,CAGJ,OAAQ4D,GAAc,CAAC,GAAGA,CAAC,CAC/B,GAAG,EA9EM7D,GAgHK,0BAA4B,GAhHjCA,GAmHM,OAAsC,CAAA,EAnH5CA,GAsHe,UAAsB,CAC1C,GACA,EACJ,EAzHSA,GA4He,gBAA4B,CAChD,EACA,GACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACJ,EA3ISA,GAmJe,kBAAoBgE,GAAuB,GAAI,EAnJpE,IAAMC,EAANjE,GC5DP,IAAMkE,GAAY,IAYX,SAASC,GACZC,EACAC,EACAC,EACAC,EAAU,EAEd,CAEI,GAAIH,EAAU,UAAYI,EAAQ,OAAS,CAACJ,EAAU,KAE3C,OAAAK,EAAM,OAAO,SAASL,EAAU,KAAK,EAAE,SAASA,EAAU,OAAS,CAAC,EAAE,OAAO,EACxF,GAEUA,EAAU,MASpB,GAESA,EAAU,gBAAgBM,GACnC,CACI,IAAMC,EAAcP,EAAU,KACxBQ,EAAUP,EAAQ,cAAcM,EAAY,QAAQ,OAAO,SAAU,QAAQ,EAC7EE,EAAaF,EAAY,UAAU,OAAOG,EAAO,MAAM,EAElD,OAAAD,EAAA,MACPF,EAAY,QAAQ,MAAM,MAC1BA,EAAY,QAAQ,MAAM,MAAA,EAG9BC,EAAQ,aAAaC,CAAU,EAExBD,CAAA,SAGFR,EAAU,gBAAgBW,EACnC,CACI,IAAMC,EAAeZ,EAAU,KAEzBa,EAAWD,EAAa,OAAS,SACjCE,EAAUF,EAAa,eAAiB,QAE1CG,EAAQ,EACRC,EAAS,EAGTF,GAAWZ,IAEXa,EAAQb,EAAY,MAAQC,EAC5Ba,EAASd,EAAY,OAASC,GAG9B,IAAAc,EACAC,EAAmB,GAEvB,GAAIL,EACJ,CACU,GAAA,CAAE,MAAAM,EAAO,IAAAC,CAAA,EAAQR,EAEvBK,EAAWhB,EAAQ,qBACfkB,EAAM,EAAIJ,EACVI,EAAM,EAAIH,EACVI,EAAI,EAAIL,EACRK,EAAI,EAAIJ,CAAA,EAIZE,EAAmB,KAAK,IAAIE,EAAI,EAAID,EAAM,CAAC,EAAI,KAAK,KAAKC,EAAI,EAAID,EAAM,GAAK,EAAG,CAAA,KAGnF,CACI,GAAM,CAAE,OAAAE,EAAQ,YAAAC,EAAa,YAAAC,EAAa,YAAAC,CAAA,EAAgBZ,EAE1DK,EAAWhB,EAAQ,qBACfoB,EAAO,EAAIN,EACXM,EAAO,EAAIL,EACXM,EAAcP,EACdQ,EAAY,EAAIR,EAChBQ,EAAY,EAAIP,EAChBQ,EAAcT,CAAA,CAClB,CAIA,GAAAG,GAAoBJ,GAAWZ,EACnC,CACU,IAAAuB,EAASvB,EAAY,WAAcc,EAEzC,QAASU,EAAI,EAAGA,EAAIxB,EAAY,MAAM,OAAQwB,IAC9C,CACI,IAAMP,GAAUO,EAAIxB,EAAY,WAAeC,EAAU,GAAMa,EAElDJ,EAAA,WAAW,QAASe,GACjC,CAEU,IAAAC,EAAaT,EAASQ,EAAK,OAASF,EAEjCR,EAAA,aAEL,KAAK,MAAMW,EAAa9B,EAAS,EAAIA,GACrCO,EAAM,OAAO,SAASsB,EAAK,KAAK,EAAE,MAAM,CAAA,CAC5C,CACH,CAAA,CACL,MAKaf,EAAA,WAAW,QAASe,GACjC,CACaV,EAAA,aAAaU,EAAK,OAAQtB,EAAM,OAAO,SAASsB,EAAK,KAAK,EAAE,MAAA,CAAO,CAAA,CAC/E,EAGE,OAAAV,CAAA,MAzGX,CACI,IAAMT,EAAUP,EAAQ,cAAcD,EAAU,QAAQ,OAAO,SAAU,QAAQ,EAC3ES,EAAaT,EAAU,OAAO,OAAOU,EAAO,MAAM,EAE7C,OAAAD,EAAA,MAAMT,EAAU,QAAQ,MAAM,MAAOA,EAAU,QAAQ,MAAM,MAAM,EAC9EQ,EAAQ,aAAaC,CAAU,EAExBD,CAAA,CAsGX,OAAAqB,EAAK,2BAA4B7B,CAAS,EAGnC,KACX,CC1IA,IAAM8B,GAAW,IAAIC,EAsCfC,GAAN,KACA,CAgBW,oBAAoBC,EAC3B,CACI,GAAM,CAAE,KAAAC,EAAM,MAAAC,EAAO,WAAAC,EAAa,CAAA,EAAMH,EAElCI,EAAWF,EAAoB,iBAAiB,EAGhDG,EAAWC,EAAkB,YAAYL,GAAQ,IAAKC,CAAK,EAE3DK,EAAQ,KAAK,KAAK,KAAK,KAAM,KAAK,IAAI,EAAGF,EAAS,KAAK,EAAKD,EAAU,CAAG,EAAID,CAAU,EACvFK,EAAS,KAAK,KAAK,KAAK,KAAM,KAAK,IAAI,EAAGH,EAAS,MAAM,EAAKD,EAAU,CAAG,EAAID,CAAU,EAEzFM,EAAmBC,GAAW,2BAA2BH,EAAOC,CAAM,EAE5E,KAAK,oBAAoBP,EAAMC,EAAOE,EAASD,EAAYM,CAAgB,EAErE,IAAAE,EAAQT,EAAM,KACdU,GAAqB,CAAE,OAAQH,EAAiB,OAAQ,MAAAF,EAAO,OAAAC,EAAQ,WAAY,EAAG,OAAQX,EAAA,CAAU,EACxGA,GAAS,IAAI,EAAG,EAAGU,EAAOC,CAAM,EAE/B,MAAA,CACH,iBAAAC,EACA,MAAAE,CAAA,CACJ,CAUG,uBAAuBF,EAC9B,CACIC,GAAW,uBAAuBD,CAAgB,CAAA,CAW9C,oBACJR,EACAC,EACAE,EACAD,EACAM,EAEJ,CACU,GAAA,CAAE,OAAAI,EAAQ,QAAAC,CAAA,EAAYL,EAEtBM,EAAOC,GAAwBd,CAAK,EAEpCG,EAAWC,EAAkB,YAAYL,GAAQ,IAAKC,CAAK,EAC3De,EAAQZ,EAAS,MACjBa,EAAab,EAAS,WACtBc,EAAad,EAAS,WACtBe,EAAef,EAAS,aACxBgB,EAAiBhB,EAAS,eAE1BG,EAASK,EAAO,OAQlB,GANJC,EAAQ,eAAe,EACfA,EAAA,MAAMX,EAAYA,CAAU,EACpCW,EAAQ,aAAeZ,EAAM,aAIzBA,EAAM,SAAS,MACnB,CACI,IAAMoB,EAAcpB,EAAM,QAE1BY,EAAQ,UAAYQ,EAAY,MAEhCR,EAAQ,WAAaQ,EAAY,WACjCR,EAAQ,SAAWQ,EAAY,KAC/BR,EAAQ,QAAUQ,EAAY,GAAA,CAIlCR,EAAQ,KAAOC,EAEX,IAAAQ,EACAC,EAGEC,EAAcvB,EAAM,WAAa,EAAI,EAa3C,QAASwB,EAAI,EAAGA,EAAID,EAAa,EAAEC,EACnC,CACU,IAAAC,EAAezB,EAAM,YAAcwB,IAAM,EAEzCE,EAAeD,EAAe,KAAK,KAAK,KAAK,IAAI,EAAGnB,CAAM,EAAKJ,EAAU,CAAE,EAAI,EAC/EyB,EAAiBD,EAAezB,EAEtC,GAAIwB,EACJ,CAIIb,EAAQ,UAAY,QACpBA,EAAQ,YAAc,QAEtB,IAAMgB,EAAgB5B,EAAM,WAEtB6B,EAAkBD,EAAc,MAChCE,EAAkBF,EAAc,MAE9BhB,EAAA,YAAcmB,EAAM,OACvB,SAASF,CAAe,EACxB,SAASC,CAAe,EACxB,aAAa,EAEZ,IAAAE,EAAiBJ,EAAc,KAAO3B,EACtCgC,EAAqBL,EAAc,SAAW3B,EAEpDW,EAAQ,WAAaoB,EACrBpB,EAAQ,cAAgB,KAAK,IAAIgB,EAAc,KAAK,EAAIK,EACxDrB,EAAQ,cAAiB,KAAK,IAAIgB,EAAc,KAAK,EAAIK,EAAsBN,CAAA,KAGnF,CAGQ,GAFIf,EAAA,UAAYZ,EAAM,MAAQkC,GAAmBlC,EAAM,MAAOY,EAAST,EAAUD,EAAU,CAAC,EAAI,KAEhGF,EAAM,SAAS,MACnB,CACI,IAAMmC,EAAiBnC,EAAM,QAAQ,MAAQ,GAAQE,EAAU,EAE/DU,EAAQ,YAAcsB,GAAmBlC,EAAM,QAASY,EAAST,EAAUgC,CAAa,CAAA,CAG5FvB,EAAQ,YAAc,OAAA,CAGtB,IAAAwB,GAAsBpB,EAAaG,EAAe,UAAY,EAE9DH,EAAaG,EAAe,SAAW,IAElBiB,EAAA,GAGnB,IAAAC,EAAcrC,EAAM,SAAS,OAAS,EAG5C,QAASwB,EAAI,EAAGA,EAAIT,EAAM,OAAQS,IAE9BH,EAAgBgB,EAAc,EAC9Bf,EAAkBe,EAAc,EAAMb,EAAIR,EAAeG,EAAe,OAASiB,EAE7EpC,EAAM,QAAU,QAECqB,GAAAH,EAAeD,EAAWO,CAAC,EAEvCxB,EAAM,QAAU,WAEHqB,IAAAH,EAAeD,EAAWO,CAAC,GAAK,GAGlDxB,EAAM,SAAS,OAEV,KAAA,mBACDe,EAAMS,CAAC,EACPxB,EACAO,EACAc,EAAgBnB,EAChBoB,EAAgBpB,EAAUwB,EAC1B,EAAA,EAIJ1B,EAAM,QAAU,QAEX,KAAA,mBACDe,EAAMS,CAAC,EACPxB,EACAO,EACAc,EAAgBnB,EAChBoB,EAAgBpB,EAAUwB,CAAA,CAGtC,CACJ,CAoBI,mBACJ3B,EACAC,EACAO,EACA+B,EAAWC,EACXC,EAAW,GAEf,CACU,GAAA,CAAE,QAAA5B,CAAA,EAAYL,EAGdkC,EAAgBzC,EAAM,cAExB0C,EAA+B,GAiB/B,GAfAtC,EAAkB,qCAEdA,EAAkB,2BAEVQ,EAAA,cAAgB,GAAG6B,CAAa,KAChC7B,EAAA,kBAAoB,GAAG6B,CAAa,KACbC,EAAA,KAI/B9B,EAAQ,cAAgB,MACxBA,EAAQ,kBAAoB,QAIhC6B,IAAkB,GAAKC,EAC3B,CACQF,EAEQ5B,EAAA,WAAWb,EAAMuC,EAAGC,CAAC,EAIrB3B,EAAA,SAASb,EAAMuC,EAAGC,CAAC,EAG/B,MAAA,CAGJ,IAAII,EAAkBL,EAEhBM,EAAcxC,EAAkB,kBAAkBL,CAAI,EACxD8C,EAAgBjC,EAAQ,YAAYb,CAAI,EAAE,MAC1C+C,EAAe,EAEnB,QAAStB,EAAI,EAAGA,EAAIoB,EAAY,OAAQ,EAAEpB,EAC1C,CACU,IAAAuB,EAAcH,EAAYpB,CAAC,EAE7BgB,EAEQ5B,EAAA,WAAWmC,EAAaJ,EAAiBJ,CAAC,EAI1C3B,EAAA,SAASmC,EAAaJ,EAAiBJ,CAAC,EAEpD,IAAIS,EAAU,GAEd,QAASC,EAAIzB,EAAI,EAAGyB,EAAIL,EAAY,OAAQ,EAAEK,EAE1CD,GAAWJ,EAAYK,CAAC,EAEbH,EAAAlC,EAAQ,YAAYoC,CAAO,EAAE,MAC5CL,GAAmBE,EAAgBC,EAAeL,EAClCI,EAAAC,CAAA,CACpB,CAER,EAGaI,GAAsB,IAAIrD,GCtVhC,IAAMsD,GAAN,KACP,CAkBI,YAAYC,EACZ,CANA,KAAiB,gBAGZ,CAAA,EAID,KAAK,UAAYA,CAAA,CAed,WACHC,EACAC,EACAC,EACAC,EAEJ,CACQ,OAAOH,GAAY,WAGnBI,EAAY,QAAS,mFAAmF,EAG9FJ,EAAA,CACN,KAAMA,EACN,MAAOE,EACP,WAAYD,CAAA,GAIdD,EAAQ,iBAAiBK,KAE3BL,EAAQ,MAAQ,IAAIK,GAAUL,EAAQ,KAAK,GAGzCA,EAAQ,wBAAwBM,KAElCN,EAAQ,aAAe,IAAIM,GAAaN,EAAQ,YAAY,GAG5D,OAAOA,EAAQ,MAAS,WAEhBA,EAAA,KAAOA,EAAQ,KAAK,SAAS,GAGzC,GAAM,CAAE,KAAAO,EAAM,MAAAC,EAAO,aAAAC,CAAA,EAAiBT,EAEhCU,EAAaV,EAAQ,YAAc,KAAK,UAAU,WAElD,CAAE,MAAAW,EAAO,iBAAAC,CAAiB,EAAIC,GAAoB,oBAAoB,CACxE,KAAAN,EACA,MAAAC,EACA,WAAAE,CAAA,CACH,EAEKI,EAAUC,GAAwBH,EAAiB,OAAQD,EAAM,MAAOA,EAAM,OAAQD,CAAU,EAiBtG,GAfID,IAAcK,EAAQ,OAAO,MAAQL,GAErCD,EAAM,OAGAG,EAAA,IAAIH,EAAM,OAAO,EACfM,EAAA,MAAM,SAASH,CAAK,EAKpBG,EAAA,MAAM,MAAM,EAAIJ,CAAU,EAClCI,EAAQ,UAAU,GAGlBN,EAAM,QACV,CAGI,IAAMQ,EAAkB,KAAK,cAAcF,EAASN,EAAM,OAAmB,EAG7E,YAAK,cAAcM,CAAO,EAE1BD,GAAoB,uBAAuBD,CAAgB,EAGpDI,CAAA,CAGX,YAAK,UAAU,QAAQ,WAAWF,EAAQ,OAAO,EAEjDD,GAAoB,uBAAuBD,CAAgB,EAEpDE,CAAA,CAQJ,cAAcA,EACrB,CACI,IAAMG,EAASH,EAAQ,OAEvBG,EAAO,SAAW,KAClBA,EAAO,eAAiB,UACxBA,EAAO,UAAY,uBAEPC,EAAA,cAAcJ,EAAS,EAAI,CAAA,CAOpC,oBACP,CAEIV,EACI,SACA,mGAAA,CACJ,CAeG,kBAAkBG,EACzB,CACIA,EAAK,YAAcA,EAAK,gBAAkB,KAAK,UAAU,WAAaA,EAAK,WAC3E,IAAMY,EAAUZ,EAAK,SAEjB,GAAA,KAAK,gBAAgBY,CAAO,EAE5B,YAAK,wBAAwBA,CAAO,EAE7B,KAAK,gBAAgBA,CAAO,EAAE,QAGnC,IAAAL,EAAU,KAAK,WAAW,CAC5B,KAAMP,EAAK,KACX,MAAOA,EAAK,MACZ,WAAYA,EAAK,YACjB,aAAcA,EAAK,YAAA,CACtB,EAEI,YAAA,gBAAgBY,CAAO,EAAI,CAC5B,QAAAL,EACA,WAAY,CAAA,EAGTA,CAAA,CAWJ,uBAAuBK,EAC9B,CACU,IAAAC,EAAgB,KAAK,gBAAgBD,CAAO,EAEpCC,EAAA,aAEVA,EAAc,aAAe,IAExB,KAAA,cAAcA,EAAc,OAAO,EACnC,KAAA,gBAAgBD,CAAO,EAAI,KACpC,CAQG,kBAAkBA,EACzB,CACI,OAAO,KAAK,gBAAgBA,CAAO,GAAG,YAAc,CAAA,CAGhD,wBAAwBA,EAChC,CACS,KAAA,gBAAgBA,CAAO,EAAE,YAAA,CAa1B,cAAcL,EAAkBO,EACxC,CAEU,IAAAC,EAAsB,KAAK,UAAU,aAAa,aAGlDC,EAAgB,KAAK,UAAU,OAAO,wBAAwB,CAChE,QAAAT,EACA,QAAAO,CAAA,CACH,EAKD,YAAK,UAAU,aAAa,KAAKC,EAAqB,EAAK,EAGpDC,CAAA,CAGJ,SACP,CACK,KAAK,UAAqB,KAEhB,QAAAC,KAAO,KAAK,gBAEf,KAAK,gBAAgBA,CAAG,GAAG,KAAK,cAAc,KAAK,gBAAgBA,CAAG,EAAE,OAAO,EAEtF,KAAK,gBAA2B,IAAA,CAEzC,EAxQa1B,GAGK,UAAY,CACtB,KAAM,CACF2B,EAAc,YACdA,EAAc,aACdA,EAAc,YAAA,EAElB,KAAM,YACV,ECgEG,IAAMC,GAAN,MAAMC,UAAiBC,EAC9B,CAaI,YAAYC,EACZ,CACQA,aAAmBC,IAETD,EAAA,CAAE,QAASA,CAAQ,GAGjC,GAAM,CAAE,QAAAE,EAAS,YAAAC,EAAa,GAAGC,CAAK,EAAIJ,GAAW,CAAA,EAE/C,MAAA,CACF,MAAO,WACP,GAAGI,CAAA,CACN,EAvBL,KAAyB,aAAuB,WAyBvCF,EAMD,KAAK,SAAWA,EAJhB,KAAK,SAAW,KAAK,cAAgB,IAAID,EAO7C,KAAK,SAAS,GAAG,SAAU,KAAK,aAAc,IAAI,EAElD,KAAK,cAAgB,GAErB,KAAK,cAAgB,GACrB,KAAK,YAAcE,GAAe,EAAA,CAGtC,IAAI,QAAQD,EACZ,CACQA,IAAY,KAAK,WAErB,KAAK,SAAS,IAAI,SAAU,KAAK,aAAc,IAAI,EAEnD,KAAK,SAAWA,EAGhB,KAAK,SAAS,GAAG,SAAU,KAAK,aAAc,IAAI,EAElD,KAAK,aAAa,EAAA,CA2BtB,IAAI,SACJ,CACI,OAAO,KAAK,QAAA,CAwBhB,IAAa,QACb,CACI,OAAO,KAAK,SAAS,MAAA,CAOf,cAAqB,CAAA,CAwBf,cAAcG,EAC9B,CACW,OAAA,KAAK,SAAS,cAAcA,CAAK,CAAA,CAsB5B,QAAQL,EACxB,CACQ,KAAK,eAAiB,CAACA,EAElB,KAAA,cAAc,QAAQA,CAAO,GAE7BA,IAAY,IAASA,GAAmC,UAAY,KAEpE,KAAA,SAAS,QAAQA,CAAO,EAGhC,KAAK,cAAyB,KAC/B,KAAK,SAAW,KAEhB,MAAM,QAAQA,CAAO,CAAA,CAGjB,mBAAmBM,EAA+BC,EAC1D,CACK,YAAK,QAAgBD,CAAM,EAAE,GAAGC,CAAI,EAE9B,IAAA,CAgDJ,gBAAgBA,EACvB,CACW,OAAA,KAAK,mBAAmB,eAAgBA,CAAI,CAAA,CAwDhD,kBAAkBA,EACzB,CACW,OAAA,KAAK,mBAAmB,iBAAkBA,CAAI,CAAA,CAyDlD,QAAQA,EACf,CACW,OAAA,KAAK,mBAAmB,OAAQA,CAAI,CAAA,CAmDxC,UAAUA,EACjB,CACW,OAAA,KAAK,mBAAmB,SAAUA,CAAI,CAAA,CAyC1C,WAAWA,EAClB,CACW,OAAA,KAAK,mBAAmB,UAAWA,CAAI,CAAA,CAmB3C,WACP,CACI,OAAO,KAAK,mBAAmB,YAAa,CAAA,CAAE,CAAA,CAmB3C,KACP,CACI,OAAO,KAAK,mBAAmB,MAAO,CAAA,CAAE,CAAA,CAoCrC,OAAOA,EACd,CACW,OAAA,KAAK,mBAAmB,MAAOA,CAAI,CAAA,CAmCvC,SAASA,EAChB,CACW,OAAA,KAAK,mBAAmB,QAASA,CAAI,CAAA,CAmDzC,YAAYA,EACnB,CACW,OAAA,KAAK,mBAAmB,WAAYA,CAAI,CAAA,CA4C5C,iBAAiBA,EACxB,CACW,OAAA,KAAK,mBAAmB,gBAAiBA,CAAI,CAAA,CAqBjD,WACP,CACI,OAAO,KAAK,mBAAmB,YAAa,CAAA,CAAE,CAAA,CA4B3C,WAAWA,EAClB,CACW,OAAA,KAAK,mBAAmB,UAAWA,CAAI,CAAA,CAmC3C,UAAUA,EACjB,CACW,OAAA,KAAK,mBAAmB,SAAUA,CAAI,CAAA,CA6B1C,QAAQA,EACf,CACW,OAAA,KAAK,mBAAmB,OAAQA,CAAI,CAAA,CA8BxC,UAAUA,EACjB,CACW,OAAA,KAAK,mBAAmB,SAAUA,CAAI,CAAA,CA6C1C,UAAUA,EACjB,CACW,OAAA,KAAK,mBAAmB,SAAUA,CAAI,CAAA,CAwC1C,oBAAoBA,EAC3B,CACW,OAAA,KAAK,mBAAmB,mBAAoBA,CAAI,CAAA,CA+BpD,QAAQA,EACf,CACW,OAAA,KAAK,mBAAmB,OAAQA,CAAI,CAAA,CAyBxC,aAAaA,EACpB,CACW,OAAA,KAAK,mBAAmB,YAAaA,CAAI,CAAA,CA8C7C,QAAQA,EACf,CACW,OAAA,KAAK,mBAAmB,OAAQA,CAAI,CAAA,CA8CxC,eAAeA,EACtB,CACW,OAAA,KAAK,mBAAmB,cAAeA,CAAI,CAAA,CAuC/C,aAAaA,EACpB,CACW,OAAA,KAAK,mBAAmB,YAAaA,CAAI,CAAA,CAqD7C,cAAcA,EACrB,CACW,OAAA,KAAK,mBAAmB,aAAcA,CAAI,CAAA,CA8B9C,cAAcA,EACrB,CACW,OAAA,KAAK,mBAAmB,aAAcA,CAAI,CAAA,CAkC9C,eAAeA,EACtB,CACW,OAAA,KAAK,mBAAmB,cAAeA,CAAI,CAAA,CAqC/C,QAAQA,EACf,CACW,OAAA,KAAK,mBAAmB,OAAQA,CAAI,CAAA,CAwBxC,OAAOA,EACd,CACW,OAAA,KAAK,mBAAmB,MAAOA,CAAI,CAAA,CA+BvC,WAAWA,EAClB,CACW,OAAA,KAAK,mBAAmB,UAAWA,CAAI,CAAA,CAqC3C,MACP,CACI,OAAO,KAAK,mBAAmB,OAAQ,CAAA,CAAE,CAAA,CA4BtC,cACP,CACW,OAAA,KAAK,QAAQ,aAAa,CAAA,CA2B9B,gBACP,CACI,OAAO,KAAK,mBAAmB,iBAAkB,CAAA,CAAE,CAAA,CAqBhD,mBAAmBA,EAC1B,CACW,OAAA,KAAK,mBAAmB,SAAUA,CAAI,CAAA,CA4B1C,kBAAkBA,EACzB,CACW,OAAA,KAAK,mBAAmB,QAASA,CAAI,CAAA,CAgDzC,gBAAgBA,EACvB,CACW,OAAA,KAAK,mBAAmB,eAAgBA,CAAI,CAAA,CA+ChD,aAAaA,EACpB,CACW,OAAA,KAAK,mBAAmB,YAAaA,CAAI,CAAA,CAuB7C,sBAAsBA,EAC7B,CACW,OAAA,KAAK,mBAAmB,YAAaA,CAAI,CAAA,CAiC7C,OACP,CACI,OAAO,KAAK,mBAAmB,QAAS,CAAA,CAAE,CAAA,CA2C9C,IAAI,WACJ,CACI,OAAO,KAAK,SAAS,SAAA,CAEzB,IAAI,UAAUC,EACd,CACI,KAAK,SAAS,UAAYA,CAAA,CA6C9B,IAAI,aACJ,CACI,OAAO,KAAK,SAAS,WAAA,CAEzB,IAAI,YAAYA,EAChB,CACI,KAAK,SAAS,YAAcA,CAAA,CAwCzB,MAAMC,EAAO,GACpB,CACI,OAAIA,EAEO,IAAIX,EAAS,KAAK,SAAS,MAAA,CAAO,GAG5C,KAAK,cAAyB,KACjB,IAAIA,EAAS,KAAK,QAAQ,EAEjC,CAWJ,UAAUY,EAAgBC,EAAqBC,EACtD,CAEIC,EAAYC,EAAQ,8FAA8F,EAGlH,IAAMC,EAAoC,CAAA,EAG1C,OAAAL,IAAUK,EAAY,MAAQL,GAC9BC,IAAUI,EAAY,MAAQJ,GAC9BC,IAAUG,EAAY,MAAQH,GAE9B,KAAK,QAAQ,YAAcG,EAEpB,IAAA,CAQJ,UAAUJ,EAAoBC,EACrC,CAGIC,EAAYC,EAAQ,qGAAqG,EAGzH,IAAME,EAAgC,CAAA,EAGtC,OAAIL,IAAU,SAAWK,EAAU,MAAQL,GACvCC,IAAU,SAAWI,EAAU,MAAQJ,GAE3C,KAAK,QAAQ,UAAYI,EAElB,IAAA,CAMJ,SACP,CAGIH,EAAYC,EAAQ,mGAAmG,EAGvH,KAAK,QAAQ,KAAK,EACZ,IAAAC,EAAc,KAAK,QAAQ,YAEjC,OAAIA,EAAY,QAAUd,EAAgB,mBAAmB,OACtDc,EAAY,QAAUd,EAAgB,mBAAmB,OACzDc,EAAY,QAAUd,EAAgB,mBAAmB,QAE5D,KAAK,QAAQ,OAAO,EAGjB,IAAA,CAOJ,cAAcM,EACrB,CAEI,OAAAM,EAAYC,EAAQ,yDAAyD,EAGtE,KAAK,mBAAmB,SAAUP,CAAI,CAAA,CAO1C,eAAeA,EACtB,CAEI,OAAAM,EAAYC,EAAQ,2DAA2D,EAGxE,KAAK,mBAAmB,UAAWP,CAAI,CAAA,CAO3C,eAAeA,EACtB,CAEI,OAAAM,EAAYC,EAAQ,wDAAwD,EAGrE,KAAK,mBAAmB,OAAQP,CAAI,CAAA,CAOxC,YAAYA,EACnB,CAEI,OAAAM,EAAYC,EAAQ,qDAAqD,EAGlE,KAAK,mBAAmB,OAAQP,CAAI,CAAA,CAOxC,mBAAmBA,EAC1B,CAEI,OAAAM,EAAYC,EAAQ,iEAAiE,EAG9E,KAAK,mBAAmB,YAAaP,CAAI,CAAA,CAO7C,YAAYA,EACnB,CAEI,OAAAM,EAAYC,EAAQ,qDAAqD,EAGlE,KAAK,mBAAmB,OAAQP,CAAI,CAAA,CAEnD,EC3+DO,IAAMU,GAAsB,CAC/B,KAAM,yBACN,OAAQ,CACJ,OAAkB;;;;;;;;;UAUlB,KAAgB;;;UAIhB,IAAe;;;;;SAAA,EAOnB,SAAU,CACN,OAAkB;;;;;;;;WASlB,KAAgB;;SAAA,CAKxB,EAGaC,GAAwB,CACjC,KAAM,yBACN,OAAQ,CACJ,OAAkB;;;;UAKlB,KAAgB;;;UAIhB,IAAe;;;;;SAAA,EAOnB,SAAU,CACN,OAAkB;;WAGlB,KAAgB;;SAAA,CAKxB,ECzEO,IAAMC,GAAU,CACnB,KAAM,WACN,SAAU,CACN,OAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;SAAA,CA8B1B,EAGaC,GAAY,CACrB,KAAM,WACN,SAAU,CACN,OAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;SAAA,CA8B1B,EClDA,IAAIC,GACAC,GAGSC,GAAN,cAAwBC,EAC/B,CACI,YAAYC,EACZ,CACU,IAAAC,EAAW,IAAIC,EAAa,CAC9B,OAAQ,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,EAAG,KAAM,WAAY,EACnE,iBAAkB,CAAE,MAAO,IAAIC,EAAU,KAAM,aAAc,EAC7D,UAAW,CAAE,MAAO,EAAG,KAAM,KAAM,EACnC,OAAQ,CAAE,MAAO,EAAG,KAAM,KAAM,CAAA,CACnC,EAEDP,KAAAA,GAAeQ,GAA4B,CACvC,KAAM,aACN,KAAM,CACFC,GACAC,GAAwBN,CAAW,EACnCO,GACAC,GACAC,EAAA,CACJ,CACH,GAEDZ,KAAAA,GAAca,GAA2B,CACrC,KAAM,aACN,KAAM,CACFC,GACAC,GAA0BZ,CAAW,EACrCa,GACAC,GACAC,EAAA,CACJ,CACH,GAEK,MAAA,CACF,UAAAlB,GACA,WAAAD,GACA,UAAW,CACP,cAAeK,EACf,cAAee,GAA6BhB,CAAW,CAAA,CAC3D,CACH,CAAA,CAET,ECwBO,IAAeiB,GAAf,cACKC,EAEZ,CAHO,aAAA,CAAA,MAAA,GAAA,SAAA,EAKa,KAAA,MAAyC,OAAA,OAAO,IAAI,EAMpE,KAAgB,WAA2C,EAM3D,KAAgB,WAA2C,GAE3D,KAAgB,YAA2B,CAAE,SAAU,EAAG,OAAQ,EAAG,QAAS,CAAE,EAKhF,KAAgB,eAAmD,EAEnE,KAAgB,cAAiD,CAAE,KAAM,OAAQ,MAAO,CAAE,EAE1F,KAAgB,MAAgC,CAAA,EAEhD,KAAO,gBAAkB,GAGzB,KAAgB,wBAAkC,IAClD,KAAU,qBAAuB,GAAA,CAMjC,IAAW,MACX,CAEI,OAAAC,EAAYC,EAAQ,0EAA0E,EAGvF,KAAK,UAAA,CAOhB,IAAW,cACX,CAEI,OAAAD,EAAYC,EAAQ,6EAA6E,EAG1F,KAAK,KAAA,CAOhB,IAAW,MACX,CAEI,OAAAD,EAAYC,EAAQ,oFAAoF,EAGjG,KAAK,YAAY,QAAA,CAO5B,IAAW,oBACX,CAGI,OAAAD,EAAYC,EAAQ,iGAAiG,EAG9G,KAAK,cAAc,KAAA,CAO9B,IAAW,mBACX,CAEI,OAAAD,EAAYC,EAAQ,+FAA+F,EAG5G,KAAK,cAAc,IAAA,CAGvB,QAAQC,EAAkB,GACjC,CACS,KAAA,KAAK,UAAW,IAA2B,EAEhD,KAAK,mBAAmB,EAEb,QAAAC,KAAK,KAAK,MAGjB,KAAK,MAAMA,CAAC,EAAE,SAAS,QAAQ,EAGlC,KAAK,MAAiB,KAEnBD,IAEK,KAAA,MAAM,QAASE,GAASA,EAAK,QAAQ,QAAQ,EAAI,CAAC,EACtD,KAAK,MAAgB,KAC1B,CAER,EChLO,IAAMC,GAAN,MAAMA,WAA0BC,EACvC,CA8BI,YAAYC,EACZ,CACU,MAAA,EAtBV,KAAO,WAAa,EAEpB,KAAyB,MAAmE,CAAA,EAE5F,KAAiB,SAAmB,EACnB,KAAA,cAA+C,OAAA,OAAO,IAAI,EAC3E,KAAQ,cAA0B,CAAA,EAClC,KAAQ,UAAY,EACpB,KAAQ,UAAY,EACpB,KAAQ,sBAAwB,EAChC,KAAQ,kBAAoB,GAE5B,KAAiB,aAAwB,GAYrC,IAAMC,EAAiB,CAAE,GAAGH,GAAkB,eAAgB,GAAGE,CAAQ,EAEzE,KAAK,aAAeC,EAAe,YACnC,KAAK,QAAUA,EAAe,OAExB,IAAAC,EAAQD,EAAe,MAAM,MAAM,EAErCA,EAAe,eAGfC,EAAM,MAAM,MAAQ,SACpBA,EAAM,MAAM,MAAQ,EACdA,EAAA,MAAM,QAAUC,EAAQ,MAC9BD,EAAM,MAAM,KAAO,MAGvB,KAAK,gBAAkBD,EAAe,aAEtC,IAAMG,EAAoBF,EAAM,SAGhCA,EAAM,SAAW,KAAK,wBAEhB,IAAAG,EAAOC,GAAwBJ,CAAK,EAEtCD,EAAe,aAEXC,EAAM,UAKAA,EAAA,QAAQ,OAAS,KAAK,qBAAuBE,GAKjDF,EAAA,SAAW,KAAK,qBAAuBE,EAGjD,KAAK,OAASF,EACT,KAAA,aAAeD,EAAe,aAAe,GAC7C,KAAA,WAAaA,EAAe,YAAc,EAC1C,KAAA,SAAWA,EAAe,SAAW,EAEtCA,EAAe,eAEV,KAAA,cAAgBA,EAAe,wBAAwBM,GACtDN,EAAe,aACf,IAAIM,GAAaN,EAAe,YAAY,GAGrD,KAAK,YAA8BO,EAAkB,YAAYH,CAAI,EACrE,KAAK,WAAwBH,EAAM,YAAc,KAAK,YAAY,UAAYA,EAAM,QAAA,CAGlF,iBAAiBO,EACxB,CACU,IAAAC,EAAWF,EAAkB,kBAAkBC,CAAK,EACrD,OAAQE,GAAS,CAAC,KAAK,cAAc,SAASA,CAAI,CAAC,EACnD,OAAO,CAACA,EAAMC,EAAOC,IAASA,EAAK,QAAQF,CAAI,IAAMC,CAAK,EAG/D,GAAI,CAACF,EAAS,OAAQ,OAEtB,KAAK,cAAgB,CAAC,GAAG,KAAK,cAAe,GAAGA,CAAQ,EAEpD,IAAAI,EAEA,KAAK,oBAAsB,GAE3BA,EAAW,KAAK,UAAU,EAIfA,EAAA,KAAK,MAAM,KAAK,iBAAiB,EAGhD,GAAI,CAAE,OAAAC,EAAQ,QAAAC,CAAQ,EAAIF,EAAS,iBAC/BG,EAAgBH,EAAS,QAAQ,OAE/BZ,EAAQ,KAAK,OAEfgB,EAAW,KAAK,UAChBC,EAAW,KAAK,UAChBC,EAAuB,KAAK,sBAE1BC,EAAY,KAAK,qBAAuB,KAAK,wBAC7CC,EAAU,KAAK,SAAWD,EAE5BE,EAAc,GAEZC,EAAkBT,EAAO,MAAQ,KAAK,WACtCU,EAAmBV,EAAO,OAAS,KAAK,WAE9C,QAASW,EAAI,EAAGA,EAAIhB,EAAS,OAAQgB,IACrC,CACU,IAAAf,EAAOD,EAASgB,CAAC,EAEjBC,EAAUnB,EAAkB,YAAYG,EAAMT,EAAOa,EAAQ,EAAK,EAIxEY,EAAQ,WAAaA,EAAQ,OAEvB,IAAAC,EAAQD,EAAQ,MAAQN,EAExBQ,EAAoB,KAAK,MAAM3B,EAAM,YAAc,SAAW,EAAI,GAAK0B,CAAK,EAE5EE,EAAUH,EAAQ,OAAUN,EAE5BU,EAAcF,EAAqBP,EAAU,EAC7CU,EAAeF,EAAUR,EAAU,EAUrC,GARUC,EAAA,GAEVZ,IAAS;GAAQA,IAAS,MAAQA,IAAS,KAAQA,IAAS,MAE9CY,EAAA,GACdH,EAAuB,KAAK,KAAK,KAAK,IAAIY,EAAcZ,CAAoB,CAAC,GAG7EF,EAAWa,EAAcP,IAEbL,GAAAC,EAGWA,EAAAY,EACZd,EAAA,EAEPC,EAAWC,EAAuBK,GACtC,CACIR,EAAc,OAAO,EAEfH,IAAAA,EAAW,KAAK,UAAU,EAEhCC,EAASD,EAAS,iBAAiB,OACnCE,EAAUF,EAAS,iBAAiB,QACpCG,EAAgBH,EAAS,QAAQ,OAEtBI,EAAA,EACAC,EAAA,EACYC,EAAA,CAAA,CAIzB,IAAAa,EAAYL,EAAQP,GACnBnB,EAAM,YAAY,UAAY,IAC9BA,EAAM,SAAS,OAAS,GAW/B,GARK,KAAA,MAAMS,CAAI,EAAI,CACf,GAAIA,EAAK,YAAY,CAAC,EACtB,QAAS,CAAC,KAAK,SACf,QAAS,CAAC,KAAK,SACf,SAAAsB,EACA,QAAS,CAAA,CAAC,EAGVV,EACJ,CACS,KAAA,WACDP,EACAW,EACAT,EAAWI,EACXH,EAAWG,EACXD,EACAnB,CAAA,EAGE,IAAAgC,EAAKjB,EAAc,MAAQI,EAC3Bc,EAAKlB,EAAc,OAASI,EAE5Be,EAAQ,IAAIC,EACZnB,EAAYgB,EAAMjB,EAAc,MAChCE,EAAYgB,EAAMlB,EAAc,OAChCc,EAAeG,EAAMjB,EAAc,MACnCe,EAAgBG,EAAMlB,EAAc,MAAA,EAG1C,KAAK,MAAMN,CAAI,EAAE,QAAU,IAAIR,EAAQ,CACnC,OAAQc,EACR,MAAAmB,CAAA,CACH,EAEWlB,GAAA,KAAK,KAAKa,CAAW,CAAA,CACrC,CAGJd,EAAc,OAAO,EAErB,KAAK,UAAYC,EACjB,KAAK,UAAYC,EACjB,KAAK,sBAAwBC,EAG7B,KAAK,cAAgB,KAAK,cAAcV,EAAUM,CAAO,CAAA,CAO7D,IAAoB,cACpB,CAEI,OAAAsB,EAAYC,EAAQ,6EAA6E,EAG1F,KAAK,KAAA,CAGR,cAAcC,EAAoBxB,EAC1C,CACI,IAAMyB,EAAe,KAAK,cAE1B,QAASf,EAAI,EAAGA,EAAIc,EAAS,OAAQd,IACrC,CACU,IAAAgB,EAAQF,EAASd,CAAC,EAExB,QAASiB,EAAI,EAAGA,EAAI,KAAK,cAAc,OAAQA,IAC/C,CAEU,IAAAC,EAAS,KAAK,cAAcD,CAAC,EAE/BE,EAAKJ,EAAaC,CAAK,EAEtBG,IAAIA,EAAKJ,EAAaC,CAAK,EAAI1B,EAAQ,YAAY0B,CAAK,EAAE,OAE3D,IAAAI,EAAKL,EAAaG,CAAM,EAEvBE,IAAIA,EAAKL,EAAaG,CAAM,EAAI5B,EAAQ,YAAY4B,CAAM,EAAE,OAEjE,IAAIG,EAAQ/B,EAAQ,YAAY0B,EAAQE,CAAM,EAAE,MAC5CI,EAASD,GAASF,EAAKC,GAEvBE,IAEA,KAAK,MAAMN,CAAK,EAAE,QAAQE,CAAM,EAAII,GAIxCD,EAAQ/B,EAAQ,YAAY0B,EAAQE,CAAM,EAAE,MAC5CI,EAASD,GAASF,EAAKC,GAEnBE,IAEA,KAAK,MAAMJ,CAAM,EAAE,QAAQF,CAAK,EAAIM,EACxC,CACJ,CACJ,CAGI,WACR,CACS,KAAA,oBAEL,IAAMC,EAAoB,KAAK,WACzBC,EAAmBC,GAAW,2BAChC,KAAK,aACL,KAAK,aACLF,CAAA,EAGJ,KAAK,cAAcC,EAAiB,QAAS,KAAK,OAAQD,CAAiB,EAE3E,IAAMG,EAAaH,GAAqB,KAAK,qBAAuB,KAAK,yBACnEI,EAAU,IAAIlD,EAAQ,CACxB,OAAQ,IAAImD,GAAY,CACpB,SAAUJ,EAAiB,OAC3B,WAAAE,EACA,UAAW,8BACX,oBAAqB,KAAK,OAAA,CAC7B,CAAA,CAEJ,EAEG,KAAK,gBAEGC,EAAA,OAAO,MAAQ,KAAK,eAGhC,IAAMvC,EAAW,CACb,iBAAAoC,EACA,QAAAG,CAAA,EAGC,YAAA,MAAM,KAAK,iBAAiB,EAAIvC,EAE9BA,CAAA,CAIH,cAAcE,EAAoCd,EAAkBkD,EAC5E,CACIlD,EAAM,SAAW,KAAK,qBACdc,EAAA,MAAMoC,EAAYA,CAAU,EAC5BpC,EAAA,KAAOV,GAAwBJ,CAAK,EAC5CA,EAAM,SAAW,KAAK,wBACtBc,EAAQ,aAAed,EAAM,aAE7B,IAAMqD,EAASrD,EAAM,QACfsD,EAAkBD,GAAQ,OAAS,EAkBzC,GAhBIA,IAEAvC,EAAQ,UAAYwC,EACpBxC,EAAQ,SAAWuC,EAAO,KAC1BvC,EAAQ,WAAauC,EAAO,WAGpBvC,EAAA,YAAcyC,GAAmBF,EAAQvC,CAAO,GAGxDd,EAAM,QAGNc,EAAQ,UAAYyC,GAAmBvD,EAAM,MAAOc,CAAO,GAG3Dd,EAAM,WACV,CACI,IAAMwD,EAAgBxD,EAAM,WACtByD,EAAMC,EAAM,OAAO,SAASF,EAAc,KAAK,EAAE,QAAQ,EAEzDG,EAAiBH,EAAc,KAAON,EACtCU,EAAqBJ,EAAc,SAAWN,EAEpDpC,EAAQ,YAAc,QAAQ2C,EAAI,CAAC,EAAI,GAAG,IAAIA,EAAI,CAAC,EAAI,GAAG,IAAIA,EAAI,CAAC,EAAI,GAAG,IAAID,EAAc,KAAK,IACjG1C,EAAQ,WAAa6C,EACrB7C,EAAQ,cAAgB,KAAK,IAAI0C,EAAc,KAAK,EAAII,EACxD9C,EAAQ,cAAgB,KAAK,IAAI0C,EAAc,KAAK,EAAII,CAAA,MAIxD9C,EAAQ,YAAc,QACtBA,EAAQ,WAAa,EACrBA,EAAQ,cAAgB,EACxBA,EAAQ,cAAgB,CAC5B,CAGI,WACJA,EACAW,EACAoC,EACAC,EACA3C,EACAnB,EAEJ,CACI,IAAMS,EAAOgB,EAAQ,KACfsC,EAAiBtC,EAAQ,eAGzB6B,GAFStD,EAAM,SAEY,OAAS,GAAKmB,EAEzC6C,EAAKH,EAAKP,EAAkB,EAC5BW,EAAKH,EAAKR,EAAkB,EAE5BY,EAAUH,EAAe,QAAU5C,EACnCgD,EAAa1C,EAAQ,WAAaN,EAEpCiD,EAAe,GAEfpE,EAAM,QAAUsD,IAEDc,EAAA,GACftD,EAAQ,WAAWL,EAAMuD,EAAIC,EAAKE,EAAaD,CAAO,GAG1D,GAAM,CAAE,WAAAG,EAAY,cAAAC,EAAe,cAAAC,CAAA,EAAkBzD,EAEjDd,EAAM,QAEFoE,IAEAtD,EAAQ,WAAa,EACrBA,EAAQ,cAAgB,EACxBA,EAAQ,cAAgB,GAE5BA,EAAQ,SAASL,EAAMuD,EAAIC,EAAKE,EAAaD,CAAO,GAGpDE,IAEAtD,EAAQ,WAAauD,EACrBvD,EAAQ,cAAgBwD,EACxBxD,EAAQ,cAAgByD,EAC5B,CAGY,SAChB,CACI,MAAM,QAAQ,EAEd,QAAS/C,EAAI,EAAGA,EAAI,KAAK,MAAM,OAAQA,IACvC,CACI,GAAM,CAAE,iBAAAwB,EAAkB,QAAAG,CAAA,EAAY,KAAK,MAAM3B,CAAC,EAElDyB,GAAW,uBAAuBD,CAAgB,EAClDG,EAAQ,QAAQ,EAAI,CAAA,CAGvB,KAAK,MAAiB,IAAA,CAE/B,EAzbavD,GAEK,eAA2C,CACrD,YAAa,IACb,MAAO,IAAI4E,GACX,OAAQ,EACZ,EANG,IAAMC,GAAN7E,GCHA,SAAS8E,GACZC,EACAC,EACAC,EACAC,EAEJ,CACI,IAAMC,EAAmC,CACrC,MAAO,EACP,OAAQ,EACR,QAAS,EACT,MAAOH,EAAM,SAAWC,EAAK,wBAC7B,MAAO,CAAC,CACJ,MAAO,EACP,cAAe,CAAA,EACf,WAAY,EACZ,YAAa,CAAA,EACb,MAAO,CAAA,CAAC,CACX,CAAA,EAGLE,EAAW,QAAUF,EAAK,eAEtB,IAAAG,EAAcD,EAAW,MAAM,CAAC,EAEhCE,EAAuB,KACvBC,EAAY,GAGVC,EAAc,CAChB,UAAW,GACX,MAAO,EACP,MAAO,EACP,MAAO,EACP,UAAW,CAAA,EACX,MAAO,CAAA,CAAC,EAGNC,EAAQP,EAAK,wBAA0BD,EAAM,SAE7CS,EAAwBT,EAAM,cAAgBQ,EAC9CE,EAAwBV,EAAM,cAAgBQ,EAC9CG,EAAqBX,EAAM,WAAaA,EAAM,WAAaQ,EAAQP,EAAK,WAExEW,EAAaZ,EAAM,UAAYA,EAAM,WAErCa,EAAYC,GAClB,CACI,IAAMC,EAAQX,EAAY,MAE1B,QAASY,EAAI,EAAGA,EAAIT,EAAY,MAAOS,IACvC,CACU,IAAAC,EAAWH,EAAK,UAAUE,CAAC,EAEjCZ,EAAY,MAAM,KAAKU,EAAK,MAAME,CAAC,CAAC,EACxBZ,EAAA,cAAc,KAAKa,EAAWF,CAAK,CAAA,CAGnDX,EAAY,OAASU,EAAK,MAEdR,EAAA,GAGZC,EAAY,MAAQ,EACpBA,EAAY,MAAQ,EACpBA,EAAY,MAAM,OAAS,CAAA,EAKzBW,EAAW,IACjB,CACQ,IAAAC,EAAQf,EAAY,MAAM,OAAS,EAEvC,GAAIF,EACJ,CACQ,IAAAkB,EAAWhB,EAAY,MAAMe,CAAK,EAEtC,KAAOC,IAAa,KAEhBhB,EAAY,OAASH,EAAK,MAAMmB,CAAQ,EAAE,SAC/BA,EAAAhB,EAAY,MAAM,EAAEe,CAAK,CACxC,CAGJhB,EAAW,MAAQ,KAAK,IAAIA,EAAW,MAAOC,EAAY,KAAK,EAEjDA,EAAA,CACV,MAAO,EACP,cAAe,CAAA,EACf,MAAO,CAAA,EACP,WAAY,EACZ,YAAa,CAAA,CAAC,EAGNE,EAAA,GACDH,EAAA,MAAM,KAAKC,CAAW,EACjCD,EAAW,QAAUQ,CAAA,EAGnBU,EAAmBC,GACrBA,EAAYb,EAAwBC,EAGxC,QAASa,EAAI,EAAGA,EAAIxB,EAAM,OAAS,EAAGwB,IACtC,CACQ,IAAAC,EAEEC,EAAQF,IAAMxB,EAAM,OAErB0B,IAEDD,EAAOzB,EAAMwB,CAAC,GAGlB,IAAMG,EAAWzB,EAAK,MAAMuB,CAAI,GAAKvB,EAAK,MAAM,GAAG,EAQnD,GANiB,SAAU,KAAKuB,CAAI,GACLA,IAAS,MAAQA,IAAS;GAAQC,GAgCzD,GAzBsB,CAACnB,GAAaN,EAAM,UAAYqB,EAAgBjB,EAAY,MAAQG,EAAY,KAAK,GAIlGW,EAAA,EAETL,EAASN,CAAW,EAEfkB,GAEWrB,EAAA,cAAc,KAAK,CAAC,IAKpCG,EAAY,MAAQH,EAAY,MAEhCS,EAASN,CAAW,EAEfkB,GAEWrB,EAAA,cAAc,KAAK,CAAC,GAIpCoB,IAAS,MAAQA,IAAS;EAEjBN,EAAA,UAEJ,CAACO,EACV,CACI,IAAME,EAAaD,EAAS,UAAYA,EAAS,QAAQrB,CAAY,GAAK,GAAKI,EAE/EL,EAAY,OAASuB,EAErBvB,EAAY,WAAauB,EACzBvB,EAAY,YAAY,KAAKA,EAAY,cAAc,MAAM,EACjDA,EAAA,MAAM,KAAKoB,CAAI,CAAA,MAMnC,CACI,IAAMI,EAAUF,EAAS,QAAQrB,CAAY,GAAK,EAE5CwB,EAAgBH,EAAS,SAAWE,EAAUnB,EAE1BG,GAAcS,EAAgBjB,EAAY,MAAQG,EAAY,MAAQsB,CAAa,IAIzGhB,EAASN,CAAW,EACXW,EAAA,GAGbX,EAAY,UAAUA,EAAY,OAAO,EAAIA,EAAY,MAAQqB,EACrDrB,EAAA,MAAM,KAAKiB,CAAI,EAE3BjB,EAAY,OAASsB,CAAA,CAGVxB,EAAAmB,CAAA,CAIV,OAAAN,EAAA,EAELlB,EAAM,QAAU,SAEhB8B,GAAY3B,CAAU,EAEjBH,EAAM,QAAU,QAErB+B,GAAW5B,CAAU,EAEhBH,EAAM,QAAU,WAErBgC,GAAa7B,CAAU,EAGpBA,CACX,CAEA,SAAS2B,GAAYG,EACrB,CACI,QAASV,EAAI,EAAGA,EAAIU,EAAgB,MAAM,OAAQV,IAClD,CACU,IAAAW,EAAOD,EAAgB,MAAMV,CAAC,EAC9BY,EAAWF,EAAgB,MAAQ,EAAMC,EAAK,MAAQ,EAE5D,QAASlB,EAAI,EAAGA,EAAIkB,EAAK,cAAc,OAAQlB,IAEtCkB,EAAA,cAAclB,CAAC,GAAKmB,CAC7B,CAER,CAEA,SAASJ,GAAWE,EACpB,CACI,QAASV,EAAI,EAAGA,EAAIU,EAAgB,MAAM,OAAQV,IAClD,CACU,IAAAW,EAAOD,EAAgB,MAAMV,CAAC,EAC9BY,EAAWF,EAAgB,MAAUC,EAAK,MAEhD,QAASlB,EAAI,EAAGA,EAAIkB,EAAK,cAAc,OAAQlB,IAEtCkB,EAAA,cAAclB,CAAC,GAAKmB,CAC7B,CAER,CAEA,SAASH,GAAaC,EACtB,CACI,IAAMG,EAAQH,EAAgB,MAE9B,QAASV,EAAI,EAAGA,EAAIU,EAAgB,MAAM,OAAQV,IAClD,CACU,IAAAW,EAAOD,EAAgB,MAAMV,CAAC,EAEhCc,EAAO,EACPC,EAAaJ,EAAK,YAAYG,GAAM,EAEpCF,EAAS,EAEPI,EAAcL,EAAK,YAAY,OAI/BP,GAFiBS,EAAQF,EAAK,OAASK,EAI7C,QAASvB,EAAI,EAAGA,EAAIkB,EAAK,cAAc,OAAQlB,IAEvCA,IAAMsB,IAEOA,EAAAJ,EAAK,YAAYG,GAAM,EAE1BF,GAAAR,GAGTO,EAAA,cAAclB,CAAC,GAAKmB,CAC7B,CAER,CCrSO,SAASK,GAAkBC,EAClC,CAEI,GAAIA,IAAU,GAEV,MAAO,CAAA,EAIP,OAAOA,GAAU,WAEjBA,EAAQ,CAACA,CAAK,GAIlB,IAAMC,EAAmB,CAAA,EAEzB,QAASC,EAAI,EAAGC,EAAIH,EAAM,OAAQE,EAAIC,EAAGD,IACzC,CACU,IAAAE,EAAOJ,EAAME,CAAC,EAGhB,GAAA,MAAM,QAAQE,CAAI,EACtB,CACQ,GAAAA,EAAK,SAAW,EAEhB,MAAM,IAAI,MAAM,iEAAiEA,EAAK,MAAM,GAAG,EAE/F,GAAAA,EAAK,CAAC,EAAE,SAAW,GAAKA,EAAK,CAAC,EAAE,SAAW,EAErC,MAAA,IAAI,MAAM,4CAA4C,EAGhE,IAAMC,EAAYD,EAAK,CAAC,EAAE,WAAW,CAAC,EAChCE,EAAUF,EAAK,CAAC,EAAE,WAAW,CAAC,EAEpC,GAAIE,EAAUD,EAEJ,MAAA,IAAI,MAAM,wCAAwC,EAG5D,QAASH,EAAIG,EAAWF,EAAIG,EAASJ,GAAKC,EAAGD,IAEzCD,EAAO,KAAK,OAAO,aAAaC,CAAC,CAAC,CACtC,MAIAD,EAAO,KAAK,GAAG,MAAM,KAAKG,CAAI,CAAC,CACnC,CAGA,GAAAH,EAAO,SAAW,EAEZ,MAAA,IAAI,MAAM,oDAAoD,EAGjE,OAAAA,CACX,CCnDA,IAAIM,GAAY,EAuPVC,GAAN,KACA,CADA,aAAA,CAQoB,KAAA,MAAQ,CAAC,CAAC,IAAK,GAAG,EAAG,CAAC,IAAK,GAAG,EAAG,GAAG,EAQpD,KAAgB,QAAU,CAAC,CAAC,IAAK,GAAG,CAAC,EAMrC,KAAgB,aAAe,CAAC,CAAC,IAAK,GAAG,EAAG,CAAC,IAAK,GAAG,EAAG,CAAC,IAAK,GAAG,EAAG,GAAG,EAOvE,KAAgB,MAAQ,CAAC,CAAC,IAAK,GAAG,CAAC,EAGnC,KAAO,eAA0D,CAC7D,MAAO,KAAK,aACZ,WAAY,EACZ,QAAS,EACT,YAAa,GACb,aAAc,IAAA,EAIF,KAAA,aAAeC,GAA0B,GAAI,CAAA,CAOtD,QAAQC,EAAcC,EAC7B,CACQ,IAAAC,EAAgB,GAAGD,EAAM,UAAoB,UAC7CE,EAAe,GAiBnB,GAdIF,EAAM,MAAM,MAAQ,CAACA,EAAM,SAEVC,GAAAD,EAAM,MAAM,KAAK,SACnBE,EAAA,KAEVF,EAAM,SAAWA,EAAM,cAIZC,EAAA,GAAGD,EAAM,QAAQ,UAClBE,EAAA,IAIf,CAACC,EAAM,IAAIF,CAAa,EAC5B,CACU,IAAAG,EAAY,OAAO,OAAOJ,CAAK,EAIrCI,EAAU,WAAa,EAEjB,IAAAC,EAAM,IAAIC,GAAkB,CAC9B,MAAOF,EACP,aAAAF,EACA,aAAc,GACd,GAAG,KAAK,cAAA,CACX,EAEDN,KAGIA,GAAY,IAGPW,EAAA,aAAc,gCAAgCX,EAAS,kIAAkI,EAG9LS,EAAA,KAAK,UAAW,IACpB,CACIT,KACAO,EAAM,OAAOF,CAAa,CAAA,CAC7B,EAEKE,EAAA,IACFF,EACAI,CAAA,CACJ,CAGE,IAAAG,EAAcL,EAAM,IAAIF,CAAa,EAE1C,OAAAO,EAAkC,mBAAmBT,CAAI,EAEnDS,CAAA,CASJ,UAAUT,EAAcC,EAAkBS,EAAmB,GACpE,CACI,IAAMC,EAAa,KAAK,QAAQX,EAAMC,CAAK,EAErCW,EAAK,GAAGZ,CAAI,IAAIC,EAAM,QAAQ,IAAIS,CAAO,GAG/C,GAAI,KAAK,aAAa,IAAIE,CAAE,EAEjB,OAAA,KAAK,aAAa,IAAIA,CAAE,EAG7B,IAAAC,EAAWC,EAAkB,kBAAkBd,CAAI,EAGnDe,EAAaC,GAAoBH,EAAUZ,EAAOU,EAAYD,CAAO,EAEtE,YAAA,aAAa,IAAIE,EAAIG,CAAU,EAE7BA,CAAA,CASJ,YACHf,EACAC,EACAS,EAAmB,GAEvB,CACI,OAAO,KAAK,UAAUV,EAAMC,EAAOS,CAAO,CAAA,CAuBvC,WAAWO,EAClB,CACQ,IAAAC,EAAUD,EAAK,CAAC,EAEhB,OAAOC,GAAY,WAETA,EAAA,CACN,KAAMA,EACN,MAAOD,EAAK,CAAC,EACb,MAAOA,EAAK,CAAC,GAAG,MAChB,WAAYA,EAAK,CAAC,GAAG,WACrB,QAASA,EAAK,CAAC,GAAG,QAClB,YAAaA,EAAK,CAAC,GAAG,WAAA,EAK1BE,EAAYC,EAAQ,yHAAyH,GAIjJ,IAAMC,EAAOH,GAAS,KAEtB,GAAI,CAACG,EAEK,MAAA,IAAI,MAAM,kDAAkD,EAGtEH,EAAU,CAAE,GAAG,KAAK,eAAgB,GAAGA,CAAQ,EAE/C,IAAMI,EAAYJ,EAAQ,MAEpBjB,EAAQqB,aAAqBC,GAAYD,EAAY,IAAIC,GAAUD,CAAS,EAC5EnB,EAAee,EAAQ,aAAe,KAAK,oBAAoBjB,CAAK,EACpEuB,EAAO,IAAIjB,GAAkB,CAC/B,MAAAN,EACA,aAAAE,EACA,YAAae,EAAQ,YACrB,QAASA,EAAQ,QACjB,WAAYA,EAAQ,WACpB,aAAc,GACd,aAAcA,EAAQ,YAAA,CACzB,EAEKO,EAAYC,GAAkBR,EAAQ,KAAK,EAEjD,OAAAM,EAAK,iBAAiBC,EAAU,KAAK,EAAE,CAAC,EAExCrB,EAAM,IAAI,GAAGiB,CAAI,UAAWG,CAAI,EAE3BA,EAAA,KAAK,UAAW,IAAMpB,EAAM,OAAO,GAAGiB,CAAI,SAAS,CAAC,EAElDG,CAAA,CAOJ,UAAUH,EACjB,CACU,IAAAM,EAAW,GAAGN,CAAI,UAClBG,EAAOpB,EAAM,IAAgBuB,CAAQ,EAEvCH,GAEAA,EAAK,QAAQ,CACjB,CAUI,oBAAoBvB,EAC5B,CAII,MAAO,CAACA,EAAM,UACN,CAACA,EAAM,YAAcA,EAAM,WAAW,QAAU,IACjD,CAACA,EAAM,MAAM,MACbA,EAAM,MAAM,QAAU,QAAA,CAErC,EAkBa2B,GAAoB,IAAI9B,GC9gB9B,IAAM+B,GAAN,cAAiCC,EACxC,CACW,SACP,CACQ,KAAK,QAAQ,cAER,KAAA,QAAQ,aAAa,QAAQ,EAGtC,MAAM,QAAQ,CAAA,CAEtB,EAGaC,GAAN,KACP,CAaI,YAAYC,EACZ,CACI,KAAK,UAAYA,CAAA,CAGd,mBAAmBC,EAC1B,CACU,IAAAC,EAAqB,KAAK,kBAAkBD,CAAU,EAE5D,OAAO,KAAK,UAAU,YAAY,SAAS,mBAAmBC,CAAkB,CAAA,CAO7E,cAAcD,EAAwBE,EAC7C,CACU,IAAAD,EAAqB,KAAK,kBAAkBD,CAAU,EAG5DG,GAAcH,EAAYC,CAAkB,EAExCD,EAAW,iBAEXA,EAAW,eAAiB,GAEvB,KAAA,eAAeA,EAAYC,CAAkB,GAGtD,KAAK,UAAU,YAAY,SAAS,cAAcA,EAAoBC,CAAc,EAEhFD,EAAmB,QAAQ,cAE3B,KAAK,qBAAqBD,CAAU,CACxC,CAGG,iBAAiBA,EACxB,CACU,IAAAC,EAAqB,KAAK,kBAAkBD,CAAU,EAG5DG,GAAcH,EAAYC,CAAkB,EAE5C,KAAK,UAAU,YAAY,SAAS,iBAAiBA,CAAkB,EAEnEA,EAAmB,QAAQ,cAE3B,KAAK,qBAAqBD,CAAU,CACxC,CAGI,eAAeA,EAAwBI,EAC/C,CACU,GAAA,CAAE,QAAAC,CAAA,EAAYD,EAEdE,EAAaC,GAAkB,QAAQP,EAAW,KAAMA,EAAW,MAAM,EAE/EK,EAAQ,MAAM,EAEVC,EAAW,cAAc,OAAS,SAE7BD,EAAQ,eAGTA,EAAQ,aAAe,IAAIG,GAAU,KAAK,UAAU,OAAO,oBAAoB,IAIvF,IAAMC,EAAQC,EAAkB,kBAAkBV,EAAW,IAAI,EAC3DW,EAAQX,EAAW,OAErBY,EAAWN,EAAW,eAGpBO,EAAmBC,GAAoBL,EAAOE,EAAOL,EAAY,EAAI,EAErES,EAAUJ,EAAM,QAChBK,EAAQH,EAAiB,MAE3BI,EAAKJ,EAAiB,MACtBK,EAAKL,EAAiB,OAASA,EAAiB,QAEhDF,EAAM,UAEAM,GAAAN,EAAM,QAAQ,MAAQK,EACtBE,GAAAP,EAAM,QAAQ,MAAQK,GAGhCX,EACK,UAAW,CAACL,EAAW,QAAQ,GAAKiB,EAAMF,EAAU,CAACf,EAAW,QAAQ,GAAKkB,EAAMH,CAAO,EAC1F,MAAMC,EAAOA,CAAK,EAEvB,IAAMG,EAAOb,EAAW,gBAAkBK,EAAM,MAAM,MAAQ,SAE1DS,EAAWd,EAAW,YAAY,SAClCe,EAAaf,EAAW,WAExBK,EAAM,aAENS,EAAWT,EAAM,SAAWK,EAC5BK,EAAaV,EAAM,WAAaK,GAGhC,IAAAM,GAAsBD,EAAaD,GAAY,EAI/CE,EAAqBhB,EAAW,eAAiB,IAE5BgB,EAAA,GAGzB,QAASC,EAAI,EAAGA,EAAIV,EAAiB,MAAM,OAAQU,IACnD,CACU,IAAAC,EAAOX,EAAiB,MAAMU,CAAC,EAErC,QAASE,EAAI,EAAGA,EAAID,EAAK,cAAc,OAAQC,IAC/C,CACU,IAAAC,EAAOF,EAAK,MAAMC,CAAC,EACnBE,EAAWrB,EAAW,MAAMoB,CAAI,EAEtC,GAAIC,GAAU,QACd,CACI,IAAMC,EAAUD,EAAS,QAEjBtB,EAAA,QACJuB,EACAT,GAAc,QACd,KAAK,MAAMK,EAAK,cAAcC,CAAC,EAAIE,EAAS,OAAO,EACnD,KAAK,MAAMf,EAAWe,EAAS,QAAUL,CAAkB,EAC3DM,EAAQ,KAAK,MACbA,EAAQ,KAAK,MAAA,CACjB,CACJ,CAGQhB,GAAAS,CAAA,CAChB,CAGI,kBAAkBrB,EAC1B,CACW,OAAAA,EAAW,SAAS,KAAK,UAAU,GAAG,GAAK,KAAK,YAAYA,CAAU,CAAA,CAG1E,YAAYA,EACnB,CAEU,IAAA6B,EAAkB,IAAIjC,GAE5B,OAAAI,EAAW,SAAS,KAAK,UAAU,GAAG,EAAI6B,EAErC,KAAA,eAAe7B,EAAY6B,CAAe,EAExCA,CAAA,CAGH,qBAAqB7B,EAC7B,CACI,IAAMK,EAAU,KAAK,kBAAkBL,CAAU,EAAE,QAE7C8B,EAAa9B,EAAW,OAAO,WAC/B+B,EAAcC,EAAM,IAAI,GAAGF,CAAoB,SAAS,EAGxD,CAAE,EAAAG,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,CAAA,EAAMpC,EAAW,eAE5BqC,EAAK,KAAK,KAAMJ,EAAIA,EAAMC,EAAIA,CAAE,EAChCI,EAAK,KAAK,KAAMH,EAAIA,EAAMC,EAAIA,CAAE,EAChCG,GAAc,KAAK,IAAIF,CAAE,EAAI,KAAK,IAAIC,CAAE,GAAK,EAE7CE,EAAYT,EAAY,qBAAuB/B,EAAW,OAAO,SAEjEyC,EAAWF,EAAaR,EAAY,cAAc,OAAS,EAAIS,GAErEnC,EAAQ,aAAa,UAAU,cAAc,SAAS,UAAYoC,CAAA,CAG/D,SACP,CACI,KAAK,UAAY,IAAA,CAEzB,EAtMa3C,GAGK,UAAY,CACtB,KAAM,CACF4C,EAAc,WACdA,EAAc,YACdA,EAAc,WAAA,EAElB,KAAM,YACV,EA8LJ,SAASvC,GAAcwC,EAAuBC,EAC9C,CACIA,EAAM,eAAiBD,EAAU,eACjCC,EAAM,gBAAkBD,EAAU,gBAClCC,EAAM,WAAaD,EAAU,WAC7BC,EAAM,eAAiBD,EAAU,eACjCC,EAAM,oBAAsBD,EAAU,oBACtCC,EAAM,eAAiBD,EAAU,eACjCC,EAAM,mBAAqBD,EAAU,mBACrCC,EAAM,WAAaD,EAAU,WAC7BC,EAAM,aAAeD,EAAU,YACnC,CCrOO,IAAME,GAAN,cAAgCC,EACvC,CAUI,YAAYC,EACZ,CACU,MAAA,EATV,KAAO,kBAAoB,GAC3B,KAAO,WAAqB,KAYxB,KAAK,UAAYA,EAERA,EAAA,QAAQ,iBAAiB,IAAI,IAAI,CAAA,CAIvC,kBACP,CACI,IAAMC,EAAO,KAAK,WAEdA,EAAK,iBAELA,EAAK,aAAa,CACtB,CAIG,SACP,CACU,GAAA,CAAE,SAAAC,CAAS,EAAI,KAAK,UAE1BA,EAAS,kBAAkB,KAAK,UAAU,IAAM,KAC1CA,EAAS,qBAAqB,KAAK,cAAc,EACjDA,EAAS,uBAAuB,KAAK,UAAU,EACrD,KAAK,UAAU,QAAQ,iBAAiB,OAAO,IAAI,EACnD,KAAK,eAAiB,KACrB,KAAK,UAAqB,IAAA,CAEnC,EC1CO,IAAMC,GAAN,KACP,CAaI,YAAYC,EACZ,CACI,KAAK,UAAYA,CAAA,CAGd,mBAAmBC,EAC1B,CACU,IAAAC,EAAU,KAAK,YAAYD,CAAQ,EAEnCE,EAASF,EAAS,SAEpB,OAAAC,EAAQ,aAAeC,CAKpB,CAGJ,cAAcF,EAAoBG,EACzC,CACU,IAAAC,EAAoB,KAAK,YAAYJ,CAAQ,EAEnD,GAAIA,EAAS,eACb,CACI,IAAMK,EAAaL,EAAS,gBAAkB,KAAK,UAAU,WAAaA,EAAS,YAE/EI,EAAkB,aAAeJ,EAAS,UAAYA,EAAS,aAAeK,IAG9E,KAAK,eAAeL,CAAQ,EAAE,MAAOM,GACrC,CACI,QAAQ,MAAMA,CAAC,CAAA,CAClB,EAGLN,EAAS,eAAiB,GAE1BO,GAAiBH,EAAmBJ,CAAQ,CAAA,CAGhD,KAAK,UAAU,YAAY,MAAM,WAAWI,EAAmBD,CAAc,CAAA,CAG1E,iBAAiBH,EACxB,CACU,IAAAI,EAAoB,KAAK,YAAYJ,CAAQ,EAEjCI,EAAA,SAAS,cAAcA,CAAiB,CAAA,CAG9D,MAAc,eAAeJ,EAC7B,CACIA,EAAS,eAAiB,GACpB,IAAAI,EAAoB,KAAK,YAAYJ,CAAQ,EAEnD,GAAII,EAAkB,kBAAmB,OAKzC,IAAMI,EAAoBJ,EAAkB,eAE5CA,EAAkB,eAAiB,KAEnCA,EAAkB,kBAAoB,GAEtCJ,EAAS,YAAcA,EAAS,gBAAkB,KAAK,UAAU,WAAaA,EAAS,WAEvF,IAAIS,EAAiB,KAAK,UAAU,SAAS,kBAAkBT,CAAQ,EAEnEQ,IAGiBC,EAAAA,EAAe,QAAQ,IACxC,CACI,KAAK,UAAU,SAAS,uBAAuBL,EAAkB,UAAU,EACtE,KAAA,UAAU,SAAS,qBAAqBI,CAAiB,CAAA,CACjE,GAGLJ,EAAkB,eAAiBK,EACnCL,EAAkB,WAAaJ,EAAS,SAExCI,EAAkB,QAAU,MAAMK,EAG5B,IAAAC,EAAcV,EAAS,aAAeA,EAAS,kBAEjDU,IAGAA,EAAY,mBAAqB,IAGrCN,EAAkB,kBAAoB,GAEtCG,GAAiBH,EAAmBJ,CAAQ,CAAA,CAGxC,YAAYA,EACpB,CACW,OAAAA,EAAS,SAAS,KAAK,UAAU,GAAG,GAAK,KAAK,YAAYA,CAAQ,CAAA,CAGtE,YAAYA,EACnB,CACI,IAAMI,EAAoB,IAAIO,GAAkB,KAAK,SAAS,EAE9D,OAAAP,EAAkB,WAAaJ,EAC/BI,EAAkB,UAAYJ,EAAS,eACvCI,EAAkB,QAAUQ,EAAQ,MAClBR,EAAA,OAAS,CAAE,KAAM,EAAG,KAAM,EAAG,KAAM,EAAG,KAAM,CAAE,EAChEA,EAAkB,YAAe,KAAK,UAAU,aAAeJ,EAAS,aAExEA,EAAS,YAAcA,EAAS,gBAAkB,KAAK,UAAU,WAAaA,EAAS,WACvFA,EAAS,SAAS,KAAK,UAAU,GAAG,EAAII,EAEjCA,CAAA,CAGJ,SACP,CACI,KAAK,UAAY,IAAA,CAEzB,EA3IaN,GAGK,UAAY,CACtB,KAAM,CACFe,EAAc,WACdA,EAAc,YACdA,EAAc,WAAA,EAElB,KAAM,UACV,ECjBG,SAASC,IAChB,CACI,GAAM,CAAE,UAAAC,CAAU,EAAIC,EAAW,IAAA,EAAM,aAAa,EAE5C,MAAA,iCAAkC,KAAKD,CAAS,CAC5D,CCLA,IAAME,GAAQ,6BAERC,GAAU,+BAGHC,GAAN,KACP,CAQI,aACA,CARA,KAAO,QAAU,SAAS,gBAAgBF,GAAO,KAAK,EACtD,KAAO,cAAgB,SAAS,gBAAgBA,GAAO,eAAe,EACtE,KAAO,WAAa,SAAS,gBAAgBC,GAAS,KAAK,EAC3D,KAAO,aAAe,SAAS,gBAAgBA,GAAS,OAAO,EAM3D,GAAM,CAAE,cAAAE,EAAe,QAAAC,EAAS,aAAAC,EAAc,WAAAC,CAAA,EAAe,KAG/CH,EAAA,aAAa,QAAS,OAAO,EAC7BA,EAAA,aAAa,SAAU,OAAO,EAC5CA,EAAc,MAAM,SAAW,SAE/BC,EAAQ,YAAYD,CAAa,EAEjCA,EAAc,YAAYE,CAAY,EACtCF,EAAc,YAAYG,CAAU,EAEpC,KAAK,MAAQC,EAAW,IAAI,EAAE,YAAY,CAAA,CAGvC,SACP,CACI,KAAK,QAAQ,OAAO,EACpB,KAAK,cAAc,OAAO,EAC1B,KAAK,aAAa,OAAO,EACzB,KAAK,WAAW,OAAO,EACvB,KAAK,MAAM,IAAM,GACjB,KAAK,MAAM,OAAO,EAElB,KAAK,QAAU,KACf,KAAK,cAAgB,KACrB,KAAK,aAAe,KACpB,KAAK,WAAa,KAClB,KAAK,MAAQ,KACb,KAAK,iBAAmB,IAAA,CAEhC,EC5CgB,SAAAC,GAAoBC,EAAcC,EAClD,CACI,IAAMC,EAAaD,EAAM,WACnBE,EAAyB,CAAA,EACzBC,EAAkC,CAAA,EAIlCC,EAAQ,0BAERC,EAAUN,EAAK,MAAMK,CAAK,EAEhC,SAASE,EAAcL,EACvB,CACSE,EAAOF,CAAU,IAElBC,EAAa,KAAKD,CAAU,EAE5BE,EAAOF,CAAU,EAAI,GACzB,CAGA,GAAA,MAAM,QAAQA,CAAU,EAExB,QAASM,EAAI,EAAGA,EAAIN,EAAW,OAAQM,IAErBD,EAAAL,EAAWM,CAAC,CAAC,OAK/BD,EAAcL,CAAU,EAGxBI,GAEQA,EAAA,QAASG,GACjB,CACI,IAAMP,EAAaO,EAAM,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,EAE5CF,EAAcL,CAAU,CAAA,CAC3B,EAGM,QAAAM,KAAKP,EAAM,UACtB,CACI,IAAMC,EAAaD,EAAM,UAAUO,CAAC,EAAE,WAEtCD,EAAcL,CAAoB,CAAA,CAG/B,OAAAC,CACX,CCtDA,eAAsBO,GAAiBC,EACvC,CAGU,IAAAC,EAAO,MAFI,MAAMC,EAAW,IAAI,EAAE,MAAMF,CAAG,GAErB,KAAK,EAE3BG,EAAS,IAAI,WASZ,OAPiB,MAAM,IAAI,QAAQ,CAACC,EAASC,IACpD,CACIF,EAAO,UAAY,IAAMC,EAAQD,EAAO,MAAgB,EACxDA,EAAO,QAAUE,EACjBF,EAAO,cAAcF,CAAI,CAAA,CAC5B,CAGL,CCasB,eAAAK,GAAYC,EAA4BC,EAC9D,CACU,IAAAC,EAAU,MAAMC,GAAiBF,CAAG,EAEnC,MAAA;wBACaD,EAAM,UAAU;uBACjBA,EAAM,UAAU;sBACjBA,EAAM,SAAS;oBACjBE,CAAO;MAE3B,CC1Ca,IAAAE,GAAA,IAA4B,IASzC,eAAsBC,GAClBC,EAEJ,CACI,IAAMC,EAAeD,EAChB,OAAQE,GAAeC,EAAM,IAAI,GAAGD,CAAU,UAAU,CAAC,EACzD,IAAKA,GACN,CACI,GAAI,CAACJ,GAAsB,IAAII,CAAU,EACzC,CACI,GAAM,CAAE,QAAAE,CAAQ,EAAID,EAAM,IAAmB,GAAGD,CAAU,UAAU,EAC9DG,EAA8B,CAAA,EAE5BD,EAAA,QAASE,GACjB,CACI,IAAMC,EAAMD,EAAM,IAGZE,EAFQF,EAAM,MAEF,IAAKG,IAAU,CAAE,OAAQA,EAAK,OAAQ,MAAOA,EAAK,KAAA,EAAQ,EAGnEJ,EAAA,KACL,GAAGG,EAAI,IAAKE,GACRC,GACI,CACI,WAAYD,EAAM,OAClB,UAAWA,EAAM,MACjB,WAAAR,CAAA,EAEJK,CAAA,CACJ,CACJ,CACJ,CACH,EACqBT,GAAA,IAClBI,EACA,QAAQ,IAAIG,CAAQ,EAAE,KAAMO,GAAQA,EAAI,KAAK;CAAI,CAAC,CAAA,CACtD,CAGG,OAAAd,GAAsB,IAAII,CAAU,CAAA,CAC9C,EAEL,OAAQ,MAAM,QAAQ,IAAID,CAAY,GAAG,KAAK;CAAI,CACtD,CC7CO,SAASY,GACZC,EACAC,EACAC,EACAC,EACAC,EAEJ,CACI,GAAM,CAAE,WAAAC,EAAY,aAAAC,EAAc,QAAAC,CAAA,EAAYH,EAE9CC,EAAW,UAAY,UAAUJ,EAAM,QAAQ,mCAAmCD,CAAI,SACtFK,EAAW,aAAa,QAAS,oBAAoBH,CAAU,qDAAqD,EACpHI,EAAa,YAAcH,EAE3B,GAAM,CAAE,MAAAK,EAAO,OAAAC,CAAO,EAAIL,EAAa,MAEvC,OAAAG,EAAQ,aAAa,QAASC,EAAM,SAAA,CAAU,EAC9CD,EAAQ,aAAa,SAAUE,EAAO,SAAA,CAAU,EAEzC,IAAI,cAAA,EAAgB,kBAAkBF,CAAO,CACxD,CChBgB,SAAAG,GAA4BC,EAAkBC,EAC9D,CAGI,IAAMC,EAAmBC,GAAW,2BAChCH,EAAM,MACNA,EAAM,OACNC,CAAA,EAIE,CAAE,QAAAG,CAAA,EAAYF,EAEpB,OAAAE,EAAQ,UAAU,EAAG,EAAGJ,EAAM,MAAOA,EAAM,MAAM,EACzCI,EAAA,UAAUJ,EAAO,EAAG,CAAC,EAGtBE,CACX,CCtBgB,SAAAG,GAAaC,EAAkBC,EAAaC,EAC5D,CACW,OAAA,IAAI,QAAc,MAAOC,GAChC,CAKQD,GAEA,MAAM,IAAI,QAAeC,GAAY,WAAWA,EAAS,GAAG,CAAC,EAGjEH,EAAM,OAAS,IACf,CACYG,EAAA,CAAA,EAGZH,EAAM,IAAM,mCAAmC,mBAAmBC,CAAG,CAAC,GACtED,EAAM,YAAc,WAAA,CACvB,CACL,CC5BA,IAAII,GAYG,SAASC,GACZC,EACAC,EACAC,EACAC,EAEJ,CAC2BA,IAAAA,EAAAL,KAA2BA,GAAyB,IAAIM,KAE/E,GAAM,CAAE,WAAAC,EAAY,aAAAC,EAAc,QAAAC,CAAA,EAAYJ,EAE9CE,EAAW,UAAY,UAAUJ,EAAM,QAAQ,mCAAmCD,CAAI,SAE3EK,EAAA,aAAa,QAAS,mDAAmD,EAEhFH,IAEAI,EAAa,YAAcJ,GAItB,SAAA,KAAK,YAAYK,CAAO,EAE3B,IAAAC,EAAgBH,EAAW,sBAAsB,EAEvDE,EAAQ,OAAO,EAGT,IAAAE,EAAgBR,EAAM,QAAU,EAE/B,MAAA,CACH,MAAOO,EAAc,MAAQC,EAC7B,OAAQD,EAAc,OAASC,CAAA,CAEvC,CCvBO,IAAMC,GAAN,KACP,CAyBI,YAAYC,EACZ,CAPA,KAAiB,gBAIZ,CAAA,EAID,KAAK,UAAYA,EACZ,KAAA,cAAgBA,EAAS,OAASC,GAAa,MAAA,CAOjD,WAAWC,EAClB,CACW,OAAA,KAAK,kBAAkBA,CAAO,CAAA,CAOlC,kBAAkBC,EACzB,CACI,IAAMC,EAAUD,EAAK,SAEjB,GAAA,KAAK,gBAAgBC,CAAO,EAE5B,YAAK,wBAAwBA,CAAO,EAE7B,KAAK,gBAAgBA,CAAO,EAAE,QAGzC,IAAMC,EAAU,KAAK,qBAAqBF,CAAI,EACzC,KAAMG,IAEE,KAAA,gBAAgBF,CAAO,EAAE,QAAUE,EAEjCA,EACV,EAEA,YAAA,gBAAgBF,CAAO,EAAI,CAC5B,QAAS,KACT,QAAAC,EACA,WAAY,CAAA,EAGTA,CAAA,CAQJ,kBAAkBD,EACzB,CACI,OAAO,KAAK,gBAAgBA,CAAO,GAAG,YAAc,IAAA,CAGhD,wBAAwBA,EAChC,CACS,KAAA,gBAAgBA,CAAO,EAAE,YAAA,CAQ3B,uBAAuBA,EAC9B,CACU,IAAAG,EAAgB,KAAK,gBAAgBH,CAAO,EAE7CG,IAESA,EAAA,aAEVA,EAAc,aAAe,IAEzBA,EAAc,QAET,KAAA,SAASA,EAAc,OAAO,EAKrBA,EAAA,QAAQ,KAAMD,GAC5B,CACIC,EAAc,QAAUD,EAEnB,KAAA,SAASC,EAAc,OAAO,CAAA,CACtC,EAAE,MAAM,IACT,CAEIC,EAAK,yCAAyC,CAAA,CAEjD,EAGA,KAAA,gBAAgBJ,CAAO,EAAI,MACpC,CAQG,kBAAkBF,EACzB,CACW,OAAA,KAAK,qBAAqBA,CAAO,CAAA,CAG5C,MAAc,qBAAqBA,EACnC,CACI,GAAM,CAAE,KAAAC,EAAM,MAAAM,EAAO,WAAAC,EAAY,aAAAC,CAAA,EAAiBT,EAO5CU,EAAeC,EAAQ,IAAIC,EAAkB,EAC7CC,EAAeC,GAAoBb,EAAMM,CAAK,EAC9CQ,EAAU,MAAMC,GAAWH,CAAY,EACvCI,EAAWC,GAAgBjB,EAAMM,EAAOQ,EAASL,CAAY,EAE7DS,EAAQ,KAAK,KAAK,KAAK,KAAM,KAAK,IAAI,EAAGF,EAAS,KAAK,EAAKV,EAAM,QAAU,CAAG,EAAIC,CAAU,EAC7FY,EAAS,KAAK,KAAK,KAAK,KAAM,KAAK,IAAI,EAAGH,EAAS,MAAM,EAAKV,EAAM,QAAU,CAAG,EAAIC,CAAU,EAE/Fa,EAAQX,EAAa,MAGrBY,EAAe,EAEfD,EAAA,OAASF,EAAQ,GAAKG,EACtBD,EAAA,QAAUD,EAAS,GAAKE,EAE9B,IAAMC,EAASC,GAAUvB,EAAMM,EAAOC,EAAYO,EAASL,CAAY,EAEvE,MAAMe,GAAaJ,EAAOE,EAAQG,GAAA,GAAcb,EAAa,OAAS,CAAC,EAEvE,IAAMc,EAA0CN,EAC5CO,EAEA,KAAK,gBAGcA,EAAAC,GAA4BR,EAAOb,CAAU,GAGpE,IAAMJ,EAAU0B,GAAwBF,EAAmBA,EAAiB,OAASD,EACjFN,EAAM,MAAQC,EACdD,EAAM,OAASC,EACfd,CAAA,EAGA,OAAAC,IAAcL,EAAQ,OAAO,MAAQK,GAErC,KAAK,gBAEL,KAAK,UAAU,QAAQ,WAAWL,EAAQ,MAAM,EAChD2B,GAAW,uBAAuBH,CAAgB,GAGtDjB,EAAQ,OAAOD,CAAwB,EAEhCN,CAAA,CAGJ,qBAAqB4B,EAC5B,CACmBA,EAAA,KAAM5B,GACrB,CACI,KAAK,SAASA,CAAO,CAAA,CACxB,EAAE,MAAM,IACT,CAEIE,EAAK,yCAAyC,CAAA,CAEjD,CAAA,CAGG,SAASF,EACjB,CACgB6B,EAAA,cAAc7B,EAAS,EAAI,EACvCA,EAAQ,OAAO,SAAW,KAC1BA,EAAQ,OAAO,eAAiB,SAAA,CAG7B,SACP,CAEK,KAAK,UAAqB,KAChB,QAAA8B,KAAO,KAAK,gBAEf,KAAK,gBAAgBA,CAAG,GAAG,KAAK,qBAAqB,KAAK,gBAAgBA,CAAG,EAAE,OAAO,EAE7F,KAAK,gBAA2B,IAAA,CAEzC,EAhOarC,GAGK,UAAY,CACtB,KAAM,CACFsC,EAAc,YACdA,EAAc,aACdA,EAAc,YAAA,EAElB,KAAM,UACV,ECPG,IAAMC,GAAN,MAAMA,WAAqBC,EAClC,CAcI,eAAeC,EACf,CACI,IAAIC,EAAUD,EAAK,CAAC,GAAK,CAAA,EAErBC,aAAmB,eAGnBC,EAAYC,EAAQ,2DAA2D,EAGrEF,EAAA,CACN,UAAWA,EACX,IAAKD,EAAK,CAAC,EACX,QAASA,EAAK,CAAC,CAAA,GAIvBC,EAAU,CAAE,GAAGH,GAAa,eAAgB,GAAGG,CAAQ,EAEvD,IAAMG,EAAYH,EAAQ,WAAa,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CAAC,EAE5EI,EAAMJ,EAAQ,IAEbI,IAEGJ,EAAQ,UAEFI,EAAA,IAAI,aAAaD,EAAU,MAAM,EAIjCC,EAAA,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CAAC,GAIvD,IAAMC,EAAUL,EAAQ,SAAW,IAAI,YAAY,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CAAC,EAE/DM,EAAcN,EAAQ,mBAEtBO,EAAiB,IAAIC,GAAO,CAC9B,KAAML,EACN,MAAO,2BACP,YAAAG,EACA,MAAOG,EAAY,OAASA,EAAY,QAAA,CAC3C,EAEKC,EAAW,IAAIF,GAAO,CACxB,KAAMJ,EACN,MAAO,qBACP,YAAAE,EACA,MAAOG,EAAY,OAASA,EAAY,QAAA,CAC3C,EAEKE,EAAc,IAAIH,GAAO,CAC3B,KAAMH,EACN,MAAO,oBACP,YAAAC,EACA,MAAOG,EAAY,MAAQA,EAAY,QAAA,CAC1C,EAEK,MAAA,CACF,WAAY,CACR,UAAW,CACP,OAAQF,EACR,OAAQ,YACR,OAAQ,EACR,OAAQ,CAAA,EAEZ,IAAK,CACD,OAAQG,EACR,OAAQ,YACR,OAAQ,EACR,OAAQ,CAAA,CACZ,EAEJ,YAAAC,EACA,SAAUX,EAAQ,QAAA,CACrB,EArFL,KAAO,UAAuB,MAAA,CAyF9B,IAAI,WACJ,CACW,OAAA,KAAK,WAAW,UAAU,OAAO,IAAA,CAS5C,IAAI,UAAUY,EACd,CACS,KAAA,WAAW,UAAU,OAAO,KAAOA,CAAA,CAI5C,IAAI,KACJ,CACW,OAAA,KAAK,WAAW,IAAI,OAAO,IAAA,CAStC,IAAI,IAAIA,EACR,CACS,KAAA,WAAW,IAAI,OAAO,KAAOA,CAAA,CAItC,IAAI,SACJ,CACI,OAAO,KAAK,YAAY,IAAA,CAG5B,IAAI,QAAQA,EACZ,CACI,KAAK,YAAY,KAAOA,CAAA,CAEhC,EA3Iaf,GAEK,eAAsC,CAChD,SAAU,gBACV,mBAAoB,EACxB,EALG,IAAMgB,GAANhB,GC/BA,IAAMiB,GAAY,CACrB,KAAM,aACN,OAAQ,CACJ,OAAkB;;;;;;;;;;;;UAalB,KAAgB;;;;SAAA,EAOpB,SAAU,CACN,OAAkB;;;;;;;;;;;;UAalB,KAAgB;;;;;;;;;;;;;;;SAAA,CAkBxB,EAGaC,GAAc,CACvB,KAAM,aACN,OAAQ,CACJ,OAAkB;;;;UAKlB,KAAgB;;;;SAAA,EAOpB,SAAU,CACN,OAAkB;;;;;UAMlB,KAAgB;;;;;;;;;SAAA,CAYxB,EC9EA,IAAIC,GACAC,GAMSC,GAAN,cAAiCC,EACxC,CACI,aACA,CACIH,KAAAA,GAAeI,GAA4B,CACvC,KAAM,uBACN,KAAM,CACFC,GACAC,GACAC,EAAA,CACJ,CACH,GAEDN,KAAAA,GAAcO,GAA2B,CACrC,KAAM,uBACN,KAAM,CACFC,GACAC,GACAC,EAAA,CACJ,CACH,GAEK,IAAAC,EAAiB,IAAIC,EAAa,CACpC,UAAW,CAAE,MAAO,IAAIC,EAAU,KAAM,aAAc,EACtD,YAAa,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,EAAG,KAAM,WAAY,EACxE,aAAc,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,CAAC,CAAC,EAAG,KAAM,WAAY,EACnE,kBAAmB,CAAE,MAAO,IAAIA,EAAU,KAAM,aAAc,EAC9D,YAAa,CAAE,MAAO,IAAI,aAAa,CAAC,IAAK,IAAK,GAAK,EAAG,CAAC,EAAG,KAAM,WAAY,CAAA,CACnF,EAEK,MAAA,CACF,UAAAb,GACA,WAAAD,GACA,UAAW,CACP,cAAe,IAAIa,EAAa,CAC5B,iBAAkB,CAAE,MAAO,IAAIC,EAAU,KAAM,aAAc,EAC7D,OAAQ,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,EAAG,KAAM,WAAY,EACnE,OAAQ,CAAE,MAAO,EAAG,KAAM,KAAM,CAAA,CACnC,EACD,eAAAF,EACA,SAAUG,EAAQ,MAAM,OACxB,SAAUA,EAAQ,MAAM,OAAO,KAAA,CACnC,CACH,CAAA,CAGE,eACHC,EAAeC,EACfC,EACAC,EAAiBC,EACjBC,EAEJ,CACU,IAAAT,EAAiB,KAAK,UAAU,eAEhCU,EAAeD,EAAQ,MACvBE,EAAgBF,EAAQ,OACxBG,EAAgBH,EAAQ,cAExBI,EAAoBb,EAAe,SAAS,kBAEhCa,EAAA,IACdP,EAAO,EAAII,EAAeN,EAC1BE,EAAO,EAAII,EAAeL,EAC1BC,EAAO,EAAIK,EAAgBP,EAC3BE,EAAO,EAAIK,EAAgBN,EAC3BC,EAAO,GAAKF,EACZE,EAAO,GAAKD,CAAA,EAEhBQ,EAAkB,OAAO,EAEVb,EAAA,SAAS,UAAYY,EAAc,SACnCZ,EAAA,SAAS,YAAcY,EAAc,YACrCZ,EAAA,SAAS,aAAeY,EAAc,aACrDZ,EAAe,SAAS,kBAAoBa,EAC7Bb,EAAA,SAAS,YAAY,CAAC,EAAII,EAC1BJ,EAAA,SAAS,YAAY,CAAC,EAAIK,EAC1BL,EAAA,SAAS,YAAY,CAAC,EAAIO,EAC1BP,EAAA,SAAS,YAAY,CAAC,EAAIQ,EAErCC,IAEK,KAAA,UAAU,SAAWA,EAAQ,OAC7B,KAAA,UAAU,SAAWA,EAAQ,OAAO,MAC7C,CAER,ECzGO,IAAMK,GAAN,cAA2BC,EAClC,CACI,aACA,CACU,MAAA,CACF,UAAW,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CAAC,EACpD,IAAK,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CAAC,EAC9C,QAAS,IAAI,YAAY,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CAAC,CAAA,CAC9C,CAAA,CAET,ECNgB,SAAAC,GAAaC,EAA4BC,EACzD,CACU,IAAAC,EAAUF,EAAa,OAAO,EAC9BG,EAAUH,EAAa,OAAO,EAEpCC,EAAU,CAAC,EAAI,CAACC,EAAUF,EAAa,MACvCC,EAAU,CAAC,EAAI,CAACE,EAAUH,EAAa,OACvCC,EAAU,CAAC,GAAK,EAAIC,GAAWF,EAAa,MAC5CC,EAAU,CAAC,EAAI,CAACE,EAAUH,EAAa,OACvCC,EAAU,CAAC,GAAK,EAAIC,GAAWF,EAAa,MAC5CC,EAAU,CAAC,GAAK,EAAIE,GAAWH,EAAa,OAC5CC,EAAU,CAAC,EAAI,CAACC,EAAUF,EAAa,MACvCC,EAAU,CAAC,GAAK,EAAIE,GAAWH,EAAa,MAChD,CCVO,SAASI,GAAYC,EAAmBC,EAAgBC,EAAgBC,EAC/E,CACI,IAAIC,EAAQ,EACNC,EAAOL,EAAM,QAAUC,GAAU,GAEjCK,EAAIH,EAAO,EACXI,EAAIJ,EAAO,EACXK,EAAIL,EAAO,EACXM,EAAIN,EAAO,EACXO,EAAKP,EAAO,GACZQ,EAAKR,EAAO,GAIlB,IAFUD,GAAAD,EAEHG,EAAQC,GACf,CACU,IAAAO,EAAIZ,EAAME,CAAM,EAChBW,EAAIb,EAAME,EAAS,CAAC,EAE1BF,EAAME,CAAM,EAAKI,EAAIM,EAAMJ,EAAIK,EAAKH,EACpCV,EAAME,EAAS,CAAC,EAAKK,EAAIK,EAAMH,EAAII,EAAKF,EAE9BT,GAAAD,EAEVG,GAAA,CAER,CC1BgB,SAAAU,GAAOC,EAA4BC,EACnD,CACI,IAAMC,EAAUF,EAAa,QAEvBG,EAAQD,EAAQ,MAAM,MACtBE,EAASF,EAAQ,MAAM,OAEzBG,EAAU,EACVC,EAAU,EAEVN,EAAa,uBAEbK,EAAUL,EAAa,OAAO,EAC9BM,EAAUN,EAAa,OAAO,GAGlCC,EAAI,CAAC,EAAIA,EAAI,CAAC,EAAI,CAACI,EACnBJ,EAAI,CAAC,EAAIA,EAAI,CAAC,EAAI,EAAII,EACtBJ,EAAI,CAAC,EAAIA,EAAI,CAAC,EAAI,CAACK,EACnBL,EAAI,CAAC,EAAIA,EAAI,CAAC,EAAI,EAAIK,EAEtB,IAAMC,EAAgBC,EAAO,OAEfD,EAAA,SAASP,EAAa,eAAe,MAAM,EAEzDO,EAAc,IAAMP,EAAa,MACjCO,EAAc,IAAMP,EAAa,OAEjCO,EAAc,OAAO,EAErBA,EAAc,MAAMP,EAAa,MAAQG,EAAOH,EAAa,OAASI,CAAM,EAEhEK,GAAAR,EAAK,EAAG,EAAGM,CAAa,CACxC,CC1BA,IAAMG,GAAa,IAAIC,GAGVC,GAAN,KACP,CAOI,aACA,CAPA,KAAO,SAAoB,GAQlB,KAAA,SAAW,IAAIC,GAAa,CAC7B,QAASH,GAAW,QAAQ,MAAM,EAClC,UAAWA,GAAW,UAAU,MAAM,EACtC,IAAKA,GAAW,IAAI,MAAM,CAAA,CAC7B,CAAA,CAGE,SACP,CACI,KAAK,SAAS,QAAQ,EACtB,KAAK,QAAQ,QAAQ,CAAA,CAE7B,EAOaI,GAAN,KACP,CAcI,YAAYC,EACZ,CAHA,KAAiB,OAAgBC,GAAM,UAInC,KAAK,UAAYD,CAAA,CAGd,mBAAmBE,EAC1B,CACU,IAAAC,EAAmB,KAAK,qBAAqBD,CAAU,EAEvDE,EAAaD,EAAiB,SAEpC,KAAK,gBAAgBD,CAAU,EAE/B,IAAMG,EAAWF,EAAiB,SAE9B,GAAAE,GAAYA,IAAaD,EAC7B,CACU,GAAA,CAAE,cAAAE,CAAA,EAAkBH,EAEnB,MAAA,CAACG,EAAc,SAAS,sBAC3BA,EACAJ,EAAW,OAAA,CACf,CAGJ,OAAQE,IAAeC,CAAA,CAQpB,cAAcE,EAA4BC,EACjD,CACU,IAAAC,EAAU,KAAK,UAAU,YAAY,MAG3C,KAAK,gBAAgBF,CAAY,EAE3B,IAAAJ,EAAmB,KAAK,qBAAqBI,CAAY,EAEzD,CAAE,SAAAG,EAAU,SAAAL,CAAA,EAAaF,EAE/B,GAAIE,EACJ,CACIF,EAAiB,gBAAjBA,EAAiB,cAAkB,IAAIQ,IAEvC,IAAML,EAAgBH,EAAiB,cAEnCI,EAAa,gBAEb,KAAK,qBAAqBA,CAAY,EAEtCD,EAAc,SAAWI,EACzBJ,EAAc,WAAaC,EAC3BD,EAAc,UAAYC,EAAa,eACzBD,EAAA,WAAWC,EAAa,QAAQ,GAGlDD,EAAc,YAAe,KAAK,UAAU,aAAeC,EAAa,aAEhEE,EAAA,WAAWH,EAAeE,CAAc,CAAA,MAIhDC,EAAQ,MAAMD,CAAc,EAE5BL,EAAiB,SAAjBA,EAAiB,OAAW,IAAIS,IAEhC,KAAK,iBAAiBL,CAAY,EAElCC,EAAe,IAAID,CAAY,CACnC,CAGG,QAAQA,EACf,CACI,GAAM,CAAE,OAAAM,CAAA,EAAW,KAAK,qBAAqBN,CAAY,EAEzDM,EAAO,OAAO,CAAC,EAAI,KAAK,UAAU,eAAe,UAG3C,IAAAC,EAAgBD,EAAO,UAAU,cAAc,SAErDC,EAAc,iBAAmBP,EAAa,eAC9CO,EAAc,OAAS,KAAK,UAAU,aAAeP,EAAa,aAElEQ,GACIR,EAAa,gBACbO,EAAc,OACd,CAAA,EAGJ,KAAK,OAAO,UAAYE,GAA0BT,EAAa,eAAgBA,EAAa,QAAQ,OAAO,EAEtG,KAAA,UAAU,QAAQ,KAAK,CACxB,SAAUZ,GACV,OAAAkB,EACA,MAAO,KAAK,MAAA,CACf,CAAA,CAGE,iBAAiBN,EACxB,CACU,IAAAJ,EAAmB,KAAK,qBAAqBI,CAAY,EAEzD,CAAE,SAAAF,CAAA,EAAaF,EAErB,GAAIE,EACJ,CACU,GAAA,CAAE,cAAAC,CAAA,EAAkBH,EAEtBI,EAAa,eAAe,KAAK,qBAAqBA,CAAY,EAExDD,EAAA,SAAS,cAAcA,CAAa,CAAA,SAE7CC,EAAa,cACtB,CACU,GAAA,CAAE,OAAAM,CAAA,EAAWV,EAGZU,EAAA,eACHN,EAAa,MACbA,EAAa,OACbA,EAAa,eAAe,OAC5BA,EAAa,OAAO,EACpBA,EAAa,OAAO,EACpBA,EAAa,OAAA,CACjB,CACJ,CAGI,qBAAqBL,EAC7B,CACW,OAAAA,EAAW,SAAS,KAAK,UAAU,GAAG,GAAK,KAAK,sBAAsBA,CAAU,CAAA,CAGnF,sBAAsBK,EAC9B,CACU,IAAAU,EAAU,IAAIpB,GAEpB,OAAAoB,EAAQ,WAAaV,EACrBA,EAAa,SAAS,KAAK,UAAU,GAAG,EAAIU,EAErCA,CAAA,CAGH,qBAAqBV,EAC7B,CACU,IAAAW,EAAiB,KAAK,qBAAqBX,CAAY,EAEvD,CAAE,SAAAG,CAAA,EAAaQ,EAEfC,EAAQZ,EAAa,QAAQ,OAAO,MAEtCY,EAAM,cAAgB,WAEtBA,EAAM,YAAc,SACpBA,EAAM,OAAO,GAGVC,GAAAb,EAAcG,EAAS,GAAG,EACpBW,GAAAd,EAAcG,EAAS,SAAS,CAAA,CAG1C,SACP,CACI,KAAK,UAAY,IAAA,CAGb,gBAAgBH,EACxB,CACU,IAAAW,EAAiB,KAAK,qBAAqBX,CAAY,EACvDe,EAAUf,EAAa,QAEzBgB,EAAqB,GAEzB,OAAI,KAAK,UAAU,OAASC,GAAa,QAEfD,EAAA,KAAK,UAA4B,QAAQ,SAAS,mBAG5EL,EAAe,SAAWI,EAAQ,cAAc,WAAaC,GAAsBD,EAAQ,OAAO,cAE3FJ,EAAe,QAAA,CAE9B,EA1ManB,GAGK,UAAY,CACtB,KAAM,CACF0B,EAAc,WACdA,EAAc,YACdA,EAAc,WAAA,EAElB,KAAM,cACV,ECvBG,IAAMC,GAAN,MAAMA,WAAsBC,EACnC,CAuBI,eAAeC,EACf,CACI,MAAM,CAAA,CAAE,EAER,IAAIC,EAAUD,EAAK,CAAC,GAAK,CAAA,EAErB,OAAOC,GAAY,WAInBC,EAAYC,EAAQ,8FAA8F,EAGxGF,EAAA,CACN,MAAOA,EACP,OAAQD,EAAK,CAAC,EACd,UAAWA,EAAK,CAAC,EACjB,UAAWA,EAAK,CAAC,CAAA,GAIzB,KAAK,MAAMC,CAAO,CAAA,CAOf,MAAMA,EACb,CACIA,EAAU,CAAE,GAAGH,GAAc,eAAgB,GAAGG,CAAQ,EAEnD,KAAA,UAAY,KAAK,WAAaA,EAAQ,UACtC,KAAA,UAAY,KAAK,WAAaA,EAAQ,UAEtC,KAAA,MAAQ,KAAK,OAASA,EAAQ,MAC9B,KAAA,OAAS,KAAK,QAAUA,EAAQ,OAE/B,IAAAG,EAAQ,KAAK,UAAY,KAAK,UAC9BC,EAAQ,CAAA,EACRC,EAAM,CAAA,EACNC,EAAU,CAAA,EAEVC,EAAY,KAAK,UAAY,EAC7BC,EAAY,KAAK,UAAY,EAE7BC,EAAS,KAAK,MAASF,EACvBG,EAAS,KAAK,OAAUF,EAE9B,QAASG,EAAI,EAAGA,EAAIR,EAAOQ,IAC3B,CACU,IAAAC,EAAKD,EAAI,KAAK,UACdE,EAAMF,EAAI,KAAK,UAAa,EAElCP,EAAM,KAAKQ,EAAIH,EAAOI,EAAIH,CAAK,EAC/BL,EAAI,KAAKO,EAAIL,EAAWM,EAAIL,CAAS,CAAA,CAGzC,IAAMM,EAAWP,EAAYC,EAE7B,QAASG,EAAI,EAAGA,EAAIG,EAAUH,IAC9B,CACI,IAAMI,EAAOJ,EAAIJ,EACXS,EAAQL,EAAIJ,EAAa,EAEzBU,EAASD,EAAO,KAAK,UAAaD,EAClCG,EAAUF,EAAO,KAAK,UAAaD,EAAO,EAC1CI,GAAWH,EAAO,GAAK,KAAK,UAAaD,EACzCK,GAAWJ,EAAO,GAAK,KAAK,UAAaD,EAAO,EAE9CT,EAAA,KAAKW,EAAOC,EAAQC,EACxBD,EAAQE,EAAQD,CAAA,CAAM,CAG9B,KAAK,QAAQ,CAAC,EAAE,KAAO,IAAI,aAAaf,CAAK,EAC7C,KAAK,QAAQ,CAAC,EAAE,KAAO,IAAI,aAAaC,CAAG,EAC3C,KAAK,YAAY,KAAO,IAAI,YAAYC,CAAO,EAG1C,KAAA,QAAQ,CAAC,EAAE,OAAO,EAClB,KAAA,QAAQ,CAAC,EAAE,OAAO,EACvB,KAAK,YAAY,OAAO,CAAA,CAEhC,EA3GaT,GAEK,eAA6D,CACvE,MAAO,IACP,OAAQ,IACR,UAAW,GACX,UAAW,EACf,EAPG,IAAMwB,GAANxB,GCCA,IAAMyB,GAAN,MAAMA,WAA0BC,EACvC,CAoCI,YAAYC,EAAoC,CAAA,EAChD,CACIA,EAAU,CAAE,GAAGF,GAAkB,eAAgB,GAAGE,CAAQ,EAEtD,MAAA,CACF,MAAOA,EAAQ,MACf,OAAQA,EAAQ,OAChB,UAAW,EACX,UAAW,CAAA,CACd,EAED,KAAK,OAAOA,CAAO,CAAA,CAOhB,OAAOA,EACd,CACS,KAAA,MAAQA,EAAQ,OAAS,KAAK,MAC9B,KAAA,OAASA,EAAQ,QAAU,KAAK,OAChC,KAAA,eAAiBA,EAAQ,eAAiB,KAAK,eAC/C,KAAA,gBAAkBA,EAAQ,gBAAkB,KAAK,gBACjD,KAAA,WAAaA,EAAQ,WAAa,KAAK,WACvC,KAAA,YAAcA,EAAQ,YAAc,KAAK,YACzC,KAAA,WAAaA,EAAQ,WAAa,KAAK,WACvC,KAAA,cAAgBA,EAAQ,cAAgB,KAAK,cAE7C,KAAA,SAAWA,EAAQ,QAAQ,EAC3B,KAAA,SAAWA,EAAQ,QAAQ,EAEhC,KAAK,UAAU,EACf,KAAK,gBAAgB,CAAA,CAIlB,iBACP,CACI,IAAMC,EAAI,KAAK,UACT,CACF,MAAAC,EACA,OAAAC,EACA,WAAAC,EACA,YAAAC,EACA,WAAAC,EACA,cAAAC,EACA,SAAAC,EACA,SAAAC,CAAA,EACA,KAEEC,EAAIN,EAAaC,EACjBM,EAAST,EAAQQ,EAAI,EAAMR,EAAQQ,EAEnCE,EAAIN,EAAaC,EACjBM,EAASV,EAASS,EAAI,EAAMT,EAASS,EAErCE,EAAQ,KAAK,IAAIH,EAAQE,CAAM,EAE/BE,EAAgBP,EAAWN,EAC3Bc,EAAgBP,EAAWN,EAE/BF,EAAA,CAAC,EAAIA,EAAE,CAAC,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAI,CAACc,EAC/Bd,EAAE,CAAC,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAKG,EAAaU,EAASC,EACtDd,EAAE,CAAC,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIC,EAASG,EAAcS,EAASC,EAC7Dd,EAAA,CAAC,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIC,EAAQa,EAErCd,EAAA,CAAC,EAAIA,EAAE,CAAC,EAAIA,EAAE,CAAC,EAAIA,EAAE,CAAC,EAAI,CAACe,EAC7Bf,EAAE,CAAC,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAKK,EAAaQ,EAASE,EACtDf,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIE,EAAUI,EAAgBO,EAASE,EACjEf,EAAA,EAAE,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIA,EAAE,EAAE,EAAIE,EAASa,EAEpC,KAAA,UAAU,WAAW,EAAE,OAAO,CAAA,CAIhC,WACP,CACI,IAAMC,EAAM,KAAK,IAEbA,EAAA,CAAC,EAAIA,EAAI,CAAC,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAI,EAClCA,EAAA,CAAC,EAAIA,EAAI,CAAC,EAAIA,EAAI,CAAC,EAAIA,EAAI,CAAC,EAAI,EAEhCA,EAAA,CAAC,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAI,EACnCA,EAAA,EAAE,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAI,EAElC,IAAAC,EAAO,EAAM,KAAK,eAClBC,EAAO,EAAM,KAAK,gBAExBF,EAAI,CAAC,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIC,EAAO,KAAK,WACnDD,EAAI,CAAC,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIE,EAAO,KAAK,WAEnDF,EAAI,CAAC,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAI,EAAKC,EAAO,KAAK,YACxDD,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAIA,EAAI,EAAE,EAAI,EAAKE,EAAO,KAAK,cAEpD,KAAA,UAAU,KAAK,EAAE,OAAO,CAAA,CAErC,EAtIarB,GAGK,eAA2C,CAErD,MAAO,IAEP,OAAQ,IAER,UAAW,GAEX,UAAW,GAEX,WAAY,GAEZ,aAAc,GAGd,cAAe,IAEf,eAAgB,GACpB,EArBG,IAAMsB,GAANtB,GCxBA,IAAMuB,GAAN,cAAqCC,EAC5C,CACI,aACA,CACU,MAAA,EACD,KAAA,SAAW,IAAIC,EAAkB,CAGnC,SACP,CACI,KAAK,SAAS,QAAQ,CAAA,CAE9B,EAMaC,GAAN,KACP,CAaI,YAAYC,EACZ,CACI,KAAK,UAAYA,CAAA,CAGd,cAAcC,EAAyBC,EAC9C,CACU,IAAAC,EAAY,KAAK,cAAcF,CAAM,EAEvCA,EAAO,eAAoB,KAAA,uBAAuBA,EAAQE,CAAS,EAEvE,KAAK,UAAU,YAAY,MAAM,WAAWA,EAAWD,CAAc,CAAA,CAGlE,iBAAiBD,EACxB,CACU,IAAAE,EAAY,KAAK,cAAcF,CAAM,EAEvCA,EAAO,eAAoB,KAAA,uBAAuBA,EAAQE,CAAS,EAE7DA,EAAA,SAAS,cAAcA,CAAS,CAAA,CAGvC,mBAAmBF,EAC1B,CACU,IAAAE,EAAY,KAAK,cAAcF,CAAM,EAEpC,MAAA,CAACE,EAAU,SAAS,sBACvBA,EACAF,EAAO,QAAA,CACX,CAGI,uBAAuBA,EAAyBG,EACxD,CACKA,EAAgB,SACZ,OAAOH,CAAM,EAGFG,EAAA,WAAWH,EAAO,QAAQ,CAAA,CAGtC,cAAcA,EACtB,CACW,OAAAA,EAAO,SAAS,KAAK,UAAU,GAAG,GAAK,KAAK,eAAeA,CAAM,CAAA,CAGpE,eAAeA,EACvB,CACU,IAAAI,EAAUJ,EAAO,SAAS,KAAK,UAAU,GAAG,EAAI,IAAIL,GAEpDU,EAAgBD,EAEtB,OAAAC,EAAc,WAAaL,EAC3BK,EAAc,UAAYL,EAAO,eACjCK,EAAc,QAAUL,EAAO,SAC/BK,EAAc,YAAe,KAAK,UAAU,aAAeL,EAAO,aAG7DA,EAAO,eAEH,KAAA,uBAAuBA,EAAQK,CAAa,EAG9CD,CAAA,CAGJ,SACP,CACK,KAAK,UAAqB,IAAA,CAEnC,EArFaN,GAGK,UAAY,CACtB,KAAM,CACFQ,EAAc,WACdA,EAAc,YACdA,EAAc,WAAA,EAElB,KAAM,iBACV,EC/BG,IAAMC,GAAN,KACP,CAYI,YAAYC,EACZ,CACI,KAAK,UAAYA,CAAA,CAGd,KAAKC,EAAsBC,EAAsBC,EACxD,CACwB,KAAK,UAAU,YAEvB,MAAM,MAAMA,CAAc,EAEtCA,EAAe,IAAI,CACf,aAAc,SACd,UAAW,GACX,OAAQ,aACR,UAAAD,EACA,aAAAD,CAAA,CACkB,CAAA,CAGnB,IAAIG,EAAuBC,EAAuBF,EACzD,CACI,KAAK,UAAU,YAAY,MAAM,MAAMA,CAAc,EAErDA,EAAe,IAAI,CACf,aAAc,SACd,OAAQ,YACR,UAAW,EAAA,CACd,CAAA,CAGE,QAAQG,EACf,CACQA,EAAY,SAAW,aAElB,KAAA,UAAU,OAAO,KAAKA,CAAW,EAEjCA,EAAY,SAAW,aAEvB,KAAA,UAAU,OAAO,IAAI,CAC9B,CAGG,SACP,CACI,KAAK,UAAY,IAAA,CAEzB,EA5DaP,GAEK,UAAY,CACtB,KAAM,CACFQ,EAAc,WACdA,EAAc,YACdA,EAAc,WAAA,EAElB,KAAM,QACV,ECnBJ,IAAIC,GAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECAb,IAAIC,GAAW;AAAA;AAAA;AAAA;AAAA;AAAA;ECAf,IAAIC,GAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECaN,IAAMC,GAAN,cAAgCC,EACvC,CACI,aACA,CACU,IAAAC,EAAaC,GAAW,KAAK,CAC/B,OAAQ,CAAE,OAAAC,GAAQ,WAAY,YAAa,EAC3C,SAAU,CAAE,OAAAA,GAAQ,WAAY,cAAe,EAC/C,KAAM,oBAAA,CACT,EAEKC,EAAYC,GAAU,KAAK,CAC7B,OAAAC,GACA,SAAAC,GACA,KAAM,oBAAA,CACT,EAEK,MAAA,CACF,WAAAN,EACA,UAAAG,CAAA,CACH,CAAA,CAET,ECxBA,IAAMI,GAA+B,IAAIC,EAOzB,SAAAC,GAA0BC,EAA2BC,EACrE,CACIA,EAAO,MAAM,EAMb,IAAMC,EAAeD,EAAO,OAE5B,QAASE,EAAI,EAAGA,EAAIH,EAAY,OAAQG,IACxC,CACU,IAAAC,EAAaJ,EAAYG,CAAC,EAE5B,GAAAC,EAAW,oBAAsB,EAEjC,SAGE,IAAAC,EAAcD,EAAW,aAAeA,EAAW,kBAErDC,GAAa,kBAENJ,EAAA,OAASJ,GAAqB,SAASQ,EAAY,6BAA6B,EAClF,OAAOD,EAAW,cAAc,EAEhCC,GAAa,iCAEXJ,EAAA,OAASJ,GACX,SAASQ,EAAY,iCAAiC,qBAAqB,EAC3E,OAAOD,EAAW,cAAc,EAIrCH,EAAO,OAASG,EAAW,eAGxBH,EAAA,UAAUG,EAAW,MAAM,CAAA,CAGtC,OAAAH,EAAO,OAASC,EAETD,CACX,CClCA,IAAMK,GAAe,IAAIC,GAAS,CAC9B,WAAY,CACR,UAAW,CACP,OAAQ,IAAI,aAAa,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CAAC,EACjD,OAAQ,YACR,OAAQ,EACR,OAAQ,CAAA,CACZ,EAEJ,YAAa,IAAI,YAAY,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CAAC,CACnD,CAAC,EAsCKC,GAAN,KACA,CADA,aAAA,CAMI,KAAO,KAAO,GAMd,KAAO,aAAwB,KAM/B,KAAO,YAAwB,KAM/B,KAAO,QAAoB,KAMpB,KAAA,OAAS,IAAIC,GAMpB,KAAO,UAAuB,KAM9B,KAAO,cAAyB,GAMhC,KAAO,oBAAqC,KAMrC,KAAA,YAAc,CAAE,EAAG,EAAG,EAAG,EAAG,MAAO,EAAG,OAAQ,CAAE,EAevD,KAAO,kBAAoB,GAG3B,KAAO,iBAAmB,EAAA,CAC9B,EAOaC,GAAN,KACP,CA4BI,YAAYC,EACZ,CAjBA,KAAQ,kBAAoB,EAC5B,KAAQ,aAA6B,CAAA,EAEpB,KAAA,sBAAwB,IAAIC,EAAa,CACtD,WAAY,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,KAAM,WAAY,EAC5D,YAAa,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,KAAM,WAAY,EAC7D,YAAa,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,KAAM,WAAY,EAC7D,aAAc,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,KAAM,WAAY,EAC9D,aAAc,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,KAAM,WAAY,EAC9D,eAAgB,CAAE,MAAO,IAAI,aAAa,CAAC,EAAG,KAAM,WAAY,CAAA,CACnE,EAED,KAAiB,uBAAoC,IAAIC,GAAU,CAAA,CAAE,EAMjE,KAAK,SAAWF,CAAA,CAOpB,IAAW,mBACX,CACI,OAAO,KAAK,mBAAmB,WAAA,CAQ5B,KAAKG,EACZ,CACI,IAAMH,EAAW,KAAK,SAEhBI,EAAUD,EAAY,aAAa,QAInCE,EAAa,KAAK,gBAAgB,EAExCA,EAAW,KAAO,GAElBA,EAAW,QAAUD,EACrBC,EAAW,UAAYF,EAAY,UACxBE,EAAA,oBAAsBL,EAAS,aAAa,cAEvD,IAAMM,EAAqBN,EAAS,aAAa,aAAa,aAAa,OAErEO,EAAiBD,EAAmB,WACpCE,EAAgBF,EAAmB,UAGzC,GAAIF,EAAQ,MAAOK,GAAW,CAACA,EAAO,OAAO,EAC7C,CACIJ,EAAW,KAAO,GAElB,MAAA,CAGJ,IAAMK,EAASL,EAAW,OAM1B,GAJK,KAAA,qBAAqBF,EAAaO,CAAM,EAE7C,KAAK,uBAAuBL,EAAYL,EAAS,aAAa,aAAcQ,EAAeD,EAAgB,CAAC,EAExGF,EAAW,KAEX,OAGE,IAAAM,EAAqB,KAAK,uBAAuB,EAEjDC,EAAmB,KAAK,sBAAsBL,CAAc,EAC9DM,EAAU,EACVC,EAAU,EAEVH,IAEAE,EAAUF,EAAmB,OAAO,KACpCG,EAAUH,EAAmB,OAAO,MAGnC,KAAA,sBACDN,EACAQ,EAASC,EACTF,EACAN,EAAmB,MACnBA,EAAmB,MAAA,EAKvB,KAAK,qBAAqBD,EAAYK,EAAQV,EAAUW,CAAkB,CAAA,CA8BvE,wBAAwB,CAAE,QAAAI,EAAS,QAAAX,CAAA,EAC1C,CAGU,IAAAC,EAAa,KAAK,gBAAgB,EAExC,KAAK,kBAAoBA,EACzBA,EAAW,KAAO,GAElBA,EAAW,QAAUD,EAErB,IAAME,EAAqBS,EAAQ,OAE7BR,EAAiBD,EAAmB,WACpCE,EAAgBF,EAAmB,UAGzC,GAAIF,EAAQ,MAAOK,GAAW,CAACA,EAAO,OAAO,EAEzC,OAAAJ,EAAW,KAAO,GAEXU,EAGX,IAAML,EAASL,EAAW,OAU1B,GAJOK,EAAA,QAAQK,EAAQ,KAAK,EAE5B,KAAK,uBAAuBV,EAAYK,EAAO,UAAWF,EAAeD,EAAgB,CAAC,EAEtFF,EAAW,KAEJ,OAAAU,EAGX,IAAMH,EAAmBL,EAIpB,KAAA,sBACDF,EAJY,EACA,EAKZO,EACAN,EAAmB,MACnBA,EAAmB,MAAA,EAOvBD,EAAW,oBAAsBW,EAAY,kBACzCN,EAAO,MACPA,EAAO,OACPL,EAAW,WACXA,EAAW,SAAA,EAGfA,EAAW,YAAcY,EAAQ,MAKjCZ,EAAW,aAAeU,EAIT,KAAK,SAGb,aAAa,iBAAiB,EAKlC,KAAA,uBAAuBV,EAAY,EAAI,EAE5C,IAAMa,EAAgBb,EAAW,oBAEjC,OAAAa,EAAc,OAAO,UAAY,sBAE1BA,CAAA,CAIJ,KACP,CACI,IAAMlB,EAAW,KAAK,SAEhBK,EAAa,KAAK,eAAe,EAGnCA,EAAW,OAKfL,EAAS,eAAe,IAAI,EAE5BA,EAAS,aAAa,iBAAiB,EAEvC,KAAK,kBAAoBK,EAEpB,KAAA,uBAAuBA,EAAY,EAAK,EAGzCA,EAAW,eAECW,EAAA,cAAcX,EAAW,WAAW,EAIxCW,EAAA,cAAcX,EAAW,YAAY,EAAA,CAS9C,eAAec,EAAiCT,EAAgBU,EACvE,CACU,IAAAC,EAAuBF,EAAkB,aAAa,OAAO,YAE7DG,EAAcN,EAAY,kBAC5BN,EAAO,MACPA,EAAO,OACPW,EACA,EAAA,EAGAE,EAAIb,EAAO,KACXc,EAAId,EAAO,KAEXU,IAEAG,GAAKH,EAAe,KACpBI,GAAKJ,EAAe,MAGpBG,EAAA,KAAK,MAAMA,EAAIF,CAAoB,EACnCG,EAAA,KAAK,MAAMA,EAAIH,CAAoB,EAEvC,IAAMI,EAAQ,KAAK,KAAKf,EAAO,MAAQW,CAAoB,EACrDK,EAAS,KAAK,KAAKhB,EAAO,OAASW,CAAoB,EAE7D,YAAK,SAAS,aAAa,cACvBF,EACAG,EACA,CAAE,EAAAC,EAAG,EAAAC,CAAE,EACP,CAAE,MAAAC,EAAO,OAAAC,CAAO,EAChB,CAAE,EAAG,EAAG,EAAG,CAAE,CAAA,EAGVJ,CAAA,CAUJ,YAAYb,EAAgBkB,EAAgBC,EAAuBC,EAC1E,CACI,IAAM7B,EAAW,KAAK,SAEhBK,EAAa,KAAK,kBAIlByB,EAFsBzB,EAAW,sBAEOuB,EAGxCrB,EAAiBP,EAAS,aAAa,iBAAiB,aAAa,OAAO,YAC5E+B,EAAa,KAAK,sBAAsBxB,CAAc,EAGxDM,EAAU,EACVC,EAAU,EAEd,GAAIgB,EACJ,CACU,IAAAE,EAAS,KAAK,0BAA0B,EAE9CnB,EAAUmB,EAAO,EACjBlB,EAAUkB,EAAO,CAAA,CAGhB,KAAA,sBAAsBL,EAAOC,EAAQvB,EAAYQ,EAASC,EAASiB,EAAYD,EAAeD,CAAK,EAIxG,IAAMI,EAAgBxB,EAAO,QACvBA,EACA,KAAK,sBAAsB,EAE5B,KAAA,0BAA0BwB,EAAeN,EAAO3B,CAAQ,CAAA,CAW1D,sBAAsBkC,EAAsBC,EACnD,CACI,IAAMC,EAAO,KAAK,kBAEZC,EAAeH,EAAa,IAC9BE,EAAK,aAAa,QAAQ,MAC1B,EAAG,EACHA,EAAK,aAAa,QAAQ,OAC1BA,EAAK,OAAO,KAAMA,EAAK,OAAO,IAAA,EAG5BE,EAAiBH,EAAO,eAAe,OAAOI,EAAO,MAAM,EAE3DC,EAAcL,EAAO,aAAeA,EAAO,kBAE7C,OAAAK,GAAeA,EAAY,uBAGZF,EAAA,QAAQE,EAAY,qBAAqB,EAG5DF,EAAe,OAAO,EACtBD,EAAa,QAAQC,CAAc,EACtBD,EAAA,MACT,EAAMF,EAAO,QAAQ,KAAK,MAC1B,EAAMA,EAAO,QAAQ,KAAK,MAAA,EAG9BE,EAAa,UAAUF,EAAO,OAAO,EAAGA,EAAO,OAAO,CAAC,EAEhDE,CAAA,CAGJ,SACP,CACS,KAAA,oBAAoB,QAAQ,EAAI,EACpC,KAAK,mBAA8B,IAAA,CAGhC,uBACR,CACI,YAAK,qBAAL,KAAK,mBAAuB,IAAII,IAEzB,KAAK,kBAAA,CASR,0BAA0BhC,EAAgBkB,EAAgB3B,EAClE,CAES,GAAAA,EAA4B,YAAY,aAC7C,CACI,IAAM0C,EAAiB1C,EAA4B,YAAY,aAC1D,eAAe,KAAK,qBAAqB,EAEzC,KAAA,uBAAuB,YAAY0C,EAAe,CAAC,CAAA,MAIxD,KAAK,uBAAuB,YAAY,KAAK,sBAAuB,CAAC,EAMzE,KAAK,uBAAuB,YAAYf,EAAM,OAAQ,CAAC,EACvD,KAAK,uBAAuB,YAAYA,EAAM,OAAO,MAAO,CAAC,EAEtDlB,EAAA,OAAO,CAAC,EAAI,KAAK,uBAExBT,EAAS,QAAQ,KAAK,CAClB,SAAUL,GACV,OAAQc,EACR,MAAOA,EAAO,OACd,SAAU,eAAA,CACb,EAGGT,EAAS,OAAS2C,GAAa,OAE/B3C,EAAS,aAAa,iBAAiB,CAC3C,CAUI,qBACJK,EACAK,EACAV,EACAW,EAEJ,CAqBI,GAnBAN,EAAW,YAAcY,EAAQ,MAKjCZ,EAAW,aAAeW,EAAY,kBAClCN,EAAO,MACPA,EAAO,OACPL,EAAW,WACXA,EAAW,SAAA,EAUXA,EAAW,cACf,CACIL,EAAS,aAAa,iBAAiB,EAGvC,IAAM4C,EAAe5C,EAAS,aAAa,gBAAgBK,EAAW,mBAAmB,EAEzFA,EAAW,YAAc,KAAK,eAAeuC,EAAclC,EAAQC,GAAoB,MAAM,CAAA,CAGjGX,EAAS,aAAa,KAAKK,EAAW,aAAc,EAAI,EAGxDL,EAAS,eAAe,KAAK,CACzB,OAAQU,CAAA,CACX,CAAA,CAYG,sBACJL,EACAQ,EACAC,EACAF,EACAiC,EACAC,EAEJ,CACI,IAAMC,EAAc1C,EAAW,YAE/B0C,EAAY,EAAIlC,EAAUD,EAC1BmC,EAAY,EAAIjC,EAAUF,EAC1BmC,EAAY,MAAQF,EAAcjC,EAClCmC,EAAY,OAASD,EAAelC,CAAA,CAchC,sBACJe,EACAC,EACAvB,EACAQ,EACAC,EACAiB,EACAD,EACAD,EAEJ,CACU,IAAAmB,EAAW,KAAK,sBAAsB,SACtCC,EAAcD,EAAS,aACvBE,EAAYF,EAAS,WACrBG,EAAaH,EAAS,YACtBI,EAAaJ,EAAS,YACtBD,EAAcC,EAAS,aACvB9B,EAAgB8B,EAAS,eAG3BlB,GAEAmB,EAAY,CAAC,EAAI5C,EAAW,OAAO,KAAOQ,EAC1CoC,EAAY,CAAC,EAAI5C,EAAW,OAAO,KAAOS,IAI1CmC,EAAY,CAAC,EAAI,EACjBA,EAAY,CAAC,EAAI,GAGTA,EAAA,CAAC,EAAItB,EAAM,MAAM,MACjBsB,EAAA,CAAC,EAAItB,EAAM,MAAM,OAEnBuB,EAAA,CAAC,EAAIvB,EAAM,OAAO,MAClBuB,EAAA,CAAC,EAAIvB,EAAM,OAAO,OAC5BuB,EAAU,CAAC,EAAI,EAAIA,EAAU,CAAC,EAC9BA,EAAU,CAAC,EAAI,EAAIA,EAAU,CAAC,EAEnBC,EAAA,CAAC,EAAIxB,EAAM,OAAO,WAClBwB,EAAA,CAAC,EAAIxB,EAAM,OAAO,YAC7BwB,EAAW,CAAC,EAAI,EAAMA,EAAW,CAAC,EAClCA,EAAW,CAAC,EAAI,EAAMA,EAAW,CAAC,EAElCC,EAAW,CAAC,EAAI,GAAMD,EAAW,CAAC,EAClCC,EAAW,CAAC,EAAI,GAAMD,EAAW,CAAC,EACvBC,EAAA,CAAC,EAAKzB,EAAM,MAAM,MAAQuB,EAAU,CAAC,EAAM,GAAMC,EAAW,CAAC,EAC7DC,EAAA,CAAC,EAAKzB,EAAM,MAAM,OAASuB,EAAU,CAAC,EAAM,GAAMC,EAAW,CAAC,EAEzE,IAAME,EAAc,KAAK,SAAS,aAAa,iBAAiB,aAEpDN,EAAA,CAAC,EAAIlC,EAAUkB,EACfgB,EAAA,CAAC,EAAIjC,EAAUiB,EAC3BgB,EAAY,CAAC,EAAIM,EAAY,OAAO,MAAQtB,EAC5CgB,EAAY,CAAC,EAAIM,EAAY,OAAO,OAAStB,EAGzCH,aAAkBX,IAASW,EAAO,OAAO,SAAW,MAGxD,IAAMgB,EAAe,KAAK,SAAS,aAAa,gBAAgBhB,CAAM,EAEtE,KAAK,SAAS,aAAa,KAAKA,EAAQ,CAAC,CAACC,CAAK,EAE3CD,aAAkBX,GAEJC,EAAA,CAAC,EAAIU,EAAO,MAAM,MAClBV,EAAA,CAAC,EAAIU,EAAO,MAAM,SAKlBV,EAAA,CAAC,EAAI0B,EAAa,MAClB1B,EAAA,CAAC,EAAI0B,EAAa,QAGpC1B,EAAc,CAAC,EAAI0B,EAAa,OAAS,GAAK,EAE9C,KAAK,sBAAsB,OAAO,CAAA,CAQ9B,sBAAsBrC,EAC9B,CACQ,IAAA+C,EAAe,KAAK,kBAAoB,EAE5C,KAAOA,EAAe,GAAK,KAAK,aAAaA,CAAY,EAAE,MAErD,EAAAA,EAGN,OAAOA,EAAe,GAAK,KAAK,aAAaA,CAAY,EAAE,aACrD,KAAK,aAAaA,CAAY,EAAE,aAAa,OAAO,YACpD/C,CAAA,CAOF,2BACR,CACI,IAAIM,EAAU,EACVC,EAAU,EACVyC,EAAY,KAAK,kBAErB,KAAOA,EAAY,GACnB,CACIA,IACM,IAAAC,EAAiB,KAAK,aAAaD,CAAS,EAE9C,GAAA,CAACC,EAAe,KACpB,CACI3C,EAAU2C,EAAe,OAAO,KAChC1C,EAAU0C,EAAe,OAAO,KAChC,KAAA,CACJ,CAGJ,MAAO,CAAE,EAAG3C,EAAS,EAAGC,CAAQ,CAAA,CAQ5B,qBAAqBX,EAAgCO,EAC7D,CA4BI,GAxBIP,EAAY,YAEcsD,GAAAtD,EAAY,YAAaO,CAAM,EAGpDP,EAAY,aAAa,YAE9BO,EAAO,MAAM,EAGNA,EAAA,QAAQP,EAAY,aAAa,UAAU,EAG3CO,EAAA,YAAYP,EAAY,UAAU,cAAc,GAQ3CA,EAAA,UAAU,oBAAoB,GAAMO,CAAM,EAGtDP,EAAY,UAChB,CAKI,IAAMuD,GADcvD,EAAY,UAAU,aAAeA,EAAY,UAAU,mBACtC,sBAErCuD,GAEAhD,EAAO,YAAYgD,CAAoB,CAC3C,CACJ,CAGI,uBAAuBrD,EAAwBwB,EACvD,CACI,IAAM8B,EAAetD,EAAW,aAE1BK,EAASL,EAAW,OAEpBD,EAAUC,EAAW,QACrBuD,EAAevD,EAAW,kBAC1BwD,EAAcxD,EAAW,iBAS/B,GAHA,KAAK,uBAAuB,YAAYsD,EAAa,OAAO,MAAO,CAAC,EACpE,KAAK,uBAAuB,YAAYtD,EAAW,YAAY,OAAQ,CAAC,EAEpEuD,IAAiBC,EAGjBzD,EAAQwD,CAAY,EAAE,MAAM,KAAMD,EAActD,EAAW,oBAAqBwB,CAAK,MAGzF,CACI,IAAIiC,EAAOzD,EAAW,aAEhB0D,EAAc/C,EAAY,kBAC5BN,EAAO,MACPA,EAAO,OACPoD,EAAK,OAAO,YACZ,EAAA,EAIAE,EAAOD,EAGX,QAASE,EAAIL,EAAcK,EAAIJ,EAAaI,IAC5C,CACU,IAAAxD,EAASL,EAAQ6D,CAAC,EAExB,GAAI,CAACxD,EAAO,QAAS,SAErBA,EAAO,MAAM,KAAMqD,EAAME,EAAM,EAAI,EACnC,IAAME,EAAIJ,EAEHA,EAAAE,EACAA,EAAAE,CAAA,CAGX9D,EAAQyD,CAAW,EAAE,MAAM,KAAMC,EAAMzD,EAAW,oBAAqBwB,CAAK,EAG5Eb,EAAY,cAAc+C,CAAW,CAAA,CACzC,CAGI,uBACJ1D,EACA8D,EACA3D,EACAD,EAKA6D,EAEJ,CACI,IAAMpE,EAAW,KAAK,SAEhBU,EAASL,EAAW,OACpBD,EAAUC,EAAW,QAMvB0B,EAAa,IAEbsC,EAAU,EAEVC,EAAY,GAEZC,EAAgB,GAEhBC,EAAU,GAEVC,EAAiB,GAEjBC,EAAoB,GACpBC,EAAmB,GAEvB,QAASV,EAAI,EAAGA,EAAI7D,EAAQ,OAAQ6D,IACpC,CACU,IAAAxD,EAASL,EAAQ6D,CAAC,EAGxB,GAAI,CAACxD,EAAO,QAAS,SAwBrB,GAtBIiE,IAAsB,KAAwBA,EAAAT,GAC/BU,EAAAV,EACNlC,EAAA,KAAK,IAAIA,EAAYtB,EAAO,aAAe,UAClDF,EAAiBE,EAAO,UAAU,EACxC4D,GAAW5D,EAAO,QAEdA,EAAO,YAAc,MAET6D,EAAA,GAEP7D,EAAO,YAAc,WAEZ6D,IAAAA,EAAA9D,GAGbC,EAAO,iBAESgE,EAAA,IAKjB,CAFiB,CAAC,EAAEhE,EAAO,oBAAsBT,EAAS,MAG9D,CACcwE,EAAA,GACV,KAAA,CAGJ,GAAI/D,EAAO,eAAiB,EAAGT,EAA2B,YAAY,eAAiB,IACvF,CAGI4E,EAAK,sHAAsH,EAGjHJ,EAAA,GACV,KAAA,CAGMA,EAAA,GACVD,IAAAA,EAAkB9D,EAAO,cAAA,CAI7B,GAAI,CAAC+D,EACL,CACInE,EAAW,KAAO,GAElB,MAAA,CAoBA,GAdAoE,GAEO/D,EAAA,UAAU,EAAGyD,EAAS,MAAQ5D,EAAgB,EAAG4D,EAAS,OAAS5D,CAAc,EAI5FG,EACK,MAAMqB,CAAU,EAChB,KAAA,EACA,MAAM,EAAIA,CAAU,EACpB,KAAKsC,EAAU,GAAKD,CAAiB,EAItC,CAAC1D,EAAO,WACZ,CACIL,EAAW,KAAO,GAElB,MAAA,CAWJA,EAAW,UAAYiE,EACvBjE,EAAW,WAAa0B,EACxB1B,EAAW,cAAgBkE,EAC3BlE,EAAW,kBAAoBqE,EAC/BrE,EAAW,iBAAmBsE,CAAA,CAG1B,gBACR,CACS,YAAA,oBAEE,KAAK,aAAa,KAAK,iBAAiB,CAAA,CAG3C,wBACR,CACQ,IAAAhE,EAEAkE,EAAQ,KAAK,kBAAoB,EAErC,KAAOA,EAAQ,IAEXA,IACqBlE,EAAA,KAAK,aAAakE,CAAK,EAExC,EAAClE,EAAmB,OAApB,CAMD,OAAAA,CAAA,CAGH,iBACR,CACI,IAAIN,EAAa,KAAK,aAAa,KAAK,iBAAiB,EAEzD,OAAKA,IAEDA,EAAa,KAAK,aAAa,KAAK,iBAAiB,EAAI,IAAIR,IAG5D,KAAA,oBAEEQ,CAAA,CAEf,EAz6BaN,GAGK,UAAY,CACtB,KAAM,CACF+E,EAAc,YACdA,EAAc,YAAA,EAElB,KAAM,QACV",
6
+ "names": ["require_parse_svg_path", "__commonJSMin", "exports", "module", "parse", "length", "segment", "path", "data", "_", "command", "args", "type", "parseValues", "number", "numbers", "LoaderParserPriority", "assertPath", "path", "removeUrlParams", "url", "escapeRegExp", "string", "replaceAll", "str", "find", "replace", "normalizeStringPosix", "allowAboveRoot", "res", "lastSegmentLength", "lastSlash", "dots", "code", "i", "lastSlashIndex", "matchFile", "matchProtocol", "customBaseUrl", "customRootUrl", "baseUrl", "DOMAdapter", "rootUrl", "protocol", "isAbsolute", "trailingSeparator", "segments", "joined", "arg", "prevArg", "hasRoot", "end", "matchedSlash", "proto", "origpath", "root", "index", "ext", "start", "extIdx", "firstNonSlashEnd", "startDot", "startPart", "preDotState", "ret", "convertToList", "input", "transform", "forceTransform", "item", "processX", "base", "ids", "depth", "result", "tags", "id", "i", "value", "createStringVariations", "string", "regex", "vars", "split", "isSingleItem", "item", "Resolver", "bundleId", "assetId", "assetBundleId", "bundleIdentifier", "preferOrders", "prefer", "basePath", "rootPath", "searchParams", "queryValues", "key", "asset", "alias", "src", "convertToList", "value", "v", "manifest", "warn", "bundle", "assets", "assetNames", "convertedAssets", "srcs", "aliases", "ids", "bundleAssetId", "bundleIds", "name", "keyCheck", "data", "format", "userDefinedLoadParser", "userDefinedParser", "srcsToUse", "createStringVariations", "aliasesToUse", "resolvedAssets", "parseUrl", "url", "p", "formattedAsset", "singleAsset", "isSingleItem", "out", "results", "result", "i", "keys", "preferredOrder", "priorityKey", "filteredAssets", "preferred", "preference", "paramConnector", "assetData", "loadParser", "parser", "progressSize", "path", "getUrlExtension", "copySearchParams", "targetUrl", "sourceUrl", "searchParams", "_Spritesheet", "optionsOrTexture", "arg1", "options", "TextureSource", "texture", "data", "cachePrefix", "Texture", "metaResolution", "resolve", "initialFrameIndex", "frameIndex", "maxFrames", "i", "rect", "frame", "trim", "sourceSize", "orig", "Rectangle", "animations", "animName", "frameName", "callback", "destroyBase", "Spritesheet", "validImages", "getCacheableAssets", "keys", "asset", "ignoreMultiPack", "out", "key", "basePath", "path", "item", "i", "out2", "spritesheetAsset", "ExtensionType", "Spritesheet", "value", "split", "extension", "format", "Resolver", "LoaderParserPriority", "options", "loader", "imageTexture", "imageFilename", "textureOptions", "cachePrefix", "texture", "Texture", "imagePath", "copySearchParams", "spritesheet", "multiPacks", "promises", "itemUrl", "res", "sp", "_resolvedAsset", "extensions", "spritesheetAsset", "tempBounds", "Bounds", "addMaskBounds", "mask", "bounds", "skipUpdateTransform", "boundsToMask", "getGlobalBounds", "addMaskLocalBounds", "mask", "bounds", "localRoot", "boundsToMask", "boundsPool", "tempMatrix", "matrixPool", "relativeMask", "getMatrixRelativeToParent", "getLocalBounds", "target", "root", "matrix", "warn", "AlphaMask", "options", "mask", "Sprite", "bounds", "skipUpdateTransform", "addMaskBounds", "localRoot", "addMaskLocalBounds", "point", "hitTestFn", "ExtensionType", "ColorMask", "options", "mask", "ExtensionType", "StencilMask", "options", "mask", "bounds", "skipUpdateTransform", "addMaskBounds", "localRoot", "addMaskLocalBounds", "point", "hitTestFn", "Container", "ExtensionType", "ImageSource", "TextureSource", "options", "resource", "ExtensionType", "promise", "detectVideoAlphaMode", "gl", "DOMAdapter", "video", "resolve", "texture", "framebuffer", "pixel", "_VideoSource", "TextureSource", "options", "elapsedMS", "Ticker", "source", "detectVideoAlphaMode", "resolve", "reject", "event", "value", "resource", "ExtensionType", "VideoSource", "CacheClass", "key", "result", "warn", "value", "keys", "convertToList", "cacheableAssets", "i", "parser", "cacheableMap", "cacheKeys", "cachedAssets", "val", "cacheMap", "Cache", "sources", "extensions", "ExtensionType", "textureSourceFrom", "options", "hasResource", "res", "opts", "i", "sources", "Source", "resourceToTexture", "skipCache", "resource", "Cache", "texture", "Texture", "textureFrom", "id", "TextureSource", "extensions", "AlphaMask", "ColorMask", "StencilMask", "VideoSource", "ImageSource", "CanvasSource", "BufferImageSource", "ResizePlugin", "options", "dom", "width", "height", "clientWidth", "clientHeight", "ExtensionType", "TickerPlugin", "options", "ticker", "UPDATE_PRIORITY", "Ticker", "oldTicker", "ExtensionType", "buildUvs", "vertices", "verticesStride", "verticesOffset", "uvs", "uvsOffset", "uvsStride", "size", "matrix", "index", "a", "b", "c", "d", "tx", "ty", "x", "y", "buildSimpleUvs", "transformVertices", "vertices", "m", "offset", "stride", "size", "a", "b", "c", "d", "tx", "ty", "index", "i", "x", "y", "identityMatrix", "Matrix", "BatchableGraphics", "rgb", "bgr", "renderable", "multiplyHexColors", "gpuBuffer", "buildCircle", "ExtensionType", "shape", "points", "x", "y", "dx", "dy", "rx", "ry", "circle", "ellipse", "roundedRect", "halfWidth", "halfHeight", "n", "m", "j1", "j2", "j3", "j4", "x0", "y0", "x1", "x2", "y1", "y2", "i", "a", "vertices", "verticesStride", "verticesOffset", "indices", "indicesOffset", "centerX", "centerY", "count", "centerIndex", "buildEllipse", "buildRoundedRectangle", "getOrientationOfPoints", "points", "m", "area", "i", "x1", "y1", "x2", "y2", "square", "x", "y", "nx", "ny", "innerWeight", "outerWeight", "clockwise", "verts", "ix", "iy", "ox", "oy", "exx", "eyy", "eix", "eiy", "eox", "eoy", "round", "cx", "cy", "sx", "sy", "ex", "ey", "cx2p0x", "cy2p0y", "angle0", "angle1", "startAngle", "angleDiff", "absAngleDiff", "radius", "segCount", "angleInc", "i", "angle", "buildLine", "points", "lineStyle", "flipAlignment", "closed", "vertices", "indices", "eps", "style", "alignment", "orientation", "getOrientationOfPoints", "firstPoint", "Point", "lastPoint", "closedShape", "closedPath", "midPointX", "midPointY", "length", "indexCount", "indexStart", "width", "widthSquared", "miterLimitSquared", "x0", "y0", "x1", "y1", "x2", "y2", "perpX", "perpY", "perp1x", "perp1y", "dist", "ratio", "dx0", "dy0", "dx1", "dy1", "dot", "cross", "c1", "c2", "px", "py", "pDist", "imx", "imy", "omx", "omy", "smallerInsideSegmentSq", "insideWeight", "smallerInsideDiagonalSq", "eps2", "buildPixelLine", "points", "closed", "vertices", "indices", "eps", "fx", "fy", "lx", "ly", "closePath", "verts", "length", "indexStart", "i", "triangulateWithHoles", "points", "holes", "vertices", "verticesStride", "verticesOffset", "indices", "indicesOffset", "triangles", "earcut", "i", "index", "emptyArray", "buildPolygon", "ExtensionType", "shape", "points", "i", "vertices", "verticesStride", "verticesOffset", "indices", "indicesOffset", "triangulateWithHoles", "buildRectangle", "ExtensionType", "shape", "points", "rectData", "x", "y", "width", "height", "vertices", "verticesStride", "verticesOffset", "indices", "indicesOffset", "count", "verticesIndex", "buildTriangle", "ExtensionType", "shape", "points", "vertices", "verticesStride", "verticesOffset", "indices", "indicesOffset", "count", "verticesIndex", "emptyColorStops", "_FillGradient", "args", "uid", "options", "ensureGradientOptions", "definedProps", "stop", "offset", "color", "Color", "x0", "y0", "x1", "y1", "dx", "dy", "flip", "temp", "colorStops", "defaultSize", "canvas", "context", "getCanvas", "gradient", "addColorStops", "Texture", "ImageSource", "dist", "angle", "Matrix", "r0", "r1", "ox", "oy", "scale", "cx", "cy", "m", "FillGradient", "i", "width", "height", "DOMAdapter", "deprecation", "tempTextureMatrix", "Matrix", "tempRect", "Rectangle", "generateTextureMatrix", "out", "style", "shape", "matrix", "textureMatrix", "bounds", "tx", "ty", "sx", "sy", "mTx", "mTy", "a1", "b1", "c1", "d1", "sourceStyle", "FillGradient", "shapeBuilders", "extensions", "ExtensionType", "buildRectangle", "buildPolygon", "buildTriangle", "buildCircle", "buildEllipse", "buildRoundedRectangle", "tempRect", "Rectangle", "tempTextureMatrix", "Matrix", "buildContextBatches", "context", "gpuContext", "geometryData", "batches", "i", "instruction", "addTextureToGeometryData", "isStroke", "shapePath", "style", "hole", "addShapePathToGeometryData", "data", "points", "build", "rect", "matrix", "vertices", "uvs", "indices", "indexOffset", "vertOffset", "transformVertices", "texture", "textureUvs", "graphicsBatch", "BigPool", "BatchableGraphics", "shape", "holes", "topology", "close", "lineStyle", "buildPixelLine", "buildLine", "holeIndices", "otherPoints", "getHoleArrays", "holePoints", "triangulateWithHoles", "uvsOffset", "Texture", "textureMatrix", "generateTextureFillMatrix", "buildUvs", "buildSimpleUvs", "holePrimitives", "holeArrays", "k", "holePrimitive", "GpuGraphicsContext", "GraphicsContextRenderData", "InstructionSet", "options", "maxTextures", "DefaultBatcher", "deprecation", "v8_3_4", "_GraphicsContextSystem", "renderer", "context", "gpuContext", "buildContextBatches", "batchMode", "graphicsData", "BigPool", "batches", "geometryData", "vertexSize", "indexSize", "i", "batcher", "batch", "geometry", "drawBatches", "getTextureBatchBindGroup", "ExtensionType", "GraphicsContextSystem", "GraphicsGpuData", "batch", "BigPool", "GraphicsPipe", "renderer", "adaptor", "State", "graphics", "context", "wasBatched", "gpuContext", "instructionSet", "batches", "i", "shader", "localUniforms", "color32BitToUniform", "gpuData", "batchPipe", "roundPixels", "batchClone", "BatchableGraphics", "ExtensionType", "BatchableMesh", "value", "uvBuffer", "uvs", "transformedUvs", "textureMatrix", "MeshGpuData", "MeshPipe", "renderer", "adaptor", "UniformGroup", "Matrix", "BindGroup", "mesh", "meshData", "wasBatched", "isBatched", "geometry", "batchableMesh", "instructionSet", "batcher", "gpuBatchableMesh", "getAdjustedBlendModeBlend", "localUniforms", "color32BitToUniform", "_a", "_b", "gpuMesh", "BatchableMesh", "ExtensionType", "GlParticleContainerAdaptor", "particleContainerPipe", "container", "state", "renderer", "shader", "gl", "buffer", "glType", "createIndicesForQuads", "size", "outBuffer", "totalIndices", "i", "j", "generateParticleUpdateFunction", "properties", "generateUpdateFunction", "dynamic", "funcFragments", "offset", "property", "attributeInfo", "getAttributeInfoFromFormat", "functionSource", "ParticleBuffer", "options", "size", "properties", "staticVertexSize", "dynamicVertexSize", "i", "property", "attributeInfo", "getAttributeInfoFromFormat", "ViewableBuffer", "createIndicesForQuads", "geometry", "Geometry", "dynamicOffset", "staticOffset", "Buffer", "BufferUsage", "uploadFunction", "key", "getParticleSyncKey", "generateParticleUpdateFunction", "particles", "uploadStatic", "dynamicAttributeBuffer", "staticAttributeBuffer", "keyGen", "fragment", "vertex", "wgsl", "ParticleShader", "Shader", "glProgram", "GlProgram", "vertex", "fragment", "gpuProgram", "GpuProgram", "wgsl", "Texture", "TextureStyle", "Matrix", "Color", "ParticleContainerPipe", "renderer", "adaptor", "State", "UniformGroup", "Matrix", "ParticleShader", "_renderable", "renderable", "instructionSet", "ParticleBuffer", "container", "children", "buffer", "state", "getAdjustedBlendModeBlend", "uniforms", "transformationMatrix", "color32BitToUniform", "GlParticleContainerPipe", "ParticleContainerPipe", "renderer", "GlParticleContainerAdaptor", "ExtensionType", "GpuParticleContainerAdaptor", "particleContainerPipe", "container", "renderer", "shader", "state", "buffer", "GpuParticleContainerPipe", "ParticleContainerPipe", "renderer", "GpuParticleContainerAdaptor", "ExtensionType", "updateTextBounds", "batchableSprite", "text", "texture", "bounds", "padding", "updateQuadBounds", "paddingOffset", "paddingOffsetY", "BatchableText", "BatchableSprite", "renderer", "text", "canvasText", "CanvasTextPipe", "renderer", "text", "gpuText", "newKey", "instructionSet", "batchableText", "resolution", "updateTextBounds", "BatchableText", "ExtensionType", "repetitionMap", "FillPattern", "texture", "repetition", "uid", "Matrix", "transform", "value", "parseSVGPath", "svgPath", "path", "commands", "parse", "subpaths", "currentSubPath", "lastX", "lastY", "i", "command", "type", "data", "warn", "Circle", "_Circle", "x", "y", "radius", "r2", "dx", "dy", "width", "alignment", "outerWidth", "distance", "out", "Rectangle", "circle", "Ellipse", "_Ellipse", "x", "y", "halfWidth", "halfHeight", "normx", "normy", "strokeWidth", "alignment", "strokeOuterWidth", "strokeInnerWidth", "innerHorizontal", "innerVertical", "outerHorizontal", "outerVertical", "normalizedX", "normalizedY", "innerEllipse", "outerEllipse", "out", "Rectangle", "ellipse", "squaredDistanceToLineSegment", "x", "y", "x1", "y1", "x2", "y2", "a", "b", "c", "d", "dot", "lenSq", "param", "xx", "yy", "dx", "dy", "tempRect", "tempRect2", "Polygon", "_Polygon", "points", "flat", "p", "i", "il", "area", "length", "x1", "y1", "x2", "y2", "polygon", "thisBounds", "otherBounds", "x", "y", "inside", "j", "xi", "yi", "xj", "yj", "strokeWidth", "alignment", "strokeWidthSquared", "rightWidthSquared", "leftWidthSquared", "iterationLength", "distanceSquared", "squaredDistanceToLineSegment", "sign", "out", "Rectangle", "minX", "maxX", "minY", "maxY", "n", "pointsDesc", "currentPoint", "deprecation", "isCornerWithinStroke", "pX", "pY", "cornerX", "cornerY", "radius", "strokeWidthInner", "strokeWidthOuter", "dx", "dy", "distance", "RoundedRectangle", "_RoundedRectangle", "x", "y", "width", "height", "out", "Rectangle", "rectangle", "radius2", "strokeWidth", "alignment", "innerX", "innerY", "innerWidth", "innerHeight", "rightBound", "bottomBound", "RECURSION_LIMIT", "FLT_EPSILON", "PATH_DISTANCE_EPSILON", "curveAngleToleranceEpsilon", "mAngleTolerance", "mCuspLimit", "buildAdaptiveBezier", "points", "sX", "sY", "cp1x", "cp1y", "cp2x", "cp2y", "eX", "eY", "smoothness", "smoothing", "GraphicsContextSystem", "distanceTolerance", "begin", "recursive", "x1", "y1", "x2", "y2", "x3", "y3", "x4", "y4", "level", "pi", "x12", "y12", "x23", "y23", "x34", "y34", "x123", "y123", "x234", "y234", "x1234", "y1234", "dx", "dy", "d2", "d3", "da1", "da2", "a23", "RECURSION_LIMIT", "FLT_EPSILON", "PATH_DISTANCE_EPSILON", "curveAngleToleranceEpsilon", "mAngleTolerance", "buildAdaptiveQuadratic", "points", "sX", "sY", "cp1x", "cp1y", "eX", "eY", "smoothness", "smoothing", "GraphicsContextSystem", "distanceTolerance", "begin", "recursive", "x1", "y1", "x2", "y2", "x3", "y3", "level", "pi", "x12", "y12", "x23", "y23", "x123", "y123", "dx", "dy", "d", "da", "buildArc", "points", "x", "y", "radius", "start", "end", "clockwise", "steps", "dist", "f", "t", "i", "cs", "sn", "nx", "ny", "buildArcTo", "points", "x1", "y1", "x2", "y2", "radius", "fromX", "a1", "b1", "a2", "b2", "mm", "dd", "cc", "tt", "k1", "k2", "j1", "j2", "cx", "cy", "px", "py", "qx", "qy", "startAngle", "endAngle", "buildArc", "TAU", "out", "mapToEllipse", "x", "y", "rx", "ry", "cosPhi", "sinPhi", "centerX", "centerY", "xp", "yp", "approxUnitArc", "ang1", "ang2", "a1", "a", "x1", "y1", "x2", "y2", "vectorAngle", "ux", "uy", "vx", "vy", "sign", "dot", "getArcCenter", "px", "py", "cx", "cy", "largeArcFlag", "sweepFlag", "pxp", "pyp", "rxSq", "rySq", "pxpSq", "pypSq", "radicant", "centerXp", "centerYp", "vx1", "vy1", "vx2", "vy2", "buildArcToSvg", "points", "xAxisRotation", "lambda", "ratio", "segments", "lastX", "lastY", "outCurvePoint", "i", "curve", "buildAdaptiveBezier", "roundedShapeArc", "g", "points", "radius", "vecFrom", "p", "pp", "x", "y", "len", "nx", "ny", "sharpCorner", "i", "p1", "p2", "pRadius", "p3", "v1", "v2", "angle", "radDirection", "drawDirection", "halfAngle", "cRadius", "lenOut", "cX", "cY", "startAngle", "endAngle", "roundedShapeQuadraticCurve", "smoothness", "distance", "pointLerp", "t", "numPoints", "thisPoint", "lastPoint", "nextPoint", "lastEdgeLength", "start", "lastOffsetDistance", "nextEdgeLength", "end", "nextOffsetDistance", "tempRectangle", "Rectangle", "ShapePath", "graphicsPath2D", "Bounds", "x", "y", "points", "fromX", "fromY", "radius", "startAngle", "endAngle", "counterclockwise", "buildArc", "x1", "y1", "x2", "y2", "buildArcTo", "rx", "ry", "xAxisRotation", "largeArcFlag", "sweepFlag", "buildArcToSvg", "cp1x", "cp1y", "cp2x", "cp2y", "smoothness", "currentPoly", "buildAdaptiveBezier", "smoothing", "buildAdaptiveQuadratic", "path", "transform", "shapePrimitives", "start", "instruction", "mainShape", "i", "shapePrimitive", "polygon", "mainPolygon", "closePath", "w", "h", "Circle", "close", "Polygon", "sides", "rotation", "delta", "angle", "corner", "sideLength", "internalAngle", "x0", "y0", "a1", "a2", "x3", "y3", "useQuadratic", "roundedShapeQuadraticCurve", "roundedShapeArc", "width", "height", "fillet", "maxFillet", "inset", "right", "bottom", "dir", "size", "chamfer", "radiusX", "radiusY", "Ellipse", "RoundedRectangle", "shape", "matrix", "lastShape", "lx", "ly", "t", "tempX", "bounds", "boundsRect", "GraphicsPath", "_GraphicsPath", "instructions", "signed", "uid", "parseSVGPath", "ShapePath", "path", "transform", "args", "cp2x", "cp2y", "x", "y", "smoothness", "last", "lastPoint", "Point", "cp1x", "cp1y", "currentX", "currentY", "cpx1", "cpy1", "w", "h", "radius", "points", "innerRadius", "rotation", "startAngle", "len", "delta", "polygon", "i", "r", "angle", "deep", "newGraphicsPath2D", "instruction", "matrix", "a", "b", "c", "d", "tx", "ty", "cpx2", "cpy2", "rx", "ry", "data", "adjustTransform", "warn", "out", "index", "lastInstruction", "currentMatrix", "parseSVGFloatAttribute", "svg", "id", "defaultValue", "value", "parseSVGDefinitions", "svg", "session", "definitions", "i", "definition", "j", "child", "parseLinearGradient", "parseRadialGradient", "x0", "parseSVGFloatAttribute", "y0", "x1", "y1", "gradientUnit", "gradient", "FillGradient", "k", "stop", "offset", "color", "Color", "_child", "warn", "extractSvgUrlId", "url", "match", "styleAttributes", "parseSVGStyle", "svg", "session", "style", "strokeStyle", "fillStyle", "result", "key", "attribute", "parseAttribute", "styleParts", "i", "stylePart", "value", "id", "extractSvgUrlId", "Color", "checkForNestedPattern", "subpathsWithArea", "areas", "s", "b", "largestArea", "secondArea", "smallestArea", "largestToSecondRatio", "secondToSmallestRatio", "extractSubpaths", "pathData", "part", "calculatePathArea", "coords", "numbers", "xs", "ys", "i", "minX", "maxX", "minY", "maxY", "appendSVGPath", "graphicsPath", "tempPath", "GraphicsPath", "instruction", "SVGParser", "svg", "graphicsContext", "div", "session", "GraphicsPath", "parseSVGDefinitions", "children", "fillStyle", "strokeStyle", "parseSVGStyle", "i", "child", "renderChildren", "f1", "s1", "noStyle", "x", "y", "x1", "y1", "x2", "y2", "cx", "cy", "r", "rx", "ry", "points", "pointsString", "d", "graphicsPath", "width", "height", "fillRule", "subpaths", "extractSubpaths", "hasExplicitEvenodd", "hasMultipleSubpaths", "subpathsWithArea", "subpath", "calculatePathArea", "a", "b", "checkForNestedPattern", "isMainShape", "newPath", "appendSVGPath", "isHole", "useEvenoddForGraphicsPath", "parseSVGFloatAttribute", "n", "warn", "isColorLike", "value", "Color", "isFillPattern", "FillPattern", "isFillGradient", "FillGradient", "isTexture", "Texture", "handleColorLike", "fill", "defaultStyle", "temp", "handleTexture", "handleFillPattern", "handleFillGradient", "handleFillObject", "style", "color", "toFillStyle", "objectStyle", "toStrokeStyle", "width", "alignment", "miterLimit", "cap", "join", "pixelLine", "rest", "tmpPoint", "Point", "tempMatrix", "Matrix", "_GraphicsContext", "eventemitter3_default", "uid", "GraphicsPath", "Bounds", "clone", "value", "toFillStyle", "toStrokeStyle", "style", "texture", "tint", "dx", "dy", "dw", "dh", "Color", "alpha", "path", "lastInstruction", "deprecation", "v8_0_0", "x", "y", "i", "holePath", "radius", "startAngle", "endAngle", "counterclockwise", "t", "x1", "y1", "x2", "y2", "rx", "ry", "xAxisRotation", "largeArcFlag", "sweepFlag", "cp1x", "cp1y", "cp2x", "cp2y", "smoothness", "radiusX", "radiusY", "instructions", "transformedX", "transformedY", "cpx", "cpy", "w", "h", "points", "close", "sides", "rotation", "transform", "corner", "useQuadratic", "width", "height", "fillet", "chamfer", "innerRadius", "svg", "SVGParser", "state", "angle", "a", "b", "c", "d", "bounds", "instruction", "action", "data", "alignment", "outerPadding", "_bounds", "point", "hasHit", "k", "shapes", "shape", "transformedPoint", "strokeStyle", "holes", "holeShapes", "j", "options", "destroyTextureSource", "Texture", "GraphicsContext", "_TextStyle", "eventemitter3_default", "style", "uid", "convertV7Tov8Style", "fullStyle", "key", "thisKey", "value", "GraphicsContext", "toFillStyle", "toStrokeStyle", "defaultStyle", "filterPadding", "i", "options", "destroyTextureSource", "cb", "target", "property", "newValue", "Color", "FillGradient", "FillPattern", "TextStyle", "oldStyle", "defaults", "deprecation", "v8_0_0", "color", "obj", "warn", "gradientFill", "fillGradientStops", "fills", "stop", "index", "tempBounds", "Bounds", "getPo2TextureFromSource", "image", "width", "height", "resolution", "bounds", "texture", "TexturePool", "_internalCanvas", "_internalContext", "ensureInternalCanvas", "width", "height", "DOMAdapter", "nextPow2", "checkRow", "data", "y", "x", "index", "checkColumn", "top", "bottom", "stride", "getCanvasBoundingBox", "args", "options", "canvas", "resolution", "output", "left", "right", "Rectangle", "LRU", "max", "ttl", "resetTtl", "key", "item", "keys", "bypass", "result", "x", "value", "evicted", "lru", "genericFontFamilies", "fontStringFromTextStyle", "style", "fontSizeString", "fontFamilies", "i", "fontFamily", "contextSettings", "_CanvasTextMetrics", "result", "proto", "DOMAdapter", "text", "style", "width", "height", "lines", "lineWidths", "lineHeight", "maxLineWidth", "fontProperties", "canvas", "wordWrap", "textKey", "font", "fontStringFromTextStyle", "context", "i", "lineWidth", "strokeWidth", "measurements", "letterSpacing", "useExperimentalLetterSpacing", "metrics", "metricWidth", "actualBoundingBoxLeft", "boundsWidth", "val", "line", "cache", "whiteSpace", "collapseSpaces", "collapseNewlines", "canPrependSpaces", "wordWrapWidth", "tokens", "token", "currIsBreakingSpace", "lastIsBreakingSpace", "tokenWidth", "characters", "j", "char", "lastChar", "k", "nextChar", "characterWidth", "isLastToken", "newLine", "key", "_nextChar", "_token", "breakWords", "_char", "_index", "_breakWords", "properties", "c", "segmenter", "s", "segments", "segment", "lru", "CanvasTextMetrics", "PRECISION", "getCanvasFillStyle", "fillStyle", "context", "textMetrics", "padding", "Texture", "Color", "FillPattern", "fillPattern", "pattern", "tempMatrix", "Matrix", "FillGradient", "fillGradient", "isLinear", "isLocal", "width", "height", "gradient", "isNearlyVertical", "start", "end", "center", "innerRadius", "outerCenter", "outerRadius", "ratio", "i", "stop", "globalStop", "warn", "tempRect", "Rectangle", "CanvasTextGeneratorClass", "options", "text", "style", "resolution", "padding", "measured", "CanvasTextMetrics", "width", "height", "canvasAndContext", "CanvasPool", "frame", "getCanvasBoundingBox", "canvas", "context", "font", "fontStringFromTextStyle", "lines", "lineHeight", "lineWidths", "maxLineWidth", "fontProperties", "strokeStyle", "linePositionX", "linePositionY", "passesCount", "i", "isShadowPass", "dsOffsetText", "dsOffsetShadow", "shadowOptions", "dropShadowColor", "dropShadowAlpha", "Color", "dropShadowBlur", "dropShadowDistance", "getCanvasFillStyle", "strokePadding", "linePositionYShift", "strokeWidth", "x", "y", "isStroke", "letterSpacing", "useExperimentalLetterSpacing", "currentPosition", "stringArray", "previousWidth", "currentWidth", "currentChar", "textStr", "j", "CanvasTextGenerator", "CanvasTextSystem", "_renderer", "options", "_resolution", "_style", "_textKey", "deprecation", "TextStyle", "TextureStyle", "text", "style", "textureStyle", "resolution", "frame", "canvasAndContext", "CanvasTextGenerator", "texture", "getPo2TextureFromSource", "filteredTexture", "source", "TexturePool", "textKey", "activeTexture", "filters", "currentRenderTarget", "resultTexture", "key", "ExtensionType", "Graphics", "_Graphics", "ViewContainer", "options", "GraphicsContext", "context", "roundPixels", "rest", "point", "method", "args", "value", "deep", "width", "color", "alpha", "deprecation", "v8_0_0", "strokeStyle", "fillStyle", "localUniformMSDFBit", "localUniformMSDFBitGl", "mSDFBit", "mSDFBitGl", "gpuProgram", "glProgram", "SdfShader", "Shader", "maxTextures", "uniforms", "UniformGroup", "Matrix", "compileHighShaderGpuProgram", "colorBit", "generateTextureBatchBit", "localUniformMSDFBit", "mSDFBit", "roundPixelsBit", "compileHighShaderGlProgram", "colorBitGl", "generateTextureBatchBitGl", "localUniformMSDFBitGl", "mSDFBitGl", "roundPixelsBitGl", "getBatchSamplersUniformGroup", "AbstractBitmapFont", "eventemitter3_default", "deprecation", "v8_0_0", "destroyTextures", "i", "page", "_DynamicBitmapFont", "AbstractBitmapFont", "options", "dynamicOptions", "style", "Texture", "requestedFontSize", "font", "fontStringFromTextStyle", "TextureStyle", "CanvasTextMetrics", "chars", "charList", "char", "index", "self", "pageData", "canvas", "context", "textureSource", "currentX", "currentY", "currentMaxCharHeight", "fontScale", "padding", "skipTexture", "maxTextureWidth", "maxTextureHeight", "i", "metrics", "width", "textureGlyphWidth", "height", "paddedWidth", "paddedHeight", "xAdvance", "px", "py", "frame", "Rectangle", "deprecation", "v8_0_0", "newChars", "measureCache", "first", "j", "second", "c1", "c2", "total", "amount", "textureResolution", "canvasAndContext", "CanvasPool", "resolution", "texture", "ImageSource", "stroke", "strokeThickness", "getCanvasFillStyle", "shadowOptions", "rgb", "Color", "dropShadowBlur", "dropShadowDistance", "x", "y", "fontProperties", "tx", "ty", "descent", "lineHeight", "removeShadow", "shadowBlur", "shadowOffsetX", "shadowOffsetY", "TextStyle", "DynamicBitmapFont", "getBitmapTextLayout", "chars", "style", "font", "trimEnd", "layoutData", "currentLine", "previousChar", "firstWord", "currentWord", "scale", "adjustedLetterSpacing", "adjustedWordWrapWidth", "adjustedLineHeight", "breakWords", "nextWord", "word", "start", "j", "position", "nextLine", "index", "lastChar", "checkIsOverflow", "lineWidth", "i", "char", "isEnd", "charData", "spaceWidth", "kerning", "nextCharWidth", "alignCenter", "alignRight", "alignJustify", "measurementData", "line", "offset", "width", "indy", "spaceIndex", "totalSpaces", "resolveCharacters", "chars", "result", "i", "j", "item", "startCode", "endCode", "fontCount", "BitmapFontManagerClass", "lru", "text", "style", "fontFamilyKey", "overrideFill", "Cache", "styleCopy", "fnt", "DynamicBitmapFont", "warn", "dynamicFont", "trimEnd", "bitmapFont", "id", "segments", "CanvasTextMetrics", "layoutData", "getBitmapTextLayout", "args", "options", "deprecation", "v8_0_0", "name", "textStyle", "TextStyle", "font", "flatChars", "resolveCharacters", "cacheKey", "BitmapFontManager", "BitmapTextGraphics", "Graphics", "BitmapTextPipe", "renderer", "bitmapText", "graphicsRenderable", "instructionSet", "syncWithProxy", "proxyGraphics", "context", "bitmapFont", "BitmapFontManager", "SdfShader", "chars", "CanvasTextMetrics", "style", "currentY", "bitmapTextLayout", "getBitmapTextLayout", "padding", "scale", "tx", "ty", "tint", "fontSize", "lineHeight", "linePositionYShift", "i", "line", "j", "char", "charData", "texture", "proxyRenderable", "fontFamily", "dynamicFont", "Cache", "a", "b", "c", "d", "dx", "dy", "worldScale", "fontScale", "distance", "ExtensionType", "container", "proxy", "BatchableHTMLText", "BatchableSprite", "renderer", "text", "htmlText", "HTMLTextPipe", "renderer", "htmlText", "gpuText", "newKey", "instructionSet", "batchableHTMLText", "resolution", "e", "updateTextBounds", "oldTexturePromise", "texturePromise", "renderGroup", "BatchableHTMLText", "Texture", "ExtensionType", "isSafari", "userAgent", "DOMAdapter", "nssvg", "nsxhtml", "HTMLTextRenderData", "foreignObject", "svgRoot", "styleElement", "domElement", "DOMAdapter", "extractFontFamilies", "text", "style", "fontFamily", "fontFamilies", "dedupe", "regex", "matches", "addFontFamily", "i", "match", "loadFontAsBase64", "url", "blob", "DOMAdapter", "reader", "resolve", "reject", "loadFontCSS", "style", "url", "dataSrc", "loadFontAsBase64", "FontStylePromiseCache", "getFontCss", "fontFamilies", "fontPromises", "fontFamily", "Cache", "entries", "promises", "entry", "url", "out", "face", "style", "loadFontCSS", "css", "getSVGUrl", "text", "style", "resolution", "fontCSS", "htmlTextData", "domElement", "styleElement", "svgRoot", "width", "height", "getTemporaryCanvasFromImage", "image", "resolution", "canvasAndContext", "CanvasPool", "context", "loadSVGImage", "image", "url", "delay", "resolve", "tempHTMLTextRenderData", "measureHtmlText", "text", "style", "fontStyleCSS", "htmlTextRenderData", "HTMLTextRenderData", "domElement", "styleElement", "svgRoot", "contentBounds", "doublePadding", "HTMLTextSystem", "renderer", "RendererType", "options", "text", "textKey", "promise", "texture", "activeTexture", "warn", "style", "resolution", "textureStyle", "htmlTextData", "BigPool", "HTMLTextRenderData", "fontFamilies", "extractFontFamilies", "fontCSS", "getFontCss", "measured", "measureHtmlText", "width", "height", "image", "uvSafeOffset", "svgURL", "getSVGUrl", "loadSVGImage", "isSafari", "resource", "canvasAndContext", "getTemporaryCanvasFromImage", "getPo2TextureFromSource", "CanvasPool", "texturePromise", "TexturePool", "key", "ExtensionType", "_MeshGeometry", "Geometry", "args", "options", "deprecation", "v8_0_0", "positions", "uvs", "indices", "shrinkToFit", "positionBuffer", "Buffer", "BufferUsage", "uvBuffer", "indexBuffer", "value", "MeshGeometry", "tilingBit", "tilingBitGl", "gpuProgram", "glProgram", "TilingSpriteShader", "Shader", "compileHighShaderGpuProgram", "localUniformBit", "tilingBit", "roundPixelsBit", "compileHighShaderGlProgram", "localUniformBitGl", "tilingBitGl", "roundPixelsBitGl", "tilingUniforms", "UniformGroup", "Matrix", "Texture", "width", "height", "matrix", "anchorX", "anchorY", "texture", "textureWidth", "textureHeight", "textureMatrix", "uTextureTransform", "QuadGeometry", "MeshGeometry", "setPositions", "tilingSprite", "positions", "anchorX", "anchorY", "applyMatrix", "array", "stride", "offset", "matrix", "index", "size", "a", "b", "c", "d", "tx", "ty", "x", "y", "setUvs", "tilingSprite", "uvs", "texture", "width", "height", "anchorX", "anchorY", "textureMatrix", "Matrix", "applyMatrix", "sharedQuad", "QuadGeometry", "TilingSpriteGpuData", "MeshGeometry", "TilingSpritePipe", "renderer", "State", "renderable", "tilingSpriteData", "couldBatch", "canBatch", "batchableMesh", "tilingSprite", "instructionSet", "batcher", "geometry", "BatchableMesh", "TilingSpriteShader", "shader", "localUniforms", "color32BitToUniform", "getAdjustedBlendModeBlend", "gpuData", "renderableData", "style", "setUvs", "setPositions", "texture", "_nonPowOf2wrapping", "RendererType", "ExtensionType", "_PlaneGeometry", "MeshGeometry", "args", "options", "deprecation", "v8_0_0", "total", "verts", "uvs", "indices", "verticesX", "verticesY", "sizeX", "sizeY", "i", "x", "y", "totalSub", "xpos", "ypos", "value", "value2", "value3", "value4", "PlaneGeometry", "_NineSliceGeometry", "PlaneGeometry", "options", "p", "width", "height", "_leftWidth", "_rightWidth", "_topHeight", "_bottomHeight", "_anchorX", "_anchorY", "w", "scaleW", "h", "scaleH", "scale", "anchorOffsetX", "anchorOffsetY", "uvs", "_uvw", "_uvh", "NineSliceGeometry", "NineSliceSpriteGpuData", "BatchableMesh", "NineSliceGeometry", "NineSliceSpritePipe", "renderer", "sprite", "instructionSet", "gpuSprite", "batchableSprite", "gpuData", "batchableMesh", "ExtensionType", "FilterPipe", "renderer", "filterEffect", "container", "instructionSet", "_filterEffect", "_container", "instruction", "ExtensionType", "vertex", "fragment", "source", "PassthroughFilter", "Filter", "gpuProgram", "GpuProgram", "source", "glProgram", "GlProgram", "vertex", "fragment", "tempProjectionMatrix", "Matrix", "getGlobalRenderableBounds", "renderables", "bounds", "actualMatrix", "i", "renderable", "renderGroup", "quadGeometry", "Geometry", "FilterData", "Bounds", "FilterSystem", "renderer", "UniformGroup", "BindGroup", "instruction", "filters", "filterData", "colorTextureSource", "rootResolution", "rootAntialias", "filter", "bounds", "previousFilterData", "globalResolution", "offsetX", "offsetY", "texture", "TexturePool", "Texture", "outputTexture", "lastRenderSurface", "previousBounds", "backgroundResolution", "backTexture", "x", "y", "width", "height", "input", "output", "clear", "isFinalTarget", "resolution", "offset", "filterToApply", "outputMatrix", "sprite", "data", "mappedMatrix", "worldTransform", "Matrix", "renderGroup", "PassthroughFilter", "batchUniforms", "RendererType", "renderTarget", "sourceWidth", "sourceHeight", "globalFrame", "uniforms", "outputFrame", "inputSize", "inputPixel", "inputClamp", "rootTexture", "currentIndex", "lastIndex", "prevFilterData", "getGlobalRenderableBounds", "filterFrameTransform", "inputTexture", "firstEnabled", "lastEnabled", "flip", "tempTexture", "flop", "i", "t", "viewPort", "paddingMultiplier", "padding", "antialias", "blendRequired", "enabled", "clipToViewport", "firstEnabledIndex", "lastEnabledIndex", "warn", "index", "ExtensionType"]
7
+ }