@pixi-ui-editor/runtime-pixi 0.17.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,30 +4,33 @@ PixiJS runtime that loads and renders scene documents produced by [Pixi UI Edito
4
4
 
5
5
  Consumes documents validated against [`@pixi-ui-editor/schema`](https://www.npmjs.com/package/@pixi-ui-editor/schema).
6
6
 
7
- ## Install
7
+ ## Install
8
8
 
9
9
  ```bash
10
- pnpm add @pixi-ui-editor/runtime-pixi
11
- ```
12
-
13
- ## Reparent live views
14
-
15
- Use `reparentPreservingWorld` for a live Pixi `Container` created by game code or taken from a
16
- mounted scene. It recalculates the ancestor chain instead of reading Pixi's render-pass cache, so the
17
- view does not jump even before the first frame:
18
-
19
- ```ts
20
- import { reparentPreservingWorld } from "@pixi-ui-editor/runtime-pixi";
21
-
22
- if (!reparentPreservingWorld(symbolView, bonusLayer, 0)) {
23
- // The destination parent has a singular transform, for example scale.x === 0.
24
- }
25
- ```
26
-
27
- `containerWorldMatrix`, `applyWorldTransform`, and `matchWorldTransform` expose the same live-view
28
- layer for lower-level use. A singular parent returns `false` without writing a non-finite transform.
29
- Use `NodeTransformSpace` instead when moving serialized document nodes: it additionally resolves
30
- layout profiles, anchors, Canvas scaling, and layout-managed rectangles.
10
+ pnpm add @pixi-ui-editor/runtime-pixi
11
+ ```
12
+
13
+ ## Reparent live views
14
+
15
+ Use `reparentPreservingWorld` for a live Pixi `Container` created by game code or taken from a
16
+ mounted scene. It recalculates the ancestor chain instead of reading Pixi's render-pass cache, so the
17
+ view does not jump even before the first frame:
18
+
19
+ ```ts
20
+ import { reparentPreservingWorld } from "@pixi-ui-editor/runtime-pixi";
21
+
22
+ if (!reparentPreservingWorld(symbolView, bonusLayer, 0)) {
23
+ // World transform could not be preserved: the destination parent, or the view's own current
24
+ // world matrix, is singular (for example scale.x === 0). The tree move still happened.
25
+ }
26
+ ```
27
+
28
+ `containerWorldMatrix`, `applyWorldTransform`, and `matchWorldTransform` expose the same live-view
29
+ layer for lower-level use. `applyWorldTransform` returns `false` and leaves the local transform
30
+ untouched when either the target world matrix or the current parent is singular; on its successful
31
+ branch it also clears any stale `view.skew` so it cannot shear the result.
32
+ Use `NodeTransformSpace` instead when moving serialized document nodes: it additionally resolves
33
+ layout profiles, anchors, Canvas scaling, and layout-managed rectangles.
31
34
 
32
35
  ## Spawn a preset
33
36
 
@@ -111,33 +114,33 @@ app.stage.addChild(root);
111
114
  root.resize({ width: app.screen.width, height: app.screen.height });
112
115
  ```
113
116
 
114
- Call `root.resize(...)` after the Pixi renderer changes size. It applies one uniform scale and centers
115
- the unchanged authored viewport; letterbox and pillarbox space never reveal off-viewport content.
116
- Hosts must not reproduce the fit formula or add their own viewport mask. Spawned prefab views stay
117
- unclipped because they are scene content rather than player-screen boundaries.
118
-
119
- Use `resolveViewport` for physical host measurements. It returns `null` while the host is collapsed or
120
- non-finite, preventing a transient `0×0` measurement from selecting desktop and applying a singular
121
- transform. `resolveProfileForViewport` and `fitViewportToHost` remain available as low-level primitives;
122
- passing the live profile to the former enables a five-percent breakpoint dead zone.
123
-
124
- ```ts
125
- const resolved = resolveViewport(
126
- document.settings,
127
- scene.layout.referenceViewports,
128
- host,
129
- mounted.profile,
130
- );
131
- if (resolved === null) return; // keep the last usable profile and transform
132
- if (resolved.profile !== mounted.profile) applyProfile(mounted, document, sceneId, resolved.profile);
133
- mounted.root.resize(host);
134
- ```
135
-
136
- Crossing the breakpoint does not require rebuilding or reloading assets. `SceneViewResult.profile` is
137
- the source of truth for the live tree, and `applyProfile` updates its reference viewport, Canvas scale,
138
- node transforms/styles, layout-managed children, page groups, item tables, scroll content, and fixed-grid
139
- line breaks in place. Runtime state such as the current button/page, capacity override, and scroll offset
140
- is retained; applying the already-live profile is a no-op.
117
+ Call `root.resize(...)` after the Pixi renderer changes size. It applies one uniform scale and centers
118
+ the unchanged authored viewport; letterbox and pillarbox space never reveal off-viewport content.
119
+ Hosts must not reproduce the fit formula or add their own viewport mask. Spawned prefab views stay
120
+ unclipped because they are scene content rather than player-screen boundaries.
121
+
122
+ Use `resolveViewport` for physical host measurements. It returns `null` while the host is collapsed or
123
+ non-finite, preventing a transient `0×0` measurement from selecting desktop and applying a singular
124
+ transform. `resolveProfileForViewport` and `fitViewportToHost` remain available as low-level primitives;
125
+ passing the live profile to the former enables a five-percent breakpoint dead zone.
126
+
127
+ ```ts
128
+ const resolved = resolveViewport(
129
+ document.settings,
130
+ scene.layout.referenceViewports,
131
+ host,
132
+ mounted.profile,
133
+ );
134
+ if (resolved === null) return; // keep the last usable profile and transform
135
+ if (resolved.profile !== mounted.profile) applyProfile(mounted, document, sceneId, resolved.profile);
136
+ mounted.root.resize(host);
137
+ ```
138
+
139
+ Crossing the breakpoint does not require rebuilding or reloading assets. `SceneViewResult.profile` is
140
+ the source of truth for the live tree, and `applyProfile` updates its reference viewport, Canvas scale,
141
+ node transforms/styles, layout-managed children, page groups, item tables, scroll content, and fixed-grid
142
+ line breaks in place. Runtime state such as the current button/page, capacity override, and scroll offset
143
+ is retained; applying the already-live profile is a no-op.
141
144
 
142
145
  ## Localization
143
146
 
@@ -8,7 +8,8 @@ export declare function containerWorldMatrix(view: Container): Matrix;
8
8
  /**
9
9
  * Ставит локальный transform `view` так, чтобы его мировой transform стал равен `world`,
10
10
  * в системе координат текущего родителя `view`.
11
- * `false` — родитель необратим (нулевой масштаб), transform не изменён.
11
+ * `false` — сохранить мировой transform не удалось (вырожден сам `world` либо родитель `view`),
12
+ * локальный transform при этом не изменён, чтобы вызывающий мог откатиться по снимку.
12
13
  */
13
14
  export declare function applyWorldTransform(view: Container, world: Matrix): boolean;
14
15
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"liveTransform.d.ts","sourceRoot":"","sources":["../src/liveTransform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAiB5C;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAW5D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CA8B3E;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAStG;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAE/E"}
1
+ {"version":3,"file":"liveTransform.d.ts","sourceRoot":"","sources":["../src/liveTransform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAiB5C;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAW5D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAsC3E;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAStG;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAE/E"}
@@ -26,9 +26,15 @@ export function containerWorldMatrix(view) {
26
26
  /**
27
27
  * Ставит локальный transform `view` так, чтобы его мировой transform стал равен `world`,
28
28
  * в системе координат текущего родителя `view`.
29
- * `false` — родитель необратим (нулевой масштаб), transform не изменён.
29
+ * `false` — сохранить мировой transform не удалось (вырожден сам `world` либо родитель `view`),
30
+ * локальный transform при этом не изменён, чтобы вызывающий мог откатиться по снимку.
30
31
  */
31
32
  export function applyWorldTransform(view, world) {
33
+ const worldAffine = affineFromMatrix(world);
34
+ // Вырожденная исходная мировая матрица (узел уже побывал под родителем с нулевым масштабом):
35
+ // любое разложение назад в локальный transform — молчаливый мусор, а не сохранение картинки.
36
+ if (invertAffine(worldAffine) === undefined)
37
+ return false;
32
38
  const parentWorld = view.parent === null ? undefined : affineFromMatrix(containerWorldMatrix(view.parent));
33
39
  const source = {
34
40
  x: view.position.x,
@@ -43,11 +49,15 @@ export function applyWorldTransform(view, world) {
43
49
  pivotX: view.pivot.x,
44
50
  pivotY: view.pivot.y,
45
51
  };
46
- const preserved = transformRelativeToParent(affineFromMatrix(world), parentWorld, source);
52
+ const preserved = transformRelativeToParent(worldAffine, parentWorld, source);
47
53
  if (preserved !== undefined) {
48
54
  view.position.set(preserved.x, preserved.y);
49
55
  view.scale.set(preserved.scaleX, preserved.scaleY);
50
56
  view.rotation = preserved.rotation;
57
+ // Разложение схемы по построению без skew, а итоговая локальная матрица — ровно
58
+ // `inverseParent * world`. Уже стоявший на вьюхе skew в неё не входит, иначе он лёг бы поверх
59
+ // записанных значений и перекосил узел (fallback-ветка чистит его сама через setFromMatrix).
60
+ view.skew.set(0, 0);
51
61
  return true;
52
62
  }
53
63
  const inverseParent = parentWorld === undefined ? IDENTITY_TRANSFORM : invertAffine(parentWorld);
@@ -55,7 +65,7 @@ export function applyWorldTransform(view, world) {
55
65
  return false;
56
66
  // The shared schema decomposition rejected an otherwise valid affine transform because it needs
57
67
  // skew. Pixi can represent that final branch, so let its own decomposition retain it exactly.
58
- view.setFromMatrix(matrixFromAffine(multiplyAffine(inverseParent, affineFromMatrix(world))));
68
+ view.setFromMatrix(matrixFromAffine(multiplyAffine(inverseParent, worldAffine)));
59
69
  return true;
60
70
  }
61
71
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"liveTransform.js","sourceRoot":"","sources":["../src/liveTransform.ts"],"names":[],"mappings":"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","sourcesContent":["import { Container, Matrix } from \"pixi.js\";\nimport {\n IDENTITY_TRANSFORM,\n invertAffine,\n multiplyAffine,\n transformRelativeToParent,\n type AffineTransform,\n} from \"./transformSpace.js\";\n\nfunction affineFromMatrix(matrix: Matrix): AffineTransform {\n return { a: matrix.a, b: matrix.b, c: matrix.c, d: matrix.d, tx: matrix.tx, ty: matrix.ty };\n}\n\nfunction matrixFromAffine(matrix: AffineTransform): Matrix {\n return new Matrix(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty);\n}\n\n/**\n * Мировая матрица узла, пересчитанная обходом предков.\n * Не опирается на кэш `worldTransform`, который Pixi обновляет только в рендер-проходе, — поэтому\n * корректна и до первого тика.\n */\nexport function containerWorldMatrix(view: Container): Matrix {\n const chain: Container[] = [];\n for (let current: Container | null = view; current !== null; current = current.parent) chain.push(current);\n\n let world = IDENTITY_TRANSFORM;\n for (let index = chain.length - 1; index >= 0; index -= 1) {\n const current = chain[index]!;\n current.updateLocalTransform();\n world = multiplyAffine(world, affineFromMatrix(current.localTransform));\n }\n return matrixFromAffine(world);\n}\n\n/**\n * Ставит локальный transform `view` так, чтобы его мировой transform стал равен `world`,\n * в системе координат текущего родителя `view`.\n * `false` — родитель необратим (нулевой масштаб), transform не изменён.\n */\nexport function applyWorldTransform(view: Container, world: Matrix): boolean {\n const parentWorld = view.parent === null ? undefined : affineFromMatrix(containerWorldMatrix(view.parent));\n const source = {\n x: view.position.x,\n y: view.position.y,\n width: 1,\n height: 1,\n scaleX: view.scale.x,\n scaleY: view.scale.y,\n rotation: view.rotation,\n // Schema pivots are normalized and multiplied by width/height in the shared kernel. Using a\n // unit rectangle bridges Pixi's pixel pivot without exposing fake dimensions to callers.\n pivotX: view.pivot.x,\n pivotY: view.pivot.y,\n };\n const preserved = transformRelativeToParent(affineFromMatrix(world), parentWorld, source);\n if (preserved !== undefined) {\n view.position.set(preserved.x, preserved.y);\n view.scale.set(preserved.scaleX, preserved.scaleY);\n view.rotation = preserved.rotation;\n return true;\n }\n\n const inverseParent = parentWorld === undefined ? IDENTITY_TRANSFORM : invertAffine(parentWorld);\n if (inverseParent === undefined) return false;\n\n // The shared schema decomposition rejected an otherwise valid affine transform because it needs\n // skew. Pixi can represent that final branch, so let its own decomposition retain it exactly.\n view.setFromMatrix(matrixFromAffine(multiplyAffine(inverseParent, affineFromMatrix(world))));\n return true;\n}\n\n/**\n * Переносит `view` под `newParent` (опционально на позицию `index` среди его детей),\n * не двигая `view` на экране. Перенос в дереве выполняется всегда; `false` — мировой transform\n * сохранить не удалось.\n */\nexport function reparentPreservingWorld(view: Container, newParent: Container, index?: number): boolean {\n const world = containerWorldMatrix(view);\n view.parent?.removeChild(view);\n if (index === undefined) {\n newParent.addChild(view);\n } else {\n newParent.addChildAt(view, Math.min(newParent.children.length, Math.max(0, index)));\n }\n return applyWorldTransform(view, world);\n}\n\n/** Оставляет `view` под текущим родителем, но совмещает его мировой transform с `source`. */\nexport function matchWorldTransform(view: Container, source: Container): boolean {\n return applyWorldTransform(view, containerWorldMatrix(source));\n}\n"]}
1
+ {"version":3,"file":"liveTransform.js","sourceRoot":"","sources":["../src/liveTransform.ts"],"names":[],"mappings":"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","sourcesContent":["import { Container, Matrix } from \"pixi.js\";\r\nimport {\r\n IDENTITY_TRANSFORM,\r\n invertAffine,\r\n multiplyAffine,\r\n transformRelativeToParent,\r\n type AffineTransform,\r\n} from \"./transformSpace.js\";\r\n\r\nfunction affineFromMatrix(matrix: Matrix): AffineTransform {\r\n return { a: matrix.a, b: matrix.b, c: matrix.c, d: matrix.d, tx: matrix.tx, ty: matrix.ty };\r\n}\r\n\r\nfunction matrixFromAffine(matrix: AffineTransform): Matrix {\r\n return new Matrix(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty);\r\n}\r\n\r\n/**\r\n * Мировая матрица узла, пересчитанная обходом предков.\r\n * Не опирается на кэш `worldTransform`, который Pixi обновляет только в рендер-проходе, — поэтому\r\n * корректна и до первого тика.\r\n */\r\nexport function containerWorldMatrix(view: Container): Matrix {\r\n const chain: Container[] = [];\r\n for (let current: Container | null = view; current !== null; current = current.parent) chain.push(current);\r\n\r\n let world = IDENTITY_TRANSFORM;\r\n for (let index = chain.length - 1; index >= 0; index -= 1) {\r\n const current = chain[index]!;\r\n current.updateLocalTransform();\r\n world = multiplyAffine(world, affineFromMatrix(current.localTransform));\r\n }\r\n return matrixFromAffine(world);\r\n}\r\n\r\n/**\r\n * Ставит локальный transform `view` так, чтобы его мировой transform стал равен `world`,\r\n * в системе координат текущего родителя `view`.\r\n * `false` — сохранить мировой transform не удалось (вырожден сам `world` либо родитель `view`),\r\n * локальный transform при этом не изменён, чтобы вызывающий мог откатиться по снимку.\r\n */\r\nexport function applyWorldTransform(view: Container, world: Matrix): boolean {\r\n const worldAffine = affineFromMatrix(world);\r\n // Вырожденная исходная мировая матрица (узел уже побывал под родителем с нулевым масштабом):\r\n // любое разложение назад в локальный transform — молчаливый мусор, а не сохранение картинки.\r\n if (invertAffine(worldAffine) === undefined) return false;\r\n const parentWorld = view.parent === null ? undefined : affineFromMatrix(containerWorldMatrix(view.parent));\r\n const source = {\r\n x: view.position.x,\r\n y: view.position.y,\r\n width: 1,\r\n height: 1,\r\n scaleX: view.scale.x,\r\n scaleY: view.scale.y,\r\n rotation: view.rotation,\r\n // Schema pivots are normalized and multiplied by width/height in the shared kernel. Using a\r\n // unit rectangle bridges Pixi's pixel pivot without exposing fake dimensions to callers.\r\n pivotX: view.pivot.x,\r\n pivotY: view.pivot.y,\r\n };\r\n const preserved = transformRelativeToParent(worldAffine, parentWorld, source);\r\n if (preserved !== undefined) {\r\n view.position.set(preserved.x, preserved.y);\r\n view.scale.set(preserved.scaleX, preserved.scaleY);\r\n view.rotation = preserved.rotation;\r\n // Разложение схемы по построению без skew, а итоговая локальная матрица — ровно\r\n // `inverseParent * world`. Уже стоявший на вьюхе skew в неё не входит, иначе он лёг бы поверх\r\n // записанных значений и перекосил узел (fallback-ветка чистит его сама через setFromMatrix).\r\n view.skew.set(0, 0);\r\n return true;\r\n }\r\n\r\n const inverseParent = parentWorld === undefined ? IDENTITY_TRANSFORM : invertAffine(parentWorld);\r\n if (inverseParent === undefined) return false;\r\n\r\n // The shared schema decomposition rejected an otherwise valid affine transform because it needs\r\n // skew. Pixi can represent that final branch, so let its own decomposition retain it exactly.\r\n view.setFromMatrix(matrixFromAffine(multiplyAffine(inverseParent, worldAffine)));\r\n return true;\r\n}\r\n\r\n/**\r\n * Переносит `view` под `newParent` (опционально на позицию `index` среди его детей),\r\n * не двигая `view` на экране. Перенос в дереве выполняется всегда; `false` — мировой transform\r\n * сохранить не удалось.\r\n */\r\nexport function reparentPreservingWorld(view: Container, newParent: Container, index?: number): boolean {\r\n const world = containerWorldMatrix(view);\r\n view.parent?.removeChild(view);\r\n if (index === undefined) {\r\n newParent.addChild(view);\r\n } else {\r\n newParent.addChildAt(view, Math.min(newParent.children.length, Math.max(0, index)));\r\n }\r\n return applyWorldTransform(view, world);\r\n}\r\n\r\n/** Оставляет `view` под текущим родителем, но совмещает его мировой transform с `source`. */\r\nexport function matchWorldTransform(view: Container, source: Container): boolean {\r\n return applyWorldTransform(view, containerWorldMatrix(source));\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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"}
package/dist/scene.js CHANGED
@@ -237,7 +237,8 @@ function wireSpineConnectors(nodes, nodeViews) {
237
237
  * следующая не завела собственный обход с чуть другой областью видимости.
238
238
  *
239
239
  * Стрелки подключаются только в runtime-сцене: на authoring-канвасе контрол инертен, как и клик по
240
- * самой точке пагинатора. Вместимость таблицы, наоборот, видна и в редакторе это не интерактивность.
240
+ * самой точке пагинатора. Вместимость таблицы и видимость ноды-фона активной страницы пагинатора,
241
+ * наоборот, видны и в редакторе — это не интерактивность.
241
242
  */
242
243
  function wireNodeReferences(nodes, nodeViews, interaction) {
243
244
  const arrowView = (nodeId) => {
@@ -249,8 +250,10 @@ function wireNodeReferences(nodes, nodeViews, interaction) {
249
250
  if (node.type === "item-table" && view instanceof ItemTableNodeView) {
250
251
  view.setItems((node.items ?? []).map((itemId) => nodeViews.get(itemId)));
251
252
  }
252
- else if (node.type === "pagination" && view instanceof PaginationNodeView && interaction === "runtime") {
253
- view.setArrows({ previous: arrowView(node.prevButtonNodeId), next: arrowView(node.nextButtonNodeId) });
253
+ else if (node.type === "pagination" && view instanceof PaginationNodeView) {
254
+ if (interaction === "runtime")
255
+ view.setArrows({ previous: arrowView(node.prevButtonNodeId), next: arrowView(node.nextButtonNodeId) });
256
+ view.setActiveBackground(node.activeBackgroundNodeId === undefined ? undefined : nodeViews.get(node.activeBackgroundNodeId));
254
257
  }
255
258
  else if (node.type === "page-group" && view instanceof PageGroupNodeView && interaction === "runtime") {
256
259
  view.setArrows({ up: arrowView(node.pageUpButtonNodeId), down: arrowView(node.pageDownButtonNodeId) });
package/dist/scene.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"scene.js","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,qBAAqB,EAAiJ,MAAM,wBAAwB,CAAC;AAC3R,OAAO,EAAE,SAAS,EAAwB,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAwB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,wBAAwB,EAAE,uBAAuB,EAAmB,MAAM,aAAa,CAAC;AACvI,OAAO,EAAE,QAAQ,EAA6B,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACtI,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAwB,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAiC,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAiB,MAAM,gBAAgB,CAAC;AAgCjE,MAAM,uBAAuB,GAAG,IAAI,OAAO,EAAiD,CAAC;AAE7F,SAAS,sBAAsB,CAAC,QAAyB,EAAE,IAAY;IACrE,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC;IACjF,OAAO,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;AACpE,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,cAAc,CAC5B,QAAyB,EACzB,OAAe,EACf,OAAwB,EACxB,OAA8B;IAE9B,oBAAoB,EAAE,CAAC;IACvB,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACxF,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IAE5E,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,2CAA2C,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC/C,MAAM,gBAAgB,GAA8B,EAAE,CAAC;IACvD,sGAAsG;IACtG,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAEvG,6FAA6F;IAC7F,8EAA8E;IAC9E,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5D,MAAM,mBAAmB,GAAG,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrE,MAAM,WAAW,GAAG,cAAc,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,oBAAoB,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;IAEzE,wFAAwF;IACxF,MAAM,KAAK,GAAG,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAEvE,MAAM,UAAU,GAAG,CAAC,QAAoB,EAAa,EAAE;QACrD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtE,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,UAAsB,EAAY,EAAE;YACrE,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAEnC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,8BAA8B,MAAM,IAAI,CAAC,CAAC;YAC7E,CAAC;YAED,MAAM,QAAQ,GAAG,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACxD,MAAM,SAAS,GAAG,wBAAwB,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YAC3E,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC,QAAQ,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;YACnU,IAAI,aAAa,CAAC,IAAI,CAAC;gBAAE,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;YAC3E,+FAA+F;YAC/F,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;YACvC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC7B,IAAI,IAAI,YAAY,uBAAuB;gBAAE,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEzE,+FAA+F;YAC/F,uGAAuG;YACvG,8FAA8F;YAC9F,iGAAiG;YACjG,oGAAoG;YACpG,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrF,MAAM,QAAQ,GAAG,UAAU,EAAE,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,0BAA0B,CAAqB,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACtI,8FAA8F;YAC9F,0FAA0F;YAC1F,gGAAgG;YAChG,+FAA+F;YAC/F,sFAAsF;YACtF,8FAA8F;YAC9F,oCAAoC;YACpC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI;gBACtC,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,QAAQ,KAAK,SAAS;oBACtB,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE;oBAC5D,CAAC,CAAC,UAAU,EAAE,IAAI,KAAK,YAAY;wBACjC,CAAC,CAAC,UAAU;wBACZ,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;YAC7D,KAAK,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC5D,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACzC,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;gBAChD,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,YAAY,mBAAmB,EAAE,CAAC;oBAC1F,MAAM,UAAU,GAAG,IAAI,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;oBAChE,eAAe,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;oBACtD,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;gBAClC,CAAC;qBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,YAAY,kBAAkB,EAAE,CAAC;oBACxG,MAAM,UAAU,GAAG,IAAI,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;oBAChE,oFAAoF;oBACpF,gFAAgF;oBAChF,MAAM,GAAG,GAAG,uBAAuB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC;oBAClE,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;oBAC9E,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;gBACjC,CAAC;qBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,YAAY,iBAAiB,EAAE,CAAC;oBACtG,mFAAmF;oBACnF,2FAA2F;oBAC3F,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC;oBAClD,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;oBAC7C,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAC3B,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;oBAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;oBACpK,IAAI,QAAQ,CAAC,UAAU,KAAK,UAAU,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,eAAe,KAAK,CAAC,IAAI,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;wBAC/K,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;wBACrD,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,YAAY,mBAAmB;4BAAE,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;oBACrG,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QAClC,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YAC3C,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC1C,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,cAAc,IAAI,WAAW,KAAK,SAAS,CAAC,CAAC;IAChH,uBAAuB,CAAC,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IACxD,2FAA2F;IAC3F,sEAAsE;IACtE,MAAM,YAAY,GAAG,IAAI,iBAAiB,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7F,kBAAkB,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3C,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC5C,kBAAkB,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IACxD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAE3D,qGAAqG;AACrG,SAAS,kBAAkB,CAAC,IAAyB,EAAE,IAA8C,EAAE,OAAwB,EAAE,SAAsC,EAAE,SAAyC;IAChN,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,KAAK,KAAK,qBAAqB;YAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7D,CAAC;IACD,MAAM,QAAQ,GAAG,0BAA0B,CAAqB,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/E,KAAK,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,YAAY,QAAQ,IAAI,SAAS,CAAC,MAAM,YAAY,mBAAmB,EAAE,CAAC;YAChH,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,KAAK,UAAU,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,eAAe,KAAK,CAAC,IAAI,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC/K,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACrD,IAAI,SAAS,KAAK,SAAS;gBAAE,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAqB,EAAE,QAAyB,EAAE,OAAe,EAAE,OAAwB;IACtH,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO;QAAE,OAAO;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IAC5E,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,2CAA2C,CAAC,CAAC;IAEvG,MAAM,KAAK,GAAG,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAA8B,EAAE,CAAC,SAAS,YAAY,aAAa,IAAI,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAC1K,KAAK,MAAM,KAAK,IAAI,YAAY;QAAE,KAAK,CAAC,oBAAoB,GAAG,KAAK,CAAC;IAErE,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5D,MAAM,mBAAmB,GAAG,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,oBAAoB,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;IAEzE,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,UAAsB,EAAQ,EAAE;QAClE,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,IAAI,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO;QACzD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrF,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;QAEvN,MAAM,SAAS,GAAG,wBAAwB,CAAC,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACzG,MAAM,QAAQ,GAAG,UAAU,EAAE,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,0BAA0B,CAAqB,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtI,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI;YACtC,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,QAAQ,KAAK,SAAS;gBACtB,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE;gBAC5D,CAAC,CAAC,UAAU,EAAE,IAAI,KAAK,YAAY;oBACjC,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;QAC7D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ;YAAE,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACpE,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,IAAI,QAAQ,YAAY,mBAAmB;YAAE,kBAAkB,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACrJ,CAAC,CAAC;IAEF,IAAI,CAAC;QACH,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,WAAW;YAAE,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC/E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAqC,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3D,CAAC;YAAS,CAAC;QACT,KAAK,MAAM,KAAK,IAAI,YAAY;YAAE,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC;IACtE,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAwB,EAAE,SAAyC;IAC9F,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;YAAE,SAAS;QACpC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,CAAC,IAAI,YAAY,aAAa,CAAC;YAAE,SAAS;QAC/C,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YACnE,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YACrD,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CAAC,KAAwB,EAAE,SAAyC,EAAE,WAAiC;IAChI,MAAM,SAAS,GAAG,CAAC,MAA0B,EAA+B,EAAE;QAC5E,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtE,OAAO,IAAI,YAAY,cAAc,IAAI,IAAI,YAAY,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACnG,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,YAAY,iBAAiB,EAAE,CAAC;YACpE,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,YAAY,kBAAkB,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACzG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACzG,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,YAAY,iBAAiB,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACxG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,KAAwB,EAAE,SAAyC;IAC7F,MAAM,OAAO,GAAG,IAAI,GAAG,EAA8B,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,SAAS;QACnE,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,CAAC,IAAI,YAAY,gBAAgB,CAAC;YAAE,SAAS;QAClD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC/B,IAAI,CAAC,OAAO;oBAAE,OAAO;gBACrB,KAAK,MAAM,KAAK,IAAI,KAAK;oBAAE,IAAI,KAAK,KAAK,IAAI;wBAAE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACzE,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAe,EAAE,IAAY,EAAE,OAAwB,EAAE,UAAuB,EAAE,UAAmB,EAAE,MAAyB,EAAE,mBAAyC;IACxM,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAC3E,IAAI,CAAC,CAAC,IAAI,YAAY,QAAQ,CAAC;QAAE,OAAO;IACxC,IAAI,IAAI,YAAY,aAAa;QAAE,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;IAC/E,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,IAAI,MAAM,KAAK,SAAS,IAAI,gBAAgB,CAAC,MAAM,CAAC,IAAI,YAAY,IAAI,IAAI,IAAI,OAAQ,IAAiC,CAAC,UAAU,KAAK,UAAU;QAAG,IAAgG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC9S,IAAI,UAAU,KAAK,SAAS,IAAI,aAAa,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,MAAM,YAAY,mBAAmB,EAAE,CAAC;QACxG,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;SAAM,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,KAAK,aAAa,IAAI,IAAI,CAAC,MAAM,YAAY,mBAAmB,EAAE,CAAC;QACvH,MAAM,GAAG,GAAG,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC;QAC7D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5E,CAAC;SAAM,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,YAAY,iBAAiB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAChJ,mGAAmG;QACnG,gGAAgG;QAChG,8FAA8F;QAC9F,mFAAmF;QACnF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,eAAe,CAAC,IAAe,EAAE,IAAY,EAAE,OAAwB,EAAE,SAA8B;IACrH,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAChI,IAAI,IAAI,YAAY,QAAQ;QAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACvH,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,sBAAsB,CAAC,IAAe,EAAE,YAAoB;IAC1E,MAAM,UAAU,GAAG,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,KAAK,MAAM,OAAO,IAAI,UAAU;YAAE,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IACD,gGAAgG;IAChG,qFAAqF;IACrF,MAAM,KAAK,GAAG,CAAC,IAAe,EAAQ,EAAE;QACtC,IAAI,IAAI,YAAY,uBAAuB;YAAE,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QAChF,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;YAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,oBAAoB,CAAC,QAAyB,EAAE,KAAY;IAC1E,OAAO,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC;AACtD,CAAC;AAID,SAAS,WAAW,CAAC,QAAyB,EAAE,QAAgB,EAAE,aAAa,GAA4B,EAAE;IAC3G,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IAC/E,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,QAAQ,2CAA2C,CAAC,CAAC;IAC1G,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3H,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,IAAI,cAAc,EAAE,CAAC;IAChE,MAAM,QAAQ,GAAiD;QAC7D,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QAClG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;QAC5K,GAAG,CAAC,aAAa,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,eAAe,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACjI,GAAG,CAAC,aAAa,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,eAAe,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,CAAC;KAClI,CAAC;IACF,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACnC,MAAM,KAAK,GAAU,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC7O,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AACjG,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,eAAe,CAAC,QAAyB,EAAE,QAAgB,EAAE,OAAwB,EAAE,OAA8B,EAAE,aAAa,GAA4B,EAAE;IAChL,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjE,OAAO,EAAE,GAAG,cAAc,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,CAAC;AACxJ,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAyB,EAAE,QAAgB,EAAE,OAAwB,EAAE,cAA+B,EAAE,OAAsI,EAAE,aAAa,GAA4B,EAAE;IAC9T,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjE,OAAO,EAAE,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,CAAC;AAC7K,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAyB,EACzB,OAAe,EACf,OAAwB,EACxB,cAA+B,EAC/B,OAAgK;IAEhK,yGAAyG;IACzG,0GAA0G;IAC1G,wFAAwF;IACxF,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;IACjC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC/D,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,CAAC;QAClM,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC;QACjE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,CAAC;QAC/D,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,CAAC;KAC5E,CAAC,CAAC;IACH,OAAO,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;AACpO,CAAC","sourcesContent":["import { type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { createStableId, isLayoutGroup, isParticleEffect, resolveLayoutGroupSettings, resolveOwnerNodeGraph, type EffectDefinition, type GridLayoutSettings, type LayoutProfileId, type ProjectDocument, type Scene, type SpineReferenceFrame, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container, Texture, type Ticker } from \"pixi.js\";\r\nimport { loadSceneSpines } from \"./assets/spine.js\";\r\nimport { loadSceneTextures, type FileUrlResolver } from \"./assets/textures.js\";\r\nimport { loadSceneFonts } from \"./assets/fonts.js\";\r\nimport { loadSceneBitmapFonts } from \"./assets/bitmapFonts.js\";\r\nimport type { SceneAssetCache } from \"./assets/cache.js\";\r\nimport { getCanvasLogicalSize, getCanvasScale, resolveAnchoredTransform, resolveProfileTransform, type LayoutSize } from \"./layout.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./views/NodeView.js\";\r\nimport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\r\nimport { createNodeView } from \"./views/createNodeView.js\";\r\nimport { applyLayoutGroup, applyLayoutItem, createGridLineBreak, initializePixiLayout, LayoutItemContainer } from \"./layoutGroups.js\";\r\nimport { LayoutGroupNodeView } from \"./views/basic.js\";\r\nimport { PageItemContainer } from \"./pageGroup.js\";\r\nimport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\r\nimport { PaginationNodeView, type PaginationArrow } from \"./views/PaginationNodeView.js\";\r\nimport { ItemTableNodeView } from \"./views/ItemTableNodeView.js\";\r\nimport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\r\nimport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\r\nimport { ScrollItemContainer } from \"./scrollView.js\";\r\nimport { ScrollViewNodeView } from \"./views/ScrollViewNodeView.js\";\r\nimport { SpineNodeView } from \"./views/SpineNodeView.js\";\r\nimport { ParticleEmitterNodeView } from \"./views/ParticleEmitterNodeView.js\";\r\nimport { SceneLocalization, type SceneLocalizationOptions } from \"./localization.js\";\r\nimport { SceneViewport } from \"./SceneViewport.js\";\r\nimport { createSceneAudio, type AudioBus } from \"./audio/bus.js\";\r\n\r\nexport type BuildSceneViewOptions = {\r\n /** Explicit: an editor canvas must pass \"authoring\", Preview and the consuming app \"runtime\". */\r\n interaction: SceneInteractionMode;\r\n textures?: ReadonlyMap<string, Texture>;\r\n spines?: ReadonlyMap<string, SkeletonData>;\r\n fonts?: ReadonlyMap<string, string>;\r\n bitmapFonts?: ReadonlyMap<string, string>;\r\n /**\r\n * Шина звуковых событий (обычно `createRuntimeAudio(...)`). Без неё сцена не публикует звуковые\r\n * события вовсе — ровно так строится инертный authoring-канвас редактора.\r\n */\r\n audio?: AudioBus;\r\n /**\r\n * The host's own Application ticker, driving self-updating content such as Spine skeletons.\r\n * Without it they fall back to `Ticker.shared`, which runs a second rAF loop independent of the\r\n * renderer that draws them — see the same rule as `updateParticleEmitters`.\r\n */\r\n ticker?: Ticker;\r\n /** Called after Yoga changes a managed rectangle; authoring hosts use it to refresh overlays. */\r\n onLayout?: () => void;\r\n /**\r\n * Начальное состояние локализации. Опция необязательна: при наличии `Text.textKey` base locale\r\n * каталога применяется и без неё, а документ без ключей выглядит ровно как раньше.\r\n */\r\n localization?: SceneLocalizationOptions;\r\n /** Internal host boundary override: prefab views are spawnable content, not screen viewports. */\r\n clipToViewport?: boolean;\r\n};\r\n\r\nexport type SceneViewResult = { root: SceneViewport; nodeViews: Map<string, Container>; localization: SceneLocalization; readonly profile: LayoutProfileId };\nconst particleEmitterRegistry = new WeakMap<Container, readonly ParticleEmitterNodeView[]>();\r\n\r\nfunction spineReferenceFrameFor(document: ProjectDocument, node: UINode): SpineReferenceFrame | undefined {\r\n if (node.type !== \"spine\") return undefined;\r\n const asset = document.assets.find((candidate) => candidate.id === node.assetId);\r\n return asset?.type === \"spine\" ? asset.referenceFrame : undefined;\r\n}\r\n\r\n/** Builds a PixiJS display tree for a scene without depending on DOM or editor state. */\r\nexport function buildSceneView(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n profile: LayoutProfileId,\r\n options: BuildSceneViewOptions,\r\n): SceneViewResult {\r\n initializePixiLayout();\r\n const { interaction, textures, spines, fonts, bitmapFonts, ticker, onLayout } = options;\r\n const scene = document.scenes.find((candidate) => candidate.id === sceneId);\r\n\r\n if (scene === undefined) {\r\n throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n }\r\n\r\n const nodeViews = new Map<string, Container>();\r\n const particleEmitters: ParticleEmitterNodeView[] = [];\r\n // Резолв «id ассета → имя звука» живёт здесь: вьюхи знают только id, а документ — только эта функция.\r\n const sceneAudio = options.audio === undefined ? undefined : createSceneAudio(document, options.audio);\r\n\r\n // Materialized prefab children use instance-scoped IDs, so authoring and runtime can address\r\n // multiple instances independently without changing canonical definition IDs.\r\n const screenSize = scene.layout.referenceViewports[profile];\r\n const referenceResolution = scene.layout.preferredViewports[profile];\r\n const canvasScale = getCanvasScale(screenSize, referenceResolution);\r\n const canvasSize = getCanvasLogicalSize(screenSize, referenceResolution);\r\n\r\n // Единый резолвер иерархии: тот же граф, что видит редактор, включая вложенные пресеты.\r\n const owner = resolveOwnerNodeGraph(document, scene);\r\n const prefabIds = new Set(document.prefabs.map((prefab) => prefab.id));\r\n\r\n const buildOwner = (rootSize: LayoutSize): Container => {\r\n const nodesById = new Map(owner.nodes.map((node) => [node.id, node]));\r\n\r\n const buildNode = (nodeId: string, parentSize: LayoutSize): NodeView => {\r\n const node = nodesById.get(nodeId);\r\n\r\n if (node === undefined) {\r\n throw new Error(`Scene '${sceneId}' references missing node '${nodeId}'.`);\r\n }\r\n\r\n const resolved = resolveProfileTransform(node, profile);\r\n const transform = resolveAnchoredTransform(resolved.transform, parentSize);\r\n const view = createNodeView(node, interaction, textures, spines, (prefabId) => prefabIds.has(prefabId), fonts, sceneAudio, node.type === \"particle-emitter\" ? document.effects.find((effect) => effect.id === node.effectId && isParticleEffect(effect)) : undefined, spineReferenceFrameFor(document, node), ticker, bitmapFonts);\r\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, parentSize);\r\n // Yoga owns only the group's inner layoutContent; the outer NodeView keeps authored transform.\r\n view.update(node, profile, parentSize);\r\n nodeViews.set(node.id, view);\r\n if (view instanceof ParticleEmitterNodeView) particleEmitters.push(view);\r\n\r\n // Прямые дети корня сцены разрешают якоря относительно логического Canvas, а не размера корня.\r\n // Прямой ребёнок grid-layout (сам `node` здесь) не владеет своим отрисованным размером: Unity-подобная\r\n // фиксированная ячейка полностью переопределяет authored transform (см. applyLayoutItem). Его\r\n // собственным потомкам нужен именно cellWidth/cellHeight, а не anchor-resolved authored-размер —\r\n // иначе они не отслеживают изменение Cell width/height и якорятся относительно устаревшего размера.\r\n const gridParent = node.parentId === null ? undefined : nodesById.get(node.parentId);\r\n const gridCell = gridParent?.type === \"grid-layout\" ? resolveLayoutGroupSettings<GridLayoutSettings>(gridParent, profile) : undefined;\r\n // Та же логика для прямого ребёнка page-group (страницы): `PageItemContainer`/`updateManaged`\r\n // растягивают её на весь resolved rectangle группы независимо от собственных anchors ноды\r\n // (см. NodeView.applyResolvedTransform, managedByLayout). Здесь `node` — сама страница, поэтому\r\n // это переопределённый размер, который она фактически получит, — `parentSize`, уже разрешённый\r\n // как rectangle page-group. Без этой ветки дети страницы якорились бы относительно её\r\n // anchor-resolved authored-размера, который может расходиться с фактическим rectangle группы,\r\n // особенно в другом layout-профиле.\r\n const childSize = node.parentId === null\r\n ? rootSize\r\n : gridCell !== undefined\r\n ? { width: gridCell.cellWidth, height: gridCell.cellHeight }\r\n : gridParent?.type === \"page-group\"\r\n ? parentSize\r\n : { width: transform.width, height: transform.height };\r\n for (const [childIndex, childId] of node.children.entries()) {\r\n const childNode = nodesById.get(childId);\r\n const childView = buildNode(childId, childSize);\r\n if (isLayoutGroup(node) && childNode !== undefined && view instanceof LayoutGroupNodeView) {\r\n const layoutItem = new LayoutItemContainer(childView, onLayout);\r\n applyLayoutItem(layoutItem, childNode, node, profile);\r\n view.addLayoutChild(layoutItem);\r\n } else if (node.type === \"scroll-view\" && childNode !== undefined && view instanceof ScrollViewNodeView) {\r\n const scrollItem = new ScrollItemContainer(childView, onLayout);\r\n // Как и у layout-item: собственный (не растянутый якорями) размер ребёнка — List не\r\n // предоставляет per-item override размера, в отличие от Yoga flexGrow/cellSize.\r\n const own = resolveProfileTransform(childNode, profile).transform;\r\n scrollItem.sync(childNode, profile, { width: own.width, height: own.height });\r\n view.addScrollItem(scrollItem);\r\n } else if (node.type === \"page-group\" && childNode !== undefined && view instanceof PageGroupNodeView) {\r\n // Unlike a scroll-view item, a page fills the group's own resolved rect completely\r\n // (`childSize`, computed above): a page is a full sub-screen, not content sized to itself.\r\n const pageItem = new PageItemContainer(childView);\r\n pageItem.sync(childNode, profile, childSize);\r\n view.addPageItem(pageItem);\r\n } else {\r\n view.addChild(childView);\r\n }\r\n if (node.type === \"grid-layout\") {\r\n const settings = node.layoutGroup.overrides?.[profile] === undefined ? node.layoutGroup.base : { ...node.layoutGroup.base, ...node.layoutGroup.overrides[profile] };\r\n if (settings.constraint !== \"flexible\" && settings.constraintCount !== undefined && (childIndex + 1) % settings.constraintCount === 0 && childIndex + 1 < node.children.length) {\r\n const lineBreak = createGridLineBreak(node, profile);\r\n if (lineBreak !== undefined && view instanceof LayoutGroupNodeView) view.addLayoutChild(lineBreak);\r\n }\r\n }\r\n }\r\n\r\n return view;\r\n };\r\n\r\n const ownerRoot = new Container();\r\n for (const rootNodeId of owner.rootNodeIds) {\r\n ownerRoot.addChild(buildNode(rootNodeId, rootSize));\r\n }\r\n\r\n return ownerRoot;\r\n };\r\n\r\n const canvasRoot = buildOwner(canvasSize);\r\n canvasRoot.scale.set(canvasScale);\r\n const hostRoot = new SceneViewport(canvasRoot, screenSize, options.clipToViewport ?? interaction === \"runtime\");\r\n particleEmitterRegistry.set(hostRoot, particleEmitters);\r\n // Контроллер применяет переводы сразу к уже созданным views, поэтому keyed Text показывает\r\n // базовую локаль без единого дополнительного вызова со стороны хоста.\r\n const localization = new SceneLocalization(document, scene, nodeViews, options.localization);\r\n wireCheckboxGroups(owner.nodes, nodeViews);\r\n wireSpineConnectors(owner.nodes, nodeViews);\r\n wireNodeReferences(owner.nodes, nodeViews, interaction);\r\n return { root: hostRoot, nodeViews, localization, profile };\n}\n\nconst GRID_LINE_BREAK_LABEL = \"__layout-grid-line-break__\";\n\n/** Recreates only technical Yoga line breaks while retaining every authored NodeView and wrapper. */\nfunction syncGridLineBreaks(view: LayoutGroupNodeView, node: Extract<UINode, { type: \"grid-layout\" }>, profile: LayoutProfileId, nodesById: ReadonlyMap<string, UINode>, nodeViews: ReadonlyMap<string, Container>): void {\n for (const child of [...view.layoutTarget.children]) {\n if (child.label === GRID_LINE_BREAK_LABEL) child.destroy();\n }\n const settings = resolveLayoutGroupSettings<GridLayoutSettings>(node, profile);\n for (const [childIndex, childId] of node.children.entries()) {\n const childNode = nodesById.get(childId);\n const childView = nodeViews.get(childId);\n if (childNode !== undefined && childView instanceof NodeView && childView.parent instanceof LayoutItemContainer) {\n view.addLayoutChild(childView.parent);\n }\n if (settings.constraint !== \"flexible\" && settings.constraintCount !== undefined && (childIndex + 1) % settings.constraintCount === 0 && childIndex + 1 < node.children.length) {\n const lineBreak = createGridLineBreak(node, profile);\n if (lineBreak !== undefined) view.addLayoutChild(lineBreak);\n }\n }\n}\n\n/**\n * Applies another layout profile to an already-built scene without loading assets or replacing views.\n * Runtime-only state owned by the views (button state, page, capacity overrides, scroll position) is\n * retained. Reapplying the live profile is an observable no-op.\n */\nexport function applyProfile(view: SceneViewResult, document: ProjectDocument, sceneId: string, profile: LayoutProfileId): void {\n if (view.profile === profile) return;\n const scene = document.scenes.find((candidate) => candidate.id === sceneId);\n if (scene === undefined) throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\n\n const owner = resolveOwnerNodeGraph(document, scene);\n const nodesById = new Map(owner.nodes.map((node) => [node.id, node]));\n const activeSpines = [...view.nodeViews.values()].filter((candidate): candidate is SpineNodeView => candidate instanceof SpineNodeView && candidate.activeConnectorBones);\n for (const spine of activeSpines) spine.activeConnectorBones = false;\n\n const screenSize = scene.layout.referenceViewports[profile];\n const referenceResolution = scene.layout.preferredViewports[profile];\n const canvasSize = getCanvasLogicalSize(screenSize, referenceResolution);\n\n const updateNode = (nodeId: string, parentSize: LayoutSize): void => {\n const node = nodesById.get(nodeId);\n const nodeView = view.nodeViews.get(nodeId);\n if (node === undefined || nodeView === undefined) return;\n const parentNode = node.parentId === null ? undefined : nodesById.get(node.parentId);\n updateNodeView(nodeView, node, profile, parentSize, parentNode, node.type === \"particle-emitter\" ? document.effects.find((effect) => effect.id === node.effectId) : undefined, spineReferenceFrameFor(document, node));\n\n const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);\n const gridCell = parentNode?.type === \"grid-layout\" ? resolveLayoutGroupSettings<GridLayoutSettings>(parentNode, profile) : undefined;\n const childSize = node.parentId === null\n ? canvasSize\n : gridCell !== undefined\n ? { width: gridCell.cellWidth, height: gridCell.cellHeight }\n : parentNode?.type === \"page-group\"\n ? parentSize\n : { width: transform.width, height: transform.height };\n for (const childId of node.children) updateNode(childId, childSize);\n if (node.type === \"grid-layout\" && nodeView instanceof LayoutGroupNodeView) syncGridLineBreaks(nodeView, node, profile, nodesById, view.nodeViews);\n };\n\n try {\n for (const rootNodeId of owner.rootNodeIds) updateNode(rootNodeId, canvasSize);\n view.root.content.scale.set(getCanvasScale(screenSize, referenceResolution));\n view.root.setReferenceViewport(screenSize);\n (view as { profile: LayoutProfileId }).profile = profile;\n } finally {\n for (const spine of activeSpines) spine.activeConnectorBones = true;\n }\n}\n\r\nfunction wireSpineConnectors(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>): void {\r\n for (const node of nodes) {\r\n if (node.type !== \"spine\") continue;\r\n const view = nodeViews.get(node.id);\r\n if (!(view instanceof SpineNodeView)) continue;\r\n view.setConnectorBones((node.connectors ?? []).flatMap((connector) => {\r\n const target = nodeViews.get(connector.targetNodeId);\r\n return target === undefined ? [] : [{ ...connector, target }];\r\n }));\r\n }\r\n}\r\n\r\n/**\r\n * Разрешает все ссылки «нода → нода» в живые views: элементы item table и кнопки-стрелки пагинатора.\r\n * Та же форма, что у `wireSpineConnectors`: документ хранит id, а во что он превратился, знает только\r\n * собранная сцена, поэтому сами виды никогда не резолвят id. Один проход на все виды ссылок, чтобы\r\n * следующая не завела собственный обход с чуть другой областью видимости.\r\n *\r\n * Стрелки подключаются только в runtime-сцене: на authoring-канвасе контрол инертен, как и клик по\r\n * самой точке пагинатора. Вместимость таблицы, наоборот, видна и в редакторе — это не интерактивность.\r\n */\r\nfunction wireNodeReferences(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>, interaction: SceneInteractionMode): void {\r\n const arrowView = (nodeId: string | undefined): PaginationArrow | undefined => {\r\n const view = nodeId === undefined ? undefined : nodeViews.get(nodeId);\r\n return view instanceof ButtonNodeView || view instanceof StagedButtonNodeView ? view : undefined;\r\n };\r\n for (const node of nodes) {\r\n const view = nodeViews.get(node.id);\r\n if (node.type === \"item-table\" && view instanceof ItemTableNodeView) {\r\n view.setItems((node.items ?? []).map((itemId) => nodeViews.get(itemId)));\r\n } else if (node.type === \"pagination\" && view instanceof PaginationNodeView && interaction === \"runtime\") {\r\n view.setArrows({ previous: arrowView(node.prevButtonNodeId), next: arrowView(node.nextButtonNodeId) });\r\n } else if (node.type === \"page-group\" && view instanceof PageGroupNodeView && interaction === \"runtime\") {\r\n view.setArrows({ up: arrowView(node.pageUpButtonNodeId), down: arrowView(node.pageDownButtonNodeId) });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Authored `group` gives sibling checkboxes radio-button behavior: checking one force-unchecks its\r\n * live group-mates (same `parentId`, same `group`), without touching the document. Runs once per\r\n * scene build; `CheckboxNodeView.forceCheck` never re-emits `onCheck`, so this can't recurse.\r\n */\r\nfunction wireCheckboxGroups(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>): void {\r\n const byGroup = new Map<string, CheckboxNodeView[]>();\r\n for (const node of nodes) {\r\n if (node.type !== \"checkbox\" || node.group === undefined) continue;\r\n const view = nodeViews.get(node.id);\r\n if (!(view instanceof CheckboxNodeView)) continue;\r\n const key = `${node.parentId ?? \"\"}::${node.group}`;\r\n const group = byGroup.get(key) ?? [];\r\n group.push(view);\r\n byGroup.set(key, group);\r\n }\r\n for (const group of byGroup.values()) {\r\n if (group.length < 2) continue;\r\n for (const view of group) {\r\n view.onCheck.connect((checked) => {\r\n if (!checked) return;\r\n for (const other of group) if (other !== view) other.forceCheck(false);\r\n });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Applies a node's resolved transform, visibility, and content to an existing display object,\r\n * so editors can update views in place without rebuilding the scene tree.\r\n */\r\nexport function updateNodeView(view: Container, node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize, parentNode?: UINode, effect?: EffectDefinition, spineReferenceFrame?: SpineReferenceFrame): void {\r\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, parentSize);\r\n if (!(view instanceof NodeView)) return;\r\n if (view instanceof SpineNodeView) view.setReferenceFrame(spineReferenceFrame);\r\n if (node.type === \"particle-emitter\" && effect !== undefined && isParticleEffect(effect) && \"syncEffect\" in view && typeof (view as { syncEffect?: unknown }).syncEffect === \"function\") (view as { syncEffect(effect: import(\"@pixi-ui-editor/schema\").ParticleEffectDefinition): void }).syncEffect(effect);\r\n if (parentNode !== undefined && isLayoutGroup(parentNode) && view.parent instanceof LayoutItemContainer) {\r\n applyLayoutItem(view.parent, node, parentNode, profile);\r\n } else if (parentNode !== undefined && parentNode.type === \"scroll-view\" && view.parent instanceof ScrollItemContainer) {\r\n const own = resolveProfileTransform(node, profile).transform;\r\n view.parent.sync(node, profile, { width: own.width, height: own.height });\r\n } else if (parentNode !== undefined && parentNode.type === \"page-group\" && view.parent instanceof PageItemContainer && parentSize !== undefined) {\r\n // A page is position-managed exactly like a layout/scroll item: it fills the group's own rectangle\r\n // (`parentSize`, the same value `buildSceneView` passes as `childSize`). Without this branch an\r\n // in-place update fell through to `view.update` and handed the page back its authored x/y and\r\n // anchors, so editing anything inside a page group knocked its pages out of place.\r\n view.parent.sync(node, profile, parentSize);\r\n } else {\r\n view.update(node, profile, parentSize);\r\n }\r\n}\r\n\r\n/** Previews a resolved editor rectangle without consulting content bounds or rebuilding the view. */\r\nexport function previewNodeView(view: Container, node: UINode, profile: LayoutProfileId, transform: UINode[\"transform\"]): void {\r\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, undefined, { width: transform.width, height: transform.height });\r\n if (view instanceof NodeView) view.preview(node, transform, resolveProfileTransform(node, profile).visible, profile);\r\n}\r\n\r\n/** Hosts call this from their own Application ticker; runtime never subscribes to Ticker.shared. */\r\nexport function updateParticleEmitters(root: Container, deltaSeconds: number): void {\r\n const registered = particleEmitterRegistry.get(root);\r\n if (registered !== undefined) {\r\n for (const emitter of registered) emitter.updateParticles(deltaSeconds);\r\n return;\r\n }\r\n // Backward-compatible fallback for hosts that assemble a display tree manually instead of using\r\n // buildSceneView. Built scenes always take the O(emitter count) registry path above.\r\n const visit = (view: Container): void => {\r\n if (view instanceof ParticleEmitterNodeView) view.updateParticles(deltaSeconds);\r\n for (const child of view.children) visit(child);\r\n };\r\n visit(root);\r\n}\r\n\r\n/** Lists the nodes a scene renders, including nodes of prefab definitions its prefab instances expand to. */\r\nexport function collectRenderedNodes(document: ProjectDocument, scene: Scene): UINode[] {\r\n return resolveOwnerNodeGraph(document, scene).nodes;\r\n}\r\n\r\nexport type PrefabViewConfiguration = Pick<Extract<UINode, { type: \"prefab-instance\" }>, \"propertyOverrides\" | \"locallyAddedNodes\"> & { instanceId?: string };\r\n\r\nfunction prefabScene(document: ProjectDocument, prefabId: string, configuration: PrefabViewConfiguration = {}): { document: ProjectDocument; sceneId: string; instanceId: string } {\r\n const prefab = document.prefabs.find((candidate) => candidate.id === prefabId);\r\n if (prefab === undefined) throw new Error(`Prefab '${prefabId}' does not exist in the project document.`);\r\n const width = Math.max(1, ...prefab.nodes.map((node) => Math.abs(node.transform.x) + Math.max(0, node.transform.width)));\r\n const height = Math.max(1, ...prefab.nodes.map((node) => Math.abs(node.transform.y) + Math.max(0, node.transform.height)));\r\n const instanceId = configuration.instanceId ?? createStableId();\r\n const instance: Extract<UINode, { type: \"prefab-instance\" }> = {\r\n id: instanceId, name: prefab.name, type: \"prefab-instance\", prefabId, parentId: null, children: [],\r\n visible: true, transform: { x: 0, y: 0, width, height, scaleX: 1, scaleY: 1, rotation: 0, anchorMinX: 0, anchorMaxX: 0, anchorMinY: 0, anchorMaxY: 0, pivotX: 0, pivotY: 0 },\r\n ...(configuration.propertyOverrides === undefined ? {} : { propertyOverrides: structuredClone(configuration.propertyOverrides) }),\r\n ...(configuration.locallyAddedNodes === undefined ? {} : { locallyAddedNodes: structuredClone(configuration.locallyAddedNodes) }),\r\n };\r\n const sceneId = createStableId();\r\n const viewport = { width, height };\r\n const scene: Scene = { id: sceneId, name: prefab.name, rootNodeIds: [instance.id], nodes: [instance], layout: { referenceViewports: { desktop: viewport, mobile: viewport }, preferredViewports: { desktop: viewport, mobile: viewport } } };\r\n return { document: { ...document, scenes: [...document.scenes, scene] }, sceneId, instanceId };\r\n}\r\n\r\n/** Builds a fresh runtime prefab instance without requiring it to already exist in a scene. */\r\nexport function buildPrefabView(document: ProjectDocument, prefabId: string, profile: LayoutProfileId, options: BuildSceneViewOptions, configuration: PrefabViewConfiguration = {}): SceneViewResult & { instanceId: string } {\r\n const synthetic = prefabScene(document, prefabId, configuration);\r\n return { ...buildSceneView(synthetic.document, synthetic.sceneId, profile, { ...options, clipToViewport: false }), instanceId: synthetic.instanceId };\r\n}\r\n\r\n/** Loads a prefab's assets and returns a fresh display tree suitable for dynamic game-code spawning. */\r\nexport async function loadPrefabView(document: ProjectDocument, prefabId: string, profile: LayoutProfileId, resolveFileUrl: FileUrlResolver, options: { interaction: SceneInteractionMode; ticker?: Ticker; localization?: SceneLocalizationOptions; assetCache?: SceneAssetCache }, configuration: PrefabViewConfiguration = {}): Promise<SceneViewResult & { instanceId: string }> {\r\n const synthetic = prefabScene(document, prefabId, configuration);\r\n return { ...await loadSceneView(synthetic.document, synthetic.sceneId, profile, resolveFileUrl, { ...options, clipToViewport: false }), instanceId: synthetic.instanceId };\r\n}\r\n\r\n/** Loads a scene's textures and Spine data, then builds its display tree in one call. */\r\nexport async function loadSceneView(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n profile: LayoutProfileId,\r\n resolveFileUrl: FileUrlResolver,\r\n options: { interaction: SceneInteractionMode; ticker?: Ticker; localization?: SceneLocalizationOptions; clipToViewport?: boolean; assetCache?: SceneAssetCache },\r\n): Promise<SceneViewResult> {\r\n // Без assetCache каждый вызов начинает с пустых кэшей: для одиночной загрузки сцены это нормально, а вот\r\n // игровой код, который поднимает пресеты по одному, обязан передать собственный кэш — иначе один и тот же\r\n // скелет, атлас и текстура парсятся заново на каждую вьюху и дублируются в видеопамяти.\r\n const cache = options.assetCache;\r\n const [textures, spines, fonts, bitmapFonts] = await Promise.all([\r\n loadSceneTextures(document, sceneId, (asset) => (asset.type === \"image\" ? resolveFileUrl(asset.source.uri) : undefined), resolveFileUrl, cache?.textures, cache?.spritesheets, cache?.bitmapFonts),\r\n loadSceneSpines(document, sceneId, resolveFileUrl, cache?.spines),\r\n loadSceneFonts(document, sceneId, resolveFileUrl, cache?.fonts),\r\n loadSceneBitmapFonts(document, sceneId, resolveFileUrl, cache?.bitmapFonts),\r\n ]);\r\n return buildSceneView(document, sceneId, profile, { interaction: options.interaction, textures, spines, fonts, bitmapFonts, ticker: options.ticker, localization: options.localization, clipToViewport: options.clipToViewport });\r\n}\r\n"]}
1
+ {"version":3,"file":"scene.js","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { createStableId, isLayoutGroup, isParticleEffect, resolveLayoutGroupSettings, resolveOwnerNodeGraph, type EffectDefinition, type GridLayoutSettings, type LayoutProfileId, type ProjectDocument, type Scene, type SpineReferenceFrame, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container, Texture, type Ticker } from \"pixi.js\";\r\nimport { loadSceneSpines } from \"./assets/spine.js\";\r\nimport { loadSceneTextures, type FileUrlResolver } from \"./assets/textures.js\";\r\nimport { loadSceneFonts } from \"./assets/fonts.js\";\r\nimport { loadSceneBitmapFonts } from \"./assets/bitmapFonts.js\";\r\nimport type { SceneAssetCache } from \"./assets/cache.js\";\r\nimport { getCanvasLogicalSize, getCanvasScale, resolveAnchoredTransform, resolveProfileTransform, type LayoutSize } from \"./layout.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./views/NodeView.js\";\r\nimport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\r\nimport { createNodeView } from \"./views/createNodeView.js\";\r\nimport { applyLayoutGroup, applyLayoutItem, createGridLineBreak, initializePixiLayout, LayoutItemContainer } from \"./layoutGroups.js\";\r\nimport { LayoutGroupNodeView } from \"./views/basic.js\";\r\nimport { PageItemContainer } from \"./pageGroup.js\";\r\nimport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\r\nimport { PaginationNodeView, type PaginationArrow } from \"./views/PaginationNodeView.js\";\r\nimport { ItemTableNodeView } from \"./views/ItemTableNodeView.js\";\r\nimport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\r\nimport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\r\nimport { ScrollItemContainer } from \"./scrollView.js\";\r\nimport { ScrollViewNodeView } from \"./views/ScrollViewNodeView.js\";\r\nimport { SpineNodeView } from \"./views/SpineNodeView.js\";\r\nimport { ParticleEmitterNodeView } from \"./views/ParticleEmitterNodeView.js\";\r\nimport { SceneLocalization, type SceneLocalizationOptions } from \"./localization.js\";\r\nimport { SceneViewport } from \"./SceneViewport.js\";\r\nimport { createSceneAudio, type AudioBus } from \"./audio/bus.js\";\r\n\r\nexport type BuildSceneViewOptions = {\r\n /** Explicit: an editor canvas must pass \"authoring\", Preview and the consuming app \"runtime\". */\r\n interaction: SceneInteractionMode;\r\n textures?: ReadonlyMap<string, Texture>;\r\n spines?: ReadonlyMap<string, SkeletonData>;\r\n fonts?: ReadonlyMap<string, string>;\r\n bitmapFonts?: ReadonlyMap<string, string>;\r\n /**\r\n * Шина звуковых событий (обычно `createRuntimeAudio(...)`). Без неё сцена не публикует звуковые\r\n * события вовсе — ровно так строится инертный authoring-канвас редактора.\r\n */\r\n audio?: AudioBus;\r\n /**\r\n * The host's own Application ticker, driving self-updating content such as Spine skeletons.\r\n * Without it they fall back to `Ticker.shared`, which runs a second rAF loop independent of the\r\n * renderer that draws them — see the same rule as `updateParticleEmitters`.\r\n */\r\n ticker?: Ticker;\r\n /** Called after Yoga changes a managed rectangle; authoring hosts use it to refresh overlays. */\r\n onLayout?: () => void;\r\n /**\r\n * Начальное состояние локализации. Опция необязательна: при наличии `Text.textKey` base locale\r\n * каталога применяется и без неё, а документ без ключей выглядит ровно как раньше.\r\n */\r\n localization?: SceneLocalizationOptions;\r\n /** Internal host boundary override: prefab views are spawnable content, not screen viewports. */\r\n clipToViewport?: boolean;\r\n};\r\n\r\nexport type SceneViewResult = { root: SceneViewport; nodeViews: Map<string, Container>; localization: SceneLocalization; readonly profile: LayoutProfileId };\r\nconst particleEmitterRegistry = new WeakMap<Container, readonly ParticleEmitterNodeView[]>();\r\n\r\nfunction spineReferenceFrameFor(document: ProjectDocument, node: UINode): SpineReferenceFrame | undefined {\r\n if (node.type !== \"spine\") return undefined;\r\n const asset = document.assets.find((candidate) => candidate.id === node.assetId);\r\n return asset?.type === \"spine\" ? asset.referenceFrame : undefined;\r\n}\r\n\r\n/** Builds a PixiJS display tree for a scene without depending on DOM or editor state. */\r\nexport function buildSceneView(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n profile: LayoutProfileId,\r\n options: BuildSceneViewOptions,\r\n): SceneViewResult {\r\n initializePixiLayout();\r\n const { interaction, textures, spines, fonts, bitmapFonts, ticker, onLayout } = options;\r\n const scene = document.scenes.find((candidate) => candidate.id === sceneId);\r\n\r\n if (scene === undefined) {\r\n throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n }\r\n\r\n const nodeViews = new Map<string, Container>();\r\n const particleEmitters: ParticleEmitterNodeView[] = [];\r\n // Резолв «id ассета → имя звука» живёт здесь: вьюхи знают только id, а документ — только эта функция.\r\n const sceneAudio = options.audio === undefined ? undefined : createSceneAudio(document, options.audio);\r\n\r\n // Materialized prefab children use instance-scoped IDs, so authoring and runtime can address\r\n // multiple instances independently without changing canonical definition IDs.\r\n const screenSize = scene.layout.referenceViewports[profile];\r\n const referenceResolution = scene.layout.preferredViewports[profile];\r\n const canvasScale = getCanvasScale(screenSize, referenceResolution);\r\n const canvasSize = getCanvasLogicalSize(screenSize, referenceResolution);\r\n\r\n // Единый резолвер иерархии: тот же граф, что видит редактор, включая вложенные пресеты.\r\n const owner = resolveOwnerNodeGraph(document, scene);\r\n const prefabIds = new Set(document.prefabs.map((prefab) => prefab.id));\r\n\r\n const buildOwner = (rootSize: LayoutSize): Container => {\r\n const nodesById = new Map(owner.nodes.map((node) => [node.id, node]));\r\n\r\n const buildNode = (nodeId: string, parentSize: LayoutSize): NodeView => {\r\n const node = nodesById.get(nodeId);\r\n\r\n if (node === undefined) {\r\n throw new Error(`Scene '${sceneId}' references missing node '${nodeId}'.`);\r\n }\r\n\r\n const resolved = resolveProfileTransform(node, profile);\r\n const transform = resolveAnchoredTransform(resolved.transform, parentSize);\r\n const view = createNodeView(node, interaction, textures, spines, (prefabId) => prefabIds.has(prefabId), fonts, sceneAudio, node.type === \"particle-emitter\" ? document.effects.find((effect) => effect.id === node.effectId && isParticleEffect(effect)) : undefined, spineReferenceFrameFor(document, node), ticker, bitmapFonts);\r\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, parentSize);\r\n // Yoga owns only the group's inner layoutContent; the outer NodeView keeps authored transform.\r\n view.update(node, profile, parentSize);\r\n nodeViews.set(node.id, view);\r\n if (view instanceof ParticleEmitterNodeView) particleEmitters.push(view);\r\n\r\n // Прямые дети корня сцены разрешают якоря относительно логического Canvas, а не размера корня.\r\n // Прямой ребёнок grid-layout (сам `node` здесь) не владеет своим отрисованным размером: Unity-подобная\r\n // фиксированная ячейка полностью переопределяет authored transform (см. applyLayoutItem). Его\r\n // собственным потомкам нужен именно cellWidth/cellHeight, а не anchor-resolved authored-размер —\r\n // иначе они не отслеживают изменение Cell width/height и якорятся относительно устаревшего размера.\r\n const gridParent = node.parentId === null ? undefined : nodesById.get(node.parentId);\r\n const gridCell = gridParent?.type === \"grid-layout\" ? resolveLayoutGroupSettings<GridLayoutSettings>(gridParent, profile) : undefined;\r\n // Та же логика для прямого ребёнка page-group (страницы): `PageItemContainer`/`updateManaged`\r\n // растягивают её на весь resolved rectangle группы независимо от собственных anchors ноды\r\n // (см. NodeView.applyResolvedTransform, managedByLayout). Здесь `node` — сама страница, поэтому\r\n // это переопределённый размер, который она фактически получит, — `parentSize`, уже разрешённый\r\n // как rectangle page-group. Без этой ветки дети страницы якорились бы относительно её\r\n // anchor-resolved authored-размера, который может расходиться с фактическим rectangle группы,\r\n // особенно в другом layout-профиле.\r\n const childSize = node.parentId === null\r\n ? rootSize\r\n : gridCell !== undefined\r\n ? { width: gridCell.cellWidth, height: gridCell.cellHeight }\r\n : gridParent?.type === \"page-group\"\r\n ? parentSize\r\n : { width: transform.width, height: transform.height };\r\n for (const [childIndex, childId] of node.children.entries()) {\r\n const childNode = nodesById.get(childId);\r\n const childView = buildNode(childId, childSize);\r\n if (isLayoutGroup(node) && childNode !== undefined && view instanceof LayoutGroupNodeView) {\r\n const layoutItem = new LayoutItemContainer(childView, onLayout);\r\n applyLayoutItem(layoutItem, childNode, node, profile);\r\n view.addLayoutChild(layoutItem);\r\n } else if (node.type === \"scroll-view\" && childNode !== undefined && view instanceof ScrollViewNodeView) {\r\n const scrollItem = new ScrollItemContainer(childView, onLayout);\r\n // Как и у layout-item: собственный (не растянутый якорями) размер ребёнка — List не\r\n // предоставляет per-item override размера, в отличие от Yoga flexGrow/cellSize.\r\n const own = resolveProfileTransform(childNode, profile).transform;\r\n scrollItem.sync(childNode, profile, { width: own.width, height: own.height });\r\n view.addScrollItem(scrollItem);\r\n } else if (node.type === \"page-group\" && childNode !== undefined && view instanceof PageGroupNodeView) {\r\n // Unlike a scroll-view item, a page fills the group's own resolved rect completely\r\n // (`childSize`, computed above): a page is a full sub-screen, not content sized to itself.\r\n const pageItem = new PageItemContainer(childView);\r\n pageItem.sync(childNode, profile, childSize);\r\n view.addPageItem(pageItem);\r\n } else {\r\n view.addChild(childView);\r\n }\r\n if (node.type === \"grid-layout\") {\r\n const settings = node.layoutGroup.overrides?.[profile] === undefined ? node.layoutGroup.base : { ...node.layoutGroup.base, ...node.layoutGroup.overrides[profile] };\r\n if (settings.constraint !== \"flexible\" && settings.constraintCount !== undefined && (childIndex + 1) % settings.constraintCount === 0 && childIndex + 1 < node.children.length) {\r\n const lineBreak = createGridLineBreak(node, profile);\r\n if (lineBreak !== undefined && view instanceof LayoutGroupNodeView) view.addLayoutChild(lineBreak);\r\n }\r\n }\r\n }\r\n\r\n return view;\r\n };\r\n\r\n const ownerRoot = new Container();\r\n for (const rootNodeId of owner.rootNodeIds) {\r\n ownerRoot.addChild(buildNode(rootNodeId, rootSize));\r\n }\r\n\r\n return ownerRoot;\r\n };\r\n\r\n const canvasRoot = buildOwner(canvasSize);\r\n canvasRoot.scale.set(canvasScale);\r\n const hostRoot = new SceneViewport(canvasRoot, screenSize, options.clipToViewport ?? interaction === \"runtime\");\r\n particleEmitterRegistry.set(hostRoot, particleEmitters);\r\n // Контроллер применяет переводы сразу к уже созданным views, поэтому keyed Text показывает\r\n // базовую локаль без единого дополнительного вызова со стороны хоста.\r\n const localization = new SceneLocalization(document, scene, nodeViews, options.localization);\r\n wireCheckboxGroups(owner.nodes, nodeViews);\r\n wireSpineConnectors(owner.nodes, nodeViews);\r\n wireNodeReferences(owner.nodes, nodeViews, interaction);\r\n return { root: hostRoot, nodeViews, localization, profile };\r\n}\r\n\r\nconst GRID_LINE_BREAK_LABEL = \"__layout-grid-line-break__\";\r\n\r\n/** Recreates only technical Yoga line breaks while retaining every authored NodeView and wrapper. */\r\nfunction syncGridLineBreaks(view: LayoutGroupNodeView, node: Extract<UINode, { type: \"grid-layout\" }>, profile: LayoutProfileId, nodesById: ReadonlyMap<string, UINode>, nodeViews: ReadonlyMap<string, Container>): void {\r\n for (const child of [...view.layoutTarget.children]) {\r\n if (child.label === GRID_LINE_BREAK_LABEL) child.destroy();\r\n }\r\n const settings = resolveLayoutGroupSettings<GridLayoutSettings>(node, profile);\r\n for (const [childIndex, childId] of node.children.entries()) {\r\n const childNode = nodesById.get(childId);\r\n const childView = nodeViews.get(childId);\r\n if (childNode !== undefined && childView instanceof NodeView && childView.parent instanceof LayoutItemContainer) {\r\n view.addLayoutChild(childView.parent);\r\n }\r\n if (settings.constraint !== \"flexible\" && settings.constraintCount !== undefined && (childIndex + 1) % settings.constraintCount === 0 && childIndex + 1 < node.children.length) {\r\n const lineBreak = createGridLineBreak(node, profile);\r\n if (lineBreak !== undefined) view.addLayoutChild(lineBreak);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Applies another layout profile to an already-built scene without loading assets or replacing views.\r\n * Runtime-only state owned by the views (button state, page, capacity overrides, scroll position) is\r\n * retained. Reapplying the live profile is an observable no-op.\r\n */\r\nexport function applyProfile(view: SceneViewResult, document: ProjectDocument, sceneId: string, profile: LayoutProfileId): void {\r\n if (view.profile === profile) return;\r\n const scene = document.scenes.find((candidate) => candidate.id === sceneId);\r\n if (scene === undefined) throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n\r\n const owner = resolveOwnerNodeGraph(document, scene);\r\n const nodesById = new Map(owner.nodes.map((node) => [node.id, node]));\r\n const activeSpines = [...view.nodeViews.values()].filter((candidate): candidate is SpineNodeView => candidate instanceof SpineNodeView && candidate.activeConnectorBones);\r\n for (const spine of activeSpines) spine.activeConnectorBones = false;\r\n\r\n const screenSize = scene.layout.referenceViewports[profile];\r\n const referenceResolution = scene.layout.preferredViewports[profile];\r\n const canvasSize = getCanvasLogicalSize(screenSize, referenceResolution);\r\n\r\n const updateNode = (nodeId: string, parentSize: LayoutSize): void => {\r\n const node = nodesById.get(nodeId);\r\n const nodeView = view.nodeViews.get(nodeId);\r\n if (node === undefined || nodeView === undefined) return;\r\n const parentNode = node.parentId === null ? undefined : nodesById.get(node.parentId);\r\n updateNodeView(nodeView, node, profile, parentSize, parentNode, node.type === \"particle-emitter\" ? document.effects.find((effect) => effect.id === node.effectId) : undefined, spineReferenceFrameFor(document, node));\r\n\r\n const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);\r\n const gridCell = parentNode?.type === \"grid-layout\" ? resolveLayoutGroupSettings<GridLayoutSettings>(parentNode, profile) : undefined;\r\n const childSize = node.parentId === null\r\n ? canvasSize\r\n : gridCell !== undefined\r\n ? { width: gridCell.cellWidth, height: gridCell.cellHeight }\r\n : parentNode?.type === \"page-group\"\r\n ? parentSize\r\n : { width: transform.width, height: transform.height };\r\n for (const childId of node.children) updateNode(childId, childSize);\r\n if (node.type === \"grid-layout\" && nodeView instanceof LayoutGroupNodeView) syncGridLineBreaks(nodeView, node, profile, nodesById, view.nodeViews);\r\n };\r\n\r\n try {\r\n for (const rootNodeId of owner.rootNodeIds) updateNode(rootNodeId, canvasSize);\r\n view.root.content.scale.set(getCanvasScale(screenSize, referenceResolution));\r\n view.root.setReferenceViewport(screenSize);\r\n (view as { profile: LayoutProfileId }).profile = profile;\r\n } finally {\r\n for (const spine of activeSpines) spine.activeConnectorBones = true;\r\n }\r\n}\r\n\r\nfunction wireSpineConnectors(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>): void {\r\n for (const node of nodes) {\r\n if (node.type !== \"spine\") continue;\r\n const view = nodeViews.get(node.id);\r\n if (!(view instanceof SpineNodeView)) continue;\r\n view.setConnectorBones((node.connectors ?? []).flatMap((connector) => {\r\n const target = nodeViews.get(connector.targetNodeId);\r\n return target === undefined ? [] : [{ ...connector, target }];\r\n }));\r\n }\r\n}\r\n\r\n/**\r\n * Разрешает все ссылки «нода → нода» в живые views: элементы item table и кнопки-стрелки пагинатора.\r\n * Та же форма, что у `wireSpineConnectors`: документ хранит id, а во что он превратился, знает только\r\n * собранная сцена, поэтому сами виды никогда не резолвят id. Один проход на все виды ссылок, чтобы\r\n * следующая не завела собственный обход с чуть другой областью видимости.\r\n *\r\n * Стрелки подключаются только в runtime-сцене: на authoring-канвасе контрол инертен, как и клик по\r\n * самой точке пагинатора. Вместимость таблицы и видимость ноды-фона активной страницы пагинатора,\r\n * наоборот, видны и в редакторе — это не интерактивность.\r\n */\r\nfunction wireNodeReferences(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>, interaction: SceneInteractionMode): void {\r\n const arrowView = (nodeId: string | undefined): PaginationArrow | undefined => {\r\n const view = nodeId === undefined ? undefined : nodeViews.get(nodeId);\r\n return view instanceof ButtonNodeView || view instanceof StagedButtonNodeView ? view : undefined;\r\n };\r\n for (const node of nodes) {\r\n const view = nodeViews.get(node.id);\r\n if (node.type === \"item-table\" && view instanceof ItemTableNodeView) {\r\n view.setItems((node.items ?? []).map((itemId) => nodeViews.get(itemId)));\r\n } else if (node.type === \"pagination\" && view instanceof PaginationNodeView) {\r\n if (interaction === \"runtime\") view.setArrows({ previous: arrowView(node.prevButtonNodeId), next: arrowView(node.nextButtonNodeId) });\r\n view.setActiveBackground(node.activeBackgroundNodeId === undefined ? undefined : nodeViews.get(node.activeBackgroundNodeId));\r\n } else if (node.type === \"page-group\" && view instanceof PageGroupNodeView && interaction === \"runtime\") {\r\n view.setArrows({ up: arrowView(node.pageUpButtonNodeId), down: arrowView(node.pageDownButtonNodeId) });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Authored `group` gives sibling checkboxes radio-button behavior: checking one force-unchecks its\r\n * live group-mates (same `parentId`, same `group`), without touching the document. Runs once per\r\n * scene build; `CheckboxNodeView.forceCheck` never re-emits `onCheck`, so this can't recurse.\r\n */\r\nfunction wireCheckboxGroups(nodes: readonly UINode[], nodeViews: ReadonlyMap<string, Container>): void {\r\n const byGroup = new Map<string, CheckboxNodeView[]>();\r\n for (const node of nodes) {\r\n if (node.type !== \"checkbox\" || node.group === undefined) continue;\r\n const view = nodeViews.get(node.id);\r\n if (!(view instanceof CheckboxNodeView)) continue;\r\n const key = `${node.parentId ?? \"\"}::${node.group}`;\r\n const group = byGroup.get(key) ?? [];\r\n group.push(view);\r\n byGroup.set(key, group);\r\n }\r\n for (const group of byGroup.values()) {\r\n if (group.length < 2) continue;\r\n for (const view of group) {\r\n view.onCheck.connect((checked) => {\r\n if (!checked) return;\r\n for (const other of group) if (other !== view) other.forceCheck(false);\r\n });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Applies a node's resolved transform, visibility, and content to an existing display object,\r\n * so editors can update views in place without rebuilding the scene tree.\r\n */\r\nexport function updateNodeView(view: Container, node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize, parentNode?: UINode, effect?: EffectDefinition, spineReferenceFrame?: SpineReferenceFrame): void {\r\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, parentSize);\r\n if (!(view instanceof NodeView)) return;\r\n if (view instanceof SpineNodeView) view.setReferenceFrame(spineReferenceFrame);\r\n if (node.type === \"particle-emitter\" && effect !== undefined && isParticleEffect(effect) && \"syncEffect\" in view && typeof (view as { syncEffect?: unknown }).syncEffect === \"function\") (view as { syncEffect(effect: import(\"@pixi-ui-editor/schema\").ParticleEffectDefinition): void }).syncEffect(effect);\r\n if (parentNode !== undefined && isLayoutGroup(parentNode) && view.parent instanceof LayoutItemContainer) {\r\n applyLayoutItem(view.parent, node, parentNode, profile);\r\n } else if (parentNode !== undefined && parentNode.type === \"scroll-view\" && view.parent instanceof ScrollItemContainer) {\r\n const own = resolveProfileTransform(node, profile).transform;\r\n view.parent.sync(node, profile, { width: own.width, height: own.height });\r\n } else if (parentNode !== undefined && parentNode.type === \"page-group\" && view.parent instanceof PageItemContainer && parentSize !== undefined) {\r\n // A page is position-managed exactly like a layout/scroll item: it fills the group's own rectangle\r\n // (`parentSize`, the same value `buildSceneView` passes as `childSize`). Without this branch an\r\n // in-place update fell through to `view.update` and handed the page back its authored x/y and\r\n // anchors, so editing anything inside a page group knocked its pages out of place.\r\n view.parent.sync(node, profile, parentSize);\r\n } else {\r\n view.update(node, profile, parentSize);\r\n }\r\n}\r\n\r\n/** Previews a resolved editor rectangle without consulting content bounds or rebuilding the view. */\r\nexport function previewNodeView(view: Container, node: UINode, profile: LayoutProfileId, transform: UINode[\"transform\"]): void {\r\n if (isLayoutGroup(node)) applyLayoutGroup(view, node, profile, undefined, { width: transform.width, height: transform.height });\r\n if (view instanceof NodeView) view.preview(node, transform, resolveProfileTransform(node, profile).visible, profile);\r\n}\r\n\r\n/** Hosts call this from their own Application ticker; runtime never subscribes to Ticker.shared. */\r\nexport function updateParticleEmitters(root: Container, deltaSeconds: number): void {\r\n const registered = particleEmitterRegistry.get(root);\r\n if (registered !== undefined) {\r\n for (const emitter of registered) emitter.updateParticles(deltaSeconds);\r\n return;\r\n }\r\n // Backward-compatible fallback for hosts that assemble a display tree manually instead of using\r\n // buildSceneView. Built scenes always take the O(emitter count) registry path above.\r\n const visit = (view: Container): void => {\r\n if (view instanceof ParticleEmitterNodeView) view.updateParticles(deltaSeconds);\r\n for (const child of view.children) visit(child);\r\n };\r\n visit(root);\r\n}\r\n\r\n/** Lists the nodes a scene renders, including nodes of prefab definitions its prefab instances expand to. */\r\nexport function collectRenderedNodes(document: ProjectDocument, scene: Scene): UINode[] {\r\n return resolveOwnerNodeGraph(document, scene).nodes;\r\n}\r\n\r\nexport type PrefabViewConfiguration = Pick<Extract<UINode, { type: \"prefab-instance\" }>, \"propertyOverrides\" | \"locallyAddedNodes\"> & { instanceId?: string };\r\n\r\nfunction prefabScene(document: ProjectDocument, prefabId: string, configuration: PrefabViewConfiguration = {}): { document: ProjectDocument; sceneId: string; instanceId: string } {\r\n const prefab = document.prefabs.find((candidate) => candidate.id === prefabId);\r\n if (prefab === undefined) throw new Error(`Prefab '${prefabId}' does not exist in the project document.`);\r\n const width = Math.max(1, ...prefab.nodes.map((node) => Math.abs(node.transform.x) + Math.max(0, node.transform.width)));\r\n const height = Math.max(1, ...prefab.nodes.map((node) => Math.abs(node.transform.y) + Math.max(0, node.transform.height)));\r\n const instanceId = configuration.instanceId ?? createStableId();\r\n const instance: Extract<UINode, { type: \"prefab-instance\" }> = {\r\n id: instanceId, name: prefab.name, type: \"prefab-instance\", prefabId, parentId: null, children: [],\r\n visible: true, transform: { x: 0, y: 0, width, height, scaleX: 1, scaleY: 1, rotation: 0, anchorMinX: 0, anchorMaxX: 0, anchorMinY: 0, anchorMaxY: 0, pivotX: 0, pivotY: 0 },\r\n ...(configuration.propertyOverrides === undefined ? {} : { propertyOverrides: structuredClone(configuration.propertyOverrides) }),\r\n ...(configuration.locallyAddedNodes === undefined ? {} : { locallyAddedNodes: structuredClone(configuration.locallyAddedNodes) }),\r\n };\r\n const sceneId = createStableId();\r\n const viewport = { width, height };\r\n const scene: Scene = { id: sceneId, name: prefab.name, rootNodeIds: [instance.id], nodes: [instance], layout: { referenceViewports: { desktop: viewport, mobile: viewport }, preferredViewports: { desktop: viewport, mobile: viewport } } };\r\n return { document: { ...document, scenes: [...document.scenes, scene] }, sceneId, instanceId };\r\n}\r\n\r\n/** Builds a fresh runtime prefab instance without requiring it to already exist in a scene. */\r\nexport function buildPrefabView(document: ProjectDocument, prefabId: string, profile: LayoutProfileId, options: BuildSceneViewOptions, configuration: PrefabViewConfiguration = {}): SceneViewResult & { instanceId: string } {\r\n const synthetic = prefabScene(document, prefabId, configuration);\r\n return { ...buildSceneView(synthetic.document, synthetic.sceneId, profile, { ...options, clipToViewport: false }), instanceId: synthetic.instanceId };\r\n}\r\n\r\n/** Loads a prefab's assets and returns a fresh display tree suitable for dynamic game-code spawning. */\r\nexport async function loadPrefabView(document: ProjectDocument, prefabId: string, profile: LayoutProfileId, resolveFileUrl: FileUrlResolver, options: { interaction: SceneInteractionMode; ticker?: Ticker; localization?: SceneLocalizationOptions; assetCache?: SceneAssetCache }, configuration: PrefabViewConfiguration = {}): Promise<SceneViewResult & { instanceId: string }> {\r\n const synthetic = prefabScene(document, prefabId, configuration);\r\n return { ...await loadSceneView(synthetic.document, synthetic.sceneId, profile, resolveFileUrl, { ...options, clipToViewport: false }), instanceId: synthetic.instanceId };\r\n}\r\n\r\n/** Loads a scene's textures and Spine data, then builds its display tree in one call. */\r\nexport async function loadSceneView(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n profile: LayoutProfileId,\r\n resolveFileUrl: FileUrlResolver,\r\n options: { interaction: SceneInteractionMode; ticker?: Ticker; localization?: SceneLocalizationOptions; clipToViewport?: boolean; assetCache?: SceneAssetCache },\r\n): Promise<SceneViewResult> {\r\n // Без assetCache каждый вызов начинает с пустых кэшей: для одиночной загрузки сцены это нормально, а вот\r\n // игровой код, который поднимает пресеты по одному, обязан передать собственный кэш — иначе один и тот же\r\n // скелет, атлас и текстура парсятся заново на каждую вьюху и дублируются в видеопамяти.\r\n const cache = options.assetCache;\r\n const [textures, spines, fonts, bitmapFonts] = await Promise.all([\r\n loadSceneTextures(document, sceneId, (asset) => (asset.type === \"image\" ? resolveFileUrl(asset.source.uri) : undefined), resolveFileUrl, cache?.textures, cache?.spritesheets, cache?.bitmapFonts),\r\n loadSceneSpines(document, sceneId, resolveFileUrl, cache?.spines),\r\n loadSceneFonts(document, sceneId, resolveFileUrl, cache?.fonts),\r\n loadSceneBitmapFonts(document, sceneId, resolveFileUrl, cache?.bitmapFonts),\r\n ]);\r\n return buildSceneView(document, sceneId, profile, { interaction: options.interaction, textures, spines, fonts, bitmapFonts, ticker: options.ticker, localization: options.localization, clipToViewport: options.clipToViewport });\r\n}\r\n"]}
@@ -1,5 +1,5 @@
1
1
  import { type PaginationNode, type UINode } from "@pixi-ui-editor/schema";
2
- import { Texture } from "pixi.js";
2
+ import { Container, Text, Texture } from "pixi.js";
3
3
  import { Signal } from "typed-signals";
4
4
  import { NodeView, type SceneInteractionMode } from "./NodeView.js";
5
5
  export type { PaginationNode };
@@ -14,6 +14,24 @@ export type PaginationArrow = {
14
14
  };
15
15
  enabled: boolean;
16
16
  };
17
+ /**
18
+ * One `numbers`-style item: a centered page-number label. `width`/`height` are overridden to the
19
+ * authored `dotSize` — the same fixed-footprint trick `ScrollItemContainer` uses — so the `List`
20
+ * spaces every item evenly. The active-page highlight is a separate authored node the widget only
21
+ * toggles `visible` on (see `PaginationNodeView.setActiveBackground`), never a child of this item.
22
+ */
23
+ /** @internal Exported only so DOM-free render-contract tests can exercise the footprint in isolation. */
24
+ export declare class NumberItem extends Container {
25
+ readonly numberText: Text;
26
+ private itemWidth;
27
+ private itemHeight;
28
+ constructor(numberText: Text);
29
+ get width(): number;
30
+ set width(value: number);
31
+ get height(): number;
32
+ set height(value: number);
33
+ resize(width: number, height: number): void;
34
+ }
17
35
  /**
18
36
  * Standalone page indicator: N procedurally generated items arranged by `@pixi/ui`'s `List` (the same
19
37
  * approach `ScrollViewNodeView`/`scrollView.ts` use for arranging children) — this view never
@@ -23,12 +41,11 @@ export type PaginationArrow = {
23
41
  *
24
42
  * `style` picks between two mutually exclusive, differently-rendered item kinds — image dots
25
43
  * (`Sprite`, two states) or rendered page-number text (`NumberItem`: a label, base style + an optional
26
- * highlight color, plus an optional pill background behind only the current page) — never both.
27
- * Switching `style` rebuilds every item, the same "view's required *type* changed" rule
28
- * `StagedButtonNodeView` follows for its state views; `pageCount`/`dotSize` changes do too, since the
29
- * item count/footprint is a runtime fact about this control, not scene topology it only rebuilds this
30
- * view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself
31
- * is not structural: switching pages only recreates the (one) background view that needs to move.
44
+ * highlight color) never both. Switching `style` rebuilds every item, the same "view's required
45
+ * *type* changed" rule `StagedButtonNodeView` follows for its state views; `pageCount`/`dotSize`
46
+ * changes do too, since the item count/footprint is a runtime fact about this control, not scene
47
+ * topology it only rebuilds this view's own item children, never the owning `NodeView` or the wider
48
+ * scene tree.
32
49
  *
33
50
  * With `visiblePageCount` set, the indicator becomes a fixed strip of that many slots with the active
34
51
  * page always in the middle one (4 pages, page 3 active → 2-3-4). A slot pointing outside the real
@@ -36,7 +53,10 @@ export type PaginationArrow = {
36
53
  *
37
54
  * The prev/next arrows are ordinary authored button nodes placed wherever the layout needs them; the
38
55
  * widget only takes their views (`scene.ts`'s `wireNodeReferences`, the same address → view resolution
39
- * Spine connector targets use) and steps the page on press. It never draws an arrow itself.
56
+ * Spine connector targets use) and steps the page on press. It never draws an arrow itself. The
57
+ * `numbers`-style active-page highlight follows the same reference-not-owned contract: it is an
58
+ * authored node the widget only toggles `visible` on while `style: "numbers"` — the node carries its
59
+ * own image / nine-slice / rounded corners / size / position, none of it configured here.
40
60
  */
41
61
  export declare class PaginationNodeView extends NodeView {
42
62
  private readonly list;
@@ -50,8 +70,8 @@ export declare class PaginationNodeView extends NodeView {
50
70
  private inactiveTexture;
51
71
  private numberStyle;
52
72
  private numberActiveColor;
53
- private numberActiveBackgroundTexture;
54
- private numberActiveNineSlice;
73
+ /** The authored highlight node; the widget owns only its `visible` flag while `style: "numbers"`. */
74
+ private activeBackground;
55
75
  private pageCountState;
56
76
  private currentPage;
57
77
  private dotWidth;
@@ -60,7 +80,6 @@ export declare class PaginationNodeView extends NodeView {
60
80
  /** Fires only from a click on an item (when `clickable`); setting `page` programmatically never emits. */
61
81
  readonly onPageChange: Signal<(page: number) => void>;
62
82
  constructor(node: PaginationNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, fonts: ReadonlyMap<string, string> | undefined);
63
- private createBackgroundView;
64
83
  /** How many indicator slots are drawn: the fixed authored window, or one slot per real page. */
65
84
  private get slotCount();
66
85
  /** The page a slot points at. Windowed slots slide with the current page, which keeps its middle seat. */
@@ -82,6 +101,13 @@ export declare class PaginationNodeView extends NodeView {
82
101
  }): void;
83
102
  /** На краях диапазона соответствующая стрелка недоступна — она никуда не ведёт. */
84
103
  private applyArrowState;
104
+ /**
105
+ * Связывает виджет с авторской нодой-подсветкой активной страницы. Как и стрелки, нода остаётся
106
+ * обычным узлом сцены со своим визуалом — виджет лишь владеет её флагом `visible`: показывает при
107
+ * `style: "numbers"` (активная страница есть всегда) и прячет в стиле `dots`.
108
+ */
109
+ setActiveBackground(view: Container | undefined): void;
110
+ private applyActiveBackgroundVisibility;
85
111
  protected syncContent(node: UINode): void;
86
112
  get pageCount(): number;
87
113
  /** Used by `setPaginationViewPageCount` once game code knows the real content length. */