@pixi-ui-editor/runtime-pixi 0.7.1 → 0.8.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.
Files changed (55) hide show
  1. package/dist/SceneViewport.d.ts.map +1 -1
  2. package/dist/assets/bitmapFonts.js.map +1 -1
  3. package/dist/assets/fonts.js.map +1 -1
  4. package/dist/assets/sounds.js.map +1 -1
  5. package/dist/assets/spine.js.map +1 -1
  6. package/dist/assets/textures.js.map +1 -1
  7. package/dist/controls.d.ts +8 -0
  8. package/dist/controls.d.ts.map +1 -1
  9. package/dist/controls.js +12 -1
  10. package/dist/controls.js.map +1 -1
  11. package/dist/document.d.ts.map +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/layoutGroups.d.ts.map +1 -1
  17. package/dist/layoutGroups.js.map +1 -1
  18. package/dist/localization.d.ts.map +1 -1
  19. package/dist/localization.js.map +1 -1
  20. package/dist/pageGroup.d.ts.map +1 -1
  21. package/dist/pageGroup.js.map +1 -1
  22. package/dist/particles.d.ts.map +1 -1
  23. package/dist/particles.js.map +1 -1
  24. package/dist/scene.js.map +1 -1
  25. package/dist/scrollView.d.ts.map +1 -1
  26. package/dist/scrollView.js.map +1 -1
  27. package/dist/views/ButtonNodeView.d.ts +12 -0
  28. package/dist/views/ButtonNodeView.d.ts.map +1 -1
  29. package/dist/views/ButtonNodeView.js +25 -7
  30. package/dist/views/ButtonNodeView.js.map +1 -1
  31. package/dist/views/CheckboxNodeView.d.ts.map +1 -1
  32. package/dist/views/InputNodeView.d.ts.map +1 -1
  33. package/dist/views/NodeView.d.ts +1 -1
  34. package/dist/views/NodeView.d.ts.map +1 -1
  35. package/dist/views/NodeView.js +1 -1
  36. package/dist/views/NodeView.js.map +1 -1
  37. package/dist/views/PageGroupNodeView.d.ts.map +1 -1
  38. package/dist/views/PaginationNodeView.d.ts.map +1 -1
  39. package/dist/views/PaginationNodeView.js.map +1 -1
  40. package/dist/views/ParticleEmitterNodeView.d.ts.map +1 -1
  41. package/dist/views/ScrollViewNodeView.d.ts.map +1 -1
  42. package/dist/views/SpineNodeView.d.ts.map +1 -1
  43. package/dist/views/StagedButtonNodeView.d.ts +12 -1
  44. package/dist/views/StagedButtonNodeView.d.ts.map +1 -1
  45. package/dist/views/StagedButtonNodeView.js +27 -9
  46. package/dist/views/StagedButtonNodeView.js.map +1 -1
  47. package/dist/views/ValueControlNodeViews.d.ts.map +1 -1
  48. package/dist/views/basic.d.ts +27 -1
  49. package/dist/views/basic.d.ts.map +1 -1
  50. package/dist/views/basic.js +44 -0
  51. package/dist/views/basic.js.map +1 -1
  52. package/dist/views/createNodeView.d.ts.map +1 -1
  53. package/dist/views/createNodeView.js +4 -1
  54. package/dist/views/createNodeView.js.map +1 -1
  55. package/package.json +5 -2
@@ -1 +1 @@
1
- {"version":3,"file":"SceneViewport.d.ts","sourceRoot":"","sources":["../src/SceneViewport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtF;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,SAAS;IAC1C,QAAQ,CAAC,iBAAiB,EAAE,UAAU,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;gBAEhB,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO;IAiB5E,sFAAsF;IACtF,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,cAAc;CAMzC"}
1
+ {"version":3,"file":"SceneViewport.d.ts","sourceRoot":"","sources":["../src/SceneViewport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtF;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,SAAS;IAC1C,QAAQ,CAAC,iBAAiB,EAAE,UAAU,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAE5B,YAAY,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAe3E;IAED,sFAAsF;IACtF,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,cAAc,CAKvC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"bitmapFonts.js","sourceRoot":"","sources":["../../src/assets/bitmapFonts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Asset, ProjectDocument, UINode } from \"@pixi-ui-editor/schema\";\r\nimport { BitmapFont, Cache, bitmapFontXMLStringParser, type Texture } from \"pixi.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { sharedBitmapFontCache } from \"./cache.js\";\r\nimport { loadTexture } from \"./loadTexture.js\";\r\n// Type-only: erased at compile time, so this does not create a runtime import cycle even though\r\n// `textures.ts` imports a value (`loadBitmapFontGlyphTexture`) from this file.\r\nimport type { FileUrlResolver } from \"./textures.js\";\r\n\r\ntype BitmapFontAsset = Extract<Asset, { type: \"bitmapFont\" }>;\r\n\r\nconst keyOf = (asset: BitmapFontAsset) => `${asset.files.xml.uri}#${asset.files.texture.uri}`;\r\n/**\r\n * The synthetic family every loaded font installs under — never whatever `<info face>` its XML\r\n * declares. Two uploaded bitmap fonts could share the same exporter-generated face name, and the\r\n * asset id is the only identity PixiJS's `${fontFamily}-bitmap` Cache key is guaranteed not to collide on.\r\n */\r\nconst familyOf = (assetId: string) => `bitmap-font-${assetId}`;\r\nconst fromNodes = (nodes: UINode[]) => nodes.flatMap((node) => (node.type === \"bitmap-text\" ? [node.assetId] : []));\r\n\r\n/**\r\n * Shared by `loadSceneFonts`'s reasoning (see `sharedFontCache`): a loaded `BitmapFont` registers into\r\n * PixiJS's own global `Cache`, so re-parsing the same asset under a caller-scoped cache would still\r\n * collide there. `cache` defaults to that shared map but accepts a `SceneAssetCache.bitmapFonts` from\r\n * the caller, the same override every other scene asset loader takes.\r\n */\r\nfunction loadFont(asset: BitmapFontAsset, resolveFileUrl: FileUrlResolver, cache: Map<string, Promise<BitmapFont | undefined>>): Promise<BitmapFont | undefined> {\r\n const key = keyOf(asset);\r\n let pending = cache.get(key);\r\n if (pending === undefined) {\r\n pending = (async () => {\r\n const xmlUrl = resolveFileUrl(asset.files.xml.uri);\r\n const textureUrl = resolveFileUrl(asset.files.texture.uri);\r\n if (xmlUrl === undefined || textureUrl === undefined) return undefined;\r\n try {\r\n const [xml, texture] = await Promise.all([fetch(xmlUrl).then((response) => response.text()), loadTexture(textureUrl)]);\r\n const font = new BitmapFont({ data: bitmapFontXMLStringParser.parse(xml), textures: [texture] });\r\n Cache.set(`${familyOf(asset.id)}-bitmap`, font);\r\n return font;\r\n } catch (error) { console.warn(`Unable to load bitmap font asset '${asset.id}'. Text using it will not render.`, error); return undefined; }\r\n })();\r\n cache.set(key, pending);\r\n }\r\n return pending;\r\n}\r\n\r\n/**\r\n * Loads scene bitmap fonts before views are built, mirroring `loadSceneFonts`. Unlike a regular\r\n * `FontFace`, PixiJS resolves a `BitmapText`'s font by looking up `Cache` for `${fontFamily}-bitmap`\r\n * (see `BitmapFontManager.getFont`), so loading here means parsing the XML, building one `BitmapFont`\r\n * from the already-fetched texture, and registering it in that cache — there is no URL-based loader\r\n * to delegate to, since our XML and texture live at unrelated asset URIs, not a fixed relative pair.\r\n */\r\nexport async function loadSceneBitmapFonts(document: ProjectDocument, sceneId: string, resolveFileUrl: FileUrlResolver, cache: Map<string, Promise<BitmapFont | undefined>> = sharedBitmapFontCache): Promise<Map<string, string>> {\r\n const scene = document.scenes.find((item) => item.id === sceneId);\r\n if (scene === undefined) throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n const ids = new Set(fromNodes(collectRenderedNodes(document, scene)));\r\n const fonts = new Map<string, string>();\r\n await Promise.all([...ids].map(async (id) => {\r\n const asset = document.assets.find((item) => item.id === id);\r\n if (asset?.type !== \"bitmapFont\") return;\r\n const font = await loadFont(asset, resolveFileUrl, cache);\r\n if (font !== undefined) fonts.set(id, familyOf(asset.id));\r\n }));\r\n return fonts;\r\n}\r\n\r\n/**\r\n * Resolves one glyph's already-cropped `Texture` from a bitmap font asset, for reuse as a plain image\r\n * asset (an Image node, a Button/Checkbox state, ...) — see `BitmapFontAsset.frames`. `BitmapFont`\r\n * builds one `Texture` per character up front (see its constructor), so this is a lookup, not a crop.\r\n */\r\nexport async function loadBitmapFontGlyphTexture(asset: BitmapFontAsset, glyph: string, resolveFileUrl: FileUrlResolver, cache: Map<string, Promise<BitmapFont | undefined>> = sharedBitmapFontCache): Promise<Texture | undefined> {\r\n const font = await loadFont(asset, resolveFileUrl, cache);\r\n return font?.chars[glyph]?.texture;\r\n}\r\n"]}
1
+ {"version":3,"file":"bitmapFonts.js","sourceRoot":"","sources":["../../src/assets/bitmapFonts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,yBAAyB,EAAgB,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAO/C,MAAM,KAAK,GAAG,CAAC,KAAsB,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;AAC9F;;;;GAIG;AACH,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,eAAe,OAAO,EAAE,CAAC;AAC/D,MAAM,SAAS,GAAG,CAAC,KAAe,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEpH;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,KAAsB,EAAE,cAA+B,EAAE,KAAmD;IAC5H,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;YACpB,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnD,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3D,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YACvE,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBACvH,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,IAAI,EAAE,yBAAyB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACjG,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBAChD,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,qCAAqC,KAAK,CAAC,EAAE,mCAAmC,EAAE,KAAK,CAAC,CAAC;gBAAC,OAAO,SAAS,CAAC;YAAC,CAAC;QAC9I,CAAC,CAAC,EAAE,CAAC;QACL,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAyB,EAAE,OAAe,EAAE,cAA+B,EAAE,KAAK,GAAiD,qBAAqB;IACjM,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IAClE,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,2CAA2C,CAAC,CAAC;IACvG,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,IAAI,KAAK,EAAE,IAAI,KAAK,YAAY;YAAE,OAAO;QACzC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;QAC1D,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC,CAAC;IACJ,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,KAAsB,EAAE,KAAa,EAAE,cAA+B,EAAE,KAAK,GAAiD,qBAAqB;IAClM,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;IAC1D,OAAO,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;AACrC,CAAC","sourcesContent":["import type { Asset, ProjectDocument, UINode } from \"@pixi-ui-editor/schema\";\r\nimport { BitmapFont, Cache, bitmapFontXMLStringParser, type Texture } from \"pixi.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { sharedBitmapFontCache } from \"./cache.js\";\r\nimport { loadTexture } from \"./loadTexture.js\";\r\n// Type-only: erased at compile time, so this does not create a runtime import cycle even though\r\n// `textures.ts` imports a value (`loadBitmapFontGlyphTexture`) from this file.\r\nimport type { FileUrlResolver } from \"./textures.js\";\r\n\r\ntype BitmapFontAsset = Extract<Asset, { type: \"bitmapFont\" }>;\r\n\r\nconst keyOf = (asset: BitmapFontAsset) => `${asset.files.xml.uri}#${asset.files.texture.uri}`;\r\n/**\r\n * The synthetic family every loaded font installs under — never whatever `<info face>` its XML\r\n * declares. Two uploaded bitmap fonts could share the same exporter-generated face name, and the\r\n * asset id is the only identity PixiJS's `${fontFamily}-bitmap` Cache key is guaranteed not to collide on.\r\n */\r\nconst familyOf = (assetId: string) => `bitmap-font-${assetId}`;\r\nconst fromNodes = (nodes: UINode[]) => nodes.flatMap((node) => (node.type === \"bitmap-text\" ? [node.assetId] : []));\r\n\r\n/**\r\n * Shared by `loadSceneFonts`'s reasoning (see `sharedFontCache`): a loaded `BitmapFont` registers into\r\n * PixiJS's own global `Cache`, so re-parsing the same asset under a caller-scoped cache would still\r\n * collide there. `cache` defaults to that shared map but accepts a `SceneAssetCache.bitmapFonts` from\r\n * the caller, the same override every other scene asset loader takes.\r\n */\r\nfunction loadFont(asset: BitmapFontAsset, resolveFileUrl: FileUrlResolver, cache: Map<string, Promise<BitmapFont | undefined>>): Promise<BitmapFont | undefined> {\r\n const key = keyOf(asset);\r\n let pending = cache.get(key);\r\n if (pending === undefined) {\r\n pending = (async () => {\r\n const xmlUrl = resolveFileUrl(asset.files.xml.uri);\r\n const textureUrl = resolveFileUrl(asset.files.texture.uri);\r\n if (xmlUrl === undefined || textureUrl === undefined) return undefined;\r\n try {\r\n const [xml, texture] = await Promise.all([fetch(xmlUrl).then((response) => response.text()), loadTexture(textureUrl)]);\r\n const font = new BitmapFont({ data: bitmapFontXMLStringParser.parse(xml), textures: [texture] });\r\n Cache.set(`${familyOf(asset.id)}-bitmap`, font);\r\n return font;\r\n } catch (error) { console.warn(`Unable to load bitmap font asset '${asset.id}'. Text using it will not render.`, error); return undefined; }\r\n })();\r\n cache.set(key, pending);\r\n }\r\n return pending;\r\n}\r\n\r\n/**\r\n * Loads scene bitmap fonts before views are built, mirroring `loadSceneFonts`. Unlike a regular\r\n * `FontFace`, PixiJS resolves a `BitmapText`'s font by looking up `Cache` for `${fontFamily}-bitmap`\r\n * (see `BitmapFontManager.getFont`), so loading here means parsing the XML, building one `BitmapFont`\r\n * from the already-fetched texture, and registering it in that cache — there is no URL-based loader\r\n * to delegate to, since our XML and texture live at unrelated asset URIs, not a fixed relative pair.\r\n */\r\nexport async function loadSceneBitmapFonts(document: ProjectDocument, sceneId: string, resolveFileUrl: FileUrlResolver, cache: Map<string, Promise<BitmapFont | undefined>> = sharedBitmapFontCache): Promise<Map<string, string>> {\r\n const scene = document.scenes.find((item) => item.id === sceneId);\r\n if (scene === undefined) throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n const ids = new Set(fromNodes(collectRenderedNodes(document, scene)));\r\n const fonts = new Map<string, string>();\r\n await Promise.all([...ids].map(async (id) => {\r\n const asset = document.assets.find((item) => item.id === id);\r\n if (asset?.type !== \"bitmapFont\") return;\r\n const font = await loadFont(asset, resolveFileUrl, cache);\r\n if (font !== undefined) fonts.set(id, familyOf(asset.id));\r\n }));\r\n return fonts;\r\n}\r\n\r\n/**\r\n * Resolves one glyph's already-cropped `Texture` from a bitmap font asset, for reuse as a plain image\r\n * asset (an Image node, a Button/Checkbox state, ...) — see `BitmapFontAsset.frames`. `BitmapFont`\r\n * builds one `Texture` per character up front (see its constructor), so this is a lookup, not a crop.\r\n */\r\nexport async function loadBitmapFontGlyphTexture(asset: BitmapFontAsset, glyph: string, resolveFileUrl: FileUrlResolver, cache: Map<string, Promise<BitmapFont | undefined>> = sharedBitmapFontCache): Promise<Texture | undefined> {\r\n const font = await loadFont(asset, resolveFileUrl, cache);\r\n return font?.chars[glyph]?.texture;\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../src/assets/fonts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Asset, ProjectDocument, UINode } from \"@pixi-ui-editor/schema\";\r\nimport type { FileUrlResolver } from \"./textures.js\";\r\nimport { sharedFontCache } from \"./cache.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\n\r\nconst keyOf = (asset: Extract<Asset, { type: \"font\" }>) => `${asset.source.uri}#${asset.source.version ?? \"\"}`;\r\nconst fromNodes = (nodes: UINode[]) => nodes.flatMap((node) => {\r\n if (node.type === \"text\" && node.style?.fontAssetId) return [node.style.fontAssetId];\r\n if (node.type === \"input\" && node.textStyle.fontAssetId) return [node.textStyle.fontAssetId];\r\n if (node.type === \"slider\" && node.valueTextStyle?.fontAssetId) return [node.valueTextStyle.fontAssetId];\r\n return [];\r\n});\r\n\r\n/** Loads scene fonts before views are built. A load failure is a warning and keeps system fallback usable. */\r\nexport async function loadSceneFonts(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Promise<string | undefined>> = sharedFontCache,\r\n): Promise<Map<string, string>> {\r\n const scene = document.scenes.find((item) => item.id === sceneId);\r\n if (scene === undefined) throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n const ids = new Set(fromNodes(collectRenderedNodes(document, scene)));\r\n const fonts = new Map<string, string>();\r\n await Promise.all([...ids].map(async (id) => {\r\n const asset = document.assets.find((item) => item.id === id);\r\n if (asset?.type !== \"font\") return;\r\n const key = keyOf(asset);\r\n let pending = cache.get(key);\r\n if (pending === undefined) {\r\n pending = (async () => {\r\n const url = resolveFileUrl(asset.source.uri);\r\n if (url === undefined || typeof FontFace === \"undefined\" || typeof globalThis.document === \"undefined\") return undefined;\r\n try { const face = new FontFace(asset.family, `url(${JSON.stringify(url)})`, { weight: asset.weight, style: asset.style }); await face.load(); globalThis.document.fonts.add(face); return asset.family; }\r\n catch (error) { console.warn(`Unable to load font asset '${asset.id}'. Using system fallback.`, error); return undefined; }\r\n })();\r\n cache.set(key, pending);\r\n }\r\n const family = await pending; if (family !== undefined) fonts.set(id, family);\r\n }));\r\n return fonts;\r\n}\r\n"]}
1
+ {"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../src/assets/fonts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Asset, ProjectDocument, UINode } from \"@pixi-ui-editor/schema\";\r\nimport type { FileUrlResolver } from \"./textures.js\";\r\nimport { sharedFontCache } from \"./cache.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\n\r\nconst keyOf = (asset: Extract<Asset, { type: \"font\" }>) => `${asset.source.uri}#${asset.source.version ?? \"\"}`;\r\nconst fromNodes = (nodes: UINode[]) => nodes.flatMap((node) => {\r\n if (node.type === \"text\" && node.style?.fontAssetId) return [node.style.fontAssetId];\r\n if (node.type === \"input\" && node.textStyle.fontAssetId) return [node.textStyle.fontAssetId];\r\n if (node.type === \"slider\" && node.valueTextStyle?.fontAssetId) return [node.valueTextStyle.fontAssetId];\r\n return [];\r\n});\r\n\r\n/** Loads scene fonts before views are built. A load failure is a warning and keeps system fallback usable. */\r\nexport async function loadSceneFonts(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Promise<string | undefined>> = sharedFontCache,\r\n): Promise<Map<string, string>> {\r\n const scene = document.scenes.find((item) => item.id === sceneId);\r\n if (scene === undefined) throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n const ids = new Set(fromNodes(collectRenderedNodes(document, scene)));\r\n const fonts = new Map<string, string>();\r\n await Promise.all([...ids].map(async (id) => {\r\n const asset = document.assets.find((item) => item.id === id);\r\n if (asset?.type !== \"font\") return;\r\n const key = keyOf(asset);\r\n let pending = cache.get(key);\r\n if (pending === undefined) {\r\n pending = (async () => {\r\n const url = resolveFileUrl(asset.source.uri);\r\n if (url === undefined || typeof FontFace === \"undefined\" || typeof globalThis.document === \"undefined\") return undefined;\r\n try { const face = new FontFace(asset.family, `url(${JSON.stringify(url)})`, { weight: asset.weight, style: asset.style }); await face.load(); globalThis.document.fonts.add(face); return asset.family; }\r\n catch (error) { console.warn(`Unable to load font asset '${asset.id}'. Using system fallback.`, error); return undefined; }\r\n })();\r\n cache.set(key, pending);\r\n }\r\n const family = await pending; if (family !== undefined) fonts.set(id, family);\r\n }));\r\n return fonts;\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sounds.js","sourceRoot":"","sources":["../../src/assets/sounds.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE,KAAK,UAAU,SAAS,CAAC,MAAmB;IAC1C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,OAAc,CAAC;QACnB,IAAI,CAAC;YACH,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;gBACnB,MAAM;gBACN,OAAO,EAAE,IAAI;gBACb,0FAA0F;gBAC1F,8FAA8F;gBAC9F,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aACtF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,QAAyB,EACzB,GAAqB,EACrB,cAA+B,EAC/B,QAA4B,IAAI,GAAG,EAAE;IAErC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAC;IACxC,KAAK,MAAM,OAAO,IAAI,GAAG,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO;YAAE,SAAS;QACtC,IAAI,CAAC;YACH,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC7C,IAAI,GAAG,KAAK,SAAS;oBAAE,SAAS;gBAChC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,CAAC,QAAQ,CAAC,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,MAAM,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;gBACzG,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;gBACvD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACtC,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,mCAAmC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,iBAAiB,CAC/B,QAAyB,EACzB,cAA+B,EAC/B,QAA4B,IAAI,GAAG,EAAE;IAErC,OAAO,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;AAC9I,CAAC;AAED,0GAA0G;AAC1G,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAyB,EACzB,OAAe,EACf,cAA+B,EAC/B,QAA4B,IAAI,GAAG,EAAE;IAErC,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;IACvG,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,KAAK,CAAC,KAAK,EAAE,sBAAsB,KAAK,SAAS;QAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACnG,KAAK,MAAM,IAAI,IAAI,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;QACzD,KAAK,MAAM,OAAO,IAAI,mBAAmB,CAAC,IAAI,CAAC;YAAE,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,OAAO;gBAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACnH,CAAC;IACD,OAAO,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;AAC/D,CAAC;AAOD,qGAAqG;AACrG,MAAM,UAAU,wBAAwB;IACtC,IAAI,OAA2B,CAAC;IAChC,IAAI,YAA+B,CAAC;IACpC,IAAI,eAA2C,CAAC;IAChD,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,YAAsC,CAAC;IAE3C,MAAM,kBAAkB,GAAG,GAAG,EAAE;QAC9B,IAAI,YAAY,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;QACzH,YAAY,GAAG,SAAS,CAAC;IAC3B,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,kBAAkB,EAAE,CAAC;QACrB,YAAY,EAAE,IAAI,EAAE,CAAC;QACrB,eAAe,GAAG,SAAS,CAAC;QAC5B,YAAY,GAAG,SAAS,CAAC;QACzB,OAAO,GAAG,SAAS,CAAC;IACtB,CAAC,CAAC;IACF,MAAM,uBAAuB,GAAG,CAAC,KAAY,EAAE,EAAE;QAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAgD,CAAC;QACvE,OAAO,OAAO,CAAC,YAAY,EAAE,KAAK,KAAK,WAAW,CAAC;IACrD,CAAC,CAAC;IACF,MAAM,aAAa,GAAG,CAAC,KAAiB,EAAE,EAAE;QAC1C,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,YAAY,KAAK,SAAS;YAAE,OAAO;QACxE,YAAY,GAAG,GAAG,EAAE;YAClB,YAAY,GAAG,SAAS,CAAC;YACzB,eAAe,EAAE,IAAI,EAAE,CAAC;YACxB,eAAe,GAAG,SAAS,CAAC;YAC5B,MAAM,OAAO,GAAI,YAAY,EAAE,OAA2E,EAAE,YAAY,CAAC;YACzH,IAAI,OAAO,EAAE,MAAM,KAAK,SAAS;gBAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;;gBACnE,KAAK,EAAE,CAAC;QACf,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAuB;QACnC,MAAM,CAAC,KAAK,EAAE,MAAM;YAClB,MAAM,WAAW,GAAG,KAAK,EAAE,sBAAsB,CAAC;YAClD,MAAM,SAAS,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAClF,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;YAClC,aAAa,GAAG,MAAM,CAAC;YACvB,IAAI,WAAW,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBACzD,WAAW,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,IAAI,OAAO,KAAK,WAAW,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC1D,IAAI,eAAe,KAAK,SAAS;oBAAE,eAAe,CAAC,MAAM,GAAG,aAAa,CAAC;gBAC1E,OAAO;YACT,CAAC;YAED,WAAW,EAAE,CAAC;YACd,OAAO,GAAG,WAAW,CAAC;YACtB,YAAY,GAAG,SAAS,CAAC;YACzB,MAAM,KAAK,GAAG,GAAG,EAAE;gBACjB,IAAI,OAAO,KAAK,WAAW,IAAI,YAAY,KAAK,SAAS;oBAAE,OAAO;gBAClE,kBAAkB,EAAE,CAAC;gBACrB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;oBACrE,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;wBAC9B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;4BAC5B,IAAI,OAAO,KAAK,WAAW,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gCAAC,eAAe,GAAG,QAAQ,CAAC;gCAAC,QAAQ,CAAC,MAAM,GAAG,aAAa,CAAC;4BAAC,CAAC;;gCACtH,QAAQ,CAAC,IAAI,EAAE,CAAC;wBACvB,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;oBACvC,CAAC;yBAAM,CAAC;wBACN,eAAe,GAAG,MAAM,CAAC;wBACzB,IAAI,uBAAuB,CAAC,SAAS,CAAC;4BAAE,aAAa,CAAC,KAAK,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,aAAa,CAAC,KAAK,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC,CAAC;YACF,KAAK,EAAE,CAAC;QACV,CAAC;QACD,IAAI,EAAE,WAAW;KAClB,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import type { Sound, IMediaInstance } from \"@pixi/sound\";\r\nimport type { ProjectDocument, Scene } from \"@pixi-ui-editor/schema\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { collectNodeAssetIds } from \"../views/createNodeView.js\";\r\nimport type { FileUrlResolver } from \"./textures.js\";\r\n\r\nasync function loadSound(source: ArrayBuffer): Promise<Sound> {\r\n const { Sound } = await import(\"@pixi/sound\");\r\n return new Promise((resolve, reject) => {\r\n let created: Sound;\r\n try {\r\n created = Sound.from({\r\n source,\r\n preload: true,\r\n // @pixi/sound's runtime uses the Node-style `null` success value although its declaration\r\n // only mentions Error. Accept both null and undefined or every successful decode is rejected.\r\n loaded: (error, loaded) => error == null ? resolve(loaded ?? created) : reject(error),\r\n });\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nasync function loadSoundAssets(\r\n document: ProjectDocument,\r\n ids: Iterable<string>,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Sound> = new Map(),\r\n): Promise<Map<string, Sound>> {\r\n const assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const sounds = new Map<string, Sound>();\r\n for (const assetId of ids) {\r\n const asset = assetsById.get(assetId);\r\n if (asset?.type !== \"sound\") continue;\r\n try {\r\n let loaded = cache.get(asset.source.uri);\r\n if (loaded === undefined) {\r\n const url = resolveFileUrl(asset.source.uri);\r\n if (url === undefined) continue;\r\n const response = await fetch(url);\r\n if (!response.ok) throw new Error(`Unable to fetch '${url}': ${response.status} ${response.statusText}`);\r\n loaded = await loadSound(await response.arrayBuffer());\r\n cache.set(asset.source.uri, loaded);\r\n }\r\n sounds.set(asset.id, loaded);\r\n } catch (error) {\r\n console.warn(`Unable to load sound for asset '${asset.id}'.`, error);\r\n }\r\n }\r\n return sounds;\r\n}\r\n\r\n/** Loads every sound asset up front, useful for an editor Preview whose assignments change live. */\r\nexport function loadProjectSounds(\r\n document: ProjectDocument,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Sound> = new Map(),\r\n): Promise<Map<string, Sound>> {\r\n return loadSoundAssets(document, document.assets.filter((asset) => asset.type === \"sound\").map((asset) => asset.id), resolveFileUrl, cache);\r\n}\r\n\r\n/** Loads the background track and button sounds used by one rendered scene. Failed assets stay silent. */\r\nexport async function loadSceneSounds(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Sound> = new Map(),\r\n): Promise<Map<string, Sound>> {\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 const assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const ids = new Set<string>();\r\n if (scene.audio?.backgroundMusicAssetId !== undefined) ids.add(scene.audio.backgroundMusicAssetId);\r\n for (const node of collectRenderedNodes(document, scene)) {\r\n for (const assetId of collectNodeAssetIds(node)) if (assetsById.get(assetId)?.type === \"sound\") ids.add(assetId);\r\n }\r\n return loadSoundAssets(document, ids, resolveFileUrl, cache);\r\n}\r\n\r\nexport type SceneAudioPlayback = {\r\n update(audio: Scene[\"audio\"], sounds: ReadonlyMap<string, Sound>): void;\r\n stop(): void;\r\n};\r\n\r\n/** Owns one scene's looping background track and retries browser-blocked autoplay on first input. */\r\nexport function createSceneAudioPlayback(): SceneAudioPlayback {\r\n let assetId: string | undefined;\r\n let currentSound: Sound | undefined;\r\n let currentInstance: IMediaInstance | undefined;\r\n let currentVolume = 1;\r\n let pendingStart: (() => void) | undefined;\r\n\r\n const removePendingStart = () => {\r\n if (pendingStart !== undefined && typeof window !== \"undefined\") window.removeEventListener(\"pointerdown\", pendingStart);\r\n pendingStart = undefined;\r\n };\r\n const stopCurrent = () => {\r\n removePendingStart();\r\n currentSound?.stop();\r\n currentInstance = undefined;\r\n currentSound = undefined;\r\n assetId = undefined;\r\n };\r\n const audioContextIsSuspended = (sound: Sound) => {\r\n const context = sound.context as { audioContext?: { state?: string } };\r\n return context.audioContext?.state === \"suspended\";\r\n };\r\n const scheduleRetry = (start: () => void) => {\r\n if (typeof window === \"undefined\" || pendingStart !== undefined) return;\r\n pendingStart = () => {\r\n pendingStart = undefined;\r\n currentInstance?.stop();\r\n currentInstance = undefined;\r\n const context = (currentSound?.context as { audioContext?: { resume?: () => Promise<void> } } | undefined)?.audioContext;\r\n if (context?.resume !== undefined) void context.resume().finally(start);\r\n else start();\r\n };\r\n window.addEventListener(\"pointerdown\", pendingStart, { once: true });\r\n };\r\n\r\n const playback: SceneAudioPlayback = {\r\n update(audio, sounds) {\r\n const nextAssetId = audio?.backgroundMusicAssetId;\r\n const nextSound = nextAssetId === undefined ? undefined : sounds.get(nextAssetId);\r\n const volume = audio?.volume ?? 1;\r\n currentVolume = volume;\r\n if (nextAssetId === undefined || nextSound === undefined) {\r\n stopCurrent();\r\n return;\r\n }\r\n if (assetId === nextAssetId && currentSound === nextSound) {\r\n if (currentInstance !== undefined) currentInstance.volume = currentVolume;\r\n return;\r\n }\r\n\r\n stopCurrent();\r\n assetId = nextAssetId;\r\n currentSound = nextSound;\r\n const start = () => {\r\n if (assetId !== nextAssetId || currentSound !== nextSound) return;\r\n removePendingStart();\r\n try {\r\n const result = nextSound.play({ loop: true, volume: currentVolume });\r\n if (result instanceof Promise) {\r\n void result.then((instance) => {\r\n if (assetId === nextAssetId && currentSound === nextSound) { currentInstance = instance; instance.volume = currentVolume; }\r\n else instance.stop();\r\n }).catch(() => scheduleRetry(start));\r\n } else {\r\n currentInstance = result;\r\n if (audioContextIsSuspended(nextSound)) scheduleRetry(start);\r\n }\r\n } catch {\r\n scheduleRetry(start);\r\n }\r\n };\r\n start();\r\n },\r\n stop: stopCurrent,\r\n };\r\n return playback;\r\n}\r\n"]}
1
+ {"version":3,"file":"sounds.js","sourceRoot":"","sources":["../../src/assets/sounds.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Sound, IMediaInstance } from \"@pixi/sound\";\r\nimport type { ProjectDocument, Scene } from \"@pixi-ui-editor/schema\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { collectNodeAssetIds } from \"../views/createNodeView.js\";\r\nimport type { FileUrlResolver } from \"./textures.js\";\r\n\r\nasync function loadSound(source: ArrayBuffer): Promise<Sound> {\r\n const { Sound } = await import(\"@pixi/sound\");\r\n return new Promise((resolve, reject) => {\r\n let created: Sound;\r\n try {\r\n created = Sound.from({\r\n source,\r\n preload: true,\r\n // @pixi/sound's runtime uses the Node-style `null` success value although its declaration\r\n // only mentions Error. Accept both null and undefined or every successful decode is rejected.\r\n loaded: (error, loaded) => error == null ? resolve(loaded ?? created) : reject(error),\r\n });\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nasync function loadSoundAssets(\r\n document: ProjectDocument,\r\n ids: Iterable<string>,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Sound> = new Map(),\r\n): Promise<Map<string, Sound>> {\r\n const assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const sounds = new Map<string, Sound>();\r\n for (const assetId of ids) {\r\n const asset = assetsById.get(assetId);\r\n if (asset?.type !== \"sound\") continue;\r\n try {\r\n let loaded = cache.get(asset.source.uri);\r\n if (loaded === undefined) {\r\n const url = resolveFileUrl(asset.source.uri);\r\n if (url === undefined) continue;\r\n const response = await fetch(url);\r\n if (!response.ok) throw new Error(`Unable to fetch '${url}': ${response.status} ${response.statusText}`);\r\n loaded = await loadSound(await response.arrayBuffer());\r\n cache.set(asset.source.uri, loaded);\r\n }\r\n sounds.set(asset.id, loaded);\r\n } catch (error) {\r\n console.warn(`Unable to load sound for asset '${asset.id}'.`, error);\r\n }\r\n }\r\n return sounds;\r\n}\r\n\r\n/** Loads every sound asset up front, useful for an editor Preview whose assignments change live. */\r\nexport function loadProjectSounds(\r\n document: ProjectDocument,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Sound> = new Map(),\r\n): Promise<Map<string, Sound>> {\r\n return loadSoundAssets(document, document.assets.filter((asset) => asset.type === \"sound\").map((asset) => asset.id), resolveFileUrl, cache);\r\n}\r\n\r\n/** Loads the background track and button sounds used by one rendered scene. Failed assets stay silent. */\r\nexport async function loadSceneSounds(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Sound> = new Map(),\r\n): Promise<Map<string, Sound>> {\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 const assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const ids = new Set<string>();\r\n if (scene.audio?.backgroundMusicAssetId !== undefined) ids.add(scene.audio.backgroundMusicAssetId);\r\n for (const node of collectRenderedNodes(document, scene)) {\r\n for (const assetId of collectNodeAssetIds(node)) if (assetsById.get(assetId)?.type === \"sound\") ids.add(assetId);\r\n }\r\n return loadSoundAssets(document, ids, resolveFileUrl, cache);\r\n}\r\n\r\nexport type SceneAudioPlayback = {\r\n update(audio: Scene[\"audio\"], sounds: ReadonlyMap<string, Sound>): void;\r\n stop(): void;\r\n};\r\n\r\n/** Owns one scene's looping background track and retries browser-blocked autoplay on first input. */\r\nexport function createSceneAudioPlayback(): SceneAudioPlayback {\r\n let assetId: string | undefined;\r\n let currentSound: Sound | undefined;\r\n let currentInstance: IMediaInstance | undefined;\r\n let currentVolume = 1;\r\n let pendingStart: (() => void) | undefined;\r\n\r\n const removePendingStart = () => {\r\n if (pendingStart !== undefined && typeof window !== \"undefined\") window.removeEventListener(\"pointerdown\", pendingStart);\r\n pendingStart = undefined;\r\n };\r\n const stopCurrent = () => {\r\n removePendingStart();\r\n currentSound?.stop();\r\n currentInstance = undefined;\r\n currentSound = undefined;\r\n assetId = undefined;\r\n };\r\n const audioContextIsSuspended = (sound: Sound) => {\r\n const context = sound.context as { audioContext?: { state?: string } };\r\n return context.audioContext?.state === \"suspended\";\r\n };\r\n const scheduleRetry = (start: () => void) => {\r\n if (typeof window === \"undefined\" || pendingStart !== undefined) return;\r\n pendingStart = () => {\r\n pendingStart = undefined;\r\n currentInstance?.stop();\r\n currentInstance = undefined;\r\n const context = (currentSound?.context as { audioContext?: { resume?: () => Promise<void> } } | undefined)?.audioContext;\r\n if (context?.resume !== undefined) void context.resume().finally(start);\r\n else start();\r\n };\r\n window.addEventListener(\"pointerdown\", pendingStart, { once: true });\r\n };\r\n\r\n const playback: SceneAudioPlayback = {\r\n update(audio, sounds) {\r\n const nextAssetId = audio?.backgroundMusicAssetId;\r\n const nextSound = nextAssetId === undefined ? undefined : sounds.get(nextAssetId);\r\n const volume = audio?.volume ?? 1;\r\n currentVolume = volume;\r\n if (nextAssetId === undefined || nextSound === undefined) {\r\n stopCurrent();\r\n return;\r\n }\r\n if (assetId === nextAssetId && currentSound === nextSound) {\r\n if (currentInstance !== undefined) currentInstance.volume = currentVolume;\r\n return;\r\n }\r\n\r\n stopCurrent();\r\n assetId = nextAssetId;\r\n currentSound = nextSound;\r\n const start = () => {\r\n if (assetId !== nextAssetId || currentSound !== nextSound) return;\r\n removePendingStart();\r\n try {\r\n const result = nextSound.play({ loop: true, volume: currentVolume });\r\n if (result instanceof Promise) {\r\n void result.then((instance) => {\r\n if (assetId === nextAssetId && currentSound === nextSound) { currentInstance = instance; instance.volume = currentVolume; }\r\n else instance.stop();\r\n }).catch(() => scheduleRetry(start));\r\n } else {\r\n currentInstance = result;\r\n if (audioContextIsSuspended(nextSound)) scheduleRetry(start);\r\n }\r\n } catch {\r\n scheduleRetry(start);\r\n }\r\n };\r\n start();\r\n },\r\n stop: stopCurrent,\r\n };\r\n return playback;\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"spine.js","sourceRoot":"","sources":["../../src/assets/spine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAqB,MAAM,iCAAiC,CAAC;AAG5I,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,WAAW,EAAwB,MAAM,eAAe,CAAC;AAElE,4QAA4Q;AAC5Q,MAAM,oCAAoC,GAAG,iDAAiD,CAAC;AAE/F,SAAS,0BAA0B,CAAC,KAAc;IAChD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,IAAI,oCAAoC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,OAAO,oCAAoC,OAAO,oLAAoL,CAAC;IACzO,CAAC;IACD,OAAO,kCAAkC,OAAO,EAAE,CAAC;AACrD,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,uBAAuB,CAAC,KAAmB,EAAE,QAAsC;IACjG,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,IAAI,iCAAiC,CAAC,CAAC;QACtG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,eAAe,CAAC,YAA0B,EAAE,SAAkB,EAAE,UAAqD,EAAE;IACrI,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1G,IAAI,SAAS,KAAK,SAAS,IAAI,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,IAAI;QAAE,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC5H,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAyB,EACzB,OAAe,EACf,cAA+B,EAC/B,QAAmC,IAAI,GAAG,EAAE;IAE5C,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,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;QACzD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,SAAS;QAChE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO;YAAE,SAAS;QAEtC,IAAI,CAAC;YAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAC/F,OAAO,CAAC,IAAI,CAAC,+BAA+B,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAwC,EAAE,cAA+B,EAAE,QAAmC,IAAI,GAAG,EAAE;IAC1J,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,WAAW,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACpH,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACnK,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,IAAI,0BAA0B,CAAC,CAAC;QACxF,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACzC,IAAI,YAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IACnG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,EAAE,0BAA0B,WAAW,EAAE,CAAC,CAAC;QAC/F,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAClD,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import { AtlasAttachmentLoader, SkeletonJson, Spine, SpineTexture, TextureAtlas, type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { type Asset, type ProjectDocument } from \"@pixi-ui-editor/schema\";\r\nimport { Texture, type Ticker } from \"pixi.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { loadTexture, type FileUrlResolver } from \"./textures.js\";\r\n\r\n/** Matches spine-pixi-v8's \"unknown timeline/attachment/constraint type\" errors, thrown when a skeleton was exported by an incompatible Spine Editor version (e.g. pre-4.0 JSON, which names slot color timelines \"color\"/\"twoColor\" instead of the 4.x \"rgba\"/\"rgba2\"). */\r\nconst INCOMPATIBLE_SKELETON_FORMAT_PATTERN = /Invalid (?:timeline|attachment|constraint) type/;\r\n\r\nfunction describeSkeletonParseError(error: unknown): string {\r\n const message = error instanceof Error ? error.message : String(error);\r\n if (INCOMPATIBLE_SKELETON_FORMAT_PATTERN.test(message)) {\r\n return `Unsupported Spine export format (${message}). The skeleton was likely exported by a Spine Editor version incompatible with this runtime (spine-pixi-v8 4.2, Spine 4.0–4.2 JSON). Re-export it from Spine Editor 4.2 or older.`;\r\n }\r\n return `Failed to parse skeleton data: ${message}`;\r\n}\r\n\r\n/** Assigns atlas pages by their exported image filename, never by their array index. */\r\nexport function assignAtlasPageTextures(atlas: TextureAtlas, textures: ReadonlyMap<string, Texture>): void {\r\n for (const page of atlas.pages) {\r\n const texture = textures.get(page.name);\r\n if (texture === undefined) throw new Error(`Atlas page '${page.name}' has no matching texture file.`);\r\n page.setTexture(SpineTexture.from(texture.source));\r\n }\r\n}\r\n\r\n/** Creates a Spine display object, optionally assigning it to a specific renderer ticker. */\r\nexport function createSpineView(skeletonData: SkeletonData, animation?: string, options: { autoUpdate?: boolean; ticker?: Ticker } = {}): Spine {\r\n const spine = new Spine({ skeletonData, autoUpdate: options.autoUpdate ?? true, ticker: options.ticker });\r\n if (animation !== undefined && skeletonData.findAnimation(animation) !== null) spine.state.setAnimation(0, animation, true);\r\n return spine;\r\n}\r\n\r\n/** Loads the Spine data referenced by a scene. Failed assets are left out for placeholder rendering. */\r\nexport async function loadSceneSpines(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, SkeletonData> = new Map(),\r\n): Promise<Map<string, SkeletonData>> {\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 assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const spines = new Map<string, SkeletonData>();\r\n for (const node of collectRenderedNodes(document, scene)) {\r\n if (node.type !== \"spine\" || spines.has(node.assetId)) continue;\r\n const asset = assetsById.get(node.assetId);\r\n if (asset?.type !== \"spine\") continue;\r\n\r\n try { spines.set(asset.id, await loadSpineAsset(asset, resolveFileUrl, cache)); } catch (error) {\r\n console.warn(`Unable to load Spine asset '${asset.name}' (${asset.id}).`, error);\r\n }\r\n }\r\n return spines;\r\n}\r\n\r\n/** Loads one Spine asset, sharing parsed SkeletonData by skeleton file URI. */\r\nexport async function loadSpineAsset(asset: Extract<Asset, { type: \"spine\" }>, resolveFileUrl: FileUrlResolver, cache: Map<string, SkeletonData> = new Map()): Promise<SkeletonData> {\r\n const cached = cache.get(asset.files.skeleton.uri);\r\n if (cached !== undefined) return cached;\r\n const skeletonUrl = resolveFileUrl(asset.files.skeleton.uri);\r\n const atlasUrl = resolveFileUrl(asset.files.atlas.uri);\r\n if (skeletonUrl === undefined || atlasUrl === undefined) throw new Error(\"A Spine file URL could not be resolved.\");\r\n const [skeletonText, atlasText] = await Promise.all([fetch(skeletonUrl).then((response) => response.text()), fetch(atlasUrl).then((response) => response.text())]);\r\n const textures = new Map<string, Texture>();\r\n for (const file of asset.files.textures) {\r\n const url = resolveFileUrl(file.uri);\r\n if (url === undefined) throw new Error(`Texture '${file.name}' could not be resolved.`);\r\n textures.set(file.name, await loadTexture(url));\r\n }\r\n const atlas = new TextureAtlas(atlasText);\r\n assignAtlasPageTextures(atlas, textures);\r\n let skeletonData: SkeletonData;\r\n try {\r\n skeletonData = new SkeletonJson(new AtlasAttachmentLoader(atlas)).readSkeletonData(skeletonText);\r\n } catch (error) {\r\n const description = describeSkeletonParseError(error);\r\n console.error(`Spine asset '${asset.name}' (${asset.id}) could not be parsed: ${description}`);\r\n throw new Error(description, { cause: error });\r\n }\r\n cache.set(asset.files.skeleton.uri, skeletonData);\r\n return skeletonData;\r\n}\r\n"]}
1
+ {"version":3,"file":"spine.js","sourceRoot":"","sources":["../../src/assets/spine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAqB,MAAM,iCAAiC,CAAC;AAG5I,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,WAAW,EAAwB,MAAM,eAAe,CAAC;AAElE,4QAA4Q;AAC5Q,MAAM,oCAAoC,GAAG,iDAAiD,CAAC;AAE/F,SAAS,0BAA0B,CAAC,KAAc;IAChD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,IAAI,oCAAoC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,OAAO,oCAAoC,OAAO,oLAAoL,CAAC;IACzO,CAAC;IACD,OAAO,kCAAkC,OAAO,EAAE,CAAC;AACrD,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,uBAAuB,CAAC,KAAmB,EAAE,QAAsC;IACjG,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,IAAI,iCAAiC,CAAC,CAAC;QACtG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,eAAe,CAAC,YAA0B,EAAE,SAAkB,EAAE,OAAO,GAA8C,EAAE;IACrI,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1G,IAAI,SAAS,KAAK,SAAS,IAAI,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,IAAI;QAAE,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC5H,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAyB,EACzB,OAAe,EACf,cAA+B,EAC/B,KAAK,GAA8B,IAAI,GAAG,EAAE;IAE5C,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,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;QACzD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,SAAS;QAChE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO;YAAE,SAAS;QAEtC,IAAI,CAAC;YAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAC/F,OAAO,CAAC,IAAI,CAAC,+BAA+B,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAwC,EAAE,cAA+B,EAAE,KAAK,GAA8B,IAAI,GAAG,EAAE;IAC1J,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,WAAW,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACpH,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACnK,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,IAAI,0BAA0B,CAAC,CAAC;QACxF,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACzC,IAAI,YAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IACnG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,EAAE,0BAA0B,WAAW,EAAE,CAAC,CAAC;QAC/F,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAClD,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import { AtlasAttachmentLoader, SkeletonJson, Spine, SpineTexture, TextureAtlas, type SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { type Asset, type ProjectDocument } from \"@pixi-ui-editor/schema\";\r\nimport { Texture, type Ticker } from \"pixi.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { loadTexture, type FileUrlResolver } from \"./textures.js\";\r\n\r\n/** Matches spine-pixi-v8's \"unknown timeline/attachment/constraint type\" errors, thrown when a skeleton was exported by an incompatible Spine Editor version (e.g. pre-4.0 JSON, which names slot color timelines \"color\"/\"twoColor\" instead of the 4.x \"rgba\"/\"rgba2\"). */\r\nconst INCOMPATIBLE_SKELETON_FORMAT_PATTERN = /Invalid (?:timeline|attachment|constraint) type/;\r\n\r\nfunction describeSkeletonParseError(error: unknown): string {\r\n const message = error instanceof Error ? error.message : String(error);\r\n if (INCOMPATIBLE_SKELETON_FORMAT_PATTERN.test(message)) {\r\n return `Unsupported Spine export format (${message}). The skeleton was likely exported by a Spine Editor version incompatible with this runtime (spine-pixi-v8 4.2, Spine 4.0–4.2 JSON). Re-export it from Spine Editor 4.2 or older.`;\r\n }\r\n return `Failed to parse skeleton data: ${message}`;\r\n}\r\n\r\n/** Assigns atlas pages by their exported image filename, never by their array index. */\r\nexport function assignAtlasPageTextures(atlas: TextureAtlas, textures: ReadonlyMap<string, Texture>): void {\r\n for (const page of atlas.pages) {\r\n const texture = textures.get(page.name);\r\n if (texture === undefined) throw new Error(`Atlas page '${page.name}' has no matching texture file.`);\r\n page.setTexture(SpineTexture.from(texture.source));\r\n }\r\n}\r\n\r\n/** Creates a Spine display object, optionally assigning it to a specific renderer ticker. */\r\nexport function createSpineView(skeletonData: SkeletonData, animation?: string, options: { autoUpdate?: boolean; ticker?: Ticker } = {}): Spine {\r\n const spine = new Spine({ skeletonData, autoUpdate: options.autoUpdate ?? true, ticker: options.ticker });\r\n if (animation !== undefined && skeletonData.findAnimation(animation) !== null) spine.state.setAnimation(0, animation, true);\r\n return spine;\r\n}\r\n\r\n/** Loads the Spine data referenced by a scene. Failed assets are left out for placeholder rendering. */\r\nexport async function loadSceneSpines(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, SkeletonData> = new Map(),\r\n): Promise<Map<string, SkeletonData>> {\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 assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const spines = new Map<string, SkeletonData>();\r\n for (const node of collectRenderedNodes(document, scene)) {\r\n if (node.type !== \"spine\" || spines.has(node.assetId)) continue;\r\n const asset = assetsById.get(node.assetId);\r\n if (asset?.type !== \"spine\") continue;\r\n\r\n try { spines.set(asset.id, await loadSpineAsset(asset, resolveFileUrl, cache)); } catch (error) {\r\n console.warn(`Unable to load Spine asset '${asset.name}' (${asset.id}).`, error);\r\n }\r\n }\r\n return spines;\r\n}\r\n\r\n/** Loads one Spine asset, sharing parsed SkeletonData by skeleton file URI. */\r\nexport async function loadSpineAsset(asset: Extract<Asset, { type: \"spine\" }>, resolveFileUrl: FileUrlResolver, cache: Map<string, SkeletonData> = new Map()): Promise<SkeletonData> {\r\n const cached = cache.get(asset.files.skeleton.uri);\r\n if (cached !== undefined) return cached;\r\n const skeletonUrl = resolveFileUrl(asset.files.skeleton.uri);\r\n const atlasUrl = resolveFileUrl(asset.files.atlas.uri);\r\n if (skeletonUrl === undefined || atlasUrl === undefined) throw new Error(\"A Spine file URL could not be resolved.\");\r\n const [skeletonText, atlasText] = await Promise.all([fetch(skeletonUrl).then((response) => response.text()), fetch(atlasUrl).then((response) => response.text())]);\r\n const textures = new Map<string, Texture>();\r\n for (const file of asset.files.textures) {\r\n const url = resolveFileUrl(file.uri);\r\n if (url === undefined) throw new Error(`Texture '${file.name}' could not be resolved.`);\r\n textures.set(file.name, await loadTexture(url));\r\n }\r\n const atlas = new TextureAtlas(atlasText);\r\n assignAtlasPageTextures(atlas, textures);\r\n let skeletonData: SkeletonData;\r\n try {\r\n skeletonData = new SkeletonJson(new AtlasAttachmentLoader(atlas)).readSkeletonData(skeletonText);\r\n } catch (error) {\r\n const description = describeSkeletonParseError(error);\r\n console.error(`Spine asset '${asset.name}' (${asset.id}) could not be parsed: ${description}`);\r\n throw new Error(description, { cause: error });\r\n }\r\n cache.set(asset.files.skeleton.uri, skeletonData);\r\n return skeletonData;\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"textures.js","sourceRoot":"","sources":["../../src/assets/textures.ts"],"names":[],"mappings":"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","sourcesContent":["import { collectEffectAssetIds, type Asset, type ProjectDocument } from \"@pixi-ui-editor/schema\";\r\nimport { Spritesheet, type BitmapFont, type Texture, type SpritesheetData } from \"pixi.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { collectNodeAssetIds } from \"../views/createNodeView.js\";\r\nimport { loadBitmapFontGlyphTexture } from \"./bitmapFonts.js\";\r\nimport { sharedBitmapFontCache } from \"./cache.js\";\r\nimport { loadTexture } from \"./loadTexture.js\";\r\n\r\nexport type AssetUrlResolver = (asset: Asset) => string | undefined;\r\nexport type FileUrlResolver = (uri: string) => string | undefined;\r\ntype AtlasAsset = Extract<Asset, { type: \"atlas\" }>;\r\ntype BitmapFontAsset = Extract<Asset, { type: \"bitmapFont\" }>;\r\n\r\nexport { loadTexture };\r\n\r\n/** Loads and parses one atlas's Spritesheet, sharing the parse by the JSON file's URI. */\r\nexport async function loadAtlasSpritesheet(\r\n asset: AtlasAsset,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Spritesheet> = new Map(),\r\n): Promise<Spritesheet> {\r\n const cached = cache.get(asset.files.json.uri);\r\n if (cached !== undefined) return cached;\r\n\r\n const jsonUrl = resolveFileUrl(asset.files.json.uri);\r\n const textureUrl = resolveFileUrl(asset.files.texture.uri);\r\n if (jsonUrl === undefined || textureUrl === undefined) throw new Error(`Unable to resolve file URLs for atlas asset '${asset.id}'.`);\r\n\r\n const [data, texture] = await Promise.all([\r\n fetch(jsonUrl).then((response) => response.json() as Promise<SpritesheetData>),\r\n loadTexture(textureUrl),\r\n ]);\r\n const sheet = new Spritesheet(texture, data);\r\n await sheet.parse();\r\n cache.set(asset.files.json.uri, sheet);\r\n return sheet;\r\n}\r\n\r\n/** Loads textures for image nodes in a scene, resolving atlas frame ids through their Spritesheet. Leaves failed assets for placeholder rendering. */\r\nexport async function loadSceneTextures(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveAssetUrl: AssetUrlResolver,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Texture> = new Map(),\r\n spritesheetCache: Map<string, Spritesheet> = new Map(),\r\n bitmapFontCache: Map<string, Promise<BitmapFont | undefined>> = sharedBitmapFontCache,\r\n): Promise<Map<string, Texture>> {\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 assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const framesById = new Map<string, { kind: \"atlas\"; atlas: AtlasAsset; frameName: string } | { kind: \"bitmapFont\"; bitmapFont: BitmapFontAsset; frameName: string }>();\r\n for (const asset of document.assets) {\r\n if (asset.type === \"atlas\") { for (const [frameName, frameId] of Object.entries(asset.frames)) framesById.set(frameId, { kind: \"atlas\", atlas: asset, frameName }); }\r\n else if (asset.type === \"bitmapFont\") { for (const [frameName, frameId] of Object.entries(asset.frames ?? {})) framesById.set(frameId, { kind: \"bitmapFont\", bitmapFont: asset, frameName }); }\r\n }\r\n\r\n const textures = new Map<string, Texture>();\r\n\r\n for (const node of collectRenderedNodes(document, scene)) {\r\n const effect = node.type === \"particle-emitter\" ? document.effects.find((candidate) => candidate.id === node.effectId) : undefined;\r\n for (const assetId of [...collectNodeAssetIds(node), ...(effect === undefined ? [] : collectEffectAssetIds(effect))]) {\r\n if (textures.has(assetId)) continue;\r\n\r\n const asset = assetsById.get(assetId);\r\n if (asset?.type === \"image\") {\r\n const url = resolveAssetUrl(asset);\r\n if (url === undefined) continue;\r\n try {\r\n const texture = cache.get(asset.source.uri) ?? await loadTexture(url);\r\n cache.set(asset.source.uri, texture);\r\n textures.set(asset.id, texture);\r\n } catch (error) {\r\n console.warn(`Unable to load texture for asset '${asset.id}'.`, error);\r\n }\r\n continue;\r\n }\r\n // Spine и atlas-ассеты сюда тоже попадают: spine-данные грузит loadSceneSpines, а atlas-фреймы резолвятся ниже.\r\n if (asset !== undefined) continue;\r\n\r\n const frame = framesById.get(assetId);\r\n if (frame === undefined) continue;\r\n try {\r\n if (frame.kind === \"atlas\") {\r\n const sheet = await loadAtlasSpritesheet(frame.atlas, resolveFileUrl, spritesheetCache);\r\n const frameTexture = sheet.textures[frame.frameName];\r\n if (frameTexture === undefined) { console.warn(`Atlas '${frame.atlas.id}' has no frame '${frame.frameName}'.`); continue; }\r\n textures.set(assetId, frameTexture);\r\n } else {\r\n const glyphTexture = await loadBitmapFontGlyphTexture(frame.bitmapFont, frame.frameName, resolveFileUrl, bitmapFontCache);\r\n if (glyphTexture === undefined) { console.warn(`Bitmap font '${frame.bitmapFont.id}' has no glyph '${frame.frameName}'.`); continue; }\r\n textures.set(assetId, glyphTexture);\r\n }\r\n } catch (error) {\r\n console.warn(`Unable to load frame texture for '${assetId}'.`, error);\r\n }\r\n }\r\n }\r\n\r\n return textures;\r\n}\r\n"]}
1
+ {"version":3,"file":"textures.js","sourceRoot":"","sources":["../../src/assets/textures.ts"],"names":[],"mappings":"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","sourcesContent":["import { collectEffectAssetIds, type Asset, type ProjectDocument } from \"@pixi-ui-editor/schema\";\r\nimport { Spritesheet, type BitmapFont, type Texture, type SpritesheetData } from \"pixi.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { collectNodeAssetIds } from \"../views/createNodeView.js\";\r\nimport { loadBitmapFontGlyphTexture } from \"./bitmapFonts.js\";\r\nimport { sharedBitmapFontCache } from \"./cache.js\";\r\nimport { loadTexture } from \"./loadTexture.js\";\r\n\r\nexport type AssetUrlResolver = (asset: Asset) => string | undefined;\r\nexport type FileUrlResolver = (uri: string) => string | undefined;\r\ntype AtlasAsset = Extract<Asset, { type: \"atlas\" }>;\r\ntype BitmapFontAsset = Extract<Asset, { type: \"bitmapFont\" }>;\r\n\r\nexport { loadTexture };\r\n\r\n/** Loads and parses one atlas's Spritesheet, sharing the parse by the JSON file's URI. */\r\nexport async function loadAtlasSpritesheet(\r\n asset: AtlasAsset,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Spritesheet> = new Map(),\r\n): Promise<Spritesheet> {\r\n const cached = cache.get(asset.files.json.uri);\r\n if (cached !== undefined) return cached;\r\n\r\n const jsonUrl = resolveFileUrl(asset.files.json.uri);\r\n const textureUrl = resolveFileUrl(asset.files.texture.uri);\r\n if (jsonUrl === undefined || textureUrl === undefined) throw new Error(`Unable to resolve file URLs for atlas asset '${asset.id}'.`);\r\n\r\n const [data, texture] = await Promise.all([\r\n fetch(jsonUrl).then((response) => response.json() as Promise<SpritesheetData>),\r\n loadTexture(textureUrl),\r\n ]);\r\n const sheet = new Spritesheet(texture, data);\r\n await sheet.parse();\r\n cache.set(asset.files.json.uri, sheet);\r\n return sheet;\r\n}\r\n\r\n/** Loads textures for image nodes in a scene, resolving atlas frame ids through their Spritesheet. Leaves failed assets for placeholder rendering. */\r\nexport async function loadSceneTextures(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveAssetUrl: AssetUrlResolver,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Texture> = new Map(),\r\n spritesheetCache: Map<string, Spritesheet> = new Map(),\r\n bitmapFontCache: Map<string, Promise<BitmapFont | undefined>> = sharedBitmapFontCache,\r\n): Promise<Map<string, Texture>> {\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 assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const framesById = new Map<string, { kind: \"atlas\"; atlas: AtlasAsset; frameName: string } | { kind: \"bitmapFont\"; bitmapFont: BitmapFontAsset; frameName: string }>();\r\n for (const asset of document.assets) {\r\n if (asset.type === \"atlas\") { for (const [frameName, frameId] of Object.entries(asset.frames)) framesById.set(frameId, { kind: \"atlas\", atlas: asset, frameName }); }\r\n else if (asset.type === \"bitmapFont\") { for (const [frameName, frameId] of Object.entries(asset.frames ?? {})) framesById.set(frameId, { kind: \"bitmapFont\", bitmapFont: asset, frameName }); }\r\n }\r\n\r\n const textures = new Map<string, Texture>();\r\n\r\n for (const node of collectRenderedNodes(document, scene)) {\r\n const effect = node.type === \"particle-emitter\" ? document.effects.find((candidate) => candidate.id === node.effectId) : undefined;\r\n for (const assetId of [...collectNodeAssetIds(node), ...(effect === undefined ? [] : collectEffectAssetIds(effect))]) {\r\n if (textures.has(assetId)) continue;\r\n\r\n const asset = assetsById.get(assetId);\r\n if (asset?.type === \"image\") {\r\n const url = resolveAssetUrl(asset);\r\n if (url === undefined) continue;\r\n try {\r\n const texture = cache.get(asset.source.uri) ?? await loadTexture(url);\r\n cache.set(asset.source.uri, texture);\r\n textures.set(asset.id, texture);\r\n } catch (error) {\r\n console.warn(`Unable to load texture for asset '${asset.id}'.`, error);\r\n }\r\n continue;\r\n }\r\n // Spine и atlas-ассеты сюда тоже попадают: spine-данные грузит loadSceneSpines, а atlas-фреймы резолвятся ниже.\r\n if (asset !== undefined) continue;\r\n\r\n const frame = framesById.get(assetId);\r\n if (frame === undefined) continue;\r\n try {\r\n if (frame.kind === \"atlas\") {\r\n const sheet = await loadAtlasSpritesheet(frame.atlas, resolveFileUrl, spritesheetCache);\r\n const frameTexture = sheet.textures[frame.frameName];\r\n if (frameTexture === undefined) { console.warn(`Atlas '${frame.atlas.id}' has no frame '${frame.frameName}'.`); continue; }\r\n textures.set(assetId, frameTexture);\r\n } else {\r\n const glyphTexture = await loadBitmapFontGlyphTexture(frame.bitmapFont, frame.frameName, resolveFileUrl, bitmapFontCache);\r\n if (glyphTexture === undefined) { console.warn(`Bitmap font '${frame.bitmapFont.id}' has no glyph '${frame.frameName}'.`); continue; }\r\n textures.set(assetId, glyphTexture);\r\n }\r\n } catch (error) {\r\n console.warn(`Unable to load frame texture for '${assetId}'.`, error);\r\n }\r\n }\r\n }\r\n\r\n return textures;\r\n}\r\n"]}
@@ -37,6 +37,14 @@ export declare function setPageGroupViewPage(view: Container, page: number): voi
37
37
  * if a `pagination` widget is showing this group's page count.
38
38
  */
39
39
  export declare function addPageGroupViewPage(view: Container, page: Container): number | undefined;
40
+ /**
41
+ * Fades a whole subtree by driving one opacity group, the cheap `CanvasGroup.alpha` equivalent: the
42
+ * value multiplies into every descendant through PixiJS `worldAlpha`, so animating a fade is one write
43
+ * per frame regardless of how many nodes are inside. The node's authored `opacity` stays untouched in
44
+ * the document; pass `undefined` to hand control back to it. Tweening itself belongs to game code —
45
+ * the runtime deliberately ships no animation engine, the same way `page-group` ships no swipe gesture.
46
+ */
47
+ export declare function setOpacityGroupViewOpacity(view: Container, opacity: number | undefined): void;
40
48
  /** Enables or pauses editor-only automatic playback without affecting serialized node data. */
41
49
  export declare function setSpineViewAutoplay(view: Container, autoplay: boolean): void;
42
50
  /** Activates authored bone/slot part connectors on one Spine node without mutating the document. */
@@ -1 +1 @@
1
- {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAgBpC,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CASnJ;AAED,kHAAkH;AAClH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CASrH;AAED,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAE/E;AAED,4GAA4G;AAC5G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAE9E;AAED,+GAA+G;AAC/G,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE7E;AAED,yGAAyG;AACzG,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAErF;AAED,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI,CAEhF;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvE;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAElF;AAED,yHAAyH;AACzH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzE;AAED,2GAA2G;AAC3G,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAEnF;AAED,kGAAkG;AAClG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAExE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAEzF;AAED,+FAA+F;AAC/F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAG7E;AAED,oGAAoG;AACpG,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAEnF;AAED,wFAAwF;AACxF,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI,CAE1F"}
1
+ {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAgBpC,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CASnJ;AAED,kHAAkH;AAClH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CASrH;AAED,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAE/E;AAED,4GAA4G;AAC5G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAE9E;AAED,+GAA+G;AAC/G,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE7E;AAED,yGAAyG;AACzG,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAErF;AAED,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI,CAEhF;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvE;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAElF;AAED,yHAAyH;AACzH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzE;AAED,2GAA2G;AAC3G,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAEnF;AAED,kGAAkG;AAClG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAExE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAEzF;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE7F;AAED,+FAA+F;AAC/F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAG7E;AAED,oGAAoG;AACpG,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAEnF;AAED,wFAAwF;AACxF,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI,CAE1F"}
package/dist/controls.js CHANGED
@@ -4,7 +4,7 @@ import { CheckboxNodeView } from "./views/CheckboxNodeView.js";
4
4
  import { PageGroupNodeView } from "./views/PageGroupNodeView.js";
5
5
  import { PaginationNodeView } from "./views/PaginationNodeView.js";
6
6
  import { StagedButtonNodeView } from "./views/StagedButtonNodeView.js";
7
- import { ImageNodeView } from "./views/basic.js";
7
+ import { ImageNodeView, OpacityGroupNodeView } from "./views/basic.js";
8
8
  import { NodeView } from "./views/NodeView.js";
9
9
  import { ProgressBarNodeView, SliderNodeView } from "./views/ValueControlNodeViews.js";
10
10
  import { SpineNodeView } from "./views/SpineNodeView.js";
@@ -98,6 +98,17 @@ export function setPageGroupViewPage(view, page) {
98
98
  export function addPageGroupViewPage(view, page) {
99
99
  return view instanceof PageGroupNodeView ? view.addPage(page) : undefined;
100
100
  }
101
+ /**
102
+ * Fades a whole subtree by driving one opacity group, the cheap `CanvasGroup.alpha` equivalent: the
103
+ * value multiplies into every descendant through PixiJS `worldAlpha`, so animating a fade is one write
104
+ * per frame regardless of how many nodes are inside. The node's authored `opacity` stays untouched in
105
+ * the document; pass `undefined` to hand control back to it. Tweening itself belongs to game code —
106
+ * the runtime deliberately ships no animation engine, the same way `page-group` ships no swipe gesture.
107
+ */
108
+ export function setOpacityGroupViewOpacity(view, opacity) {
109
+ if (view instanceof OpacityGroupNodeView)
110
+ view.setOpacity(opacity);
111
+ }
101
112
  /** Enables or pauses editor-only automatic playback without affecting serialized node data. */
102
113
  export function setSpineViewAutoplay(view, autoplay) {
103
114
  const spine = findSpineChild(view);
@@ -1 +1 @@
1
- {"version":3,"file":"controls.js","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SkeletonData, Spine } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { type ButtonStateKey, type LayoutPadding } from \"@pixi-ui-editor/schema\";\r\nimport { Container } from \"pixi.js\";\r\nimport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\r\nimport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\r\nimport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\r\nimport { PaginationNodeView } from \"./views/PaginationNodeView.js\";\r\nimport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\r\nimport { ImageNodeView } from \"./views/basic.js\";\r\nimport { NodeView } from \"./views/NodeView.js\";\r\nimport { ProgressBarNodeView, SliderNodeView } from \"./views/ValueControlNodeViews.js\";\r\nimport { SpineNodeView } from \"./views/SpineNodeView.js\";\r\n\r\nfunction findSpineChild(view: Container): Spine | undefined {\r\n if (view instanceof NodeView) return view.getSpine();\r\n return view instanceof Spine ? view : view.children.find((child): child is Spine => child instanceof Spine);\r\n}\r\n\r\n/** Reads the current 1-based animation frame for an editor Spine node. */\r\nexport function getSpineViewPlayback(view: Container, skeletonData: SkeletonData, animation: string): { current: number; total: number } | undefined {\r\n const spine = findSpineChild(view);\r\n const track = spine?.state.tracks[0];\r\n const duration = skeletonData.findAnimation(animation)?.duration;\r\n if (track === null || track === undefined || duration === undefined || duration <= 0) return undefined;\r\n const fps = skeletonData.fps && skeletonData.fps > 0 ? skeletonData.fps : 60;\r\n const total = Math.max(1, Math.round(duration * fps));\r\n const time = track.loop ? track.trackTime % duration : Math.min(track.trackTime, duration);\r\n return { current: Math.min(total, Math.floor(time * fps) + 1), total };\r\n}\r\n\r\n/** Seeks an editor Spine node to a 1-based animation frame without changing its serialized animation settings. */\r\nexport function setSpineViewFrame(view: Container, frame: number, skeletonData: SkeletonData, animation: string): void {\r\n const spine = findSpineChild(view);\r\n const track = spine?.state.tracks[0];\r\n const duration = skeletonData.findAnimation(animation)?.duration;\r\n if (track === null || track === undefined || duration === undefined || duration <= 0) return;\r\n const fps = skeletonData.fps && skeletonData.fps > 0 ? skeletonData.fps : 60;\r\n const total = Math.max(1, Math.round(duration * fps));\r\n track.trackTime = Math.min(total, Math.max(1, Math.round(frame)) - 1) / fps;\r\n spine?.update(0);\r\n}\r\n\r\n/** Forces an editor-only button state; the node's serialized `enabled` and states stay untouched. */\r\nexport function setButtonViewState(view: Container, state: ButtonStateKey): void {\r\n if (view instanceof ButtonNodeView) view.setState(state);\r\n}\r\n\r\n/** Forces an editor-only checkbox checked state; the node's serialized `defaultChecked` stays untouched. */\r\nexport function setCheckboxViewChecked(view: Container, checked: boolean): void {\r\n if (view instanceof CheckboxNodeView) view.forceCheck(checked);\r\n}\r\n\r\n/** Forces an editor-only staged button preview stage; the document's `stages`/current stage stay untouched. */\r\nexport function setStagedButtonViewStage(view: Container, index: number): void {\r\n if (view instanceof StagedButtonNodeView) view.forceStage(index);\r\n}\r\n\r\n/** Forces an editor-only staged button visual state; the node's serialized `enabled` stays untouched. */\r\nexport function setStagedButtonViewState(view: Container, state: ButtonStateKey): void {\r\n if (view instanceof StagedButtonNodeView) view.setState(state);\r\n}\r\n\r\n/** Live-previews nine-slice border edits while dragging the canvas gizmo; commits only on release. */\r\nexport function previewNineSlice(view: Container, nineSlice: LayoutPadding): void {\r\n if (view instanceof ImageNodeView || view instanceof ButtonNodeView || view instanceof StagedButtonNodeView) view.previewNineSlice(nineSlice);\r\n}\r\n\r\n/** Applies an editor-only slider preview value without touching the document. */\r\nexport function setSliderViewValue(view: Container, value: number): void {\r\n if (view instanceof SliderNodeView) view.value = value;\r\n}\r\n\r\n/** Applies an editor-only progress preview without touching the document. */\r\nexport function setProgressBarViewProgress(view: Container, progress: number): void {\r\n if (view instanceof ProgressBarNodeView) view.progress = progress;\r\n}\r\n\r\n/** One-way sync from game code (or editor preview) into the widget: highlights a dot without emitting `onPageChange`. */\r\nexport function setPaginationViewPage(view: Container, page: number): void {\r\n if (view instanceof PaginationNodeView) view.page = page;\r\n}\r\n\r\n/** Rebuilds the widget's dots for a runtime-known page count, e.g. once actual content length is known. */\r\nexport function setPaginationViewPageCount(view: Container, pageCount: number): void {\r\n if (view instanceof PaginationNodeView) view.pageCount = pageCount;\r\n}\r\n\r\n/** Switches which direct child (\"page\") of a page group is shown; every other child is hidden. */\r\nexport function setPageGroupViewPage(view: Container, page: number): void {\r\n if (view instanceof PageGroupNodeView) view.page = page;\r\n}\r\n\r\n/**\r\n * Appends a page built at runtime (e.g. the `root` from `buildPrefabView`/`loadPrefabView`, or any\r\n * hand-built `Container`) after the last one — for a dataset that grows during play (a spin history\r\n * list, a chat log, ...) rather than one fully known at authoring time. Fits the page to the group's\r\n * current rectangle and hides it until switched to. Returns the new page's index, or `undefined` if\r\n * `view` is not a page group. Keep `setPaginationViewPageCount` in sync with the resulting `pageCount`\r\n * if a `pagination` widget is showing this group's page count.\r\n */\r\nexport function addPageGroupViewPage(view: Container, page: Container): number | undefined {\r\n return view instanceof PageGroupNodeView ? view.addPage(page) : undefined;\r\n}\r\n\r\n/** Enables or pauses editor-only automatic playback without affecting serialized node data. */\r\nexport function setSpineViewAutoplay(view: Container, autoplay: boolean): void {\r\n const spine = findSpineChild(view);\r\n if (spine !== undefined) spine.autoUpdate = autoplay;\r\n}\r\n\r\n/** Activates authored bone/slot part connectors on one Spine node without mutating the document. */\r\nexport function setSpineConnectorBonesActive(view: Container, active: boolean): void {\r\n if (view instanceof SpineNodeView) view.activeConnectorBones = active;\r\n}\r\n\r\n/** Reasserts active connector matrices after a host performs live node-view updates. */\r\nexport function refreshSpineConnectorBones(nodeViews: ReadonlyMap<string, Container>): void {\r\n for (const view of nodeViews.values()) if (view instanceof SpineNodeView && view.activeConnectorBones) view.refreshConnectorBones();\r\n}\r\n"]}
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SkeletonData, Spine } from \"@esotericsoftware/spine-pixi-v8\";\r\nimport { type ButtonStateKey, type LayoutPadding } from \"@pixi-ui-editor/schema\";\r\nimport { Container } from \"pixi.js\";\r\nimport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\r\nimport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\r\nimport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\r\nimport { PaginationNodeView } from \"./views/PaginationNodeView.js\";\r\nimport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\r\nimport { ImageNodeView, OpacityGroupNodeView } from \"./views/basic.js\";\r\nimport { NodeView } from \"./views/NodeView.js\";\r\nimport { ProgressBarNodeView, SliderNodeView } from \"./views/ValueControlNodeViews.js\";\r\nimport { SpineNodeView } from \"./views/SpineNodeView.js\";\r\n\r\nfunction findSpineChild(view: Container): Spine | undefined {\r\n if (view instanceof NodeView) return view.getSpine();\r\n return view instanceof Spine ? view : view.children.find((child): child is Spine => child instanceof Spine);\r\n}\r\n\r\n/** Reads the current 1-based animation frame for an editor Spine node. */\r\nexport function getSpineViewPlayback(view: Container, skeletonData: SkeletonData, animation: string): { current: number; total: number } | undefined {\r\n const spine = findSpineChild(view);\r\n const track = spine?.state.tracks[0];\r\n const duration = skeletonData.findAnimation(animation)?.duration;\r\n if (track === null || track === undefined || duration === undefined || duration <= 0) return undefined;\r\n const fps = skeletonData.fps && skeletonData.fps > 0 ? skeletonData.fps : 60;\r\n const total = Math.max(1, Math.round(duration * fps));\r\n const time = track.loop ? track.trackTime % duration : Math.min(track.trackTime, duration);\r\n return { current: Math.min(total, Math.floor(time * fps) + 1), total };\r\n}\r\n\r\n/** Seeks an editor Spine node to a 1-based animation frame without changing its serialized animation settings. */\r\nexport function setSpineViewFrame(view: Container, frame: number, skeletonData: SkeletonData, animation: string): void {\r\n const spine = findSpineChild(view);\r\n const track = spine?.state.tracks[0];\r\n const duration = skeletonData.findAnimation(animation)?.duration;\r\n if (track === null || track === undefined || duration === undefined || duration <= 0) return;\r\n const fps = skeletonData.fps && skeletonData.fps > 0 ? skeletonData.fps : 60;\r\n const total = Math.max(1, Math.round(duration * fps));\r\n track.trackTime = Math.min(total, Math.max(1, Math.round(frame)) - 1) / fps;\r\n spine?.update(0);\r\n}\r\n\r\n/** Forces an editor-only button state; the node's serialized `enabled` and states stay untouched. */\r\nexport function setButtonViewState(view: Container, state: ButtonStateKey): void {\r\n if (view instanceof ButtonNodeView) view.setState(state);\r\n}\r\n\r\n/** Forces an editor-only checkbox checked state; the node's serialized `defaultChecked` stays untouched. */\r\nexport function setCheckboxViewChecked(view: Container, checked: boolean): void {\r\n if (view instanceof CheckboxNodeView) view.forceCheck(checked);\r\n}\r\n\r\n/** Forces an editor-only staged button preview stage; the document's `stages`/current stage stay untouched. */\r\nexport function setStagedButtonViewStage(view: Container, index: number): void {\r\n if (view instanceof StagedButtonNodeView) view.forceStage(index);\r\n}\r\n\r\n/** Forces an editor-only staged button visual state; the node's serialized `enabled` stays untouched. */\r\nexport function setStagedButtonViewState(view: Container, state: ButtonStateKey): void {\r\n if (view instanceof StagedButtonNodeView) view.setState(state);\r\n}\r\n\r\n/** Live-previews nine-slice border edits while dragging the canvas gizmo; commits only on release. */\r\nexport function previewNineSlice(view: Container, nineSlice: LayoutPadding): void {\r\n if (view instanceof ImageNodeView || view instanceof ButtonNodeView || view instanceof StagedButtonNodeView) view.previewNineSlice(nineSlice);\r\n}\r\n\r\n/** Applies an editor-only slider preview value without touching the document. */\r\nexport function setSliderViewValue(view: Container, value: number): void {\r\n if (view instanceof SliderNodeView) view.value = value;\r\n}\r\n\r\n/** Applies an editor-only progress preview without touching the document. */\r\nexport function setProgressBarViewProgress(view: Container, progress: number): void {\r\n if (view instanceof ProgressBarNodeView) view.progress = progress;\r\n}\r\n\r\n/** One-way sync from game code (or editor preview) into the widget: highlights a dot without emitting `onPageChange`. */\r\nexport function setPaginationViewPage(view: Container, page: number): void {\r\n if (view instanceof PaginationNodeView) view.page = page;\r\n}\r\n\r\n/** Rebuilds the widget's dots for a runtime-known page count, e.g. once actual content length is known. */\r\nexport function setPaginationViewPageCount(view: Container, pageCount: number): void {\r\n if (view instanceof PaginationNodeView) view.pageCount = pageCount;\r\n}\r\n\r\n/** Switches which direct child (\"page\") of a page group is shown; every other child is hidden. */\r\nexport function setPageGroupViewPage(view: Container, page: number): void {\r\n if (view instanceof PageGroupNodeView) view.page = page;\r\n}\r\n\r\n/**\r\n * Appends a page built at runtime (e.g. the `root` from `buildPrefabView`/`loadPrefabView`, or any\r\n * hand-built `Container`) after the last one — for a dataset that grows during play (a spin history\r\n * list, a chat log, ...) rather than one fully known at authoring time. Fits the page to the group's\r\n * current rectangle and hides it until switched to. Returns the new page's index, or `undefined` if\r\n * `view` is not a page group. Keep `setPaginationViewPageCount` in sync with the resulting `pageCount`\r\n * if a `pagination` widget is showing this group's page count.\r\n */\r\nexport function addPageGroupViewPage(view: Container, page: Container): number | undefined {\r\n return view instanceof PageGroupNodeView ? view.addPage(page) : undefined;\r\n}\r\n\r\n/**\r\n * Fades a whole subtree by driving one opacity group, the cheap `CanvasGroup.alpha` equivalent: the\r\n * value multiplies into every descendant through PixiJS `worldAlpha`, so animating a fade is one write\r\n * per frame regardless of how many nodes are inside. The node's authored `opacity` stays untouched in\r\n * the document; pass `undefined` to hand control back to it. Tweening itself belongs to game code —\r\n * the runtime deliberately ships no animation engine, the same way `page-group` ships no swipe gesture.\r\n */\r\nexport function setOpacityGroupViewOpacity(view: Container, opacity: number | undefined): void {\r\n if (view instanceof OpacityGroupNodeView) view.setOpacity(opacity);\r\n}\r\n\r\n/** Enables or pauses editor-only automatic playback without affecting serialized node data. */\r\nexport function setSpineViewAutoplay(view: Container, autoplay: boolean): void {\r\n const spine = findSpineChild(view);\r\n if (spine !== undefined) spine.autoUpdate = autoplay;\r\n}\r\n\r\n/** Activates authored bone/slot part connectors on one Spine node without mutating the document. */\r\nexport function setSpineConnectorBonesActive(view: Container, active: boolean): void {\r\n if (view instanceof SpineNodeView) view.activeConnectorBones = active;\r\n}\r\n\r\n/** Reasserts active connector matrices after a host performs live node-view updates. */\r\nexport function refreshSpineConnectorBones(nodeViews: ReadonlyMap<string, Container>): void {\r\n for (const view of nodeViews.values()) if (view instanceof SpineNodeView && view.activeConnectorBones) view.refreshConnectorBones();\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEtF,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,IAAI,kBAAkB;gBAEnB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAEnE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAOtE"}
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEtF,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,IAAI,kBAAkB;IAE/B,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAGlD;CACF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAEnE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAOtE"}
package/dist/index.d.ts CHANGED
@@ -21,7 +21,7 @@ export * from "./particles.js";
21
21
  export { collectNodeAssetIds } from "./views/createNodeView.js";
22
22
  export { SceneLocalization } from "./localization.js";
23
23
  export type { SceneLocalizationOptions } from "./localization.js";
24
- export { BitmapTextNodeView, ImageNodeView, MaskNodeView, TextNodeView } from "./views/basic.js";
24
+ export { BitmapTextNodeView, ImageNodeView, MaskNodeView, OpacityGroupNodeView, TextNodeView } from "./views/basic.js";
25
25
  export type { BuildSceneViewOptions, PrefabViewConfiguration, SceneViewResult } from "./scene.js";
26
26
  export { buildPrefabView, buildSceneView, collectRenderedNodes, loadPrefabView, previewNodeView, updateNodeView, updateParticleEmitters, loadSceneView } from "./scene.js";
27
27
  export * from "./controls.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClG,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3K,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACvH,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClG,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3K,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ export { ParticleEmitterNodeView } from "./views/ParticleEmitterNodeView.js";
18
18
  export * from "./particles.js";
19
19
  export { collectNodeAssetIds } from "./views/createNodeView.js";
20
20
  export { SceneLocalization } from "./localization.js";
21
- export { BitmapTextNodeView, ImageNodeView, MaskNodeView, TextNodeView } from "./views/basic.js";
21
+ export { BitmapTextNodeView, ImageNodeView, MaskNodeView, OpacityGroupNodeView, TextNodeView } from "./views/basic.js";
22
22
  export { buildPrefabView, buildSceneView, collectRenderedNodes, loadPrefabView, previewNodeView, updateNodeView, updateParticleEmitters, loadSceneView } from "./scene.js";
23
23
  export * from "./controls.js";
24
24
  export { createSceneAssetCache } from "./assets/cache.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEjG,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3K,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC","sourcesContent":["export type { SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nexport type { Sound } from \"@pixi/sound\";\r\nexport * from \"./document.js\";\r\nexport * from \"./layout.js\";\r\nexport { SceneViewport } from \"./SceneViewport.js\";\r\nexport * from \"./layoutGroups.js\";\r\nexport * from \"./scrollView.js\";\r\nexport * from \"./pageGroup.js\";\r\nexport * from \"./views/NodeView.js\";\r\nexport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\r\nexport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\r\nexport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\r\nexport { InputNodeView } from \"./views/InputNodeView.js\";\r\nexport { ScrollViewNodeView } from \"./views/ScrollViewNodeView.js\";\r\nexport { SpineNodeView } from \"./views/SpineNodeView.js\";\r\nexport { ProgressBarNodeView, SliderNodeView } from \"./views/ValueControlNodeViews.js\";\r\nexport { PaginationNodeView } from \"./views/PaginationNodeView.js\";\r\nexport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\r\nexport { ParticleEmitterNodeView } from \"./views/ParticleEmitterNodeView.js\";\r\nexport * from \"./particles.js\";\r\nexport { collectNodeAssetIds } from \"./views/createNodeView.js\";\r\nexport { SceneLocalization } from \"./localization.js\";\r\nexport type { SceneLocalizationOptions } from \"./localization.js\";\r\nexport { BitmapTextNodeView, ImageNodeView, MaskNodeView, TextNodeView } from \"./views/basic.js\";\r\nexport type { BuildSceneViewOptions, PrefabViewConfiguration, SceneViewResult } from \"./scene.js\";\r\nexport { buildPrefabView, buildSceneView, collectRenderedNodes, loadPrefabView, previewNodeView, updateNodeView, updateParticleEmitters, loadSceneView } from \"./scene.js\";\r\nexport * from \"./controls.js\";\r\nexport { createSceneAssetCache } from \"./assets/cache.js\";\r\nexport type { SceneAssetCache } from \"./assets/cache.js\";\r\nexport * from \"./assets/textures.js\";\r\nexport * from \"./assets/spine.js\";\r\nexport * from \"./assets/fonts.js\";\r\nexport * from \"./assets/bitmapFonts.js\";\r\nexport * from \"./assets/sounds.js\";\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEvH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3K,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC","sourcesContent":["export type { SkeletonData } from \"@esotericsoftware/spine-pixi-v8\";\r\nexport type { Sound } from \"@pixi/sound\";\r\nexport * from \"./document.js\";\r\nexport * from \"./layout.js\";\r\nexport { SceneViewport } from \"./SceneViewport.js\";\r\nexport * from \"./layoutGroups.js\";\r\nexport * from \"./scrollView.js\";\r\nexport * from \"./pageGroup.js\";\r\nexport * from \"./views/NodeView.js\";\r\nexport { ButtonNodeView } from \"./views/ButtonNodeView.js\";\r\nexport { StagedButtonNodeView } from \"./views/StagedButtonNodeView.js\";\r\nexport { CheckboxNodeView } from \"./views/CheckboxNodeView.js\";\r\nexport { InputNodeView } from \"./views/InputNodeView.js\";\r\nexport { ScrollViewNodeView } from \"./views/ScrollViewNodeView.js\";\r\nexport { SpineNodeView } from \"./views/SpineNodeView.js\";\r\nexport { ProgressBarNodeView, SliderNodeView } from \"./views/ValueControlNodeViews.js\";\r\nexport { PaginationNodeView } from \"./views/PaginationNodeView.js\";\r\nexport { PageGroupNodeView } from \"./views/PageGroupNodeView.js\";\r\nexport { ParticleEmitterNodeView } from \"./views/ParticleEmitterNodeView.js\";\r\nexport * from \"./particles.js\";\r\nexport { collectNodeAssetIds } from \"./views/createNodeView.js\";\r\nexport { SceneLocalization } from \"./localization.js\";\r\nexport type { SceneLocalizationOptions } from \"./localization.js\";\r\nexport { BitmapTextNodeView, ImageNodeView, MaskNodeView, OpacityGroupNodeView, TextNodeView } from \"./views/basic.js\";\r\nexport type { BuildSceneViewOptions, PrefabViewConfiguration, SceneViewResult } from \"./scene.js\";\r\nexport { buildPrefabView, buildSceneView, collectRenderedNodes, loadPrefabView, previewNodeView, updateNodeView, updateParticleEmitters, loadSceneView } from \"./scene.js\";\r\nexport * from \"./controls.js\";\r\nexport { createSceneAssetCache } from \"./assets/cache.js\";\r\nexport type { SceneAssetCache } from \"./assets/cache.js\";\r\nexport * from \"./assets/textures.js\";\r\nexport * from \"./assets/spine.js\";\r\nexport * from \"./assets/fonts.js\";\r\nexport * from \"./assets/bitmapFonts.js\";\r\nexport * from \"./assets/sounds.js\";\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"layoutGroups.d.ts","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAAmE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAClK,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAqD,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,iHAAiH;AACjH,wBAAgB,oBAAoB,IAAI,IAAI,CAAkE;AAe9G,kHAAkH;AAClH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,IAAI,CAkC1J;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAKpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ;IAAE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IAJ1E,OAAO,CAAC,IAAI,CAAC,CAAS;IACtB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,YAAY,CAAuC;gBAEtC,QAAQ,EAAE,QAAQ,EAAmB,eAAe,CAAC,GAAE,MAAM,IAAI,aAAA;IAMtF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,GAAG,IAAI;IAQ5E,OAAO,CAAC,iBAAiB;CAU1B;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CA+BhI;AAED,mIAAmI;AACnI,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAQ9I;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEpF"}
1
+ {"version":3,"file":"layoutGroups.d.ts","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAAmE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAClK,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAqD,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjG,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,iHAAiH;AACjH,wBAAgB,oBAAoB,IAAI,IAAI,CAAkE;AAe9G,kHAAkH;AAClH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,UAAU,GAAG,IAAI,CAkC1J;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAKpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ;IAAE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IAJ1E,OAAO,CAAC,IAAI,CAAC,CAAS;IACtB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,YAAY,CAAuC;IAE3D,YAAqB,QAAQ,EAAE,QAAQ,EAAmB,eAAe,CAAC,GAAE,MAAM,IAAI,aAAA,EAIrF;IAED,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,GAAG,IAAI,CAM3E;IAED,OAAO,CAAC,iBAAiB;CAU1B;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CA+BhI;AAED,mIAAmI;AACnI,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAQ9I;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEpF"}
@@ -1 +1 @@
1
- {"version":3,"file":"layoutGroups.js","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"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","sourcesContent":["import \"@pixi/layout\";\r\nimport { isLayoutGroup, resolveLayoutGroupSettings, type LayoutAlignment, type LayoutGroupNode, type LayoutProfileId, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container } from \"pixi.js\";\r\nimport { resolveAnchoredTransform, resolveProfileTransform, type LayoutSize } from \"./layout.js\";\r\nimport { LayoutGroupNodeView } from \"./views/basic.js\";\r\nimport { NodeView } from \"./views/NodeView.js\";\r\n\r\n/** Importing @pixi/layout installs its renderer extension. Kept as a shared explicit contract for every host. */\r\nexport function initializePixiLayout(): void { /* @pixi/layout is installed by this module's side effect. */ }\r\n\r\nfunction alignmentParts(alignment: LayoutAlignment) {\r\n const [vertical, horizontal] = alignment.split(\"-\") as [\"upper\" | \"middle\" | \"lower\", \"left\" | \"center\" | \"right\"];\r\n return {\r\n horizontal: horizontal === \"left\" ? \"flex-start\" : horizontal === \"right\" ? \"flex-end\" : \"center\",\r\n vertical: vertical === \"upper\" ? \"flex-start\" : vertical === \"lower\" ? \"flex-end\" : \"center\",\r\n };\r\n}\r\n\r\nfunction layoutSize(node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize): LayoutSize {\r\n const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);\r\n return { width: transform.width, height: transform.height };\r\n}\r\n\r\n/** Applies one declarative document group to Pixi Layout; no computed Yoga data crosses the document boundary. */\r\nexport function applyLayoutGroup(view: Container, node: LayoutGroupNode, profile: LayoutProfileId, parentSize?: LayoutSize, managedSize?: LayoutSize): void {\r\n const settings = resolveLayoutGroupSettings(node, profile) as LayoutGroupNode[\"layoutGroup\"][\"base\"];\r\n const size = managedSize ?? layoutSize(node, profile, parentSize);\r\n const common = { width: size.width, height: size.height, display: \"flex\" as const };\r\n if (node.type === \"horizontal-layout\" || node.type === \"vertical-layout\") {\r\n const linear = settings as Extract<LayoutGroupNode, { type: \"horizontal-layout\" | \"vertical-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;\r\n const alignment = alignmentParts(linear.childAlignment);\r\n target.layout = {\r\n ...common,\r\n justifyContent: node.type === \"horizontal-layout\" ? alignment.horizontal : alignment.vertical,\r\n alignItems: node.type === \"horizontal-layout\" ? alignment.vertical : alignment.horizontal,\r\n flexDirection: node.type === \"horizontal-layout\" ? (linear.reverseOrder ? \"row-reverse\" : \"row\") : (linear.reverseOrder ? \"column-reverse\" : \"column\"),\r\n gap: linear.spacing,\r\n paddingLeft: linear.padding.left, paddingRight: linear.padding.right, paddingTop: linear.padding.top, paddingBottom: linear.padding.bottom,\r\n } as never;\r\n return;\r\n }\r\n const grid = settings as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const reverseX = grid.startCorner.endsWith(\"right\");\r\n const reverseY = grid.startCorner.startsWith(\"lower\");\r\n const fillsByRow = grid.constraint === \"fixed-column-count\" || (grid.constraint === \"flexible\" && grid.startAxis === \"horizontal\");\r\n const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;\r\n const alignment = alignmentParts(grid.childAlignment);\r\n target.layout = {\r\n ...common,\r\n justifyContent: fillsByRow ? alignment.horizontal : alignment.vertical,\r\n alignItems: fillsByRow ? alignment.vertical : alignment.horizontal,\r\n alignContent: fillsByRow ? alignment.vertical : alignment.horizontal,\r\n flexDirection: fillsByRow ? (reverseX ? \"row-reverse\" : \"row\") : (reverseY ? \"column-reverse\" : \"column\"),\r\n flexWrap: reverseY && fillsByRow ? \"wrap-reverse\" : \"wrap\",\r\n columnGap: grid.spacingX, rowGap: grid.spacingY,\r\n paddingLeft: grid.padding.left, paddingRight: grid.padding.right, paddingTop: grid.padding.top, paddingBottom: grid.padding.bottom,\r\n } as never;\r\n}\r\n\r\n/**\r\n * Runtime-only Yoga owner for one direct child. The wrapper receives Yoga coordinates while the\r\n * serializable NodeView keeps the shared pivot/rotation/scale/content/hit-test contract.\r\n */\r\nexport class LayoutItemContainer extends Container {\r\n private node?: UINode;\r\n private profile: LayoutProfileId = \"desktop\";\r\n private fallbackSize: LayoutSize = { width: 0, height: 0 };\r\n\r\n constructor(readonly nodeView: NodeView, private readonly onLayoutChanged?: () => void) {\r\n super();\r\n super.addChild(nodeView);\r\n this.onLayout = () => this.applyComputedSize();\r\n }\r\n\r\n sync(node: UINode, profile: LayoutProfileId, fallbackSize: LayoutSize): void {\r\n this.node = node;\r\n this.profile = profile;\r\n this.fallbackSize = fallbackSize;\r\n this.visible = resolveProfileTransform(node, profile).visible;\r\n this.applyComputedSize();\r\n }\r\n\r\n private applyComputedSize(): void {\r\n if (this.node === undefined) return;\r\n const computed = this.layout?.computedLayout;\r\n const size = computed === undefined || computed.width <= 0 || computed.height <= 0\r\n ? this.fallbackSize\r\n : { width: computed.width, height: computed.height };\r\n if (isLayoutGroup(this.node)) applyLayoutGroup(this.nodeView, this.node, this.profile, undefined, size);\r\n this.nodeView.updateManaged(this.node, this.profile, size);\r\n this.onLayoutChanged?.();\r\n }\r\n}\r\n\r\n/** Marks a direct child's technical wrapper as layout-managed. */\r\nexport function applyLayoutItem(view: LayoutItemContainer, node: UINode, parent: LayoutGroupNode, profile: LayoutProfileId): void {\r\n // Anchors belong to authored positioning and are deliberately ignored while a parent layout owns\r\n // the rectangle. Width/height remain the child's logical intrinsic size, never Pixi content bounds.\r\n const transform = resolveProfileTransform(node, profile).transform;\r\n const own = { width: transform.width, height: transform.height };\r\n const item = node.layoutItem;\r\n const settings = resolveLayoutGroupSettings(parent, profile);\r\n const base = { position: \"relative\" as const, flexGrow: item?.flexGrow ?? 0, flexShrink: item?.flexShrink ?? 0, flexBasis: item?.flexBasis, alignSelf: item?.alignSelf };\r\n view.sync(node, profile, own);\r\n if (parent.type === \"grid-layout\") {\r\n const grid = settings as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n view.layout = { ...base, width: grid.cellWidth, height: grid.cellHeight } as never;\r\n return;\r\n }\r\n const linear = settings as Extract<LayoutGroupNode, { type: \"horizontal-layout\" | \"vertical-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const horizontal = parent.type === \"horizontal-layout\";\r\n const expandsMain = horizontal\r\n ? linear.controlChildWidth && linear.forceExpandWidth\r\n : linear.controlChildHeight && linear.forceExpandHeight;\r\n const expandsCross = horizontal\r\n ? linear.controlChildHeight && linear.forceExpandHeight\r\n : linear.controlChildWidth && linear.forceExpandWidth;\r\n view.layout = {\r\n ...base,\r\n // The schema has no separate min/preferred size yet, so the logical authored rect is the safe\r\n // intrinsic fallback for both control modes. Force-expand may then replace the relevant axis.\r\n width: expandsCross && !horizontal ? undefined : own.width,\r\n height: expandsCross && horizontal ? undefined : own.height,\r\n ...(expandsMain ? { flexGrow: Math.max(1, item?.flexGrow ?? 0) } : {}),\r\n ...(expandsCross ? { alignSelf: item?.alignSelf ?? \"stretch\" } : {}),\r\n } as never;\r\n}\r\n\r\n/** A zero-visual Yoga flex item. Fixed Unity grid constraints need explicit line breaks; this is still solved entirely by Yoga. */\r\nexport function createGridLineBreak(parent: Extract<LayoutGroupNode, { type: \"grid-layout\" }>, profile: LayoutProfileId): Container | undefined {\r\n const grid = resolveLayoutGroupSettings(parent, profile) as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n if (grid.constraint === \"flexible\" || grid.constraintCount === undefined) return undefined;\r\n const lineBreak = new Container({ label: \"__layout-grid-line-break__\" });\r\n lineBreak.layout = (grid.constraint === \"fixed-column-count\"\r\n ? { flexBasis: \"100%\", width: \"100%\", height: 0 }\r\n : { flexBasis: \"100%\", height: \"100%\", width: 0 }) as never;\r\n return lineBreak;\r\n}\r\n\r\nexport function isLayoutManagedChild(node: UINode, nodes: readonly UINode[]): boolean {\r\n return node.parentId !== null && isLayoutGroup(nodes.find((candidate) => candidate.id === node.parentId) ?? node) && nodes.some((candidate) => candidate.id === node.parentId && isLayoutGroup(candidate));\r\n}\r\n"]}
1
+ {"version":3,"file":"layoutGroups.js","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"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","sourcesContent":["import \"@pixi/layout\";\r\nimport { isLayoutGroup, resolveLayoutGroupSettings, type LayoutAlignment, type LayoutGroupNode, type LayoutProfileId, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container } from \"pixi.js\";\r\nimport { resolveAnchoredTransform, resolveProfileTransform, type LayoutSize } from \"./layout.js\";\r\nimport { LayoutGroupNodeView } from \"./views/basic.js\";\r\nimport { NodeView } from \"./views/NodeView.js\";\r\n\r\n/** Importing @pixi/layout installs its renderer extension. Kept as a shared explicit contract for every host. */\r\nexport function initializePixiLayout(): void { /* @pixi/layout is installed by this module's side effect. */ }\r\n\r\nfunction alignmentParts(alignment: LayoutAlignment) {\r\n const [vertical, horizontal] = alignment.split(\"-\") as [\"upper\" | \"middle\" | \"lower\", \"left\" | \"center\" | \"right\"];\r\n return {\r\n horizontal: horizontal === \"left\" ? \"flex-start\" : horizontal === \"right\" ? \"flex-end\" : \"center\",\r\n vertical: vertical === \"upper\" ? \"flex-start\" : vertical === \"lower\" ? \"flex-end\" : \"center\",\r\n };\r\n}\r\n\r\nfunction layoutSize(node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize): LayoutSize {\r\n const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);\r\n return { width: transform.width, height: transform.height };\r\n}\r\n\r\n/** Applies one declarative document group to Pixi Layout; no computed Yoga data crosses the document boundary. */\r\nexport function applyLayoutGroup(view: Container, node: LayoutGroupNode, profile: LayoutProfileId, parentSize?: LayoutSize, managedSize?: LayoutSize): void {\r\n const settings = resolveLayoutGroupSettings(node, profile) as LayoutGroupNode[\"layoutGroup\"][\"base\"];\r\n const size = managedSize ?? layoutSize(node, profile, parentSize);\r\n const common = { width: size.width, height: size.height, display: \"flex\" as const };\r\n if (node.type === \"horizontal-layout\" || node.type === \"vertical-layout\") {\r\n const linear = settings as Extract<LayoutGroupNode, { type: \"horizontal-layout\" | \"vertical-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;\r\n const alignment = alignmentParts(linear.childAlignment);\r\n target.layout = {\r\n ...common,\r\n justifyContent: node.type === \"horizontal-layout\" ? alignment.horizontal : alignment.vertical,\r\n alignItems: node.type === \"horizontal-layout\" ? alignment.vertical : alignment.horizontal,\r\n flexDirection: node.type === \"horizontal-layout\" ? (linear.reverseOrder ? \"row-reverse\" : \"row\") : (linear.reverseOrder ? \"column-reverse\" : \"column\"),\r\n gap: linear.spacing,\r\n paddingLeft: linear.padding.left, paddingRight: linear.padding.right, paddingTop: linear.padding.top, paddingBottom: linear.padding.bottom,\r\n } as never;\r\n return;\r\n }\r\n const grid = settings as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const reverseX = grid.startCorner.endsWith(\"right\");\r\n const reverseY = grid.startCorner.startsWith(\"lower\");\r\n const fillsByRow = grid.constraint === \"fixed-column-count\" || (grid.constraint === \"flexible\" && grid.startAxis === \"horizontal\");\r\n const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;\r\n const alignment = alignmentParts(grid.childAlignment);\r\n target.layout = {\r\n ...common,\r\n justifyContent: fillsByRow ? alignment.horizontal : alignment.vertical,\r\n alignItems: fillsByRow ? alignment.vertical : alignment.horizontal,\r\n alignContent: fillsByRow ? alignment.vertical : alignment.horizontal,\r\n flexDirection: fillsByRow ? (reverseX ? \"row-reverse\" : \"row\") : (reverseY ? \"column-reverse\" : \"column\"),\r\n flexWrap: reverseY && fillsByRow ? \"wrap-reverse\" : \"wrap\",\r\n columnGap: grid.spacingX, rowGap: grid.spacingY,\r\n paddingLeft: grid.padding.left, paddingRight: grid.padding.right, paddingTop: grid.padding.top, paddingBottom: grid.padding.bottom,\r\n } as never;\r\n}\r\n\r\n/**\r\n * Runtime-only Yoga owner for one direct child. The wrapper receives Yoga coordinates while the\r\n * serializable NodeView keeps the shared pivot/rotation/scale/content/hit-test contract.\r\n */\r\nexport class LayoutItemContainer extends Container {\r\n private node?: UINode;\r\n private profile: LayoutProfileId = \"desktop\";\r\n private fallbackSize: LayoutSize = { width: 0, height: 0 };\r\n\r\n constructor(readonly nodeView: NodeView, private readonly onLayoutChanged?: () => void) {\r\n super();\r\n super.addChild(nodeView);\r\n this.onLayout = () => this.applyComputedSize();\r\n }\r\n\r\n sync(node: UINode, profile: LayoutProfileId, fallbackSize: LayoutSize): void {\r\n this.node = node;\r\n this.profile = profile;\r\n this.fallbackSize = fallbackSize;\r\n this.visible = resolveProfileTransform(node, profile).visible;\r\n this.applyComputedSize();\r\n }\r\n\r\n private applyComputedSize(): void {\r\n if (this.node === undefined) return;\r\n const computed = this.layout?.computedLayout;\r\n const size = computed === undefined || computed.width <= 0 || computed.height <= 0\r\n ? this.fallbackSize\r\n : { width: computed.width, height: computed.height };\r\n if (isLayoutGroup(this.node)) applyLayoutGroup(this.nodeView, this.node, this.profile, undefined, size);\r\n this.nodeView.updateManaged(this.node, this.profile, size);\r\n this.onLayoutChanged?.();\r\n }\r\n}\r\n\r\n/** Marks a direct child's technical wrapper as layout-managed. */\r\nexport function applyLayoutItem(view: LayoutItemContainer, node: UINode, parent: LayoutGroupNode, profile: LayoutProfileId): void {\r\n // Anchors belong to authored positioning and are deliberately ignored while a parent layout owns\r\n // the rectangle. Width/height remain the child's logical intrinsic size, never Pixi content bounds.\r\n const transform = resolveProfileTransform(node, profile).transform;\r\n const own = { width: transform.width, height: transform.height };\r\n const item = node.layoutItem;\r\n const settings = resolveLayoutGroupSettings(parent, profile);\r\n const base = { position: \"relative\" as const, flexGrow: item?.flexGrow ?? 0, flexShrink: item?.flexShrink ?? 0, flexBasis: item?.flexBasis, alignSelf: item?.alignSelf };\r\n view.sync(node, profile, own);\r\n if (parent.type === \"grid-layout\") {\r\n const grid = settings as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n view.layout = { ...base, width: grid.cellWidth, height: grid.cellHeight } as never;\r\n return;\r\n }\r\n const linear = settings as Extract<LayoutGroupNode, { type: \"horizontal-layout\" | \"vertical-layout\" }> [\"layoutGroup\"][\"base\"];\r\n const horizontal = parent.type === \"horizontal-layout\";\r\n const expandsMain = horizontal\r\n ? linear.controlChildWidth && linear.forceExpandWidth\r\n : linear.controlChildHeight && linear.forceExpandHeight;\r\n const expandsCross = horizontal\r\n ? linear.controlChildHeight && linear.forceExpandHeight\r\n : linear.controlChildWidth && linear.forceExpandWidth;\r\n view.layout = {\r\n ...base,\r\n // The schema has no separate min/preferred size yet, so the logical authored rect is the safe\r\n // intrinsic fallback for both control modes. Force-expand may then replace the relevant axis.\r\n width: expandsCross && !horizontal ? undefined : own.width,\r\n height: expandsCross && horizontal ? undefined : own.height,\r\n ...(expandsMain ? { flexGrow: Math.max(1, item?.flexGrow ?? 0) } : {}),\r\n ...(expandsCross ? { alignSelf: item?.alignSelf ?? \"stretch\" } : {}),\r\n } as never;\r\n}\r\n\r\n/** A zero-visual Yoga flex item. Fixed Unity grid constraints need explicit line breaks; this is still solved entirely by Yoga. */\r\nexport function createGridLineBreak(parent: Extract<LayoutGroupNode, { type: \"grid-layout\" }>, profile: LayoutProfileId): Container | undefined {\r\n const grid = resolveLayoutGroupSettings(parent, profile) as Extract<LayoutGroupNode, { type: \"grid-layout\" }> [\"layoutGroup\"][\"base\"];\r\n if (grid.constraint === \"flexible\" || grid.constraintCount === undefined) return undefined;\r\n const lineBreak = new Container({ label: \"__layout-grid-line-break__\" });\r\n lineBreak.layout = (grid.constraint === \"fixed-column-count\"\r\n ? { flexBasis: \"100%\", width: \"100%\", height: 0 }\r\n : { flexBasis: \"100%\", height: \"100%\", width: 0 }) as never;\r\n return lineBreak;\r\n}\r\n\r\nexport function isLayoutManagedChild(node: UINode, nodes: readonly UINode[]): boolean {\r\n return node.parentId !== null && isLayoutGroup(nodes.find((candidate) => candidate.id === node.parentId) ?? node) && nodes.some((candidate) => candidate.id === node.parentId && isLayoutGroup(candidate));\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"localization.d.ts","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,KAAK,KAAK,EAAiB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACxN,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,MAAM,MAAM,wBAAwB,GAAG;IACrC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mGAAmG;IACnG,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,MAAM,CAAiC;gBAEnC,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,GAAE,wBAA6B;IAWlI,IAAI,OAAO,IAAI,mBAAmB,CAAuC;IACzE,IAAI,UAAU,IAAI,MAAM,CAAkD;IAC1E,IAAI,MAAM,IAAI,MAAM,CAAoD;IAExE,4EAA4E;IAC5E,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAErE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAC3C,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI;IACtD,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI;IAEvD;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAM7C,OAAO,IAAI,IAAI;CAehB"}
1
+ {"version":3,"file":"localization.d.ts","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,KAAK,KAAK,EAAiB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACxN,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,MAAM,MAAM,wBAAwB,GAAG;IACrC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mGAAmG;IACnG,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,MAAM,CAAiC;IAE/C,YAAY,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,GAAE,wBAA6B,EASjI;IAED,IAAI,OAAO,IAAI,mBAAmB,CAAuC;IACzE,IAAI,UAAU,IAAI,MAAM,CAAkD;IAC1E,IAAI,MAAM,IAAI,MAAM,CAAoD;IAExE,4EAA4E;IAC5E,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAA+C;IAEpH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAmD;IAC9F,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAAgD;IACtG,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI,CAA0C;IAEjG;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAI5C;IAED,OAAO,IAAI,IAAI,CAcd;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"localization.js","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"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","sourcesContent":["import { describeLocalizedText, isTextNode, resolveOwnerNodeGraph, type LocalizationCatalog, type LocalizationParams, type ProjectDocument, type Scene, type TextNode, type TranslateFn } from \"@pixi-ui-editor/schema\";\r\nimport type { Container } from \"pixi.js\";\r\nimport { TextNodeView } from \"./views/basic.js\";\r\n\r\nexport type SceneLocalizationOptions = {\r\n /** Requested locale; без неё применяется base locale каталога. */\r\n locale?: string;\r\n /** Внешний переводчик игры: он приоритетнее документа и может заменить строку без переэкспорта. */\r\n translate?: TranslateFn;\r\n params?: LocalizationParams;\r\n};\r\n\r\n/**\r\n * Локализация уже построенной сцены.\r\n *\r\n * Контроллер владеет только строками: он мутирует существующие `TextNodeView` через их\r\n * инкрементальный `setText`, поэтому смена локали, внешнего переводчика, параметров или самой копии\r\n * документа не пересобирает root, не меняет identity `NodeView` и не трогает live-состояние\r\n * контролов. Fallback и интерполяция целиком принадлежат `@pixi-ui-editor/schema`.\r\n */\r\nexport class SceneLocalization {\r\n private document: ProjectDocument;\r\n private readonly scene: Scene;\r\n private readonly views: ReadonlyMap<string, Container>;\r\n private nodes: TextNode[];\r\n private requestedLocale: string | undefined;\r\n private translate: TranslateFn | undefined;\r\n private params: LocalizationParams | undefined;\r\n\r\n constructor(document: ProjectDocument, scene: Scene, views: ReadonlyMap<string, Container>, options: SceneLocalizationOptions = {}) {\r\n this.document = document;\r\n this.scene = scene;\r\n this.views = views;\r\n this.nodes = collectTextNodes(document, scene);\r\n this.requestedLocale = options.locale;\r\n this.translate = options.translate;\r\n this.params = options.params;\r\n this.refresh();\r\n }\r\n\r\n get catalog(): LocalizationCatalog { return this.document.localization; }\r\n get baseLocale(): string { return this.document.localization.baseLocale; }\r\n get locale(): string { return this.requestedLocale ?? this.baseLocale; }\r\n\r\n /** Полный каталог документа: словари всех локалей, а не только активной. */\r\n entries(): Readonly<Record<string, Readonly<Record<string, string>>>> { return this.document.localization.entries; }\r\n\r\n setLocale(locale: string | undefined): void { this.requestedLocale = locale; this.refresh(); }\r\n setTranslate(translate: TranslateFn | undefined): void { this.translate = translate; this.refresh(); }\r\n setParams(params: LocalizationParams | undefined): void { this.params = params; this.refresh(); }\r\n\r\n /**\r\n * Новая иммутабельная копия документа: редакторский store заменяет документ целиком, и переводы\r\n * вместе с key references обязаны обновиться без пересборки сцены.\r\n */\r\n syncDocument(document: ProjectDocument): void {\r\n this.document = document;\r\n this.nodes = collectTextNodes(document, this.scene);\r\n this.refresh();\r\n }\r\n\r\n refresh(): void {\r\n for (const node of this.nodes) {\r\n const view = this.views.get(node.id);\r\n if (!(view instanceof TextNodeView)) continue;\r\n // Вся цепочка, включая случай «ключа нет», принадлежит резолверу схемы: `source: \"literal\"`\r\n // и означает, что нода локализацию не запрашивает и снова показывает авторскую строку.\r\n const resolution = describeLocalizedText({ text: node.text, textKey: node.textKey, catalog: this.document.localization, locale: this.locale, translate: this.translate, params: this.params });\r\n if (resolution.source === \"literal\") {\r\n view.setLocalizedText(undefined);\r\n view.setText(resolution.value);\r\n continue;\r\n }\r\n view.setLocalizedText(resolution.value);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Текстовые ноды сцены, включая развёрнутые пресеты.\r\n *\r\n * Синтетическая сцена prefab-view в присланном документе отсутствует, поэтому её описание берётся\r\n * из захваченного объекта: определения пресетов при этом всё равно читаются из нового документа.\r\n */\r\nfunction collectTextNodes(document: ProjectDocument, scene: Scene): TextNode[] {\r\n const current = document.scenes.find((candidate) => candidate.id === scene.id) ?? scene;\r\n return resolveOwnerNodeGraph(document, current).nodes.filter(isTextNode);\r\n}\r\n"]}
1
+ {"version":3,"file":"localization.js","sourceRoot":"","sources":["../src/localization.ts"],"names":[],"mappings":"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","sourcesContent":["import { describeLocalizedText, isTextNode, resolveOwnerNodeGraph, type LocalizationCatalog, type LocalizationParams, type ProjectDocument, type Scene, type TextNode, type TranslateFn } from \"@pixi-ui-editor/schema\";\r\nimport type { Container } from \"pixi.js\";\r\nimport { TextNodeView } from \"./views/basic.js\";\r\n\r\nexport type SceneLocalizationOptions = {\r\n /** Requested locale; без неё применяется base locale каталога. */\r\n locale?: string;\r\n /** Внешний переводчик игры: он приоритетнее документа и может заменить строку без переэкспорта. */\r\n translate?: TranslateFn;\r\n params?: LocalizationParams;\r\n};\r\n\r\n/**\r\n * Локализация уже построенной сцены.\r\n *\r\n * Контроллер владеет только строками: он мутирует существующие `TextNodeView` через их\r\n * инкрементальный `setText`, поэтому смена локали, внешнего переводчика, параметров или самой копии\r\n * документа не пересобирает root, не меняет identity `NodeView` и не трогает live-состояние\r\n * контролов. Fallback и интерполяция целиком принадлежат `@pixi-ui-editor/schema`.\r\n */\r\nexport class SceneLocalization {\r\n private document: ProjectDocument;\r\n private readonly scene: Scene;\r\n private readonly views: ReadonlyMap<string, Container>;\r\n private nodes: TextNode[];\r\n private requestedLocale: string | undefined;\r\n private translate: TranslateFn | undefined;\r\n private params: LocalizationParams | undefined;\r\n\r\n constructor(document: ProjectDocument, scene: Scene, views: ReadonlyMap<string, Container>, options: SceneLocalizationOptions = {}) {\r\n this.document = document;\r\n this.scene = scene;\r\n this.views = views;\r\n this.nodes = collectTextNodes(document, scene);\r\n this.requestedLocale = options.locale;\r\n this.translate = options.translate;\r\n this.params = options.params;\r\n this.refresh();\r\n }\r\n\r\n get catalog(): LocalizationCatalog { return this.document.localization; }\r\n get baseLocale(): string { return this.document.localization.baseLocale; }\r\n get locale(): string { return this.requestedLocale ?? this.baseLocale; }\r\n\r\n /** Полный каталог документа: словари всех локалей, а не только активной. */\r\n entries(): Readonly<Record<string, Readonly<Record<string, string>>>> { return this.document.localization.entries; }\r\n\r\n setLocale(locale: string | undefined): void { this.requestedLocale = locale; this.refresh(); }\r\n setTranslate(translate: TranslateFn | undefined): void { this.translate = translate; this.refresh(); }\r\n setParams(params: LocalizationParams | undefined): void { this.params = params; this.refresh(); }\r\n\r\n /**\r\n * Новая иммутабельная копия документа: редакторский store заменяет документ целиком, и переводы\r\n * вместе с key references обязаны обновиться без пересборки сцены.\r\n */\r\n syncDocument(document: ProjectDocument): void {\r\n this.document = document;\r\n this.nodes = collectTextNodes(document, this.scene);\r\n this.refresh();\r\n }\r\n\r\n refresh(): void {\r\n for (const node of this.nodes) {\r\n const view = this.views.get(node.id);\r\n if (!(view instanceof TextNodeView)) continue;\r\n // Вся цепочка, включая случай «ключа нет», принадлежит резолверу схемы: `source: \"literal\"`\r\n // и означает, что нода локализацию не запрашивает и снова показывает авторскую строку.\r\n const resolution = describeLocalizedText({ text: node.text, textKey: node.textKey, catalog: this.document.localization, locale: this.locale, translate: this.translate, params: this.params });\r\n if (resolution.source === \"literal\") {\r\n view.setLocalizedText(undefined);\r\n view.setText(resolution.value);\r\n continue;\r\n }\r\n view.setLocalizedText(resolution.value);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Текстовые ноды сцены, включая развёрнутые пресеты.\r\n *\r\n * Синтетическая сцена prefab-view в присланном документе отсутствует, поэтому её описание берётся\r\n * из захваченного объекта: определения пресетов при этом всё равно читаются из нового документа.\r\n */\r\nfunction collectTextNodes(document: ProjectDocument, scene: Scene): TextNode[] {\r\n const current = document.scenes.find((candidate) => candidate.id === scene.id) ?? scene;\r\n return resolveOwnerNodeGraph(document, current).nodes.filter(isTextNode);\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"pageGroup.d.ts","sourceRoot":"","sources":["../src/pageGroup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAClC,QAAQ,CAAC,QAAQ,EAAE,QAAQ;gBAAlB,QAAQ,EAAE,QAAQ;IAKvC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;CAGrE"}
1
+ {"version":3,"file":"pageGroup.d.ts","sourceRoot":"","sources":["../src/pageGroup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAClC,QAAQ,CAAC,QAAQ,EAAE,QAAQ;IAAvC,YAAqB,QAAQ,EAAE,QAAQ,EAGtC;IAED,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAEnE;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"pageGroup.js","sourceRoot":"","sources":["../src/pageGroup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIpC;;;;;;GAMG;AACH,MAAM,OAAO,iBAAkB,SAAQ,SAAS;IACzB;IAArB,YAAqB,QAAkB;QACrC,KAAK,EAAE,CAAC;QADW,aAAQ,GAAR,QAAQ,CAAU;QAErC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,OAAwB,EAAE,IAAgB;QAC3D,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;CACF","sourcesContent":["import { type LayoutProfileId, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container } from \"pixi.js\";\r\nimport type { LayoutSize } from \"./layout.js\";\r\nimport { NodeView } from \"./views/NodeView.js\";\r\n\r\n/**\r\n * Runtime-only position owner for one direct page-group child: fills the group's whole resolved\r\n * rectangle and is shown only while it is the active page. Position and visibility are this wrapper's\r\n * job; the wrapped `NodeView` keeps its own pivot/rotation/scale/visibility contract via\r\n * `updateManaged`, the same split a layout group's `LayoutItemContainer` and a scroll-view's\r\n * `ScrollItemContainer` already use.\r\n */\r\nexport class PageItemContainer extends Container {\r\n constructor(readonly nodeView: NodeView) {\r\n super();\r\n super.addChild(nodeView);\r\n }\r\n\r\n sync(node: UINode, profile: LayoutProfileId, size: LayoutSize): void {\r\n this.nodeView.updateManaged(node, profile, size);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"pageGroup.js","sourceRoot":"","sources":["../src/pageGroup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIpC;;;;;;GAMG;AACH,MAAM,OAAO,iBAAkB,SAAQ,SAAS;IACzB,QAAQ;IAA7B,YAAqB,QAAkB;QACrC,KAAK,EAAE,CAAC;wBADW,QAAQ;QAE3B,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,OAAwB,EAAE,IAAgB;QAC3D,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;CACF","sourcesContent":["import { type LayoutProfileId, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container } from \"pixi.js\";\r\nimport type { LayoutSize } from \"./layout.js\";\r\nimport { NodeView } from \"./views/NodeView.js\";\r\n\r\n/**\r\n * Runtime-only position owner for one direct page-group child: fills the group's whole resolved\r\n * rectangle and is shown only while it is the active page. Position and visibility are this wrapper's\r\n * job; the wrapped `NodeView` keeps its own pivot/rotation/scale/visibility contract via\r\n * `updateManaged`, the same split a layout group's `LayoutItemContainer` and a scroll-view's\r\n * `ScrollItemContainer` already use.\r\n */\r\nexport class PageItemContainer extends Container {\r\n constructor(readonly nodeView: NodeView) {\r\n super();\r\n super.addChild(nodeView);\r\n }\r\n\r\n sync(node: UINode, profile: LayoutProfileId, size: LayoutSize): void {\r\n this.nodeView.updateManaged(node, profile, size);\r\n }\r\n}\r\n"]}