@openfairygui/cli 0.2.0 → 0.3.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -132,49 +132,6 @@ function inspect(doc) {
132
132
  };
133
133
  }
134
134
  //#endregion
135
- //#region ../functions/src/utils.ts
136
- /**
137
- * Wraps a transform function, assigning it a name for the transform stack.
138
- */
139
- function createTransform(name, fn) {
140
- Object.defineProperty(fn, "name", { value: name });
141
- return fn;
142
- }
143
- function parseTextureSetMode(value) {
144
- const raw = value?.trim() ?? "";
145
- if (!raw) return {
146
- kind: "auto",
147
- raw: ""
148
- };
149
- if (raw === "alone") return {
150
- kind: "standalone",
151
- raw,
152
- sizeMode: "default"
153
- };
154
- if (raw === "alone_npot") return {
155
- kind: "standalone",
156
- raw,
157
- sizeMode: "npot"
158
- };
159
- if (raw === "alone_mof") return {
160
- kind: "standalone",
161
- raw,
162
- sizeMode: "multipleOf4"
163
- };
164
- if (/^\d+$/.test(raw)) {
165
- const pageIndex = Number(raw);
166
- if (pageIndex >= 0 && pageIndex <= 10) return {
167
- kind: "page",
168
- raw,
169
- pageIndex
170
- };
171
- }
172
- return {
173
- kind: "auto",
174
- raw
175
- };
176
- }
177
- //#endregion
178
135
  //#region ../../node_modules/.pnpm/property-graph@4.1.0/node_modules/property-graph/dist/index.mjs
179
136
  var EventDispatcher = class {
180
137
  _listeners = {};
@@ -864,7 +821,7 @@ var ExtensibleProperty = class extends Property {
864
821
  };
865
822
  //#endregion
866
823
  //#region ../core/src/constants.ts
867
- const VERSION = `v0.2.0`;
824
+ const VERSION = `v0.3.0-alpha.2`;
868
825
  /** Binary package file magic number: "FGUI" as uint32. */
869
826
  const FGUI_MAGIC = 1179080009;
870
827
  /** Null string index in the binary string table. */
@@ -9449,6 +9406,9 @@ function isAttribute(name) {
9449
9406
  //#region ../../node_modules/.pnpm/fast-xml-parser@5.5.10/node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js
9450
9407
  var json2xml_default = Builder;
9451
9408
  //#endregion
9409
+ //#region ../../node_modules/.pnpm/fast-xml-parser@5.5.10/node_modules/fast-xml-parser/src/fxp.js
9410
+ const XMLValidator = { validate };
9411
+ //#endregion
9452
9412
  //#region ../core/src/utils/xml-utils.ts
9453
9413
  const defaultOptions = {
9454
9414
  ignoreAttributes: false,
@@ -9556,7 +9516,7 @@ function parseControllerPages(pagesStr) {
9556
9516
  });
9557
9517
  return pages;
9558
9518
  }
9559
- function parseBool(v) {
9519
+ function parseBool$1(v) {
9560
9520
  if (v === void 0 || v === null) return false;
9561
9521
  if (typeof v === "boolean") return v;
9562
9522
  const normalized = v.trim().toLowerCase();
@@ -16228,6 +16188,19 @@ var Document = class Document {
16228
16188
  }
16229
16189
  };
16230
16190
  //#endregion
16191
+ //#region ../core/src/validation.ts
16192
+ function sortProjectDiagnostics(diagnostics) {
16193
+ return [...diagnostics].sort((left, right) => left.path.localeCompare(right.path) || left.code.localeCompare(right.code) || left.message.localeCompare(right.message));
16194
+ }
16195
+ function createProjectValidationReport(diagnostics, complete = true) {
16196
+ const sorted = sortProjectDiagnostics(diagnostics);
16197
+ return {
16198
+ status: sorted.some((diagnostic) => diagnostic.severity === "error") ? "invalid" : complete ? "valid" : "incomplete",
16199
+ complete,
16200
+ diagnostics: sorted
16201
+ };
16202
+ }
16203
+ //#endregion
16231
16204
  //#region ../core/src/utils/resource-folder.ts
16232
16205
  function normalizeResourceFolderPath(value) {
16233
16206
  const segments = value.replace(/\\/g, "/").split("/").filter(Boolean);
@@ -16242,6 +16215,1725 @@ function resourceFolderName(value) {
16242
16215
  return normalizeResourceFolderPath(value).split("/").filter(Boolean).pop() ?? "";
16243
16216
  }
16244
16217
  //#endregion
16218
+ //#region ../core/src/uam/bridge-shared.ts
16219
+ function cloneSettings(settings) {
16220
+ return structuredClone(settings);
16221
+ }
16222
+ function liftRelations(relations) {
16223
+ return relations.map((relation) => ({
16224
+ targetNodeId: relation.target,
16225
+ type: relation.type,
16226
+ usePercent: relation.usePercent
16227
+ }));
16228
+ }
16229
+ function liftEdgeInsets(edgeInsets) {
16230
+ return {
16231
+ top: edgeInsets.top,
16232
+ bottom: edgeInsets.bottom,
16233
+ left: edgeInsets.left,
16234
+ right: edgeInsets.right
16235
+ };
16236
+ }
16237
+ function cloneListItems(items) {
16238
+ return items.map((item) => ({
16239
+ ...item,
16240
+ ...item.propertyOverrides?.length ? { propertyOverrides: item.propertyOverrides.map((property) => ({ ...property })) } : {}
16241
+ }));
16242
+ }
16243
+ //#endregion
16244
+ //#region ../core/src/uam/validate.ts
16245
+ function pushIssue(issues, path, message, code = "invalid_uam") {
16246
+ issues.push({
16247
+ severity: "error",
16248
+ code,
16249
+ path,
16250
+ message
16251
+ });
16252
+ }
16253
+ function isFiniteUamPoint(value) {
16254
+ if (typeof value !== "object" || value === null) return false;
16255
+ const point = value;
16256
+ return typeof point.x === "number" && Number.isFinite(point.x) && typeof point.y === "number" && Number.isFinite(point.y);
16257
+ }
16258
+ function isFiniteUamSize(value) {
16259
+ if (typeof value !== "object" || value === null) return false;
16260
+ const size = value;
16261
+ return typeof size.width === "number" && Number.isFinite(size.width) && typeof size.height === "number" && Number.isFinite(size.height);
16262
+ }
16263
+ function isFiniteUamEdgeInsets(value) {
16264
+ if (typeof value !== "object" || value === null) return false;
16265
+ const insets = value;
16266
+ return [
16267
+ insets.top,
16268
+ insets.bottom,
16269
+ insets.left,
16270
+ insets.right
16271
+ ].every((part) => typeof part === "number" && Number.isFinite(part));
16272
+ }
16273
+ function hasExactKeys(value, keys) {
16274
+ const actual = Object.keys(value);
16275
+ return actual.length === keys.length && actual.every((key) => keys.includes(key));
16276
+ }
16277
+ function isValidUamComponentPropertyOverride(value) {
16278
+ if (!value || typeof value !== "object" || !hasExactKeys(value, [
16279
+ "target",
16280
+ "propertyId",
16281
+ "value"
16282
+ ])) return false;
16283
+ const property = value;
16284
+ return typeof property.target === "string" && property.target.length > 0 && Number.isSafeInteger(property.propertyId) && property.propertyId >= 0 && typeof property.value === "string";
16285
+ }
16286
+ const IMAGE_RESOURCE_PROPERTY_KEYS = [
16287
+ "textureSetMode",
16288
+ "qualityOption",
16289
+ "quality",
16290
+ "smoothing",
16291
+ "duplicatePadding",
16292
+ "scaleOption",
16293
+ "scale9Grid",
16294
+ "tileGridIndice"
16295
+ ];
16296
+ function isValidUamImageResourceProperties(value) {
16297
+ if (typeof value !== "object" || value === null || !hasExactKeys(value, IMAGE_RESOURCE_PROPERTY_KEYS)) return false;
16298
+ const properties = value;
16299
+ if (typeof properties.textureSetMode !== "string" || typeof properties.qualityOption !== "string" || !Number.isInteger(properties.quality) || properties.quality < 0 || properties.quality > 100 || typeof properties.smoothing !== "boolean" || typeof properties.duplicatePadding !== "boolean" || ![
16300
+ 0,
16301
+ 1,
16302
+ 2
16303
+ ].includes(properties.scaleOption) || !Number.isInteger(properties.tileGridIndice) || properties.tileGridIndice < 0 || properties.tileGridIndice > 31) return false;
16304
+ if (properties.scaleOption !== 1) return properties.scale9Grid === null;
16305
+ if (!Array.isArray(properties.scale9Grid) || properties.scale9Grid.length !== 4 || !properties.scale9Grid.every(Number.isInteger)) return false;
16306
+ const [x, y, width, height] = properties.scale9Grid;
16307
+ return x >= 0 && y >= 0 && width > 0 && height > 0;
16308
+ }
16309
+ const MOVIE_CLIP_RESOURCE_PROPERTY_KEYS = [
16310
+ "interval",
16311
+ "repeatDelay",
16312
+ "swing",
16313
+ "smoothing",
16314
+ "frames"
16315
+ ];
16316
+ const MOVIE_CLIP_FRAME_KEYS = [
16317
+ "rectX",
16318
+ "rectY",
16319
+ "rectWidth",
16320
+ "rectHeight",
16321
+ "addDelay",
16322
+ "spriteId"
16323
+ ];
16324
+ function isValidUamMovieClipResourceProperties(value) {
16325
+ if (typeof value !== "object" || value === null || !hasExactKeys(value, MOVIE_CLIP_RESOURCE_PROPERTY_KEYS)) return false;
16326
+ const properties = value;
16327
+ if (!Number.isInteger(properties.interval) || properties.interval < 0 || !Number.isInteger(properties.repeatDelay) || properties.repeatDelay < 0 || typeof properties.swing !== "boolean" || typeof properties.smoothing !== "boolean" || !Array.isArray(properties.frames)) return false;
16328
+ return properties.frames.every((frame) => typeof frame === "object" && frame !== null && hasExactKeys(frame, MOVIE_CLIP_FRAME_KEYS) && [
16329
+ frame.rectX,
16330
+ frame.rectY,
16331
+ frame.rectWidth,
16332
+ frame.rectHeight,
16333
+ frame.addDelay
16334
+ ].every(Number.isInteger) && frame.rectWidth >= 0 && frame.rectHeight >= 0 && frame.addDelay >= 0 && typeof frame.spriteId === "string");
16335
+ }
16336
+ const TEXT_PROPERTY_KEYS = [
16337
+ "text",
16338
+ "font",
16339
+ "fontSize",
16340
+ "color",
16341
+ "align",
16342
+ "vAlign",
16343
+ "leading",
16344
+ "letterSpacing",
16345
+ "autoSize",
16346
+ "singleLine",
16347
+ "autoClearText",
16348
+ "underlaySoftness",
16349
+ "ubbEnabled",
16350
+ "underline",
16351
+ "italic",
16352
+ "bold",
16353
+ "strikethrough",
16354
+ "strokeColor",
16355
+ "strokeSize",
16356
+ "shadowColor",
16357
+ "shadowOffset"
16358
+ ];
16359
+ const PLAIN_TEXT_PROPERTY_KEYS = [
16360
+ ...TEXT_PROPERTY_KEYS,
16361
+ "demoText",
16362
+ "templateVarsEnabled",
16363
+ "faceDilate"
16364
+ ];
16365
+ function isTextColor(value) {
16366
+ return typeof value === "string" && /^#[0-9a-f]{6}(?:[0-9a-f]{2})?$/i.test(value);
16367
+ }
16368
+ function isValidUamTextProperties(value, nodeKind) {
16369
+ if (typeof value !== "object" || value === null || !hasExactKeys(value, nodeKind === "richText" ? TEXT_PROPERTY_KEYS : PLAIN_TEXT_PROPERTY_KEYS)) return false;
16370
+ const properties = value;
16371
+ const commonValid = [properties.text, properties.font].every((item) => typeof item === "string") && Number.isInteger(properties.fontSize) && properties.fontSize > 0 && isTextColor(properties.color) && Number.isInteger(properties.align) && properties.align >= 0 && properties.align <= 2 && Number.isInteger(properties.vAlign) && properties.vAlign >= 0 && properties.vAlign <= 2 && Number.isInteger(properties.leading) && Number.isInteger(properties.letterSpacing) && Number.isInteger(properties.autoSize) && properties.autoSize >= 0 && properties.autoSize <= 4 && [
16372
+ properties.singleLine,
16373
+ properties.autoClearText,
16374
+ properties.ubbEnabled,
16375
+ properties.underline,
16376
+ properties.italic,
16377
+ properties.bold,
16378
+ properties.strikethrough
16379
+ ].every((item) => typeof item === "boolean") && typeof properties.underlaySoftness === "number" && Number.isFinite(properties.underlaySoftness) && typeof properties.strokeSize === "number" && Number.isFinite(properties.strokeSize) && properties.strokeSize >= 0 && (properties.strokeColor === null ? properties.strokeSize === 1 : isTextColor(properties.strokeColor)) && isFiniteUamPoint(properties.shadowOffset) && (properties.shadowColor === null ? properties.shadowOffset.x === 0 && properties.shadowOffset.y === 0 : isTextColor(properties.shadowColor));
16380
+ if (!commonValid || nodeKind === "richText") return commonValid;
16381
+ return typeof properties.demoText === "string" && typeof properties.templateVarsEnabled === "boolean" && typeof properties.faceDilate === "number" && Number.isFinite(properties.faceDilate);
16382
+ }
16383
+ function textPropertiesFromNode(node) {
16384
+ const common = {
16385
+ text: node.text,
16386
+ font: node.font,
16387
+ fontSize: node.fontSize,
16388
+ color: node.color,
16389
+ align: node.align,
16390
+ vAlign: node.vAlign,
16391
+ leading: node.leading,
16392
+ letterSpacing: node.letterSpacing,
16393
+ autoSize: node.autoSize,
16394
+ singleLine: node.singleLine,
16395
+ autoClearText: node.autoClearText,
16396
+ underlaySoftness: node.underlaySoftness,
16397
+ ubbEnabled: node.ubbEnabled,
16398
+ underline: node.underline,
16399
+ italic: node.italic,
16400
+ bold: node.bold,
16401
+ strikethrough: node.strikethrough,
16402
+ strokeColor: node.strokeColor,
16403
+ strokeSize: node.strokeSize,
16404
+ shadowColor: node.shadowColor,
16405
+ shadowOffset: node.shadowOffset
16406
+ };
16407
+ if (node.kind === "richText") return common;
16408
+ return {
16409
+ ...common,
16410
+ demoText: node.demoText,
16411
+ templateVarsEnabled: node.templateVarsEnabled,
16412
+ faceDilate: node.faceDilate
16413
+ };
16414
+ }
16415
+ const COMPONENT_PROPERTY_KEYS = [
16416
+ "minSize",
16417
+ "maxSize",
16418
+ "pivot",
16419
+ "pivotAsAnchor",
16420
+ "overflow",
16421
+ "margin",
16422
+ "clipSoftness",
16423
+ "hitTest",
16424
+ "mask",
16425
+ "reversedMask",
16426
+ "scrollType",
16427
+ "scrollBarDisplay",
16428
+ "scrollBarFlags",
16429
+ "scrollBarMargin",
16430
+ "vtScrollBarRes",
16431
+ "hzScrollBarRes",
16432
+ "headerRes",
16433
+ "footerRes",
16434
+ "bgColor",
16435
+ "bgColorEnabled",
16436
+ "designImageAlpha",
16437
+ "designImageLayer",
16438
+ "designImageOffset",
16439
+ "idNum",
16440
+ "initName",
16441
+ "remark",
16442
+ "extensionType",
16443
+ "opaque",
16444
+ "buttonMode",
16445
+ "sound",
16446
+ "soundVolumeScale",
16447
+ "downEffect",
16448
+ "downEffectValue",
16449
+ "dropdown",
16450
+ "promptText",
16451
+ "selectionController",
16452
+ "titleType",
16453
+ "reverse",
16454
+ "wholeNumbers",
16455
+ "changeOnClick",
16456
+ "fixedGripSize",
16457
+ "autoClearItems",
16458
+ "customProperties"
16459
+ ];
16460
+ function isValidUamComponentProperties(value) {
16461
+ if (typeof value !== "object" || value === null || !hasExactKeys(value, COMPONENT_PROPERTY_KEYS)) return false;
16462
+ const properties = value;
16463
+ const strings = [
16464
+ properties.hitTest,
16465
+ properties.mask,
16466
+ properties.vtScrollBarRes,
16467
+ properties.hzScrollBarRes,
16468
+ properties.headerRes,
16469
+ properties.footerRes,
16470
+ properties.bgColor,
16471
+ properties.initName,
16472
+ properties.remark,
16473
+ properties.extensionType,
16474
+ properties.sound,
16475
+ properties.dropdown,
16476
+ properties.promptText,
16477
+ properties.selectionController
16478
+ ];
16479
+ const booleans = [
16480
+ properties.pivotAsAnchor,
16481
+ properties.reversedMask,
16482
+ properties.bgColorEnabled,
16483
+ properties.opaque,
16484
+ properties.reverse,
16485
+ properties.wholeNumbers,
16486
+ properties.changeOnClick,
16487
+ properties.fixedGripSize,
16488
+ properties.autoClearItems
16489
+ ];
16490
+ const numbers = [
16491
+ properties.overflow,
16492
+ properties.scrollType,
16493
+ properties.scrollBarDisplay,
16494
+ properties.scrollBarFlags,
16495
+ properties.designImageAlpha,
16496
+ properties.designImageLayer,
16497
+ properties.idNum,
16498
+ properties.buttonMode,
16499
+ properties.soundVolumeScale,
16500
+ properties.downEffect,
16501
+ properties.downEffectValue,
16502
+ properties.titleType
16503
+ ];
16504
+ return isFiniteUamSize(properties.minSize) && isFiniteUamSize(properties.maxSize) && isFiniteUamPoint(properties.pivot) && isFiniteUamEdgeInsets(properties.margin) && isFiniteUamPoint(properties.clipSoftness) && isFiniteUamEdgeInsets(properties.scrollBarMargin) && isFiniteUamPoint(properties.designImageOffset) && strings.every((item) => typeof item === "string") && booleans.every((item) => typeof item === "boolean") && numbers.every((item) => typeof item === "number" && Number.isFinite(item)) && Array.isArray(properties.customProperties) && properties.customProperties.every((property) => property && typeof property === "object" && hasExactKeys(property, [
16505
+ "target",
16506
+ "propertyId",
16507
+ "label"
16508
+ ]) && typeof property.target === "string" && (property.propertyId === 0 || property.propertyId === 1) && typeof property.label === "string");
16509
+ }
16510
+ function isNullableString(value) {
16511
+ return value === null || typeof value === "string";
16512
+ }
16513
+ function isValidUamComponentInstanceProperties(value) {
16514
+ if (typeof value !== "object" || value === null || !("extensionType" in value)) return false;
16515
+ const properties = value;
16516
+ const finite = (number) => typeof number === "number" && Number.isFinite(number);
16517
+ switch (properties.extensionType) {
16518
+ case "Button": return hasExactKeys(properties, [
16519
+ "extensionType",
16520
+ "title",
16521
+ "selectedTitle",
16522
+ "icon",
16523
+ "selectedIcon",
16524
+ "titleColor",
16525
+ "titleFontSize",
16526
+ "controller",
16527
+ "page",
16528
+ "checked",
16529
+ "sound",
16530
+ "soundVolumeScale"
16531
+ ]) && [
16532
+ properties.title,
16533
+ properties.selectedTitle,
16534
+ properties.icon,
16535
+ properties.selectedIcon,
16536
+ properties.titleColor,
16537
+ properties.controller,
16538
+ properties.page,
16539
+ properties.sound
16540
+ ].every((item) => typeof item === "string") && finite(properties.titleFontSize) && typeof properties.checked === "boolean" && finite(properties.soundVolumeScale);
16541
+ case "Label": return hasExactKeys(properties, [
16542
+ "extensionType",
16543
+ "title",
16544
+ "icon",
16545
+ "titleColor",
16546
+ "titleFontSize",
16547
+ "promptText"
16548
+ ]) && [
16549
+ properties.title,
16550
+ properties.icon,
16551
+ properties.titleColor,
16552
+ properties.promptText
16553
+ ].every((item) => typeof item === "string") && finite(properties.titleFontSize);
16554
+ case "ComboBox": return hasExactKeys(properties, [
16555
+ "extensionType",
16556
+ "title",
16557
+ "icon",
16558
+ "visibleItemCount",
16559
+ "selectionController",
16560
+ "autoClearItems",
16561
+ "items"
16562
+ ]) && [
16563
+ properties.title,
16564
+ properties.icon,
16565
+ properties.selectionController
16566
+ ].every((item) => typeof item === "string") && finite(properties.visibleItemCount) && typeof properties.autoClearItems === "boolean" && Array.isArray(properties.items) && properties.items.every((item) => item && typeof item === "object" && hasExactKeys(item, [
16567
+ "title",
16568
+ "value",
16569
+ "icon"
16570
+ ]) && isNullableString(item.title) && isNullableString(item.value) && isNullableString(item.icon));
16571
+ case "ProgressBar":
16572
+ case "Slider": return hasExactKeys(properties, [
16573
+ "extensionType",
16574
+ "value",
16575
+ "max",
16576
+ "min"
16577
+ ]) && [
16578
+ properties.value,
16579
+ properties.max,
16580
+ properties.min
16581
+ ].every(finite);
16582
+ case "ScrollBar": return hasExactKeys(properties, ["extensionType"]);
16583
+ default: return false;
16584
+ }
16585
+ }
16586
+ function validateControllerAction(action, knownPageIds, knownChildIds, path, issues) {
16587
+ for (const pageId of action.fromPageIds) if (!knownPageIds.has(pageId)) pushIssue(issues, `${path}.fromPageIds`, `Unknown controller page id "${pageId}".`);
16588
+ for (const pageId of action.toPageIds) if (!knownPageIds.has(pageId)) pushIssue(issues, `${path}.toPageIds`, `Unknown controller page id "${pageId}".`);
16589
+ if (action.targetNodeId && !knownChildIds.has(action.targetNodeId)) pushIssue(issues, `${path}.targetNodeId`, `Unknown target node id "${action.targetNodeId}".`);
16590
+ }
16591
+ function validateGearBinding(gear, controllerMap, path, issues) {
16592
+ const controller = controllerMap.get(gear.controllerName);
16593
+ if (!controller) {
16594
+ pushIssue(issues, `${path}.controllerName`, `Unknown gear controller "${gear.controllerName}".`);
16595
+ return;
16596
+ }
16597
+ const pageIds = new Set(controller.pages.map((page) => page.id));
16598
+ if (gear.kind === "display" || gear.kind === "display2") {
16599
+ const seen = /* @__PURE__ */ new Set();
16600
+ for (const pageId of gear.visibleOnPageIds) {
16601
+ if (seen.has(pageId)) pushIssue(issues, `${path}.visibleOnPageIds`, `Duplicate gear page id "${pageId}".`);
16602
+ seen.add(pageId);
16603
+ }
16604
+ return;
16605
+ }
16606
+ const seen = /* @__PURE__ */ new Set();
16607
+ for (const state of gear.states) {
16608
+ if (!pageIds.has(state.pageId)) pushIssue(issues, `${path}.states`, `Unknown gear state page id "${state.pageId}".`);
16609
+ if (seen.has(state.pageId)) pushIssue(issues, `${path}.states`, `Duplicate gear state page id "${state.pageId}".`);
16610
+ seen.add(state.pageId);
16611
+ }
16612
+ }
16613
+ function isSafePathSegment(value) {
16614
+ return value.length > 0 && value.trim() === value && value !== "." && value !== ".." && !/[\\/:]/.test(value) && !/[. ]$/.test(value) && !/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/i.test(value);
16615
+ }
16616
+ function normalizedResourceTarget(path, fileName) {
16617
+ if (!isSafePathSegment(fileName)) return null;
16618
+ const segments = path.replace(/\\/g, "/").split("/").filter(Boolean);
16619
+ if (segments.some((segment) => !isSafePathSegment(segment))) return null;
16620
+ return [...segments, fileName].join("/");
16621
+ }
16622
+ function isSafeRelativePath(value) {
16623
+ const segments = value.replace(/\\/g, "/").split("/").filter(Boolean);
16624
+ return segments.length > 0 && segments.every(isSafePathSegment);
16625
+ }
16626
+ function assetFileName$1(resource) {
16627
+ return resource.fileName || (resource.kind === "image" ? "" : resource.file) || resource.name;
16628
+ }
16629
+ function validatePackageOutputTargets(pkg, pkgPath, issues) {
16630
+ if (!isSafePathSegment(pkg.name)) pushIssue(issues, `${pkgPath}.name`, `Invalid package output name "${pkg.name}".`, "unsafe_path");
16631
+ const outputs = /* @__PURE__ */ new Map();
16632
+ const folderKeys = /* @__PURE__ */ new Set();
16633
+ for (const [folderIndex, folder] of pkg.folders.entries()) {
16634
+ const folderPath = `${pkgPath}.folders[${folderIndex}]`;
16635
+ if (folder.branch && !isSafePathSegment(folder.branch)) pushIssue(issues, `${folderPath}.branch`, `Invalid package branch name "${folder.branch}".`);
16636
+ const normalizedPath = normalizeResourceFolderPath(folder.path);
16637
+ if (folder.path === "/" || folder.path !== normalizedPath || !folder.path.split("/").filter(Boolean).every(isSafePathSegment)) {
16638
+ pushIssue(issues, `${folderPath}.path`, "Resource folder path must be canonical, non-root, and traversal-free.", "unsafe_path");
16639
+ continue;
16640
+ }
16641
+ if (typeof folder.favorite !== "boolean") pushIssue(issues, `${folderPath}.favorite`, "Resource folder favorite must be boolean.");
16642
+ if (typeof folder.atlas !== "string") pushIssue(issues, `${folderPath}.atlas`, "Resource folder atlas must be a string.");
16643
+ const key = `${folder.branch}\0${folder.path}`.toLowerCase();
16644
+ if (folderKeys.has(key)) pushIssue(issues, `${folderPath}.path`, `Duplicate resource folder path "${folder.path}".`, "path_collision");
16645
+ folderKeys.add(key);
16646
+ const parentPath = resourceFolderParentPath(folder.path);
16647
+ if (parentPath !== "/" && !folderKeys.has(`${folder.branch}\0${parentPath}`.toLowerCase()) && !pkg.folders.some((candidate) => candidate.branch.toLowerCase() === folder.branch.toLowerCase() && candidate.path.toLowerCase() === parentPath.toLowerCase())) pushIssue(issues, `${folderPath}.path`, `Parent resource folder "${parentPath}" does not exist.`);
16648
+ const target = folder.path.replace(/^\/+|\/+$/g, "");
16649
+ const descriptor = folder.branch ? "package_branch.xml" : "package.xml";
16650
+ if (target.toLowerCase() === descriptor) pushIssue(issues, `${folderPath}.path`, `Resource folder output "${target}" conflicts with the package descriptor.`, "path_collision");
16651
+ outputs.set(`${folder.branch}\0${target}`.toLowerCase(), folderPath);
16652
+ }
16653
+ for (const [resourceIndex, resource] of pkg.resources.entries()) {
16654
+ const resourcePath = `${pkgPath}.resources[${resourceIndex}]`;
16655
+ if (resource.branch && !isSafePathSegment(resource.branch)) pushIssue(issues, `${resourcePath}.branch`, `Invalid package branch name "${resource.branch}".`);
16656
+ const fileName = resource.kind === "component" ? `${resource.name}.xml` : assetFileName$1(resource);
16657
+ const target = normalizedResourceTarget(resource.path, fileName);
16658
+ if (!target) {
16659
+ pushIssue(issues, `${resourcePath}.path`, "Resource output path must be package-relative and traversal-free.", "unsafe_path");
16660
+ continue;
16661
+ }
16662
+ const descriptor = resource.branch ? "package_branch.xml" : "package.xml";
16663
+ if (target.toLowerCase() === descriptor) pushIssue(issues, `${resourcePath}.path`, `Resource output "${target}" conflicts with the package descriptor.`, "path_collision");
16664
+ const key = `${resource.branch}\0${target}`.toLowerCase();
16665
+ const previous = outputs.get(key);
16666
+ if (previous) pushIssue(issues, `${resourcePath}.path`, `Resource output "${target}" conflicts with ${previous}.`, "path_collision");
16667
+ else outputs.set(key, resourcePath);
16668
+ if (resource.kind !== "component" && resource.sourcePath && !isSafeRelativePath(resource.sourcePath)) pushIssue(issues, `${resourcePath}.sourcePath`, "Resource sourcePath must be package-relative and traversal-free.", "unsafe_path");
16669
+ }
16670
+ }
16671
+ function validateDisplayNode(node, controllerMap, knownChildIds, knownGroupIds, path, issues) {
16672
+ if (!isFiniteUamPoint(node.position)) pushIssue(issues, `${path}.position`, "Display node position must contain finite x and y numbers.");
16673
+ if (!isFiniteUamSize(node.size) || node.size.width < 0 || node.size.height < 0) pushIssue(issues, `${path}.size`, "Display node size must contain finite non-negative width and height values.");
16674
+ if (typeof node.locked !== "boolean") pushIssue(issues, `${path}.locked`, "Display node locked must be boolean.");
16675
+ if (typeof node.aspect !== "boolean") pushIssue(issues, `${path}.aspect`, "Display node aspect must be boolean.");
16676
+ for (const [key, value] of [["minSize", node.minSize], ["maxSize", node.maxSize]]) if (!isFiniteUamSize(value) || value.width < 0 || value.height < 0) pushIssue(issues, `${path}.${key}`, `Display node ${key} must contain finite non-negative width and height values.`);
16677
+ if (isFiniteUamSize(node.minSize) && isFiniteUamSize(node.maxSize)) {
16678
+ if (node.maxSize.width > 0 && node.maxSize.width < node.minSize.width) pushIssue(issues, `${path}.maxSize.width`, "Display node maxSize.width must be zero or at least minSize.width.");
16679
+ if (node.maxSize.height > 0 && node.maxSize.height < node.minSize.height) pushIssue(issues, `${path}.maxSize.height`, "Display node maxSize.height must be zero or at least minSize.height.");
16680
+ }
16681
+ if (!isFiniteUamPoint(node.scale)) pushIssue(issues, `${path}.scale`, "Display node scale must contain finite x and y numbers.");
16682
+ if (!isFiniteUamPoint(node.skew)) pushIssue(issues, `${path}.skew`, "Display node skew must contain finite x and y numbers.");
16683
+ if (![
16684
+ node.visible,
16685
+ node.touchable,
16686
+ node.grayed
16687
+ ].every((value) => typeof value === "boolean")) pushIssue(issues, path, "Display node visible, touchable, and grayed must be boolean.");
16688
+ if (typeof node.alpha !== "number" || !Number.isFinite(node.alpha) || node.alpha < 0 || node.alpha > 1) pushIssue(issues, `${path}.alpha`, "Display node alpha must be a finite number between 0 and 1.");
16689
+ if (typeof node.rotation !== "number" || !Number.isFinite(node.rotation)) pushIssue(issues, `${path}.rotation`, "Display node rotation must be finite.");
16690
+ if (![
16691
+ node.tooltips,
16692
+ node.filter,
16693
+ node.filterData,
16694
+ node.customData
16695
+ ].every((value) => typeof value === "string")) pushIssue(issues, path, "Display node tooltips, filter, filterData, and customData must be strings.");
16696
+ if (![
16697
+ "normal",
16698
+ "none",
16699
+ "add",
16700
+ "multiply",
16701
+ "screen",
16702
+ "erase"
16703
+ ].includes(node.blendMode)) pushIssue(issues, `${path}.blendMode`, `Unsupported display node blendMode "${node.blendMode}".`);
16704
+ if (node.filter !== "" && node.filter !== "color") pushIssue(issues, `${path}.filter`, `Unsupported display node filter "${node.filter}".`);
16705
+ else if (node.filter === "color") {
16706
+ const values = node.filterData.split(",").map((part) => Number(part.trim()));
16707
+ if (values.length !== 4 || values.some((value) => !Number.isFinite(value))) pushIssue(issues, `${path}.filterData`, "Color filterData must contain four finite comma-separated numbers.");
16708
+ } else if (node.filterData !== "") pushIssue(issues, `${path}.filterData`, "filterData must be empty when filter is empty.");
16709
+ if (node.pivot !== void 0) {
16710
+ if (!isFiniteUamPoint(node.pivot)) pushIssue(issues, `${path}.pivot`, "Display node pivot must contain finite x and y numbers.");
16711
+ }
16712
+ if (node.pivotAsAnchor !== void 0) {
16713
+ if (typeof node.pivotAsAnchor !== "boolean") pushIssue(issues, `${path}.pivotAsAnchor`, "Display node pivotAsAnchor must be boolean.");
16714
+ }
16715
+ if (node.kind === "component" && node.propertyOverrides !== void 0 && (!Array.isArray(node.propertyOverrides) || !node.propertyOverrides.every(isValidUamComponentPropertyOverride))) pushIssue(issues, `${path}.propertyOverrides`, "Component property overrides must contain a non-empty target, a non-negative integer propertyId, and a string value.");
16716
+ if (node.kind === "list" || node.kind === "tree") {
16717
+ for (const [itemIndex, item] of node.listItems.entries()) if (item.propertyOverrides !== void 0 && (!Array.isArray(item.propertyOverrides) || !item.propertyOverrides.every(isValidUamComponentPropertyOverride))) pushIssue(issues, `${path}.listItems[${itemIndex}].propertyOverrides`, "List item property overrides must contain a non-empty target, a non-negative integer propertyId, and a string value.");
16718
+ }
16719
+ if ((node.kind === "text" || node.kind === "richText" || node.kind === "textInput") && !isValidUamTextProperties(textPropertiesFromNode(node), node.kind)) pushIssue(issues, path, "Text properties must be a complete valid snapshot matching the display node kind.");
16720
+ if (node.kind === "loader" || node.kind === "loader3D") {
16721
+ if ("group" in node) pushIssue(issues, `${path}.group`, `${node.kind} display nodes must not declare a group reference.`);
16722
+ } else if (!("group" in node) || typeof node.group !== "string") pushIssue(issues, `${path}.group`, "Display node group must be a string.");
16723
+ else if (node.group && (node.group === node.id || !knownGroupIds.has(node.group))) pushIssue(issues, `${path}.group`, `Group reference "${node.group}" must target another group in the same component.`);
16724
+ for (const [gearIndex, gear] of node.gears.entries()) validateGearBinding(gear, controllerMap, `${path}.gears[${gearIndex}]`, issues);
16725
+ for (const [relationIndex, relation] of node.relations.entries()) if (relation.targetNodeId && !knownChildIds.has(relation.targetNodeId)) pushIssue(issues, `${path}.relations[${relationIndex}]`, `Unknown relation target node id "${relation.targetNodeId}".`);
16726
+ }
16727
+ function validateUamProject(project) {
16728
+ const issues = [];
16729
+ const packageIds = /* @__PURE__ */ new Set();
16730
+ const packageNames = /* @__PURE__ */ new Set();
16731
+ const declaredProjectBranches = Array.isArray(project.branches) ? project.branches : [];
16732
+ if (!Array.isArray(project.branches)) pushIssue(issues, "branches", "Project branches must be an array.");
16733
+ const projectBranchNames = /* @__PURE__ */ new Set();
16734
+ for (const [branchIndex, branchName] of declaredProjectBranches.entries()) {
16735
+ if (!isSafePathSegment(branchName)) pushIssue(issues, `branches[${branchIndex}]`, `Invalid branch name "${branchName}".`);
16736
+ if (projectBranchNames.has(branchName)) pushIssue(issues, `branches[${branchIndex}]`, `Duplicate branch name "${branchName}".`);
16737
+ if (branchIndex > 0 && declaredProjectBranches[branchIndex - 1].localeCompare(branchName) > 0) pushIssue(issues, `branches[${branchIndex}]`, "Project branches must use canonical lexical order.");
16738
+ projectBranchNames.add(branchName);
16739
+ }
16740
+ for (const [pkgIndex, pkg] of project.packages.entries()) {
16741
+ const pkgPath = `packages[${pkgIndex}]`;
16742
+ if (packageIds.has(pkg.id)) pushIssue(issues, `${pkgPath}.id`, `Duplicate package id "${pkg.id}".`, "duplicate_package_id");
16743
+ if (packageNames.has(pkg.name.toLowerCase())) pushIssue(issues, `${pkgPath}.name`, `Duplicate package name "${pkg.name}".`, "duplicate_package_name");
16744
+ packageIds.add(pkg.id);
16745
+ packageNames.add(pkg.name.toLowerCase());
16746
+ validatePackageOutputTargets(pkg, pkgPath, issues);
16747
+ const declaredBranchNames = Array.isArray(pkg.branchNames) ? pkg.branchNames : [];
16748
+ if (!Array.isArray(pkg.branchNames)) pushIssue(issues, `${pkgPath}.branchNames`, "Package branchNames must be an array.");
16749
+ const packageBranchNames = /* @__PURE__ */ new Set();
16750
+ for (const [branchIndex, branchName] of declaredBranchNames.entries()) {
16751
+ if (!branchName || !projectBranchNames.has(branchName)) pushIssue(issues, `${pkgPath}.branchNames[${branchIndex}]`, `Unknown package branch "${branchName}".`);
16752
+ if (packageBranchNames.has(branchName)) pushIssue(issues, `${pkgPath}.branchNames[${branchIndex}]`, `Duplicate package branch "${branchName}".`);
16753
+ packageBranchNames.add(branchName);
16754
+ }
16755
+ const resourceIds = /* @__PURE__ */ new Set();
16756
+ for (const [resourceIndex, resource] of pkg.resources.entries()) {
16757
+ const resourcePath = `${pkgPath}.resources[${resourceIndex}]`;
16758
+ if (resourceIds.has(resource.id)) pushIssue(issues, `${resourcePath}.id`, `Duplicate resource id "${resource.id}".`, "duplicate_resource_id");
16759
+ resourceIds.add(resource.id);
16760
+ if (resource.branch && !packageBranchNames.has(resource.branch)) pushIssue(issues, `${resourcePath}.branch`, `Unknown package branch "${resource.branch}".`);
16761
+ if (resource.branchItemIds.length > declaredBranchNames.length) pushIssue(issues, `${resourcePath}.branchItemIds`, "Branch item ids exceed the package branch table.");
16762
+ if (typeof resource.favorite !== "boolean") pushIssue(issues, `${resourcePath}.favorite`, "Resource favorite must be boolean.");
16763
+ if (resource.kind === "image" && !isValidUamImageResourceProperties(resource.image)) pushIssue(issues, `${resourcePath}.image`, "Image resource properties must be a complete valid property snapshot.");
16764
+ if (resource.kind === "movieClip") {
16765
+ if (!isFiniteUamSize(resource.dimensions) || resource.dimensions.width < 0 || resource.dimensions.height < 0) pushIssue(issues, `${resourcePath}.dimensions`, "MovieClip dimensions must contain finite non-negative width and height values.");
16766
+ if (!isValidUamMovieClipResourceProperties(resource.movieClip)) pushIssue(issues, `${resourcePath}.movieClip`, "MovieClip properties must be a complete valid property snapshot.");
16767
+ }
16768
+ if (resource.kind !== "component") continue;
16769
+ const component = resource.component;
16770
+ if (!isValidUamComponentProperties(component.properties)) pushIssue(issues, `${resourcePath}.component.properties`, "Component properties must be a complete valid property snapshot.");
16771
+ const childIds = /* @__PURE__ */ new Set();
16772
+ const groupIds = /* @__PURE__ */ new Set();
16773
+ for (const [childIndex, child] of component.displayList.entries()) {
16774
+ const childPath = `${resourcePath}.component.displayList[${childIndex}]`;
16775
+ if (childIds.has(child.id)) pushIssue(issues, `${childPath}.id`, `Duplicate child id "${child.id}".`);
16776
+ childIds.add(child.id);
16777
+ if (child.kind === "group") groupIds.add(child.id);
16778
+ }
16779
+ const controllerMap = /* @__PURE__ */ new Map();
16780
+ for (const [controllerIndex, controller] of component.controllers.entries()) {
16781
+ const controllerPath = `${resourcePath}.component.controllers[${controllerIndex}]`;
16782
+ if (controllerMap.has(controller.name)) pushIssue(issues, `${controllerPath}.name`, `Duplicate controller name "${controller.name}".`);
16783
+ controllerMap.set(controller.name, controller);
16784
+ const pageIds = /* @__PURE__ */ new Set();
16785
+ for (const [pageIndex, page] of controller.pages.entries()) {
16786
+ const pagePath = `${controllerPath}.pages[${pageIndex}]`;
16787
+ if (pageIds.has(page.id)) pushIssue(issues, `${pagePath}.id`, `Duplicate controller page id "${page.id}".`);
16788
+ pageIds.add(page.id);
16789
+ }
16790
+ for (const [actionIndex, action] of controller.actions.entries()) validateControllerAction(action, pageIds, childIds, `${controllerPath}.actions[${actionIndex}]`, issues);
16791
+ }
16792
+ for (const [childIndex, child] of component.displayList.entries()) {
16793
+ if (child.kind === "component" && child.instanceProperties !== void 0 && !isValidUamComponentInstanceProperties(child.instanceProperties)) pushIssue(issues, `${resourcePath}.component.displayList[${childIndex}].instanceProperties`, "Component instance properties must be a complete valid extension snapshot.");
16794
+ validateDisplayNode(child, controllerMap, childIds, groupIds, `${resourcePath}.component.displayList[${childIndex}]`, issues);
16795
+ }
16796
+ }
16797
+ }
16798
+ return issues;
16799
+ }
16800
+ //#endregion
16801
+ //#region ../core/src/uam/reference-validation.ts
16802
+ function findUiResource(project, value) {
16803
+ if (!value.startsWith("ui://")) return null;
16804
+ const reference = value.slice(5);
16805
+ const slashIndex = reference.indexOf("/");
16806
+ if (slashIndex >= 0) {
16807
+ const packageKey = reference.slice(0, slashIndex);
16808
+ const resourceKey = reference.slice(slashIndex + 1);
16809
+ return project.packages.find((candidate) => candidate.id === packageKey || candidate.name === packageKey)?.resources.find((resource) => resource.id === resourceKey || resource.name === resourceKey || resource.name.replace(/\.[^.]+$/, "") === resourceKey) ?? null;
16810
+ }
16811
+ const pkg = [...project.packages].sort((left, right) => right.id.length - left.id.length).find((candidate) => reference.startsWith(candidate.id));
16812
+ return pkg?.resources.find((resource) => resource.id === reference.slice(pkg.id.length)) ?? null;
16813
+ }
16814
+ function collectUiReferences(value) {
16815
+ if (Array.isArray(value)) return value.flatMap(collectUiReferences);
16816
+ if (typeof value === "object" && value !== null) return Object.values(value).flatMap(collectUiReferences);
16817
+ if (typeof value !== "string") return [];
16818
+ return [...value.matchAll(/ui:\/\/[^\s"'<>()[\]{}]+/g)].map((match) => match[0]);
16819
+ }
16820
+ function validateUamReferences(project) {
16821
+ const issues = [];
16822
+ const findResource = (packageId, resourceId) => project.packages.find((pkg) => pkg.id === packageId)?.resources.find((resource) => resource.id === resourceId);
16823
+ const pushMissing = (path, packageId, resourceId, expectedKinds, owner) => {
16824
+ const target = findResource(packageId, resourceId);
16825
+ if (target && expectedKinds.includes(target.kind)) return;
16826
+ issues.push({
16827
+ severity: "error",
16828
+ code: "dangling_resource_reference",
16829
+ path,
16830
+ message: `Resource reference "${packageId}/${resourceId}" must target ${expectedKinds.join(" or ")}.`,
16831
+ ...owner
16832
+ });
16833
+ };
16834
+ const pushMissingUi = (path, value, expectedKinds, owner) => {
16835
+ if (!value.startsWith("ui://")) return;
16836
+ const target = findUiResource(project, value);
16837
+ if (target && expectedKinds.includes(target.kind)) return;
16838
+ issues.push({
16839
+ severity: "error",
16840
+ code: "dangling_resource_reference",
16841
+ path,
16842
+ message: `Resource reference "${value}" must target ${expectedKinds.join(" or ")}.`,
16843
+ ...owner
16844
+ });
16845
+ };
16846
+ const componentKinds = ["component"];
16847
+ const visualKinds = [
16848
+ "image",
16849
+ "movieClip",
16850
+ "component",
16851
+ "spine",
16852
+ "dragonBones"
16853
+ ];
16854
+ const binaryKinds = [
16855
+ "image",
16856
+ "sound",
16857
+ "misc",
16858
+ "font",
16859
+ "movieClip",
16860
+ "spine",
16861
+ "dragonBones"
16862
+ ];
16863
+ const resourceKinds = [...binaryKinds, "component"];
16864
+ for (const [packageIndex, pkg] of project.packages.entries()) for (const [resourceIndex, resource] of pkg.resources.entries()) {
16865
+ const resourcePath = `packages[${packageIndex}].resources[${resourceIndex}]`;
16866
+ const owner = {
16867
+ packageId: pkg.id,
16868
+ resourceId: resource.id
16869
+ };
16870
+ if (resource.kind === "font") {
16871
+ const textureId = `${resource.metadata?.textureId ?? ""}`;
16872
+ if (textureId) pushMissing(`${resourcePath}.metadata.textureId`, pkg.id, textureId, ["image"], owner);
16873
+ }
16874
+ if (resource.kind === "spine" || resource.kind === "dragonBones") {
16875
+ const requireIds = Array.isArray(resource.metadata?.requireIds) ? resource.metadata.requireIds.filter((value) => typeof value === "string") : [];
16876
+ for (const [requireIndex, requireId] of requireIds.entries()) pushMissing(`${resourcePath}.metadata.requireIds[${requireIndex}]`, pkg.id, requireId, binaryKinds, owner);
16877
+ }
16878
+ if (resource.kind !== "component") continue;
16879
+ const componentPath = `${resourcePath}.component`;
16880
+ for (const [field, value] of [
16881
+ ["vtScrollBarRes", resource.component.properties.vtScrollBarRes],
16882
+ ["hzScrollBarRes", resource.component.properties.hzScrollBarRes],
16883
+ ["headerRes", resource.component.properties.headerRes],
16884
+ ["footerRes", resource.component.properties.footerRes],
16885
+ ["dropdown", resource.component.properties.dropdown]
16886
+ ]) pushMissingUi(`${componentPath}.properties.${field}`, value, componentKinds, owner);
16887
+ pushMissingUi(`${componentPath}.properties.sound`, resource.component.properties.sound, ["sound"], owner);
16888
+ for (const [nodeIndex, node] of resource.component.displayList.entries()) {
16889
+ const nodePath = `${componentPath}.displayList[${nodeIndex}]`;
16890
+ const nodeOwner = {
16891
+ ...owner,
16892
+ nodeId: node.id
16893
+ };
16894
+ if (node.kind === "image" && node.resource.resourceId) pushMissing(`${nodePath}.resource`, node.resource.packageId || pkg.id, node.resource.resourceId, ["image"], nodeOwner);
16895
+ else if (node.kind === "movieClip" && node.resource.resourceId) pushMissing(`${nodePath}.resource`, node.resource.packageId || pkg.id, node.resource.resourceId, ["movieClip"], nodeOwner);
16896
+ else if (node.kind === "component" && node.resource.resourceId) pushMissing(`${nodePath}.resource`, node.resource.packageId || pkg.id, node.resource.resourceId, componentKinds, nodeOwner);
16897
+ else if ("packageId" in node && "src" in node && node.src) pushMissing(`${nodePath}.src`, node.packageId || pkg.id, node.src, componentKinds, nodeOwner);
16898
+ if (node.kind === "text" || node.kind === "richText" || node.kind === "textInput") {
16899
+ pushMissingUi(`${nodePath}.font`, node.font, ["font"], nodeOwner);
16900
+ for (const [index, reference] of collectUiReferences(node.text).entries()) pushMissingUi(`${nodePath}.text[${index}]`, reference, resourceKinds, nodeOwner);
16901
+ }
16902
+ if (node.kind === "loader" || node.kind === "loader3D") pushMissingUi(`${nodePath}.url`, node.url, visualKinds, nodeOwner);
16903
+ if (node.kind === "list" || node.kind === "tree") {
16904
+ for (const [field, value] of [
16905
+ ["defaultItem", node.defaultItem],
16906
+ ["src", node.src],
16907
+ ["vtScrollBarRes", node.vtScrollBarRes],
16908
+ ["hzScrollBarRes", node.hzScrollBarRes],
16909
+ ["headerRes", node.headerRes],
16910
+ ["footerRes", node.footerRes]
16911
+ ]) pushMissingUi(`${nodePath}.${field}`, value, componentKinds, nodeOwner);
16912
+ for (const [itemIndex, item] of node.listItems.entries()) {
16913
+ pushMissingUi(`${nodePath}.listItems[${itemIndex}].url`, item.url ?? "", componentKinds, nodeOwner);
16914
+ pushMissingUi(`${nodePath}.listItems[${itemIndex}].icon`, item.icon ?? "", visualKinds, nodeOwner);
16915
+ pushMissingUi(`${nodePath}.listItems[${itemIndex}].selectedIcon`, item.selectedIcon ?? "", visualKinds, nodeOwner);
16916
+ }
16917
+ }
16918
+ if (node.kind === "component" && node.instanceProperties) {
16919
+ const instance = node.instanceProperties;
16920
+ if ("icon" in instance) pushMissingUi(`${nodePath}.instanceProperties.icon`, instance.icon, visualKinds, nodeOwner);
16921
+ if (instance.extensionType === "Button") {
16922
+ pushMissingUi(`${nodePath}.instanceProperties.selectedIcon`, instance.selectedIcon, visualKinds, nodeOwner);
16923
+ pushMissingUi(`${nodePath}.instanceProperties.sound`, instance.sound, ["sound"], nodeOwner);
16924
+ }
16925
+ if (instance.extensionType === "ComboBox") for (const [itemIndex, item] of instance.items.entries()) pushMissingUi(`${nodePath}.instanceProperties.items[${itemIndex}].icon`, item.icon ?? "", visualKinds, nodeOwner);
16926
+ }
16927
+ if ("icon" in node) pushMissingUi(`${nodePath}.icon`, node.icon, visualKinds, nodeOwner);
16928
+ if ("selectedIcon" in node) pushMissingUi(`${nodePath}.selectedIcon`, node.selectedIcon, visualKinds, nodeOwner);
16929
+ if ("icons" in node) for (const [iconIndex, icon] of node.icons.entries()) pushMissingUi(`${nodePath}.icons[${iconIndex}]`, icon, visualKinds, nodeOwner);
16930
+ if ("sound" in node) pushMissingUi(`${nodePath}.sound`, node.sound, ["sound"], nodeOwner);
16931
+ for (const [gearIndex, gear] of node.gears.entries()) for (const [index, reference] of collectUiReferences(gear).entries()) pushMissingUi(`${nodePath}.gears[${gearIndex}][${index}]`, reference, resourceKinds, nodeOwner);
16932
+ }
16933
+ for (const [transitionIndex, transition] of resource.component.transitions.entries()) for (const [itemIndex, item] of transition.items.entries()) for (const [field, value] of [["startValue", item.startValue], ["endValue", item.endValue]]) for (const [index, reference] of collectUiReferences(value).entries()) pushMissingUi(`${componentPath}.transitions[${transitionIndex}].items[${itemIndex}].${field}[${index}]`, reference, resourceKinds, owner);
16934
+ }
16935
+ return issues;
16936
+ }
16937
+ //#endregion
16938
+ //#region ../core/src/uam/project-source-files.ts
16939
+ function defaultAssetSourcePath(resource) {
16940
+ const fileName = resource.fileName ?? (resource.kind === "image" ? "" : resource.file) ?? "";
16941
+ return `/${[resource.path.replace(/\\/g, "/").replace(/^\/+|\/+$/g, ""), fileName].filter(Boolean).join("/")}`;
16942
+ }
16943
+ //#endregion
16944
+ //#region ../core/src/uam/source-validation.ts
16945
+ function assetFileName(resource) {
16946
+ return resource.fileName ?? (resource.kind === "image" ? "" : resource.file) ?? resource.name;
16947
+ }
16948
+ function sourceExtension(resource) {
16949
+ const fileName = assetFileName(resource);
16950
+ const dot = fileName.lastIndexOf(".");
16951
+ return dot < 0 ? "" : fileName.slice(dot + 1).toLowerCase();
16952
+ }
16953
+ function validSvg(bytes) {
16954
+ try {
16955
+ if (bytes.byteLength === 0 || bytes.byteLength > 8 * 1024 * 1024) return false;
16956
+ const source = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
16957
+ if (XMLValidator.validate(source, { allowBooleanAttributes: false }) !== true) return false;
16958
+ if (!/<svg(?:\s|>)/i.test(source)) return false;
16959
+ if (/<!\s*(?:doctype|entity)\b|<\?xml-stylesheet\b/iu.test(source)) return false;
16960
+ if (/<(?:a|animate|animatecolor|animatemotion|animatetransform|audio|canvas|discard|embed|feimage|foreignobject|iframe|image|object|script|set|style|video)(?:\s|>)/iu.test(source)) return false;
16961
+ if (/\s(?:on[\w:-]*|style|src)\s*=/iu.test(source)) return false;
16962
+ if (/\s(?:href|xlink:href)\s*=\s*['"](?!#[A-Za-z_][\w:.-]*['"])/iu.test(source)) return false;
16963
+ return !/(?:https?:|file:|javascript:|data:|\/\/)|url\s*\(\s*(?!['"]?#[A-Za-z_])/iu.test(source);
16964
+ } catch {
16965
+ return false;
16966
+ }
16967
+ }
16968
+ function validateUamSourceBytes(project) {
16969
+ const diagnostics = [];
16970
+ let complete = true;
16971
+ for (const [packageIndex, pkg] of project.packages.entries()) for (const [resourceIndex, resource] of pkg.resources.entries()) {
16972
+ if (resource.kind === "component") continue;
16973
+ const bytes = resource.sourceBytes;
16974
+ const path = `packages[${packageIndex}].resources[${resourceIndex}]`;
16975
+ const sourcePath = resource.sourcePath ?? defaultAssetSourcePath(resource);
16976
+ const base = {
16977
+ path,
16978
+ packageId: pkg.id,
16979
+ resourceId: resource.id,
16980
+ sourcePath
16981
+ };
16982
+ if (!(bytes instanceof Uint8Array)) {
16983
+ complete = false;
16984
+ diagnostics.push({
16985
+ severity: "warning",
16986
+ code: "decode_capability_unavailable",
16987
+ message: "Source bytes are not loaded, so source validation is incomplete.",
16988
+ ...base
16989
+ });
16990
+ continue;
16991
+ }
16992
+ if (bytes.byteLength === 0) {
16993
+ diagnostics.push({
16994
+ severity: "error",
16995
+ code: "corrupt_source",
16996
+ message: "Declared source file is empty.",
16997
+ ...base
16998
+ });
16999
+ continue;
17000
+ }
17001
+ if (resource.kind === "image") {
17002
+ const extension = sourceExtension(resource);
17003
+ if (extension === "png" || extension === "jpg" || extension === "jpeg") {
17004
+ if (!probeRasterImage(bytes)) diagnostics.push({
17005
+ severity: "error",
17006
+ code: "corrupt_source",
17007
+ message: `Invalid ${extension.toUpperCase()} source.`,
17008
+ ...base
17009
+ });
17010
+ } else if (extension === "svg") {
17011
+ if (!validSvg(bytes)) diagnostics.push({
17012
+ severity: "error",
17013
+ code: "corrupt_source",
17014
+ message: "Invalid or unsafe SVG source.",
17015
+ ...base
17016
+ });
17017
+ } else {
17018
+ complete = false;
17019
+ diagnostics.push({
17020
+ severity: "warning",
17021
+ code: "decode_capability_unavailable",
17022
+ message: `No host-neutral decoder is available for image extension "${extension || "(none)"}".`,
17023
+ ...base
17024
+ });
17025
+ }
17026
+ } else if (resource.kind === "movieClip") try {
17027
+ deriveMovieClipModelFromJta(bytes);
17028
+ } catch (error) {
17029
+ diagnostics.push({
17030
+ severity: "error",
17031
+ code: "corrupt_source",
17032
+ message: `Invalid MovieClip source: ${error instanceof Error ? error.message : String(error)}`,
17033
+ ...base
17034
+ });
17035
+ }
17036
+ }
17037
+ return {
17038
+ diagnostics,
17039
+ complete
17040
+ };
17041
+ }
17042
+ //#endregion
17043
+ //#region ../core/src/uam/bridge-materialize.ts
17044
+ function parseNumber(raw, fallback) {
17045
+ if (raw === void 0 || raw === "") return fallback;
17046
+ const value = Number(raw);
17047
+ return Number.isFinite(value) ? value : fallback;
17048
+ }
17049
+ function parseBool(raw, fallback) {
17050
+ if (raw === void 0 || raw === "") return fallback;
17051
+ const normalized = raw.toLowerCase();
17052
+ if (normalized === "1" || normalized === "true" || normalized === "p") return true;
17053
+ if (normalized === "0" || normalized === "false" || normalized === "s") return false;
17054
+ return fallback;
17055
+ }
17056
+ function parseLookGearValue(value) {
17057
+ if (!value || value === "-") return null;
17058
+ const parts = value.split(",");
17059
+ return {
17060
+ alpha: parseNumber(parts[0], 1),
17061
+ rotation: parseNumber(parts[1], 0),
17062
+ grayed: parseBool(parts[2], false),
17063
+ touchable: parseBool(parts[3], true)
17064
+ };
17065
+ }
17066
+ function parseGenericGearValue(kind, value) {
17067
+ if (!value || value === "-") return null;
17068
+ const parts = value.split(",");
17069
+ switch (kind) {
17070
+ case "xy": return {
17071
+ x: parseNumber(parts[0], 0),
17072
+ y: parseNumber(parts[1], 0)
17073
+ };
17074
+ case "size": return {
17075
+ width: parseNumber(parts[0], 0),
17076
+ height: parseNumber(parts[1], 0),
17077
+ scaleX: parseNumber(parts[2], 1),
17078
+ scaleY: parseNumber(parts[3], 1)
17079
+ };
17080
+ case "color": return {
17081
+ color: parts[0] || "#ffffff",
17082
+ outlineColor: parts[1] || null
17083
+ };
17084
+ case "animation": return {
17085
+ frame: parseNumber(parts[0], 0),
17086
+ playing: parseBool(parts[1], true),
17087
+ animationName: parts[2] ?? "",
17088
+ skinName: parts[3] ?? ""
17089
+ };
17090
+ case "text": return { text: value };
17091
+ case "icon": return { icon: value };
17092
+ case "fontSize": return { fontSize: parseNumber(parts[0], 12) };
17093
+ }
17094
+ }
17095
+ function defaultGenericGearValue(kind) {
17096
+ switch (kind) {
17097
+ case "xy": return {
17098
+ x: 0,
17099
+ y: 0
17100
+ };
17101
+ case "size": return {
17102
+ width: 0,
17103
+ height: 0,
17104
+ scaleX: 1,
17105
+ scaleY: 1
17106
+ };
17107
+ case "color": return {
17108
+ color: "#ffffff",
17109
+ outlineColor: null
17110
+ };
17111
+ case "animation": return {
17112
+ frame: 0,
17113
+ playing: true,
17114
+ animationName: "",
17115
+ skinName: ""
17116
+ };
17117
+ case "text": return { text: "" };
17118
+ case "icon": return { icon: "" };
17119
+ case "fontSize": return { fontSize: 12 };
17120
+ }
17121
+ }
17122
+ //#endregion
17123
+ //#region ../core/src/uam/bridge-lift.ts
17124
+ function liftDisplayNodeBase(child) {
17125
+ return {
17126
+ id: child.getId(),
17127
+ name: child.getName(),
17128
+ position: {
17129
+ x: child.getX(),
17130
+ y: child.getY()
17131
+ },
17132
+ size: {
17133
+ width: child.getWidth(),
17134
+ height: child.getHeight()
17135
+ },
17136
+ locked: child.getLocked(),
17137
+ aspect: child.getAspect(),
17138
+ minSize: {
17139
+ width: child.getMinWidth(),
17140
+ height: child.getMinHeight()
17141
+ },
17142
+ maxSize: {
17143
+ width: child.getMaxWidth(),
17144
+ height: child.getMaxHeight()
17145
+ },
17146
+ pivot: {
17147
+ x: child.getPivotX(),
17148
+ y: child.getPivotY()
17149
+ },
17150
+ pivotAsAnchor: child.getPivotAsAnchor(),
17151
+ scale: {
17152
+ x: child.getScaleX(),
17153
+ y: child.getScaleY()
17154
+ },
17155
+ skew: {
17156
+ x: child.getSkewX(),
17157
+ y: child.getSkewY()
17158
+ },
17159
+ visible: child.getVisible(),
17160
+ touchable: child.getTouchable(),
17161
+ grayed: child.getGrayed(),
17162
+ alpha: child.getAlpha(),
17163
+ rotation: child.getRotation(),
17164
+ tooltips: child.getTooltips(),
17165
+ blendMode: child.getBlendMode(),
17166
+ filter: child.getFilter(),
17167
+ filterData: child.getFilterData(),
17168
+ customData: child.getCustomData(),
17169
+ relations: liftRelations(child.getRelations()),
17170
+ gears: liftGears(child.listGears())
17171
+ };
17172
+ }
17173
+ function liftComponentDerivedControlBase(child) {
17174
+ return {
17175
+ ...liftDisplayNodeBase(child),
17176
+ group: child.getGroup(),
17177
+ src: child.getSrc(),
17178
+ packageId: child.getPackageId()
17179
+ };
17180
+ }
17181
+ function liftTitleControlBase(child) {
17182
+ return {
17183
+ ...liftComponentDerivedControlBase(child),
17184
+ title: child.getTitle(),
17185
+ icon: child.getIcon(),
17186
+ titleColor: child.getTitleColor(),
17187
+ titleFontSize: child.getTitleFontSize(),
17188
+ sound: child.getSound(),
17189
+ soundVolumeScale: child.getSoundVolumeScale()
17190
+ };
17191
+ }
17192
+ function liftAssetSourceData(resource) {
17193
+ const buffer = resource.getSourceData?.();
17194
+ if (!buffer) return {};
17195
+ const sourceBytes = buffer.getData();
17196
+ return {
17197
+ ...sourceBytes ? { sourceBytes: new Uint8Array(sourceBytes) } : { sourceBytes: null },
17198
+ ...buffer.getURI() ? { sourcePath: buffer.getURI() } : {}
17199
+ };
17200
+ }
17201
+ function baseAssetResource(kind, resource) {
17202
+ return {
17203
+ kind,
17204
+ id: resource.getId(),
17205
+ name: resource.getName(),
17206
+ path: resource.getPath(),
17207
+ exported: resource.getExported(),
17208
+ favorite: resource.getFavorite(),
17209
+ branch: resource.getBranch(),
17210
+ branchItemIds: resource.getBranchItemIds(),
17211
+ ...liftAssetSourceData(resource)
17212
+ };
17213
+ }
17214
+ function liftAssetResource(resource) {
17215
+ if (resource.propertyType === PropertyType.IMAGE_RESOURCE) {
17216
+ const image = resource;
17217
+ const scale9Grid = image.getScale9Grid();
17218
+ return {
17219
+ ...baseAssetResource("image", image),
17220
+ fileName: image.getFileName(),
17221
+ dimensions: {
17222
+ width: image.getWidth(),
17223
+ height: image.getHeight()
17224
+ },
17225
+ image: {
17226
+ textureSetMode: image.getTextureSetMode(),
17227
+ qualityOption: image.getQualityOption(),
17228
+ quality: image.getQuality(),
17229
+ smoothing: image.getSmoothing(),
17230
+ duplicatePadding: image.getDuplicatePadding(),
17231
+ scaleOption: image.getScaleOption(),
17232
+ scale9Grid: scale9Grid ? [...scale9Grid] : null,
17233
+ tileGridIndice: image.getTileGridIndice()
17234
+ }
17235
+ };
17236
+ }
17237
+ if (resource.propertyType === PropertyType.MOVIE_CLIP_RESOURCE) {
17238
+ const movieClip = resource;
17239
+ return {
17240
+ ...baseAssetResource("movieClip", movieClip),
17241
+ fileName: movieClip.getFileName(),
17242
+ dimensions: {
17243
+ width: movieClip.getWidth(),
17244
+ height: movieClip.getHeight()
17245
+ },
17246
+ movieClip: {
17247
+ interval: movieClip.getInterval(),
17248
+ repeatDelay: movieClip.getRepeatDelay(),
17249
+ swing: movieClip.getSwing(),
17250
+ smoothing: movieClip.getSmoothing(),
17251
+ frames: movieClip.listFrames().map((frame) => ({
17252
+ rectX: frame.getRectX(),
17253
+ rectY: frame.getRectY(),
17254
+ rectWidth: frame.getRectWidth(),
17255
+ rectHeight: frame.getRectHeight(),
17256
+ addDelay: frame.getAddDelay(),
17257
+ spriteId: frame.getSpriteId()
17258
+ }))
17259
+ }
17260
+ };
17261
+ }
17262
+ if (resource.propertyType === PropertyType.SOUND_RESOURCE) {
17263
+ const sound = resource;
17264
+ return {
17265
+ ...baseAssetResource("sound", sound),
17266
+ file: sound.getFile()
17267
+ };
17268
+ }
17269
+ if (resource.propertyType === PropertyType.MISC_RESOURCE) {
17270
+ const misc = resource;
17271
+ return {
17272
+ ...baseAssetResource("misc", misc),
17273
+ file: misc.getFile()
17274
+ };
17275
+ }
17276
+ if (resource.propertyType === PropertyType.FONT_RESOURCE) {
17277
+ const font = resource;
17278
+ return {
17279
+ ...baseAssetResource("font", font),
17280
+ fileName: font.getFileName(),
17281
+ metadata: {
17282
+ textureId: font.getTextureId(),
17283
+ renderMode: font.getRenderMode(),
17284
+ samplePointSize: font.getSamplePointSize(),
17285
+ ttf: font.getTtf(),
17286
+ tint: font.getTint(),
17287
+ autoScale: font.getAutoScale(),
17288
+ hasChannel: font.getHasChannel(),
17289
+ fontSize: font.getFontSize(),
17290
+ xAdvance: font.getXAdvance(),
17291
+ lineHeight: font.getLineHeight()
17292
+ }
17293
+ };
17294
+ }
17295
+ if (resource.propertyType === PropertyType.SPINE_RESOURCE || resource.propertyType === PropertyType.DRAGON_BONES_RESOURCE) {
17296
+ const skeleton = resource;
17297
+ return {
17298
+ ...baseAssetResource(resource.propertyType === PropertyType.SPINE_RESOURCE ? "spine" : "dragonBones", skeleton),
17299
+ file: skeleton.getFile(),
17300
+ dimensions: {
17301
+ width: skeleton.getWidth(),
17302
+ height: skeleton.getHeight()
17303
+ },
17304
+ metadata: {
17305
+ requireIds: skeleton.getRequireIds(),
17306
+ atlasNames: skeleton.getAtlasNames(),
17307
+ anchorX: skeleton.getAnchorX(),
17308
+ anchorY: skeleton.getAnchorY()
17309
+ }
17310
+ };
17311
+ }
17312
+ throw new Error(`UAM lift does not support resource type "${resource.propertyType}" in Gate A.`);
17313
+ }
17314
+ function liftGears(gears) {
17315
+ return gears.map((gear) => {
17316
+ const pages = gear.getPages() ? gear.getPages().split(",") : [];
17317
+ if (gear.getGearType() === GearType.Display) return {
17318
+ kind: "display",
17319
+ name: gear.getName(),
17320
+ controllerName: gear.getController()?.getName() ?? "",
17321
+ visibleOnPageIds: pages
17322
+ };
17323
+ if (gear.getGearType() === GearType.Display2) return {
17324
+ kind: "display2",
17325
+ name: gear.getName(),
17326
+ controllerName: gear.getController()?.getName() ?? "",
17327
+ visibleOnPageIds: pages,
17328
+ condition: gear.getCondition()
17329
+ };
17330
+ if (gear.getGearType() !== GearType.Look) {
17331
+ const kind = new Map([
17332
+ [GearType.XY, "xy"],
17333
+ [GearType.Size, "size"],
17334
+ [GearType.Color, "color"],
17335
+ [GearType.Animation, "animation"],
17336
+ [GearType.Text, "text"],
17337
+ [GearType.Icon, "icon"],
17338
+ [GearType.FontSize, "fontSize"]
17339
+ ]).get(gear.getGearType());
17340
+ if (!kind) throw new Error(`UAM lift does not support gear type "${gear.getGearType()}" in Gate A.`);
17341
+ const values = gear.getValues() ? gear.getValues().split("|") : [];
17342
+ const defaultValue = `${gear.getDefaultValue() ?? ""}`;
17343
+ const base = {
17344
+ name: gear.getName(),
17345
+ controllerName: gear.getController()?.getName() ?? "",
17346
+ states: pages.map((pageId, index) => ({
17347
+ pageId,
17348
+ value: parseGenericGearValue(kind, values[index] ?? null)
17349
+ })),
17350
+ defaultValue: parseGenericGearValue(kind, defaultValue) ?? defaultGenericGearValue(kind),
17351
+ condition: gear.getCondition(),
17352
+ positionsInPercent: gear.getPositionsInPercent(),
17353
+ tween: gear.getTween(),
17354
+ tweenDuration: gear.getTweenDuration(),
17355
+ tweenDelay: gear.getTweenDelay(),
17356
+ easeType: gear.getEaseType(),
17357
+ customEasePath: gear.getCustomEasePath()
17358
+ };
17359
+ switch (kind) {
17360
+ case "xy": return {
17361
+ kind,
17362
+ ...base
17363
+ };
17364
+ case "size": return {
17365
+ kind,
17366
+ ...base
17367
+ };
17368
+ case "color": return {
17369
+ kind,
17370
+ ...base
17371
+ };
17372
+ case "animation": return {
17373
+ kind,
17374
+ ...base
17375
+ };
17376
+ case "text": return {
17377
+ kind,
17378
+ ...base
17379
+ };
17380
+ case "icon": return {
17381
+ kind,
17382
+ ...base
17383
+ };
17384
+ case "fontSize": return {
17385
+ kind,
17386
+ ...base
17387
+ };
17388
+ }
17389
+ }
17390
+ const values = gear.getValues() ? gear.getValues().split("|") : [];
17391
+ const defaultValue = `${gear.getDefaultValue() ?? ""}`;
17392
+ return {
17393
+ kind: "look",
17394
+ name: gear.getName(),
17395
+ controllerName: gear.getController()?.getName() ?? "",
17396
+ states: pages.map((pageId, index) => ({
17397
+ pageId,
17398
+ value: parseLookGearValue(values[index] ?? null)
17399
+ })),
17400
+ defaultValue: parseLookGearValue(defaultValue) ?? {
17401
+ alpha: 1,
17402
+ rotation: 0,
17403
+ grayed: false,
17404
+ touchable: true
17405
+ },
17406
+ condition: gear.getCondition(),
17407
+ positionsInPercent: gear.getPositionsInPercent(),
17408
+ tween: gear.getTween(),
17409
+ tweenDuration: gear.getTweenDuration(),
17410
+ tweenDelay: gear.getTweenDelay(),
17411
+ easeType: gear.getEaseType(),
17412
+ customEasePath: gear.getCustomEasePath()
17413
+ };
17414
+ });
17415
+ }
17416
+ function liftDisplayNode(child) {
17417
+ if (child.propertyType === PropertyType.G_IMAGE) {
17418
+ const image = child;
17419
+ return {
17420
+ kind: "image",
17421
+ ...liftDisplayNodeBase(image),
17422
+ group: image.getGroup(),
17423
+ resource: { resourceId: image.getSrc() }
17424
+ };
17425
+ }
17426
+ if (child.propertyType === PropertyType.G_TEXT_FIELD || child.propertyType === PropertyType.G_RICH_TEXT_FIELD || child.propertyType === PropertyType.G_TEXT_INPUT) {
17427
+ const text = child;
17428
+ const textProperties = {
17429
+ text: text.getText(),
17430
+ font: text.getFont(),
17431
+ fontSize: text.getFontSize(),
17432
+ color: text.getColor(),
17433
+ align: text.getAlign(),
17434
+ vAlign: text.getVAlign(),
17435
+ leading: text.getLeading(),
17436
+ letterSpacing: text.getLetterSpacing(),
17437
+ autoSize: text.getAutoSize(),
17438
+ singleLine: text.getSingleLine(),
17439
+ autoClearText: text.getAutoClearText(),
17440
+ underlaySoftness: text.getUnderlaySoftness(),
17441
+ ubbEnabled: text.getUbbEnabled(),
17442
+ underline: text.getUnderline(),
17443
+ italic: text.getItalic(),
17444
+ bold: text.getBold(),
17445
+ strikethrough: text.getStrikethrough(),
17446
+ strokeColor: text.getStrokeColor(),
17447
+ strokeSize: text.getStrokeSize(),
17448
+ shadowColor: text.getShadowColor(),
17449
+ shadowOffset: text.getShadowOffset()
17450
+ };
17451
+ const plainTextProperties = {
17452
+ ...textProperties,
17453
+ demoText: text.getDemoText(),
17454
+ templateVarsEnabled: text.getTemplateVarsEnabled(),
17455
+ faceDilate: text.getFaceDilate()
17456
+ };
17457
+ const base = {
17458
+ ...liftDisplayNodeBase(text),
17459
+ group: text.getGroup()
17460
+ };
17461
+ if (child.propertyType === PropertyType.G_RICH_TEXT_FIELD) return {
17462
+ kind: "richText",
17463
+ ...base,
17464
+ ...textProperties
17465
+ };
17466
+ if (child.propertyType === PropertyType.G_TEXT_INPUT) {
17467
+ const input = child;
17468
+ return {
17469
+ kind: "textInput",
17470
+ ...base,
17471
+ ...plainTextProperties,
17472
+ promptText: input.getPromptText(),
17473
+ maxLength: input.getMaxLength(),
17474
+ restrict: input.getRestrict(),
17475
+ password: input.getPassword(),
17476
+ keyboardType: input.getKeyboardType()
17477
+ };
17478
+ }
17479
+ return {
17480
+ kind: "text",
17481
+ ...base,
17482
+ ...plainTextProperties
17483
+ };
17484
+ }
17485
+ if (child.propertyType === PropertyType.G_COMPONENT) {
17486
+ const component = child;
17487
+ const instanceProperties = liftComponentInstanceProperties(component);
17488
+ const propertyOverrides = component.getPropertyOverrides();
17489
+ return {
17490
+ kind: "component",
17491
+ ...liftDisplayNodeBase(component),
17492
+ group: component.getGroup(),
17493
+ resource: {
17494
+ packageId: component.getPackageId(),
17495
+ resourceId: component.getSrc()
17496
+ },
17497
+ ...propertyOverrides.length > 0 ? { propertyOverrides } : {},
17498
+ ...instanceProperties ? { instanceProperties } : {}
17499
+ };
17500
+ }
17501
+ if (child.propertyType === PropertyType.G_LIST || child.propertyType === PropertyType.G_TREE) {
17502
+ const list = child;
17503
+ const base = {
17504
+ ...liftDisplayNodeBase(list),
17505
+ group: list.getGroup(),
17506
+ layout: list.getLayout(),
17507
+ align: list.getAlign(),
17508
+ vAlign: list.getVAlign(),
17509
+ lineGap: list.getLineGap(),
17510
+ columnGap: list.getColumnGap(),
17511
+ lineCount: list.getLineCount(),
17512
+ columnCount: list.getColumnCount(),
17513
+ selectionMode: list.getSelectionMode(),
17514
+ defaultItem: list.getDefaultItem(),
17515
+ autoResizeItem: list.getAutoResizeItem(),
17516
+ childrenRenderOrder: list.getChildrenRenderOrder(),
17517
+ apexIndex: list.getApexIndex(),
17518
+ src: list.getSrc(),
17519
+ overflow: list.getOverflow(),
17520
+ scrollType: list.getScrollType(),
17521
+ scrollBarFlags: list.getScrollBarFlags(),
17522
+ scrollBarMargin: liftEdgeInsets(list.getScrollBarMargin()),
17523
+ vtScrollBarRes: list.getVtScrollBarRes(),
17524
+ hzScrollBarRes: list.getHzScrollBarRes(),
17525
+ headerRes: list.getHeaderRes(),
17526
+ footerRes: list.getFooterRes(),
17527
+ margin: liftEdgeInsets(list.getMargin()),
17528
+ clipSoftness: list.getClipSoftness(),
17529
+ scrollItemToViewOnClick: list.getScrollItemToViewOnClick(),
17530
+ foldInvisibleItems: list.getFoldInvisibleItems(),
17531
+ autoClearItems: list.getAutoClearItems(),
17532
+ listItems: cloneListItems(list.getListItems()),
17533
+ pageController: list.getPageController(),
17534
+ controllerOverrides: list.getControllerOverrides(),
17535
+ selectionController: list.getSelectionController()
17536
+ };
17537
+ if (child.propertyType === PropertyType.G_TREE) {
17538
+ const tree = child;
17539
+ return {
17540
+ kind: "tree",
17541
+ ...base,
17542
+ treeView: tree.getTreeView(),
17543
+ indent: tree.getIndent(),
17544
+ clickToExpand: tree.getClickToExpand()
17545
+ };
17546
+ }
17547
+ return {
17548
+ kind: "list",
17549
+ ...base
17550
+ };
17551
+ }
17552
+ if (child.propertyType === PropertyType.G_GRAPH) {
17553
+ const graph = child;
17554
+ return {
17555
+ kind: "graph",
17556
+ ...liftDisplayNodeBase(graph),
17557
+ pivot: {
17558
+ x: graph.getPivotX(),
17559
+ y: graph.getPivotY()
17560
+ },
17561
+ pivotAsAnchor: graph.getPivotAsAnchor(),
17562
+ group: graph.getGroup(),
17563
+ graphType: graph.getGraphType(),
17564
+ lineSize: graph.getLineSize(),
17565
+ lineColor: graph.getLineColor(),
17566
+ fillColor: graph.getFillColor(),
17567
+ cornerRadius: graph.getCornerRadius(),
17568
+ points: graph.getPoints(),
17569
+ sides: graph.getSides(),
17570
+ startAngle: graph.getStartAngle(),
17571
+ distances: graph.getDistances()
17572
+ };
17573
+ }
17574
+ if (child.propertyType === PropertyType.G_GROUP) {
17575
+ const group = child;
17576
+ return {
17577
+ kind: "group",
17578
+ ...liftDisplayNodeBase(group),
17579
+ group: group.getGroup(),
17580
+ layout: group.getLayout(),
17581
+ lineGap: group.getLineGap(),
17582
+ columnGap: group.getColumnGap(),
17583
+ advanced: group.getAdvanced(),
17584
+ excludeInvisibles: group.getExcludeInvisibles(),
17585
+ autoSizeDisabled: group.getAutoSizeDisabled(),
17586
+ mainGridIndex: group.getMainGridIndex()
17587
+ };
17588
+ }
17589
+ if (child.propertyType === PropertyType.G_LOADER) {
17590
+ const loader = child;
17591
+ return {
17592
+ kind: "loader",
17593
+ ...liftDisplayNodeBase(loader),
17594
+ pivot: {
17595
+ x: loader.getPivotX(),
17596
+ y: loader.getPivotY()
17597
+ },
17598
+ url: loader.getUrl(),
17599
+ fill: loader.getFill(),
17600
+ shrinkOnly: loader.getShrinkOnly(),
17601
+ autoSize: loader.getAutoSize(),
17602
+ useResize: loader.getUseResize(),
17603
+ align: loader.getAlign(),
17604
+ vAlign: loader.getVAlign(),
17605
+ frame: loader.getFrame(),
17606
+ playing: loader.getPlaying(),
17607
+ color: loader.getColor(),
17608
+ fillMethod: loader.getFillMethod(),
17609
+ fillOrigin: loader.getFillOrigin(),
17610
+ fillClockwise: loader.getFillClockwise(),
17611
+ fillAmount: loader.getFillAmount(),
17612
+ clearOnPublish: loader.getClearOnPublish()
17613
+ };
17614
+ }
17615
+ if (child.propertyType === PropertyType.G_LOADER_3D) {
17616
+ const loader = child;
17617
+ return {
17618
+ kind: "loader3D",
17619
+ ...liftDisplayNodeBase(loader),
17620
+ url: loader.getUrl(),
17621
+ fill: loader.getFill(),
17622
+ shrinkOnly: loader.getShrinkOnly(),
17623
+ autoSize: loader.getAutoSize(),
17624
+ align: loader.getAlign(),
17625
+ vAlign: loader.getVAlign(),
17626
+ animationName: loader.getAnimationName(),
17627
+ skinName: loader.getSkinName(),
17628
+ playing: loader.getPlaying(),
17629
+ frame: loader.getFrame(),
17630
+ loop: loader.getLoop(),
17631
+ color: loader.getColor(),
17632
+ clearOnPublish: loader.getClearOnPublish()
17633
+ };
17634
+ }
17635
+ if (child.propertyType === PropertyType.G_BUTTON) {
17636
+ const button = child;
17637
+ return {
17638
+ kind: "button",
17639
+ ...liftTitleControlBase(button),
17640
+ selectedTitle: button.getSelectedTitle(),
17641
+ selectedIcon: button.getSelectedIcon(),
17642
+ mode: button.getMode(),
17643
+ downEffect: button.getDownEffect(),
17644
+ downEffectValue: button.getDownEffectValue()
17645
+ };
17646
+ }
17647
+ if (child.propertyType === PropertyType.G_LABEL) return {
17648
+ kind: "label",
17649
+ ...liftTitleControlBase(child)
17650
+ };
17651
+ if (child.propertyType === PropertyType.G_COMBO_BOX) {
17652
+ const comboBox = child;
17653
+ return {
17654
+ kind: "comboBox",
17655
+ ...liftTitleControlBase(comboBox),
17656
+ items: comboBox.getItems(),
17657
+ icons: comboBox.getIcons(),
17658
+ values: comboBox.getValues(),
17659
+ selectedIndex: comboBox.getSelectedIndex(),
17660
+ visibleItemCount: comboBox.getVisibleItemCount(),
17661
+ popupDirection: comboBox.getPopupDirection()
17662
+ };
17663
+ }
17664
+ if (child.propertyType === PropertyType.G_PROGRESS_BAR) {
17665
+ const progressBar = child;
17666
+ return {
17667
+ kind: "progressBar",
17668
+ ...liftComponentDerivedControlBase(progressBar),
17669
+ titleType: progressBar.getTitleType(),
17670
+ min: progressBar.getMin(),
17671
+ max: progressBar.getMax(),
17672
+ value: progressBar.getValue(),
17673
+ reverse: progressBar.getReverse(),
17674
+ sound: progressBar.getSound(),
17675
+ soundVolumeScale: progressBar.getSoundVolumeScale()
17676
+ };
17677
+ }
17678
+ if (child.propertyType === PropertyType.G_SLIDER) {
17679
+ const slider = child;
17680
+ return {
17681
+ kind: "slider",
17682
+ ...liftComponentDerivedControlBase(slider),
17683
+ titleType: slider.getTitleType(),
17684
+ min: slider.getMin(),
17685
+ max: slider.getMax(),
17686
+ value: slider.getValue(),
17687
+ wholeNumbers: slider.getWholeNumbers()
17688
+ };
17689
+ }
17690
+ if (child.propertyType === PropertyType.G_SCROLL_BAR) {
17691
+ const scrollBar = child;
17692
+ return {
17693
+ kind: "scrollBar",
17694
+ ...liftComponentDerivedControlBase(scrollBar),
17695
+ fixedGripSize: scrollBar.getFixedGripSize()
17696
+ };
17697
+ }
17698
+ if (child.propertyType === PropertyType.G_MOVIE_CLIP) {
17699
+ const movieClip = child;
17700
+ return {
17701
+ kind: "movieClip",
17702
+ ...liftDisplayNodeBase(movieClip),
17703
+ group: movieClip.getGroup(),
17704
+ resource: {
17705
+ packageId: movieClip.getPackageId(),
17706
+ resourceId: movieClip.getSrc()
17707
+ },
17708
+ fileName: movieClip.getFileName(),
17709
+ playing: movieClip.getPlaying(),
17710
+ frame: movieClip.getFrame(),
17711
+ color: movieClip.getColor()
17712
+ };
17713
+ }
17714
+ throw new Error(`UAM lift does not support display node type "${child.propertyType}" in Gate A.`);
17715
+ }
17716
+ function liftComponentInstanceProperties(component) {
17717
+ switch (component.getInstanceExtType()) {
17718
+ case "Button": return {
17719
+ extensionType: "Button",
17720
+ title: component.getInstanceTitle(),
17721
+ selectedTitle: component.getInstanceSelectedTitle(),
17722
+ icon: component.getInstanceIcon(),
17723
+ selectedIcon: component.getInstanceSelectedIcon(),
17724
+ titleColor: component.getInstanceTitleColor(),
17725
+ titleFontSize: component.getInstanceTitleFontSize(),
17726
+ controller: component.getInstanceController(),
17727
+ page: component.getInstancePage(),
17728
+ checked: component.getInstanceChecked(),
17729
+ sound: component.getInstanceSound(),
17730
+ soundVolumeScale: component.getInstanceSoundVolumeScale()
17731
+ };
17732
+ case "Label": return {
17733
+ extensionType: "Label",
17734
+ title: component.getInstanceTitle(),
17735
+ icon: component.getInstanceIcon(),
17736
+ titleColor: component.getInstanceTitleColor(),
17737
+ titleFontSize: component.getInstanceTitleFontSize(),
17738
+ promptText: component.getInstancePromptText()
17739
+ };
17740
+ case "ComboBox": return {
17741
+ extensionType: "ComboBox",
17742
+ title: component.getInstanceTitle(),
17743
+ icon: component.getInstanceIcon(),
17744
+ visibleItemCount: component.getInstanceVisibleItemCount(),
17745
+ selectionController: component.getInstanceSelectionController(),
17746
+ autoClearItems: component.getInstanceAutoClearItems(),
17747
+ items: component.getInstanceComboItems().map((item) => ({ ...item }))
17748
+ };
17749
+ case "ProgressBar":
17750
+ case "Slider": return {
17751
+ extensionType: component.getInstanceExtType(),
17752
+ value: component.getInstanceValue(),
17753
+ max: component.getInstanceMax(),
17754
+ min: component.getInstanceMin()
17755
+ };
17756
+ case "ScrollBar": return { extensionType: "ScrollBar" };
17757
+ default: return;
17758
+ }
17759
+ }
17760
+ function liftControllers(component) {
17761
+ return component.listControllers().map((controller) => ({
17762
+ name: controller.getName(),
17763
+ selectedIndex: controller.getSelectedIndex(),
17764
+ autoRadioGroupDepth: controller.getAutoRadioGroupDepth(),
17765
+ pages: controller.listPages().map((page) => ({
17766
+ id: page.getId(),
17767
+ name: page.getName()
17768
+ })),
17769
+ actions: controller.listActions().map((action) => ({
17770
+ name: action.getName(),
17771
+ actionType: action.getActionType(),
17772
+ fromPageIds: action.getFromPage(),
17773
+ toPageIds: action.getToPage(),
17774
+ transitionName: action.getTransitionName(),
17775
+ playTimes: action.getPlayTimes(),
17776
+ delay: action.getDelay(),
17777
+ stopOnExit: action.getStopOnExit(),
17778
+ targetNodeId: action.getObjectId(),
17779
+ controllerName: action.getControllerName(),
17780
+ targetPage: action.getTargetPage()
17781
+ }))
17782
+ }));
17783
+ }
17784
+ function liftTransitions(component) {
17785
+ return component.listTransitions().map((transition) => ({
17786
+ name: transition.getName(),
17787
+ autoPlay: transition.getAutoPlay(),
17788
+ autoPlayTimes: transition.getAutoPlayTimes(),
17789
+ autoPlayDelay: transition.getAutoPlayDelay(),
17790
+ options: transition.getOptions(),
17791
+ fps: transition.getFps(),
17792
+ items: transition.listItems().map((item) => ({
17793
+ name: item.getName(),
17794
+ time: item.getTime(),
17795
+ actionType: item.getActionType(),
17796
+ targetNodeId: item.getTargetId(),
17797
+ tween: item.getTween(),
17798
+ duration: item.getDuration(),
17799
+ startValue: item.getStartValue(),
17800
+ endValue: item.getEndValue(),
17801
+ easeType: item.getEaseType(),
17802
+ repeat: item.getRepeat(),
17803
+ yoyo: item.getYoyo(),
17804
+ label: item.getLabel(),
17805
+ endLabel: item.getEndLabel(),
17806
+ path: item.getPath(),
17807
+ customEasePath: item.getCustomEasePath()
17808
+ }))
17809
+ }));
17810
+ }
17811
+ function liftComponentResource(resource) {
17812
+ return {
17813
+ kind: "component",
17814
+ id: resource.getId(),
17815
+ name: resource.getName(),
17816
+ path: resource.getPath(),
17817
+ exported: resource.getExported(),
17818
+ favorite: resource.getFavorite(),
17819
+ branch: resource.getBranch(),
17820
+ branchItemIds: resource.getBranchItemIds(),
17821
+ component: {
17822
+ size: {
17823
+ width: resource.getWidth(),
17824
+ height: resource.getHeight()
17825
+ },
17826
+ properties: liftComponentProperties(resource),
17827
+ customData: resource.getCustomData(),
17828
+ displayList: resource.listChildren().map((child) => liftDisplayNode(child)),
17829
+ controllers: liftControllers(resource),
17830
+ transitions: liftTransitions(resource)
17831
+ }
17832
+ };
17833
+ }
17834
+ function liftComponentProperties(resource) {
17835
+ return {
17836
+ minSize: {
17837
+ width: resource.getMinWidth(),
17838
+ height: resource.getMinHeight()
17839
+ },
17840
+ maxSize: {
17841
+ width: resource.getMaxWidth(),
17842
+ height: resource.getMaxHeight()
17843
+ },
17844
+ pivot: {
17845
+ x: resource.getPivotX(),
17846
+ y: resource.getPivotY()
17847
+ },
17848
+ pivotAsAnchor: resource.getPivotAsAnchor(),
17849
+ overflow: resource.getOverflow(),
17850
+ margin: resource.getMargin(),
17851
+ clipSoftness: resource.getClipSoftness(),
17852
+ hitTest: resource.getHitTest(),
17853
+ mask: resource.getMask(),
17854
+ reversedMask: resource.getReversedMask(),
17855
+ scrollType: resource.getScrollType(),
17856
+ scrollBarDisplay: resource.getScrollBarDisplay(),
17857
+ scrollBarFlags: resource.getScrollBarFlags(),
17858
+ scrollBarMargin: resource.getScrollBarMargin(),
17859
+ vtScrollBarRes: resource.getVtScrollBarRes(),
17860
+ hzScrollBarRes: resource.getHzScrollBarRes(),
17861
+ headerRes: resource.getHeaderRes(),
17862
+ footerRes: resource.getFooterRes(),
17863
+ bgColor: resource.getBgColor(),
17864
+ bgColorEnabled: resource.getBgColorEnabled(),
17865
+ designImageAlpha: resource.getDesignImageAlpha(),
17866
+ designImageLayer: resource.getDesignImageLayer(),
17867
+ designImageOffset: {
17868
+ x: resource.getDesignImageOffsetX(),
17869
+ y: resource.getDesignImageOffsetY()
17870
+ },
17871
+ idNum: resource.getIdNum(),
17872
+ initName: resource.getInitName(),
17873
+ remark: resource.getRemark(),
17874
+ extensionType: resource.getExtensionType(),
17875
+ opaque: resource.getOpaque(),
17876
+ buttonMode: resource.getButtonMode(),
17877
+ sound: resource.getSound(),
17878
+ soundVolumeScale: resource.getSoundVolumeScale(),
17879
+ downEffect: resource.getDownEffect(),
17880
+ downEffectValue: resource.getDownEffectValue(),
17881
+ dropdown: resource.getDropdown(),
17882
+ promptText: resource.getPromptText(),
17883
+ selectionController: resource.getSelectionController(),
17884
+ titleType: resource.getTitleType(),
17885
+ reverse: resource.getReverse(),
17886
+ wholeNumbers: resource.getWholeNumbers(),
17887
+ changeOnClick: resource.getChangeOnClick(),
17888
+ fixedGripSize: resource.getFixedGripSize(),
17889
+ autoClearItems: resource.getAutoClearItems(),
17890
+ customProperties: resource.getCustomProperties()
17891
+ };
17892
+ }
17893
+ function liftDocumentToUamProject(doc) {
17894
+ const root = doc.getRoot();
17895
+ return {
17896
+ projectId: root.getProjectId(),
17897
+ projectType: root.getProjectType(),
17898
+ version: root.getVersion(),
17899
+ branches: root.listBranches(),
17900
+ settings: cloneSettings(root.getSettings()),
17901
+ packages: root.listPackages().map((pkg) => {
17902
+ const sourceAtlasSettings = pkg.getSourceAtlasSettings();
17903
+ return {
17904
+ id: pkg.getId(),
17905
+ name: pkg.getName(),
17906
+ compressPNG: pkg.getCompressPNG(),
17907
+ jpegQuality: pkg.getJpegQuality(),
17908
+ branchNames: pkg.listBranchNames(),
17909
+ folders: pkg.listResourceFolders(),
17910
+ publish: {
17911
+ name: pkg.getPublishName(),
17912
+ path: pkg.getPublishPath(),
17913
+ branchPath: pkg.getPublishBranchPath(),
17914
+ packageCount: pkg.getPublishPackageCount(),
17915
+ genCode: pkg.getGenCode(),
17916
+ codePath: pkg.getCodePath(),
17917
+ useGlobalAtlasSettings: sourceAtlasSettings.useGlobal,
17918
+ maxAtlasSize: sourceAtlasSettings.maxSize,
17919
+ sizeOption: sourceAtlasSettings.sizeOption,
17920
+ forceSquare: sourceAtlasSettings.forceSquare,
17921
+ allowRotation: sourceAtlasSettings.allowRotation,
17922
+ paging: sourceAtlasSettings.paging,
17923
+ extractAlpha: sourceAtlasSettings.extractAlpha,
17924
+ maxAtlasIndex: sourceAtlasSettings.maxIndex,
17925
+ atlases: sourceAtlasSettings.atlases,
17926
+ excludedResourceIds: sourceAtlasSettings.excludedResourceIds
17927
+ },
17928
+ resources: pkg.listResources().map((resource) => {
17929
+ if (resource.propertyType === "Component") return liftComponentResource(resource);
17930
+ return liftAssetResource(resource);
17931
+ })
17932
+ };
17933
+ })
17934
+ };
17935
+ }
17936
+ //#endregion
16245
17937
  //#region ../core/src/io/project-xml-protocol.ts
16246
17938
  const mergeAttrs = (...parts) => Object.assign({}, ...parts);
16247
17939
  const mergeChildren = (...parts) => Object.assign({}, ...parts);
@@ -16842,16 +18534,21 @@ var ReaderContext = class {
16842
18534
  logger;
16843
18535
  basePath;
16844
18536
  settings = {};
18537
+ diagnostics;
16845
18538
  /** packageId → Package */
16846
18539
  packageMap = /* @__PURE__ */ new Map();
16847
18540
  /** packageId+resourceId → Property (ImageResource, Component, etc.) */
16848
18541
  resourceMap = /* @__PURE__ */ new Map();
16849
18542
  /** packageId+controllerName → Controller (for gear resolution within a component) */
16850
18543
  controllerMap = /* @__PURE__ */ new Map();
16851
- constructor(document, basePath) {
18544
+ constructor(document, basePath, diagnostics = []) {
16852
18545
  this.document = document;
16853
18546
  this.logger = document.getLogger();
16854
18547
  this.basePath = basePath;
18548
+ this.diagnostics = diagnostics;
18549
+ }
18550
+ addDiagnostic(diagnostic) {
18551
+ this.diagnostics.push(diagnostic);
16855
18552
  }
16856
18553
  registerResource(packageId, resourceId, property) {
16857
18554
  this.resourceMap.set(packageId + resourceId, property);
@@ -17011,10 +18708,10 @@ function getProtocolExtensionChildNames(protocol) {
17011
18708
  function getDisplayListVariantName$1(tagName, attrs) {
17012
18709
  if (tagName === "loader3d") return "loader3D";
17013
18710
  if (tagName === "text") {
17014
- if (parseBool(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.input))) return "inputtext";
18711
+ if (parseBool$1(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.input))) return "inputtext";
17015
18712
  }
17016
18713
  if (tagName === "list") {
17017
- if (parseBool(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.treeView))) return "tree";
18714
+ if (parseBool$1(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.treeView))) return "tree";
17018
18715
  }
17019
18716
  return tagName;
17020
18717
  }
@@ -17045,7 +18742,7 @@ function parseListItemXmlNode(item) {
17045
18742
  selectedTitle: readXmlAttr(item, specs.selectedTitle) ?? null,
17046
18743
  selectedIcon: readXmlAttr(item, specs.selectedIcon) ?? null,
17047
18744
  level: parseInt2(readXmlAttr(item, specs.level)),
17048
- isFolder: isFolder !== void 0 ? parseBool(isFolder) : null,
18745
+ isFolder: isFolder !== void 0 ? parseBool$1(isFolder) : null,
17049
18746
  ...controllers !== void 0 ? { controllers } : {},
17050
18747
  ...propertyOverrides.length > 0 ? { propertyOverrides } : {}
17051
18748
  };
@@ -17071,19 +18768,19 @@ function readCommonDisplayState(source, object, protocol) {
17071
18768
  object.setSize?.(width, height);
17072
18769
  }
17073
18770
  const locked = specs.locked ? readXmlAttr(source, specs.locked) : void 0;
17074
- if (locked !== void 0) object.setLocked(parseBool(locked));
18771
+ if (locked !== void 0) object.setLocked(parseBool$1(locked));
17075
18772
  const restrictSize = specs.restrictSize ? readXmlAttr(source, specs.restrictSize) : void 0;
17076
18773
  if (restrictSize) {
17077
18774
  const [minWidth = 0, maxWidth = 0, minHeight = 0, maxHeight = 0] = restrictSize.split(",").map((value) => parseFloat2(value));
17078
18775
  object.setMinWidth(minWidth).setMaxWidth(maxWidth).setMinHeight(minHeight).setMaxHeight(maxHeight);
17079
18776
  }
17080
18777
  const aspect = specs.aspect ? readXmlAttr(source, specs.aspect) : void 0;
17081
- if (aspect !== void 0) object.setAspect(parseBool(aspect));
18778
+ if (aspect !== void 0) object.setAspect(parseBool$1(aspect));
17082
18779
  const pivot = specs.pivot ? readXmlAttr(source, specs.pivot) : void 0;
17083
18780
  if (pivot) {
17084
18781
  const [pivotX, pivotY] = parseXYString(pivot);
17085
18782
  const anchor = specs.anchor ? readXmlAttr(source, specs.anchor) : void 0;
17086
- object.setPivot(pivotX, pivotY, parseBool(anchor));
18783
+ object.setPivot(pivotX, pivotY, parseBool$1(anchor));
17087
18784
  }
17088
18785
  const scale = specs.scale ? readXmlAttr(source, specs.scale) : void 0;
17089
18786
  if (scale) {
@@ -17102,11 +18799,11 @@ function readCommonDisplayState(source, object, protocol) {
17102
18799
  const rotation = specs.rotation ? readXmlAttr(source, specs.rotation) : void 0;
17103
18800
  if (rotation !== void 0) object.setRotation?.(parseFloat2(rotation));
17104
18801
  const visible = specs.visible ? readXmlAttr(source, specs.visible) : void 0;
17105
- if (visible !== void 0) object.setVisible?.(parseBool(visible));
18802
+ if (visible !== void 0) object.setVisible?.(parseBool$1(visible));
17106
18803
  const touchable = specs.touchable ? readXmlAttr(source, specs.touchable) : void 0;
17107
- if (touchable !== void 0) object.setTouchable?.(parseBool(touchable));
18804
+ if (touchable !== void 0) object.setTouchable?.(parseBool$1(touchable));
17108
18805
  const grayed = specs.grayed ? readXmlAttr(source, specs.grayed) : void 0;
17109
- if (grayed !== void 0) object.setGrayed?.(parseBool(grayed));
18806
+ if (grayed !== void 0) object.setGrayed?.(parseBool$1(grayed));
17110
18807
  const tooltips = specs.tooltips ? readXmlAttr(source, specs.tooltips) : void 0;
17111
18808
  if (tooltips !== void 0) object.setTooltips(tooltips);
17112
18809
  const customData = specs.customData ? readXmlAttr(source, specs.customData) : void 0;
@@ -17138,16 +18835,16 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17138
18835
  g.setSize(w, h);
17139
18836
  }
17140
18837
  const imageLocked = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.locked);
17141
- if (imageLocked !== void 0) g.setLocked(parseBool(imageLocked));
18838
+ if (imageLocked !== void 0) g.setLocked(parseBool$1(imageLocked));
17142
18839
  const imageGroup = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.group);
17143
18840
  if (imageGroup) g.setGroup(imageGroup);
17144
18841
  const imageAspect = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.aspect);
17145
- if (imageAspect !== void 0) g.setAspect(parseBool(imageAspect));
18842
+ if (imageAspect !== void 0) g.setAspect(parseBool$1(imageAspect));
17146
18843
  const imagePivot = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.pivot);
17147
18844
  if (imagePivot) {
17148
18845
  const [pivotX, pivotY] = parseXYString(imagePivot);
17149
18846
  const imageAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.anchor);
17150
- g.setPivot(pivotX, pivotY, parseBool(imageAnchor));
18847
+ g.setPivot(pivotX, pivotY, parseBool$1(imageAnchor));
17151
18848
  }
17152
18849
  const imageScale = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.scale);
17153
18850
  if (imageScale) {
@@ -17164,9 +18861,9 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17164
18861
  const imageAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.alpha);
17165
18862
  if (imageAlpha !== void 0) g.setAlpha(parseFloat2(imageAlpha, 1));
17166
18863
  const imageVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.visible);
17167
- if (imageVisible !== void 0) g.setVisible(parseBool(imageVisible));
18864
+ if (imageVisible !== void 0) g.setVisible(parseBool$1(imageVisible));
17168
18865
  const imageGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.grayed);
17169
- if (imageGrayed !== void 0) g.setGrayed(parseBool(imageGrayed));
18866
+ if (imageGrayed !== void 0) g.setGrayed(parseBool$1(imageGrayed));
17170
18867
  const imageFileName = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.fileName);
17171
18868
  if (imageFileName !== void 0) g.setFileName(imageFileName);
17172
18869
  const imagePackageId = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.image.attrs.pkg);
@@ -17209,7 +18906,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17209
18906
  break;
17210
18907
  }
17211
18908
  case "text": {
17212
- const isInputText = parseBool(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.input));
18909
+ const isInputText = parseBool$1(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.input));
17213
18910
  const g = isInputText ? doc.createGTextInput(name) : doc.createGTextField(name);
17214
18911
  const textXY = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.xy);
17215
18912
  if (textXY) {
@@ -17225,7 +18922,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17225
18922
  if (textPivot) {
17226
18923
  const [pivotX, pivotY] = parseXYString(textPivot);
17227
18924
  const textAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.anchor);
17228
- g.setPivot(pivotX, pivotY, parseBool(textAnchor));
18925
+ g.setPivot(pivotX, pivotY, parseBool$1(textAnchor));
17229
18926
  }
17230
18927
  const textRestrictSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.restrictSize);
17231
18928
  if (textRestrictSize) {
@@ -17242,11 +18939,11 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17242
18939
  const textAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.alpha);
17243
18940
  if (textAlpha !== void 0) g.setAlpha(parseFloat2(textAlpha, 1));
17244
18941
  const textVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.visible);
17245
- if (textVisible !== void 0) g.setVisible(parseBool(textVisible));
18942
+ if (textVisible !== void 0) g.setVisible(parseBool$1(textVisible));
17246
18943
  const textTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.touchable);
17247
- if (textTouchable !== void 0) g.setTouchable(parseBool(textTouchable));
18944
+ if (textTouchable !== void 0) g.setTouchable(parseBool$1(textTouchable));
17248
18945
  const textGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.grayed);
17249
- if (textGrayed !== void 0) g.setGrayed(parseBool(textGrayed));
18946
+ if (textGrayed !== void 0) g.setGrayed(parseBool$1(textGrayed));
17250
18947
  const textCustomData = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.customData);
17251
18948
  if (textCustomData !== void 0) g.setCustomData(textCustomData);
17252
18949
  const textValue = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.text);
@@ -17278,31 +18975,31 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17278
18975
  ellipsis: 4
17279
18976
  }[textAutoSize] ?? 1);
17280
18977
  const textSingleLine = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.singleLine);
17281
- if (textSingleLine !== void 0) g.setSingleLine(parseBool(textSingleLine));
18978
+ if (textSingleLine !== void 0) g.setSingleLine(parseBool$1(textSingleLine));
17282
18979
  const textAutoClearText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.autoClearText);
17283
- if (textAutoClearText !== void 0) g.setAutoClearText?.(parseBool(textAutoClearText));
18980
+ if (textAutoClearText !== void 0) g.setAutoClearText?.(parseBool$1(textAutoClearText));
17284
18981
  const textDemoText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.demoText);
17285
18982
  if (textDemoText !== void 0) g.setDemoText?.(String(textDemoText));
17286
18983
  const textVars = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.vars);
17287
- if (textVars !== void 0) g.setTemplateVarsEnabled?.(parseBool(textVars));
18984
+ if (textVars !== void 0) g.setTemplateVarsEnabled?.(parseBool$1(textVars));
17288
18985
  const textFaceDilate = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.faceDilate);
17289
18986
  if (textFaceDilate !== void 0) g.setFaceDilate?.(parseFloat2(textFaceDilate));
17290
18987
  const textUnderlaySoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underlaySoftness);
17291
18988
  if (textUnderlaySoftness !== void 0) g.setUnderlaySoftness?.(parseFloat2(textUnderlaySoftness));
17292
18989
  const textUbb = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.ubb);
17293
- if (textUbb !== void 0) g.setUbbEnabled(parseBool(textUbb));
18990
+ if (textUbb !== void 0) g.setUbbEnabled(parseBool$1(textUbb));
17294
18991
  const textLeading = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.leading);
17295
18992
  if (textLeading !== void 0) g.setLeading?.(parseInt2(textLeading));
17296
18993
  const textLetterSpacing = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.letterSpacing);
17297
18994
  if (textLetterSpacing !== void 0) g.setLetterSpacing?.(parseInt2(textLetterSpacing));
17298
18995
  const textUnderline = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underline);
17299
- if (textUnderline !== void 0) g.setUnderline?.(parseBool(textUnderline));
18996
+ if (textUnderline !== void 0) g.setUnderline?.(parseBool$1(textUnderline));
17300
18997
  const textItalic = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.italic);
17301
- if (textItalic !== void 0) g.setItalic?.(parseBool(textItalic));
18998
+ if (textItalic !== void 0) g.setItalic?.(parseBool$1(textItalic));
17302
18999
  const textBold = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.bold);
17303
- if (textBold !== void 0) g.setBold?.(parseBool(textBold));
19000
+ if (textBold !== void 0) g.setBold?.(parseBool$1(textBold));
17304
19001
  const textStrikethrough = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.strikethrough);
17305
- if (textStrikethrough !== void 0) g.setStrikethrough?.(parseBool(textStrikethrough));
19002
+ if (textStrikethrough !== void 0) g.setStrikethrough?.(parseBool$1(textStrikethrough));
17306
19003
  const textStrokeColor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.strokeColor);
17307
19004
  if (textStrokeColor) {
17308
19005
  g.setStrokeColor?.(textStrokeColor);
@@ -17328,7 +19025,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17328
19025
  const inputRestrict = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.restrict);
17329
19026
  if (inputRestrict !== void 0) input.setRestrict(String(inputRestrict));
17330
19027
  const inputPassword = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.password);
17331
- if (inputPassword !== void 0) input.setPassword(parseBool(inputPassword));
19028
+ if (inputPassword !== void 0) input.setPassword(parseBool$1(inputPassword));
17332
19029
  const inputKeyboardType = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.keyboardType);
17333
19030
  if (inputKeyboardType !== void 0) input.setKeyboardType?.(parseInt2(inputKeyboardType));
17334
19031
  }
@@ -17351,7 +19048,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17351
19048
  if (richTextPivot) {
17352
19049
  const [pivotX, pivotY] = parseXYString(richTextPivot);
17353
19050
  const richTextAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.anchor);
17354
- g.setPivot(pivotX, pivotY, parseBool(richTextAnchor));
19051
+ g.setPivot(pivotX, pivotY, parseBool$1(richTextAnchor));
17355
19052
  }
17356
19053
  const richTextRestrictSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.restrictSize);
17357
19054
  if (richTextRestrictSize) {
@@ -17368,11 +19065,11 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17368
19065
  const richTextAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.alpha);
17369
19066
  if (richTextAlpha !== void 0) g.setAlpha(parseFloat2(richTextAlpha, 1));
17370
19067
  const richTextVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.visible);
17371
- if (richTextVisible !== void 0) g.setVisible(parseBool(richTextVisible));
19068
+ if (richTextVisible !== void 0) g.setVisible(parseBool$1(richTextVisible));
17372
19069
  const richTextTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.touchable);
17373
- if (richTextTouchable !== void 0) g.setTouchable(parseBool(richTextTouchable));
19070
+ if (richTextTouchable !== void 0) g.setTouchable(parseBool$1(richTextTouchable));
17374
19071
  const richTextGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.grayed);
17375
- if (richTextGrayed !== void 0) g.setGrayed(parseBool(richTextGrayed));
19072
+ if (richTextGrayed !== void 0) g.setGrayed(parseBool$1(richTextGrayed));
17376
19073
  const richText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.text);
17377
19074
  if (richText !== void 0) g.setText(String(richText));
17378
19075
  const richTextFontSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.fontSize);
@@ -17398,7 +19095,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17398
19095
  const richTextLetterSpacing = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.letterSpacing);
17399
19096
  if (richTextLetterSpacing !== void 0) g.setLetterSpacing?.(parseInt2(richTextLetterSpacing));
17400
19097
  const richTextUbb = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.ubb);
17401
- if (richTextUbb !== void 0) g.setUbbEnabled?.(parseBool(richTextUbb));
19098
+ if (richTextUbb !== void 0) g.setUbbEnabled?.(parseBool$1(richTextUbb));
17402
19099
  const richTextAutoSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.autoSize);
17403
19100
  if (richTextAutoSize) g.setAutoSize({
17404
19101
  none: 0,
@@ -17408,19 +19105,19 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17408
19105
  ellipsis: 4
17409
19106
  }[richTextAutoSize] ?? 1);
17410
19107
  const richTextSingleLine = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.singleLine);
17411
- if (richTextSingleLine !== void 0) g.setSingleLine?.(parseBool(richTextSingleLine));
19108
+ if (richTextSingleLine !== void 0) g.setSingleLine?.(parseBool$1(richTextSingleLine));
17412
19109
  const richTextAutoClearText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.autoClearText);
17413
- if (richTextAutoClearText !== void 0) g.setAutoClearText?.(parseBool(richTextAutoClearText));
19110
+ if (richTextAutoClearText !== void 0) g.setAutoClearText?.(parseBool$1(richTextAutoClearText));
17414
19111
  const richTextUnderlaySoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.underlaySoftness);
17415
19112
  if (richTextUnderlaySoftness !== void 0) g.setUnderlaySoftness?.(parseFloat2(richTextUnderlaySoftness));
17416
19113
  const richTextUnderline = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underline);
17417
- if (richTextUnderline !== void 0) g.setUnderline?.(parseBool(richTextUnderline));
19114
+ if (richTextUnderline !== void 0) g.setUnderline?.(parseBool$1(richTextUnderline));
17418
19115
  const richTextItalic = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.italic);
17419
- if (richTextItalic !== void 0) g.setItalic?.(parseBool(richTextItalic));
19116
+ if (richTextItalic !== void 0) g.setItalic?.(parseBool$1(richTextItalic));
17420
19117
  const richTextBold = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.bold);
17421
- if (richTextBold !== void 0) g.setBold?.(parseBool(richTextBold));
19118
+ if (richTextBold !== void 0) g.setBold?.(parseBool$1(richTextBold));
17422
19119
  const richTextStrikethrough = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.strikethrough);
17423
- if (richTextStrikethrough !== void 0) g.setStrikethrough?.(parseBool(richTextStrikethrough));
19120
+ if (richTextStrikethrough !== void 0) g.setStrikethrough?.(parseBool$1(richTextStrikethrough));
17424
19121
  const richTextStrokeColor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.strokeColor);
17425
19122
  if (richTextStrokeColor) {
17426
19123
  g.setStrokeColor?.(richTextStrokeColor);
@@ -17456,7 +19153,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17456
19153
  if (inputPivot) {
17457
19154
  const [pivotX, pivotY] = parseXYString(inputPivot);
17458
19155
  const inputAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.anchor);
17459
- g.setPivot(pivotX, pivotY, parseBool(inputAnchor));
19156
+ g.setPivot(pivotX, pivotY, parseBool$1(inputAnchor));
17460
19157
  }
17461
19158
  const inputRestrictSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.restrictSize);
17462
19159
  if (inputRestrictSize) {
@@ -17473,11 +19170,11 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17473
19170
  const inputAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.alpha);
17474
19171
  if (inputAlpha !== void 0) g.setAlpha(parseFloat2(inputAlpha, 1));
17475
19172
  const inputVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.visible);
17476
- if (inputVisible !== void 0) g.setVisible(parseBool(inputVisible));
19173
+ if (inputVisible !== void 0) g.setVisible(parseBool$1(inputVisible));
17477
19174
  const inputTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.touchable);
17478
- if (inputTouchable !== void 0) g.setTouchable(parseBool(inputTouchable));
19175
+ if (inputTouchable !== void 0) g.setTouchable(parseBool$1(inputTouchable));
17479
19176
  const inputGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.grayed);
17480
- if (inputGrayed !== void 0) g.setGrayed(parseBool(inputGrayed));
19177
+ if (inputGrayed !== void 0) g.setGrayed(parseBool$1(inputGrayed));
17481
19178
  const inputText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.text);
17482
19179
  if (inputText !== void 0) g.setText(String(inputText));
17483
19180
  const inputFontSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.fontSize);
@@ -17511,27 +19208,27 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17511
19208
  ellipsis: 4
17512
19209
  }[inputAutoSize] ?? 1);
17513
19210
  const inputSingleLine = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.singleLine);
17514
- if (inputSingleLine !== void 0) g.setSingleLine?.(parseBool(inputSingleLine));
19211
+ if (inputSingleLine !== void 0) g.setSingleLine?.(parseBool$1(inputSingleLine));
17515
19212
  const inputAutoClearText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.autoClearText);
17516
- if (inputAutoClearText !== void 0) g.setAutoClearText?.(parseBool(inputAutoClearText));
19213
+ if (inputAutoClearText !== void 0) g.setAutoClearText?.(parseBool$1(inputAutoClearText));
17517
19214
  const inputDemoText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.demoText);
17518
19215
  if (inputDemoText !== void 0) g.setDemoText?.(String(inputDemoText));
17519
19216
  const inputVars = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.vars);
17520
- if (inputVars !== void 0) g.setTemplateVarsEnabled?.(parseBool(inputVars));
19217
+ if (inputVars !== void 0) g.setTemplateVarsEnabled?.(parseBool$1(inputVars));
17521
19218
  const inputFaceDilate = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.faceDilate);
17522
19219
  if (inputFaceDilate !== void 0) g.setFaceDilate?.(parseFloat2(inputFaceDilate));
17523
19220
  const inputUnderlaySoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underlaySoftness);
17524
19221
  if (inputUnderlaySoftness !== void 0) g.setUnderlaySoftness?.(parseFloat2(inputUnderlaySoftness));
17525
19222
  const inputUbb = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.ubb);
17526
- if (inputUbb !== void 0) g.setUbbEnabled?.(parseBool(inputUbb));
19223
+ if (inputUbb !== void 0) g.setUbbEnabled?.(parseBool$1(inputUbb));
17527
19224
  const inputUnderline = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underline);
17528
- if (inputUnderline !== void 0) g.setUnderline?.(parseBool(inputUnderline));
19225
+ if (inputUnderline !== void 0) g.setUnderline?.(parseBool$1(inputUnderline));
17529
19226
  const inputItalic = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.italic);
17530
- if (inputItalic !== void 0) g.setItalic?.(parseBool(inputItalic));
19227
+ if (inputItalic !== void 0) g.setItalic?.(parseBool$1(inputItalic));
17531
19228
  const inputBold = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.bold);
17532
- if (inputBold !== void 0) g.setBold?.(parseBool(inputBold));
19229
+ if (inputBold !== void 0) g.setBold?.(parseBool$1(inputBold));
17533
19230
  const inputStrikethrough = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.strikethrough);
17534
- if (inputStrikethrough !== void 0) g.setStrikethrough?.(parseBool(inputStrikethrough));
19231
+ if (inputStrikethrough !== void 0) g.setStrikethrough?.(parseBool$1(inputStrikethrough));
17535
19232
  const inputStrokeColor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.strokeColor);
17536
19233
  if (inputStrokeColor) {
17537
19234
  g.setStrokeColor?.(inputStrokeColor);
@@ -17555,7 +19252,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17555
19252
  const inputRestrict = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.restrict);
17556
19253
  if (inputRestrict !== void 0) g.setRestrict(inputRestrict);
17557
19254
  const inputPassword = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.password);
17558
- if (inputPassword !== void 0) g.setPassword(parseBool(inputPassword));
19255
+ if (inputPassword !== void 0) g.setPassword(parseBool$1(inputPassword));
17559
19256
  const inputKeyboardType = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.keyboardType);
17560
19257
  if (inputKeyboardType !== void 0) g.setKeyboardType?.(parseInt2(inputKeyboardType));
17561
19258
  obj = g;
@@ -17574,7 +19271,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17574
19271
  g.setSize(w, h);
17575
19272
  }
17576
19273
  const graphLocked = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.graph.attrs.locked);
17577
- if (graphLocked !== void 0) g.setLocked(parseBool(graphLocked));
19274
+ if (graphLocked !== void 0) g.setLocked(parseBool$1(graphLocked));
17578
19275
  const graphRestrictSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.graph.attrs.restrictSize);
17579
19276
  if (graphRestrictSize) {
17580
19277
  const parts = graphRestrictSize.split(",").map(Number);
@@ -17589,16 +19286,16 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17589
19286
  if (graphPivot) {
17590
19287
  const [pivotX, pivotY] = parseXYString(graphPivot);
17591
19288
  const graphAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.graph.attrs.anchor);
17592
- g.setPivot(pivotX, pivotY, parseBool(graphAnchor));
19289
+ g.setPivot(pivotX, pivotY, parseBool$1(graphAnchor));
17593
19290
  }
17594
19291
  const graphRotation = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.graph.attrs.rotation);
17595
19292
  if (graphRotation !== void 0) g.setRotation(parseFloat2(graphRotation));
17596
19293
  const graphAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.graph.attrs.alpha);
17597
19294
  if (graphAlpha !== void 0) g.setAlpha(parseFloat2(graphAlpha, 1));
17598
19295
  const graphVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.graph.attrs.visible);
17599
- if (graphVisible !== void 0) g.setVisible(parseBool(graphVisible));
19296
+ if (graphVisible !== void 0) g.setVisible(parseBool$1(graphVisible));
17600
19297
  const graphTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.graph.attrs.touchable);
17601
- if (graphTouchable !== void 0) g.setTouchable(parseBool(graphTouchable));
19298
+ if (graphTouchable !== void 0) g.setTouchable(parseBool$1(graphTouchable));
17602
19299
  const graphSkew = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.graph.attrs.skew);
17603
19300
  if (graphSkew) {
17604
19301
  const [skewX, skewY] = parseXYString(graphSkew);
@@ -17655,17 +19352,17 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17655
19352
  g.setSize(w, h);
17656
19353
  }
17657
19354
  const groupLocked = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.locked);
17658
- if (groupLocked !== void 0) g.setLocked(parseBool(groupLocked));
19355
+ if (groupLocked !== void 0) g.setLocked(parseBool$1(groupLocked));
17659
19356
  const groupPivot = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.pivot);
17660
19357
  if (groupPivot) {
17661
19358
  const [pivotX, pivotY] = parseXYString(groupPivot);
17662
19359
  const groupAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.anchor);
17663
- g.setPivot(pivotX, pivotY, parseBool(groupAnchor));
19360
+ g.setPivot(pivotX, pivotY, parseBool$1(groupAnchor));
17664
19361
  }
17665
19362
  const groupRef = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.group);
17666
19363
  if (groupRef) g.setGroup(groupRef);
17667
19364
  const groupVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.visible);
17668
- if (groupVisible !== void 0) g.setVisible(parseBool(groupVisible));
19365
+ if (groupVisible !== void 0) g.setVisible(parseBool$1(groupVisible));
17669
19366
  const groupLayout = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.layout);
17670
19367
  if (groupLayout) g.setLayout({
17671
19368
  none: 0,
@@ -17677,11 +19374,11 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17677
19374
  const columnGap = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.columnGap);
17678
19375
  if (columnGap !== void 0) g.setColumnGap(parseInt2(columnGap));
17679
19376
  const groupAdvanced = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.advanced);
17680
- if (groupAdvanced !== void 0) g.setAdvanced(parseBool(groupAdvanced));
19377
+ if (groupAdvanced !== void 0) g.setAdvanced(parseBool$1(groupAdvanced));
17681
19378
  const excludeInvisibles = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.excludeInvisibles);
17682
- if (excludeInvisibles !== void 0) g.setExcludeInvisibles?.(parseBool(excludeInvisibles));
19379
+ if (excludeInvisibles !== void 0) g.setExcludeInvisibles?.(parseBool$1(excludeInvisibles));
17683
19380
  const autoSizeDisabled = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.autoSizeDisabled);
17684
- if (autoSizeDisabled !== void 0) g.setAutoSizeDisabled?.(parseBool(autoSizeDisabled));
19381
+ if (autoSizeDisabled !== void 0) g.setAutoSizeDisabled?.(parseBool$1(autoSizeDisabled));
17685
19382
  const mainGridIndex = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.mainGridIndex);
17686
19383
  if (mainGridIndex !== void 0) g.setMainGridIndex?.(parseInt2(mainGridIndex));
17687
19384
  obj = g;
@@ -17703,7 +19400,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17703
19400
  if (loaderPivot) {
17704
19401
  const [pivotX, pivotY] = parseXYString(loaderPivot);
17705
19402
  const loaderAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.anchor);
17706
- g.setPivot(pivotX, pivotY, parseBool(loaderAnchor));
19403
+ g.setPivot(pivotX, pivotY, parseBool$1(loaderAnchor));
17707
19404
  }
17708
19405
  const loaderScale = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.scale);
17709
19406
  if (loaderScale) {
@@ -17711,9 +19408,9 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17711
19408
  g.setScale(scaleX, scaleY);
17712
19409
  }
17713
19410
  const loaderGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.grayed);
17714
- if (loaderGrayed !== void 0) g.setGrayed(parseBool(loaderGrayed));
19411
+ if (loaderGrayed !== void 0) g.setGrayed(parseBool$1(loaderGrayed));
17715
19412
  const loaderVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.visible);
17716
- if (loaderVisible !== void 0) g.setVisible(parseBool(loaderVisible));
19413
+ if (loaderVisible !== void 0) g.setVisible(parseBool$1(loaderVisible));
17717
19414
  const loaderUrl = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.url);
17718
19415
  if (loaderUrl) g.setUrl(loaderUrl);
17719
19416
  const loaderAlign = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.align);
@@ -17738,13 +19435,13 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17738
19435
  scaleNoBorder: 5
17739
19436
  }[loaderFill] ?? 0);
17740
19437
  const loaderShrinkOnly = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.shrinkOnly);
17741
- if (loaderShrinkOnly !== void 0) g.setShrinkOnly?.(parseBool(loaderShrinkOnly));
19438
+ if (loaderShrinkOnly !== void 0) g.setShrinkOnly?.(parseBool$1(loaderShrinkOnly));
17742
19439
  const loaderAutoSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.autoSize);
17743
- if (loaderAutoSize !== void 0) g.setAutoSize?.(parseBool(loaderAutoSize));
19440
+ if (loaderAutoSize !== void 0) g.setAutoSize?.(parseBool$1(loaderAutoSize));
17744
19441
  const useResize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.useResize);
17745
- if (useResize !== void 0) g.setUseResize?.(parseBool(useResize));
19442
+ if (useResize !== void 0) g.setUseResize?.(parseBool$1(useResize));
17746
19443
  const clearOnPublish = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.clearOnPublish);
17747
- if (clearOnPublish !== void 0) g.setClearOnPublish?.(parseBool(clearOnPublish));
19444
+ if (clearOnPublish !== void 0) g.setClearOnPublish?.(parseBool$1(clearOnPublish));
17748
19445
  const loaderColor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.color);
17749
19446
  if (loaderColor) g.setColor(loaderColor);
17750
19447
  const loaderFilter = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.filter);
@@ -17752,7 +19449,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17752
19449
  const loaderFilterData = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.filterData);
17753
19450
  if (loaderFilterData !== void 0) g.setFilterData(loaderFilterData);
17754
19451
  const loaderPlaying = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.playing);
17755
- if (loaderPlaying !== void 0) g.setPlaying?.(parseBool(loaderPlaying));
19452
+ if (loaderPlaying !== void 0) g.setPlaying?.(parseBool$1(loaderPlaying));
17756
19453
  const loaderFrame = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.frame);
17757
19454
  if (loaderFrame !== void 0) g.setFrame?.(parseInt2(loaderFrame));
17758
19455
  const fillMethod = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.fillMethod);
@@ -17791,10 +19488,10 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17791
19488
  if (loader3dPivot) {
17792
19489
  const [pivotX, pivotY] = parseXYString(loader3dPivot);
17793
19490
  const loader3dAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.anchor);
17794
- g.setPivot(pivotX, pivotY, parseBool(loader3dAnchor));
19491
+ g.setPivot(pivotX, pivotY, parseBool$1(loader3dAnchor));
17795
19492
  }
17796
19493
  const loader3dVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.visible);
17797
- if (loader3dVisible !== void 0) g.setVisible(parseBool(loader3dVisible));
19494
+ if (loader3dVisible !== void 0) g.setVisible(parseBool$1(loader3dVisible));
17798
19495
  const loader3dUrl = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.url);
17799
19496
  if (loader3dUrl) g.setUrl(loader3dUrl);
17800
19497
  const loader3dAlign = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.align);
@@ -17819,23 +19516,23 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17819
19516
  scaleNoBorder: 5
17820
19517
  }[loader3dFill] ?? 0);
17821
19518
  const loader3dShrinkOnly = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.shrinkOnly);
17822
- if (loader3dShrinkOnly !== void 0) g.setShrinkOnly?.(parseBool(loader3dShrinkOnly));
19519
+ if (loader3dShrinkOnly !== void 0) g.setShrinkOnly?.(parseBool$1(loader3dShrinkOnly));
17823
19520
  const loader3dAutoSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.autoSize);
17824
- if (loader3dAutoSize !== void 0) g.setAutoSize?.(parseBool(loader3dAutoSize));
19521
+ if (loader3dAutoSize !== void 0) g.setAutoSize?.(parseBool$1(loader3dAutoSize));
17825
19522
  const animation = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.animation);
17826
19523
  if (animation !== void 0) g.setAnimationName?.(String(animation));
17827
19524
  const skinName = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.skinName);
17828
19525
  if (skinName !== void 0) g.setSkinName?.(String(skinName));
17829
19526
  const playing = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.playing);
17830
- if (playing !== void 0) g.setPlaying?.(parseBool(playing));
19527
+ if (playing !== void 0) g.setPlaying?.(parseBool$1(playing));
17831
19528
  const frame = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.frame);
17832
19529
  if (frame !== void 0) g.setFrame?.(parseInt2(frame));
17833
19530
  const loop = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.loop);
17834
- if (loop !== void 0) g.setLoop?.(parseBool(loop));
19531
+ if (loop !== void 0) g.setLoop?.(parseBool$1(loop));
17835
19532
  const loader3dColor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.color);
17836
19533
  if (loader3dColor) g.setColor(loader3dColor);
17837
19534
  const clearOnPublish = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.clearOnPublish);
17838
- if (clearOnPublish !== void 0) g.setClearOnPublish(parseBool(clearOnPublish));
19535
+ if (clearOnPublish !== void 0) g.setClearOnPublish(parseBool$1(clearOnPublish));
17839
19536
  obj = g;
17840
19537
  break;
17841
19538
  }
@@ -17860,16 +19557,16 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17860
19557
  if (movieClipPivot) {
17861
19558
  const [pivotX, pivotY] = parseXYString(movieClipPivot);
17862
19559
  const movieClipAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.anchor);
17863
- g.setPivot(pivotX, pivotY, parseBool(movieClipAnchor));
19560
+ g.setPivot(pivotX, pivotY, parseBool$1(movieClipAnchor));
17864
19561
  }
17865
19562
  const movieClipRotation = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.rotation);
17866
19563
  if (movieClipRotation !== void 0) g.setRotation(parseFloat2(movieClipRotation));
17867
19564
  const movieClipAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.alpha);
17868
19565
  if (movieClipAlpha !== void 0) g.setAlpha(parseFloat2(movieClipAlpha, 1));
17869
19566
  const movieClipVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.visible);
17870
- if (movieClipVisible !== void 0) g.setVisible(parseBool(movieClipVisible));
19567
+ if (movieClipVisible !== void 0) g.setVisible(parseBool$1(movieClipVisible));
17871
19568
  const movieClipGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.grayed);
17872
- if (movieClipGrayed !== void 0) g.setGrayed(parseBool(movieClipGrayed));
19569
+ if (movieClipGrayed !== void 0) g.setGrayed(parseBool$1(movieClipGrayed));
17873
19570
  const movieClipFileName = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.fileName);
17874
19571
  if (movieClipFileName !== void 0) g.setFileName(movieClipFileName);
17875
19572
  const movieClipPackageId = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.pkg);
@@ -17879,7 +19576,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17879
19576
  const movieClipFilterData = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.filterData);
17880
19577
  if (movieClipFilterData !== void 0) g.setFilterData(movieClipFilterData);
17881
19578
  const playing = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.playing);
17882
- if (playing !== void 0) g.setPlaying(parseBool(playing));
19579
+ if (playing !== void 0) g.setPlaying(parseBool$1(playing));
17883
19580
  const frame = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.frame);
17884
19581
  if (frame !== void 0) g.setFrame(parseInt2(frame));
17885
19582
  const movieClipColor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.color);
@@ -17902,7 +19599,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17902
19599
  g.setSize(w, h);
17903
19600
  }
17904
19601
  const componentLocked = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.locked);
17905
- if (componentLocked !== void 0) g.setLocked(parseBool(componentLocked));
19602
+ if (componentLocked !== void 0) g.setLocked(parseBool$1(componentLocked));
17906
19603
  const componentRestrictSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.restrictSize);
17907
19604
  if (componentRestrictSize) {
17908
19605
  const parts = componentRestrictSize.split(",").map(Number);
@@ -17914,12 +19611,12 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17914
19611
  const componentGroup = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.group);
17915
19612
  if (componentGroup) g.setGroup(componentGroup);
17916
19613
  const componentAspect = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.aspect);
17917
- if (componentAspect !== void 0) g.setAspect(parseBool(componentAspect));
19614
+ if (componentAspect !== void 0) g.setAspect(parseBool$1(componentAspect));
17918
19615
  const componentPivot = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.pivot);
17919
19616
  if (componentPivot) {
17920
19617
  const [pivotX, pivotY] = parseXYString(componentPivot);
17921
19618
  const componentAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.anchor);
17922
- g.setPivot(pivotX, pivotY, parseBool(componentAnchor));
19619
+ g.setPivot(pivotX, pivotY, parseBool$1(componentAnchor));
17923
19620
  }
17924
19621
  const componentScale = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.scale);
17925
19622
  if (componentScale) {
@@ -17931,11 +19628,11 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17931
19628
  const componentAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.alpha);
17932
19629
  if (componentAlpha !== void 0) g.setAlpha(parseFloat2(componentAlpha, 1));
17933
19630
  const componentVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.visible);
17934
- if (componentVisible !== void 0) g.setVisible(parseBool(componentVisible));
19631
+ if (componentVisible !== void 0) g.setVisible(parseBool$1(componentVisible));
17935
19632
  const componentTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.touchable);
17936
- if (componentTouchable !== void 0) g.setTouchable(parseBool(componentTouchable));
19633
+ if (componentTouchable !== void 0) g.setTouchable(parseBool$1(componentTouchable));
17937
19634
  const componentGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.grayed);
17938
- if (componentGrayed !== void 0) g.setGrayed(parseBool(componentGrayed));
19635
+ if (componentGrayed !== void 0) g.setGrayed(parseBool$1(componentGrayed));
17939
19636
  const componentTooltips = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.tooltips);
17940
19637
  if (componentTooltips !== void 0) g.setTooltips(componentTooltips);
17941
19638
  const componentCustomData = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.componentInstance.attrs.customData);
@@ -17957,7 +19654,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17957
19654
  }
17958
19655
  case "list": {
17959
19656
  const treeView = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.treeView);
17960
- const isTree = treeView !== void 0 && parseBool(treeView);
19657
+ const isTree = treeView !== void 0 && parseBool$1(treeView);
17961
19658
  let g;
17962
19659
  if (isTree) {
17963
19660
  g = doc.createGTree(name).setTreeView(true);
@@ -17982,14 +19679,14 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
17982
19679
  if (listPivot) {
17983
19680
  const [pivotX, pivotY] = parseXYString(listPivot);
17984
19681
  const listAnchor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.anchor);
17985
- g.setPivot(pivotX, pivotY, parseBool(listAnchor));
19682
+ g.setPivot(pivotX, pivotY, parseBool$1(listAnchor));
17986
19683
  }
17987
19684
  const listGroup = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.group);
17988
19685
  if (listGroup) g.setGroup(listGroup);
17989
19686
  const listVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.visible);
17990
- if (listVisible !== void 0) g.setVisible(parseBool(listVisible));
19687
+ if (listVisible !== void 0) g.setVisible(parseBool$1(listVisible));
17991
19688
  const listTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.touchable);
17992
- if (listTouchable !== void 0) g.setTouchable(parseBool(listTouchable));
19689
+ if (listTouchable !== void 0) g.setTouchable(parseBool$1(listTouchable));
17993
19690
  const defaultItem = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.defaultItem);
17994
19691
  if (defaultItem) g.setDefaultItem(defaultItem);
17995
19692
  const scrollBarRes = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.scrollBarRes);
@@ -18048,7 +19745,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
18048
19745
  if (resolvedLayout === 4 && lineItemCount2 !== void 0) g.setLineCount?.(parseInt2(lineItemCount2));
18049
19746
  }
18050
19747
  const autoResizeItem = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.autoResizeItem);
18051
- if (autoResizeItem !== void 0) g.setAutoResizeItem?.(parseBool(autoResizeItem));
19748
+ if (autoResizeItem !== void 0) g.setAutoResizeItem?.(parseBool$1(autoResizeItem));
18052
19749
  const childrenRenderOrder = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.childrenRenderOrder);
18053
19750
  if (childrenRenderOrder) g.setChildrenRenderOrder?.({
18054
19751
  ascent: 0,
@@ -18111,11 +19808,11 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
18111
19808
  });
18112
19809
  }
18113
19810
  const scrollItemToViewOnClick = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.scrollItemToViewOnClick);
18114
- if (scrollItemToViewOnClick !== void 0) g.setScrollItemToViewOnClick?.(parseBool(scrollItemToViewOnClick));
19811
+ if (scrollItemToViewOnClick !== void 0) g.setScrollItemToViewOnClick?.(parseBool$1(scrollItemToViewOnClick));
18115
19812
  const foldInvisibleItems = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.foldInvisibleItems);
18116
- if (foldInvisibleItems !== void 0) g.setFoldInvisibleItems?.(parseBool(foldInvisibleItems));
19813
+ if (foldInvisibleItems !== void 0) g.setFoldInvisibleItems?.(parseBool$1(foldInvisibleItems));
18117
19814
  const autoClearItems = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.autoClearItems);
18118
- if (autoClearItems !== void 0) g.setAutoClearItems?.(parseBool(autoClearItems));
19815
+ if (autoClearItems !== void 0) g.setAutoClearItems?.(parseBool$1(autoClearItems));
18119
19816
  const listItemChildName = getProtocolChildName$2(PROJECT_XML_PROTOCOL.list, "item");
18120
19817
  const items = listItemChildName ? ensureArray(attrs[listItemChildName]) : [];
18121
19818
  if (items.length > 0) {
@@ -18180,7 +19877,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
18180
19877
  const page = extSpecs.page ? readXmlAttr(extAttrs, extSpecs.page) : void 0;
18181
19878
  if (page !== void 0) componentObj.setInstancePage?.(page);
18182
19879
  const checked = extSpecs.checked ? readXmlAttr(extAttrs, extSpecs.checked) : void 0;
18183
- if (checked !== void 0) componentObj.setInstanceChecked?.(parseBool(checked));
19880
+ if (checked !== void 0) componentObj.setInstanceChecked?.(parseBool$1(checked));
18184
19881
  const sound = extSpecs.sound ? readXmlAttr(extAttrs, extSpecs.sound) : void 0;
18185
19882
  if (sound !== void 0) componentObj.setInstanceSound?.(sound);
18186
19883
  const soundVolumeScale = extSpecs.soundVolumeScale ? readXmlAttr(extAttrs, extSpecs.soundVolumeScale) : void 0;
@@ -18192,7 +19889,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
18192
19889
  const visibleItemCount = extSpecs.visibleItemCount ? readXmlAttr(extAttrs, extSpecs.visibleItemCount) : void 0;
18193
19890
  if (visibleItemCount !== void 0) componentObj.setInstanceVisibleItemCount?.(parseInt2(visibleItemCount));
18194
19891
  const autoClearItems = extSpecs.autoClearItems ? readXmlAttr(extAttrs, extSpecs.autoClearItems) : void 0;
18195
- if (autoClearItems !== void 0) componentObj.setInstanceAutoClearItems?.(parseBool(autoClearItems));
19892
+ if (autoClearItems !== void 0) componentObj.setInstanceAutoClearItems?.(parseBool$1(autoClearItems));
18196
19893
  const value = extSpecs.value ? readXmlAttr(extAttrs, extSpecs.value) : void 0;
18197
19894
  if (value !== void 0) componentObj.setInstanceValue?.(parseInt2(value));
18198
19895
  const max = extSpecs.max ? readXmlAttr(extAttrs, extSpecs.max) : void 0;
@@ -18214,9 +19911,9 @@ function parseGear(_ctx, doc, obj, gearTag, attrs, localControllers) {
18214
19911
  const gear = doc.createGear();
18215
19912
  gear.setGearType(gearType);
18216
19913
  const tween = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.gear.attrs.tween);
18217
- gear.setTween(parseBool(tween));
19914
+ gear.setTween(parseBool$1(tween));
18218
19915
  const positionsInPercent = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.gear.attrs.positionsInPercent);
18219
- if (positionsInPercent !== void 0) gear.setPositionsInPercent(parseBool(positionsInPercent));
19916
+ if (positionsInPercent !== void 0) gear.setPositionsInPercent(parseBool$1(positionsInPercent));
18220
19917
  const ctrlName = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.gear.attrs.controller) || "";
18221
19918
  const controller = localControllers.get(ctrlName) || null;
18222
19919
  if (controller) gear.setController(controller);
@@ -18440,7 +20137,7 @@ function readComponentXml(ctx, comp, xmlContent) {
18440
20137
  comp.setPivotX?.(parseFloat(parts[0]) || 0);
18441
20138
  comp.setPivotY?.(parseFloat(parts[1]) || 0);
18442
20139
  const anchor = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.anchor);
18443
- if (anchor !== void 0) comp.setPivotAsAnchor?.(parseBool(anchor));
20140
+ if (anchor !== void 0) comp.setPivotAsAnchor?.(parseBool$1(anchor));
18444
20141
  }
18445
20142
  const margin = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.margin);
18446
20143
  if (margin) {
@@ -18463,7 +20160,7 @@ function readComponentXml(ctx, comp, xmlContent) {
18463
20160
  const bgColor = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.bgColor);
18464
20161
  if (bgColor !== void 0) comp.setBgColor?.(bgColor);
18465
20162
  const bgColorEnabled = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.bgColorEnabled);
18466
- if (bgColorEnabled !== void 0) comp.setBgColorEnabled?.(parseBool(bgColorEnabled));
20163
+ if (bgColorEnabled !== void 0) comp.setBgColorEnabled?.(parseBool$1(bgColorEnabled));
18467
20164
  const designImageAlpha = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageAlpha);
18468
20165
  if (designImageAlpha !== void 0) comp.setDesignImageAlpha?.(parseInt2(designImageAlpha));
18469
20166
  const designImageLayer = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageLayer);
@@ -18487,11 +20184,11 @@ function readComponentXml(ctx, comp, xmlContent) {
18487
20184
  });
18488
20185
  }
18489
20186
  const opaque = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.opaque);
18490
- if (opaque !== void 0) comp.setOpaque?.(parseBool(opaque));
20187
+ if (opaque !== void 0) comp.setOpaque?.(parseBool$1(opaque));
18491
20188
  const mask = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.mask);
18492
20189
  if (mask !== void 0) comp.setMask?.(mask);
18493
20190
  const reversedMask = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.reversedMask);
18494
- if (reversedMask !== void 0) comp.setReversedMask?.(parseBool(reversedMask));
20191
+ if (reversedMask !== void 0) comp.setReversedMask?.(parseBool$1(reversedMask));
18495
20192
  const hitTest = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.hitTest);
18496
20193
  if (hitTest !== void 0) comp.setHitTest?.(hitTest);
18497
20194
  const customData = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.customData);
@@ -18554,23 +20251,23 @@ function readComponentXml(ctx, comp, xmlContent) {
18554
20251
  case "ComboBox":
18555
20252
  if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ComboBox.attrs.dropdown) !== void 0) comp.setDropdown?.(String(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ComboBox.attrs.dropdown)));
18556
20253
  if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ComboBox.attrs.selectionController) !== void 0) comp.setSelectionController?.(String(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ComboBox.attrs.selectionController)));
18557
- if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ComboBox.attrs.autoClearItems) !== void 0) comp.setAutoClearItems?.(parseBool(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ComboBox.attrs.autoClearItems)));
20254
+ if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ComboBox.attrs.autoClearItems) !== void 0) comp.setAutoClearItems?.(parseBool$1(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ComboBox.attrs.autoClearItems)));
18558
20255
  break;
18559
20256
  case "Label":
18560
20257
  if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Label.attrs.prompt) !== void 0) comp.setPromptText?.(String(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Label.attrs.prompt)));
18561
20258
  break;
18562
20259
  case "ProgressBar":
18563
20260
  if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ProgressBar.attrs.titleType) !== void 0) comp.setTitleType?.(parseTitleType(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ProgressBar.attrs.titleType)));
18564
- if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ProgressBar.attrs.reverse) !== void 0) comp.setReverse?.(parseBool(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ProgressBar.attrs.reverse)));
20261
+ if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ProgressBar.attrs.reverse) !== void 0) comp.setReverse?.(parseBool$1(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ProgressBar.attrs.reverse)));
18565
20262
  break;
18566
20263
  case "Slider":
18567
20264
  if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.titleType) !== void 0) comp.setTitleType?.(parseTitleType(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.titleType)));
18568
- if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.reverse) !== void 0) comp.setReverse?.(parseBool(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.reverse)));
18569
- if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.wholeNumbers) !== void 0) comp.setWholeNumbers?.(parseBool(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.wholeNumbers)));
18570
- if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.changeOnClick) !== void 0) comp.setChangeOnClick?.(parseBool(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.changeOnClick)));
20265
+ if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.reverse) !== void 0) comp.setReverse?.(parseBool$1(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.reverse)));
20266
+ if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.wholeNumbers) !== void 0) comp.setWholeNumbers?.(parseBool$1(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.wholeNumbers)));
20267
+ if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.changeOnClick) !== void 0) comp.setChangeOnClick?.(parseBool$1(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Slider.attrs.changeOnClick)));
18571
20268
  break;
18572
20269
  case "ScrollBar":
18573
- if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ScrollBar.attrs.fixedGripSize) !== void 0) comp.setFixedGripSize?.(parseBool(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ScrollBar.attrs.fixedGripSize)));
20270
+ if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ScrollBar.attrs.fixedGripSize) !== void 0) comp.setFixedGripSize?.(parseBool$1(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.ScrollBar.attrs.fixedGripSize)));
18574
20271
  break;
18575
20272
  default: break;
18576
20273
  }
@@ -18619,7 +20316,7 @@ function readComponentXml(ctx, comp, xmlContent) {
18619
20316
  const repeat = readXmlAttr(actionDef, PROJECT_XML_PROTOCOL.controllerAction.attrs.repeat);
18620
20317
  const delay = readXmlAttr(actionDef, PROJECT_XML_PROTOCOL.controllerAction.attrs.delay);
18621
20318
  const stopOnExit = readXmlAttr(actionDef, PROJECT_XML_PROTOCOL.controllerAction.attrs.stopOnExit);
18622
- action.setTransitionName(getXmlScalar(transitionName)).setPlayTimes(parseInt2(repeat, 1)).setDelay(parseFloat2(delay)).setStopOnExit(parseBool(stopOnExit));
20319
+ action.setTransitionName(getXmlScalar(transitionName)).setPlayTimes(parseInt2(repeat, 1)).setDelay(parseFloat2(delay)).setStopOnExit(parseBool$1(stopOnExit));
18623
20320
  break;
18624
20321
  }
18625
20322
  case ControllerActionType.ChangePage: {
@@ -18661,7 +20358,7 @@ function readComponentXml(ctx, comp, xmlContent) {
18661
20358
  const autoPlayDelay = readXmlAttr(transDef, PROJECT_XML_PROTOCOL.transition.attrs.autoPlayDelay);
18662
20359
  const options = readXmlAttr(transDef, PROJECT_XML_PROTOCOL.transition.attrs.options);
18663
20360
  const fps = readXmlAttr(transDef, PROJECT_XML_PROTOCOL.transition.attrs.fps);
18664
- trans.setAutoPlay(parseBool(autoPlay));
20361
+ trans.setAutoPlay(parseBool$1(autoPlay));
18665
20362
  trans.setAutoPlayTimes(parseInt2(autoPlayTimes, 1));
18666
20363
  trans.setAutoPlayDelay(parseFloat2(autoPlayDelay));
18667
20364
  if (options !== void 0) trans.setOptions?.(parseInt2(options));
@@ -18684,10 +20381,10 @@ function readComponentXml(ctx, comp, xmlContent) {
18684
20381
  const customEaseValue = readXmlAttr(parsedItem, PROJECT_XML_PROTOCOL.transitionItem.attrs.customEase);
18685
20382
  ti.setTime(parseFloat2(time));
18686
20383
  ti.setTargetId(target || "");
18687
- ti.setTween(parseBool(tween));
20384
+ ti.setTween(parseBool$1(tween));
18688
20385
  ti.setDuration(parseFloat2(duration));
18689
20386
  ti.setRepeat(parseInt2(repeat));
18690
- ti.setYoyo(parseBool(yoyo));
20387
+ ti.setYoyo(parseBool$1(yoyo));
18691
20388
  ti.setLabel(label || "");
18692
20389
  if (label2 !== void 0) ti.setEndLabel?.(label2);
18693
20390
  if (pathValue !== void 0) ti.setPath?.(pathValue);
@@ -18726,6 +20423,10 @@ function readComponentXml(ctx, comp, xmlContent) {
18726
20423
  }
18727
20424
  //#endregion
18728
20425
  //#region ../core/src/io/project-reader.ts
20426
+ function assertWellFormedXml(content) {
20427
+ const result = XMLValidator.validate(content, { allowBooleanAttributes: true });
20428
+ if (result !== true) throw new Error(result.err.msg);
20429
+ }
18729
20430
  function getOrderedPackageResourceItems(xmlContent) {
18730
20431
  const descriptionEntry = parseXMLPreserveOrder(xmlContent).find((entry) => "packageDescription" in entry || "branchDescription" in entry);
18731
20432
  if (!descriptionEntry) return [];
@@ -18778,18 +20479,60 @@ var ProjectReader = class {
18778
20479
  this._fs = fs;
18779
20480
  }
18780
20481
  async read(projectPath, options = {}) {
20482
+ return this._read(projectPath, options);
20483
+ }
20484
+ async readDetailed(projectPath, options = {}) {
20485
+ const diagnostics = [];
20486
+ try {
20487
+ return {
20488
+ document: await this._read(projectPath, options, diagnostics),
20489
+ diagnostics,
20490
+ complete: !diagnostics.some((diagnostic) => [
20491
+ "invalid_project_xml",
20492
+ "invalid_package_xml",
20493
+ "invalid_branch_package_xml",
20494
+ "invalid_component_xml",
20495
+ "invalid_settings_json",
20496
+ "unreadable_source",
20497
+ "unsupported_resource_kind"
20498
+ ].includes(diagnostic.code))
20499
+ };
20500
+ } catch (error) {
20501
+ diagnostics.push({
20502
+ severity: "error",
20503
+ code: "invalid_project_xml",
20504
+ path: "project",
20505
+ message: error instanceof Error ? error.message : String(error),
20506
+ sourcePath: projectPath
20507
+ });
20508
+ return {
20509
+ document: null,
20510
+ diagnostics,
20511
+ complete: false
20512
+ };
20513
+ }
20514
+ }
20515
+ async _read(projectPath, options, diagnostics) {
18781
20516
  const fs = this._fs;
18782
20517
  const doc = new Document();
18783
20518
  const basePath = getProjectBasePath(fs, projectPath);
18784
20519
  doc.setProjectDir(basePath);
18785
- const ctx = new ReaderContext(doc, basePath);
18786
- const projDesc = getXmlNode(parseXML(await fs.readFile(projectPath)).projectDescription);
20520
+ const ctx = new ReaderContext(doc, basePath, diagnostics);
20521
+ const fairyContent = await fs.readFile(projectPath);
20522
+ if (diagnostics) assertWellFormedXml(fairyContent);
20523
+ const projDesc = getXmlNode(parseXML(fairyContent).projectDescription);
18787
20524
  if (projDesc) {
18788
20525
  const root = doc.getRoot();
18789
20526
  root.setProjectId(projDesc.id ?? "");
18790
20527
  root.setProjectType(this._resolveProjectType(projDesc.type ?? ""));
18791
20528
  root.setVersion(projDesc.version ?? "");
18792
- }
20529
+ } else ctx.addDiagnostic({
20530
+ severity: "error",
20531
+ code: "invalid_project_xml",
20532
+ path: "projectDescription",
20533
+ message: "Project file must contain a projectDescription root element.",
20534
+ sourcePath: projectPath
20535
+ });
18793
20536
  await this._readSettings(ctx);
18794
20537
  const assetsPath = fs.join(basePath, "assets");
18795
20538
  let packageDirs;
@@ -18801,9 +20544,20 @@ var ProjectReader = class {
18801
20544
  for (const dirName of packageDirs) {
18802
20545
  const pkgXmlPath = fs.join(assetsPath, dirName, "package.xml");
18803
20546
  if (!await fs.exists(pkgXmlPath)) continue;
18804
- await this._readPackage(ctx, dirName, pkgXmlPath, "", options);
20547
+ try {
20548
+ await this._readPackage(ctx, dirName, pkgXmlPath, "", options, diagnostics !== void 0);
20549
+ } catch (error) {
20550
+ if (!diagnostics) throw error;
20551
+ ctx.addDiagnostic({
20552
+ severity: "error",
20553
+ code: "invalid_package_xml",
20554
+ path: `packages.${dirName}`,
20555
+ message: error instanceof Error ? error.message : String(error),
20556
+ sourcePath: pkgXmlPath
20557
+ });
20558
+ }
18805
20559
  }
18806
- const branchNames = await this._readPackageBranches(ctx, options);
20560
+ const branchNames = await this._readPackageBranches(ctx, options, diagnostics !== void 0);
18807
20561
  if (branchNames.length > 0) doc.getRoot().setBranches(branchNames);
18808
20562
  this._linkPackageBranchItems(doc);
18809
20563
  for (const [_key, resource] of ctx.resourceMap) {
@@ -18812,9 +20566,22 @@ var ProjectReader = class {
18812
20566
  const compPath = getProjectComponentExtras(comp)._filePath;
18813
20567
  if (!compPath) continue;
18814
20568
  try {
18815
- readComponentXml(ctx, comp, await fs.readFile(compPath));
20569
+ const compContent = await fs.readFile(compPath);
20570
+ if (diagnostics) {
20571
+ assertWellFormedXml(compContent);
20572
+ if (!getXmlNode(parseXML(compContent).component)) throw new Error("Component XML must contain a component root element.");
20573
+ }
20574
+ readComponentXml(ctx, comp, compContent);
18816
20575
  } catch (err) {
18817
20576
  ctx.logger.warn(`Failed to parse component: ${compPath} — ${err}`);
20577
+ ctx.addDiagnostic({
20578
+ severity: "error",
20579
+ code: await fs.exists(compPath) ? "invalid_component_xml" : "missing_source",
20580
+ path: `components.${comp.getId()}`,
20581
+ message: `Failed to read component "${comp.getName()}": ${err instanceof Error ? err.message : String(err)}`,
20582
+ resourceId: comp.getId(),
20583
+ sourcePath: compPath
20584
+ });
18818
20585
  }
18819
20586
  }
18820
20587
  return doc;
@@ -18835,7 +20602,7 @@ var ProjectReader = class {
18835
20602
  }
18836
20603
  }
18837
20604
  }
18838
- async _readPackageBranches(ctx, options) {
20605
+ async _readPackageBranches(ctx, options, collectDiagnostics = false) {
18839
20606
  const fs = this._fs;
18840
20607
  let dirNames = [];
18841
20608
  try {
@@ -18855,7 +20622,18 @@ var ProjectReader = class {
18855
20622
  for (const dirName of packageDirs) {
18856
20623
  const pkgXmlPath = fs.join(branchAssetsPath, dirName, "package_branch.xml");
18857
20624
  if (!await fs.exists(pkgXmlPath)) continue;
18858
- await this._readPackage(ctx, dirName, pkgXmlPath, branchName, options);
20625
+ try {
20626
+ await this._readPackage(ctx, dirName, pkgXmlPath, branchName, options, collectDiagnostics);
20627
+ } catch (error) {
20628
+ if (!collectDiagnostics) throw error;
20629
+ ctx.addDiagnostic({
20630
+ severity: "error",
20631
+ code: "invalid_branch_package_xml",
20632
+ path: `branches.${branchName}.packages.${dirName}`,
20633
+ message: error instanceof Error ? error.message : String(error),
20634
+ sourcePath: pkgXmlPath
20635
+ });
20636
+ }
18859
20637
  }
18860
20638
  }
18861
20639
  return branchNames;
@@ -18884,21 +20662,35 @@ var ProjectReader = class {
18884
20662
  name: "i18n.json",
18885
20663
  key: "i18n"
18886
20664
  }
18887
- ]) try {
20665
+ ]) {
18888
20666
  const filePath = fs.join(settingsPath, name);
18889
- if (await fs.exists(filePath)) {
18890
- const content = await fs.readFile(filePath);
18891
- assignSetting(ctx.settings, key, JSON.parse(content));
20667
+ try {
20668
+ if (await fs.exists(filePath)) {
20669
+ const content = await fs.readFile(filePath);
20670
+ assignSetting(ctx.settings, key, JSON.parse(content));
20671
+ }
20672
+ } catch (error) {
20673
+ ctx.addDiagnostic({
20674
+ severity: "error",
20675
+ code: "invalid_settings_json",
20676
+ path: `settings.${name}`,
20677
+ message: `Failed to read ${name}: ${error instanceof Error ? error.message : String(error)}`,
20678
+ sourcePath: filePath
20679
+ });
18892
20680
  }
18893
- } catch {}
20681
+ }
18894
20682
  ctx.document.getRoot().setSettings(ctx.settings);
18895
20683
  }
18896
- async _readPackage(ctx, dirName, pkgXmlPath, branchName = "", options = {}) {
20684
+ async _readPackage(ctx, dirName, pkgXmlPath, branchName = "", options = {}, validateSyntax = false) {
18897
20685
  const fs = this._fs;
18898
20686
  const content = await fs.readFile(pkgXmlPath);
20687
+ if (validateSyntax) assertWellFormedXml(content);
18899
20688
  const xml = parseXML(content);
18900
20689
  const desc = branchName ? getXmlNode(xml.branchDescription) : getXmlNode(xml.packageDescription);
18901
- if (!desc) return;
20690
+ if (!desc) {
20691
+ if (validateSyntax) throw new Error(`Package XML must contain a ${branchName ? "branchDescription" : "packageDescription"} root element.`);
20692
+ return;
20693
+ }
18902
20694
  let pkg = ctx.document.getRoot().getPackage(dirName);
18903
20695
  if (!pkg) pkg = ctx.document.createPackage(dirName);
18904
20696
  if (branchName) pkg.addBranchName(branchName);
@@ -18921,7 +20713,7 @@ var ProjectReader = class {
18921
20713
  pkg.setBranchNames(parsedBranchNames);
18922
20714
  }
18923
20715
  const compressPNG = readXmlAttr(desc, PROJECT_XML_PROTOCOL.packageDescription.attrs.compressPNG);
18924
- if (compressPNG !== void 0) pkg.setCompressPNG(parseBool(compressPNG));
20716
+ if (compressPNG !== void 0) pkg.setCompressPNG(parseBool$1(compressPNG));
18925
20717
  const jpegQuality = readXmlAttr(desc, PROJECT_XML_PROTOCOL.packageDescription.attrs.jpegQuality);
18926
20718
  if (jpegQuality !== void 0 && jpegQuality !== null && jpegQuality !== "") pkg.setJpegQuality(parseInt2(jpegQuality, 0));
18927
20719
  }
@@ -18932,11 +20724,11 @@ var ProjectReader = class {
18932
20724
  pkg.setPublishPath(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.path) || "");
18933
20725
  pkg.setPublishBranchPath(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.branchPath) || "");
18934
20726
  pkg.setPublishPackageCount(parseInt2(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.packageCount), 0));
18935
- pkg.setGenCode(parseBool(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.genCode)));
20727
+ pkg.setGenCode(parseBool$1(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.genCode)));
18936
20728
  pkg.setCodePath(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.codePath) || "");
18937
20729
  const globalAtlas = ctx.settings.publish?.atlasSetting;
18938
20730
  const maxAtlasSize = readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.maxAtlasSize);
18939
- const sizeOption = parseBool(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.npot)) ? "npot" : readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.sizeOption) || globalAtlas?.sizeOption || "pot";
20731
+ const sizeOption = parseBool$1(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.npot)) ? "npot" : readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.sizeOption) || globalAtlas?.sizeOption || "pot";
18940
20732
  const square = readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.square);
18941
20733
  const rotation = readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.rotation);
18942
20734
  const multiPage = readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.multiPage);
@@ -18944,10 +20736,10 @@ var ProjectReader = class {
18944
20736
  useGlobal: maxAtlasSize === void 0,
18945
20737
  maxSize: parseInt2(maxAtlasSize, globalAtlas?.maxSize ?? 2048),
18946
20738
  sizeOption: sizeOption === "npot" || sizeOption === "mof" ? sizeOption : "pot",
18947
- forceSquare: square === void 0 ? globalAtlas?.forceSquare ?? false : parseBool(square),
18948
- allowRotation: rotation === void 0 ? globalAtlas?.allowRotation ?? false : parseBool(rotation),
18949
- paging: multiPage === void 0 ? globalAtlas?.paging ?? true : parseBool(multiPage),
18950
- extractAlpha: parseBool(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.extractAlpha)),
20739
+ forceSquare: square === void 0 ? globalAtlas?.forceSquare ?? false : parseBool$1(square),
20740
+ allowRotation: rotation === void 0 ? globalAtlas?.allowRotation ?? false : parseBool$1(rotation),
20741
+ paging: multiPage === void 0 ? globalAtlas?.paging ?? true : parseBool$1(multiPage),
20742
+ extractAlpha: parseBool$1(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.extractAlpha)),
18951
20743
  maxIndex: parseInt2(readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.maxAtlasIndex), 10),
18952
20744
  atlases: ensureArray(publish.atlas).flatMap((value) => {
18953
20745
  const atlas = getXmlNode(value);
@@ -18955,7 +20747,7 @@ var ProjectReader = class {
18955
20747
  return [{
18956
20748
  index: parseInt2(readXmlAttr(atlas, PROJECT_XML_PROTOCOL.packagePublishAtlas.attrs.index)),
18957
20749
  name: readXmlAttr(atlas, PROJECT_XML_PROTOCOL.packagePublishAtlas.attrs.name) || "",
18958
- compression: parseBool(readXmlAttr(atlas, PROJECT_XML_PROTOCOL.packagePublishAtlas.attrs.compression))
20750
+ compression: parseBool$1(readXmlAttr(atlas, PROJECT_XML_PROTOCOL.packagePublishAtlas.attrs.compression))
18959
20751
  }];
18960
20752
  }),
18961
20753
  excludedResourceIds: (readXmlAttr(publish, PROJECT_XML_PROTOCOL.packagePublish.attrs.excluded) || "").split(",").filter(Boolean)
@@ -18976,7 +20768,7 @@ var ProjectReader = class {
18976
20768
  if (resource) createdResources.push(resource);
18977
20769
  }
18978
20770
  await this._hydratePackageImageSizes(createdResources, packageDir);
18979
- if (options.hydrateResourceBytes) await this._hydratePackageResourceBytes(ctx.document, createdResources, packageDir);
20771
+ if (options.hydrateResourceBytes) await this._hydratePackageResourceBytes(ctx, createdResources, packageDir, pkg.getId());
18980
20772
  return;
18981
20773
  }
18982
20774
  for (const tagName of [
@@ -19000,7 +20792,7 @@ var ProjectReader = class {
19000
20792
  }
19001
20793
  }
19002
20794
  await this._hydratePackageImageSizes(createdResources, packageDir);
19003
- if (options.hydrateResourceBytes) await this._hydratePackageResourceBytes(ctx.document, createdResources, packageDir);
20795
+ if (options.hydrateResourceBytes) await this._hydratePackageResourceBytes(ctx, createdResources, packageDir, pkg.getId());
19004
20796
  }
19005
20797
  async _readPackageFolders(pkg, packageDir, branch, metadataEntries) {
19006
20798
  const metadata = new Map(metadataEntries.map((attrs) => {
@@ -19027,7 +20819,7 @@ var ProjectReader = class {
19027
20819
  folders.push({
19028
20820
  branch,
19029
20821
  path,
19030
- favorite: parseBool(readXmlAttr(attrs ?? {}, PROJECT_XML_PROTOCOL.packageResourceFolder.attrs.favorite)),
20822
+ favorite: parseBool$1(readXmlAttr(attrs ?? {}, PROJECT_XML_PROTOCOL.packageResourceFolder.attrs.favorite)),
19031
20823
  atlas: readXmlAttr(attrs ?? {}, PROJECT_XML_PROTOCOL.packageResourceFolder.attrs.atlas) ?? ""
19032
20824
  });
19033
20825
  await visit(childDirectory, path, childEntries);
@@ -19057,8 +20849,9 @@ var ProjectReader = class {
19057
20849
  } catch {}
19058
20850
  }
19059
20851
  }
19060
- async _hydratePackageResourceBytes(doc, resources, packageDir) {
20852
+ async _hydratePackageResourceBytes(ctx, resources, packageDir, packageId) {
19061
20853
  const fs = this._fs;
20854
+ const doc = ctx.document;
19062
20855
  for (const resource of resources) {
19063
20856
  const fileName = this._primaryResourceFileName(resource);
19064
20857
  if (!fileName) continue;
@@ -19066,7 +20859,18 @@ var ProjectReader = class {
19066
20859
  const sourcePath = this._packageRelativeSourcePath(resourcePath, fileName);
19067
20860
  if (!sourcePath) continue;
19068
20861
  const filePath = fs.join(packageDir, sourcePath.replace(/^\/+/, ""));
19069
- if (!await fs.exists(filePath)) continue;
20862
+ if (!await fs.exists(filePath)) {
20863
+ ctx.addDiagnostic({
20864
+ severity: "error",
20865
+ code: "missing_source",
20866
+ path: `packages.${packageId}.resources.${resource.getId()}`,
20867
+ message: `Declared source file is missing: ${sourcePath}`,
20868
+ packageId,
20869
+ resourceId: resource.getId(),
20870
+ sourcePath: filePath
20871
+ });
20872
+ continue;
20873
+ }
19070
20874
  try {
19071
20875
  const data = new Uint8Array(await fs.readFileRaw(filePath));
19072
20876
  const buffer = doc.createBuffer().setURI(sourcePath).setData(data);
@@ -19076,8 +20880,28 @@ var ProjectReader = class {
19076
20880
  if (size) resource.setWidth(size.width).setHeight(size.height);
19077
20881
  } else if (resource.propertyType === "MovieClipResource") try {
19078
20882
  applyDerivedMovieClipModel(doc, resource, deriveMovieClipModelFromJta(data));
19079
- } catch {}
19080
- } catch {}
20883
+ } catch (error) {
20884
+ ctx.addDiagnostic({
20885
+ severity: "error",
20886
+ code: "corrupt_source",
20887
+ path: `packages.${packageId}.resources.${resource.getId()}`,
20888
+ message: `MovieClip source is invalid: ${error instanceof Error ? error.message : String(error)}`,
20889
+ packageId,
20890
+ resourceId: resource.getId(),
20891
+ sourcePath: filePath
20892
+ });
20893
+ }
20894
+ } catch (error) {
20895
+ ctx.addDiagnostic({
20896
+ severity: "error",
20897
+ code: "unreadable_source",
20898
+ path: `packages.${packageId}.resources.${resource.getId()}`,
20899
+ message: `Declared source file cannot be read: ${error instanceof Error ? error.message : String(error)}`,
20900
+ packageId,
20901
+ resourceId: resource.getId(),
20902
+ sourcePath: filePath
20903
+ });
20904
+ }
19081
20905
  }
19082
20906
  }
19083
20907
  _primaryResourceFileName(resource) {
@@ -19107,8 +20931,8 @@ var ProjectReader = class {
19107
20931
  const id = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageResource.attrs.id) ?? "";
19108
20932
  const name = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageResource.attrs.name) ?? "";
19109
20933
  const path = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageResource.attrs.path) ?? "/";
19110
- const exported = parseBool(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageResource.attrs.exported));
19111
- const favorite = parseBool(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageResource.attrs.favorite));
20934
+ const exported = parseBool$1(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageResource.attrs.exported));
20935
+ const favorite = parseBool$1(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageResource.attrs.favorite));
19112
20936
  switch (tagName) {
19113
20937
  case "image": {
19114
20938
  const res = doc.createImageResource(name.replace(/\.\w+$/, ""));
@@ -19136,7 +20960,7 @@ var ProjectReader = class {
19136
20960
  if (qualityOption !== void 0) res.setQualityOption(qualityOption);
19137
20961
  const quality = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageImageResource.attrs.quality);
19138
20962
  if (quality !== void 0) res.setQuality(parseInt2(quality));
19139
- res.setDuplicatePadding(parseBool(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageImageResource.attrs.duplicatePadding)));
20963
+ res.setDuplicatePadding(parseBool$1(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageImageResource.attrs.duplicatePadding)));
19140
20964
  res.setSmoothing(readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageImageResource.attrs.smoothing) !== "false");
19141
20965
  pkg.addResource(res);
19142
20966
  ctx.registerResource(pkg.getId(), id, res);
@@ -19262,7 +21086,17 @@ var ProjectReader = class {
19262
21086
  ctx.registerResource(pkg.getId(), id, res);
19263
21087
  return res;
19264
21088
  }
19265
- default: return null;
21089
+ default:
21090
+ ctx.addDiagnostic({
21091
+ severity: "error",
21092
+ code: "unsupported_resource_kind",
21093
+ path: `packages.${pkg.getId()}.resources.${id || name}`,
21094
+ message: `Unsupported declared resource kind "${tagName}".`,
21095
+ packageId: pkg.getId(),
21096
+ resourceId: id,
21097
+ sourcePath: fs.join(packageDir, path.replace(/^\//, ""), name)
21098
+ });
21099
+ return null;
19266
21100
  }
19267
21101
  }
19268
21102
  _resolveProjectType(typeStr) {
@@ -24923,6 +26757,9 @@ var PlatformIO = class {
24923
26757
  async readProject(projectPath, options) {
24924
26758
  return new ProjectReader(this.createFileSystem()).read(projectPath, options);
24925
26759
  }
26760
+ async readProjectDetailed(projectPath, options) {
26761
+ return new ProjectReader(this.createFileSystem()).readDetailed(projectPath, options);
26762
+ }
24926
26763
  async writeProject(doc, projectPath, options) {
24927
26764
  return new ProjectWriter(this.createFileSystem()).write(doc, projectPath, options);
24928
26765
  }
@@ -24934,6 +26771,66 @@ var PlatformIO = class {
24934
26771
  }
24935
26772
  };
24936
26773
  //#endregion
26774
+ //#region ../functions/src/validate.ts
26775
+ /** Validate one authoritative UAM snapshot without mutating it. */
26776
+ function validateProject(project, options = {}) {
26777
+ const diagnostics = [
26778
+ ...options.readDiagnostics ?? [],
26779
+ ...validateUamProject(project),
26780
+ ...validateUamReferences(project)
26781
+ ];
26782
+ let complete = options.complete ?? true;
26783
+ if (options.validateSources) {
26784
+ const source = validateUamSourceBytes(project);
26785
+ diagnostics.push(...source.diagnostics);
26786
+ complete = complete && source.complete;
26787
+ }
26788
+ return createProjectValidationReport(diagnostics, complete);
26789
+ }
26790
+ //#endregion
26791
+ //#region ../functions/src/utils.ts
26792
+ /**
26793
+ * Wraps a transform function, assigning it a name for the transform stack.
26794
+ */
26795
+ function createTransform(name, fn) {
26796
+ Object.defineProperty(fn, "name", { value: name });
26797
+ return fn;
26798
+ }
26799
+ function parseTextureSetMode(value) {
26800
+ const raw = value?.trim() ?? "";
26801
+ if (!raw) return {
26802
+ kind: "auto",
26803
+ raw: ""
26804
+ };
26805
+ if (raw === "alone") return {
26806
+ kind: "standalone",
26807
+ raw,
26808
+ sizeMode: "default"
26809
+ };
26810
+ if (raw === "alone_npot") return {
26811
+ kind: "standalone",
26812
+ raw,
26813
+ sizeMode: "npot"
26814
+ };
26815
+ if (raw === "alone_mof") return {
26816
+ kind: "standalone",
26817
+ raw,
26818
+ sizeMode: "multipleOf4"
26819
+ };
26820
+ if (/^\d+$/.test(raw)) {
26821
+ const pageIndex = Number(raw);
26822
+ if (pageIndex >= 0 && pageIndex <= 10) return {
26823
+ kind: "page",
26824
+ raw,
26825
+ pageIndex
26826
+ };
26827
+ }
26828
+ return {
26829
+ kind: "auto",
26830
+ raw
26831
+ };
26832
+ }
26833
+ //#endregion
24937
26834
  //#region ../functions/src/publish/resource-references.ts
24938
26835
  function addReference(target, ownerPackageId, packageId, resourceId) {
24939
26836
  if (!packageId || !resourceId) return;
@@ -29090,11 +30987,11 @@ function printReport(report) {
29090
30987
  }
29091
30988
  //#endregion
29092
30989
  //#region ../functions/src/adapters/node/plugins.ts
29093
- const importNative$2 = new Function("id", "return import(id)");
30990
+ const importNative$3 = new Function("id", "return import(id)");
29094
30991
  async function loadPlugins(doc, pluginsDir) {
29095
30992
  if (!pluginsDir) return [];
29096
- const fs = await importNative$2("node:fs/promises");
29097
- const path = await importNative$2("node:path");
30993
+ const fs = await importNative$3("node:fs/promises");
30994
+ const path = await importNative$3("node:path");
29098
30995
  let entries;
29099
30996
  try {
29100
30997
  entries = await fs.readdir(pluginsDir, { withFileTypes: true });
@@ -29134,7 +31031,7 @@ function resolvePluginMain(path, pluginDir, manifest) {
29134
31031
  return mainPath;
29135
31032
  }
29136
31033
  async function loadPlugin(mainPath) {
29137
- const { createJiti } = await importNative$2("jiti");
31034
+ const { createJiti } = await importNative$3("jiti");
29138
31035
  const mod = await createJiti(import.meta.url).import(mainPath);
29139
31036
  const defaultExport = mod.default;
29140
31037
  return isObject(defaultExport) ? defaultExport : mod;
@@ -29144,9 +31041,9 @@ function isObject(value) {
29144
31041
  }
29145
31042
  //#endregion
29146
31043
  //#region ../functions/src/adapters/node/publish.ts
29147
- const importNative$1 = new Function("id", "return import(id)");
31044
+ const importNative$2 = new Function("id", "return import(id)");
29148
31045
  async function createNodePublishFileSystem() {
29149
- const [fs, path] = await Promise.all([importNative$1("node:fs/promises"), importNative$1("node:path")]);
31046
+ const [fs, path] = await Promise.all([importNative$2("node:fs/promises"), importNative$2("node:path")]);
29150
31047
  return {
29151
31048
  async readFileRaw(filePath) {
29152
31049
  const data = await fs.readFile(filePath);
@@ -29174,11 +31071,11 @@ async function resolveNodeAssetsPath(document, assetsPath) {
29174
31071
  if (assetsPath) return assetsPath;
29175
31072
  const projectDir = document.getProjectDir?.() ?? "";
29176
31073
  if (!projectDir) return void 0;
29177
- return (await importNative$1("node:path")).join(projectDir, "assets");
31074
+ return (await importNative$2("node:path")).join(projectDir, "assets");
29178
31075
  }
29179
31076
  async function loadSharpBackend() {
29180
31077
  try {
29181
- const loaded = await importNative$1("sharp");
31078
+ const loaded = await importNative$2("sharp");
29182
31079
  return loaded.default ?? loaded;
29183
31080
  } catch {
29184
31081
  return;
@@ -29187,7 +31084,7 @@ async function loadSharpBackend() {
29187
31084
  async function loadNodePublishPlugins(document, assetsPath) {
29188
31085
  const projectDir = document.getProjectDir?.() || (assetsPath ? resolveProjectBasePath(assetsPath) : "");
29189
31086
  if (!projectDir) return [];
29190
- return loadPlugins(document, (await importNative$1("node:path")).join(projectDir, "plugins"));
31087
+ return loadPlugins(document, (await importNative$2("node:path")).join(projectDir, "plugins"));
29191
31088
  }
29192
31089
  /**
29193
31090
  * Publish a FairyGUI project through the standard Node host adapter.
@@ -29215,9 +31112,9 @@ async function publishNode(options) {
29215
31112
  }
29216
31113
  //#endregion
29217
31114
  //#region ../functions/src/adapters/node/restore.ts
29218
- const importNative = new Function("id", "return import(id)");
31115
+ const importNative$1 = new Function("id", "return import(id)");
29219
31116
  async function createNodeRestoreFileSystem() {
29220
- const [fs, path] = await Promise.all([importNative("node:fs/promises"), importNative("node:path")]);
31117
+ const [fs, path] = await Promise.all([importNative$1("node:fs/promises"), importNative$1("node:path")]);
29221
31118
  return {
29222
31119
  async readFile(filePath) {
29223
31120
  return fs.readFile(filePath, "utf-8");
@@ -29282,7 +31179,7 @@ async function createNodeRestoreFileSystem() {
29282
31179
  async function createRestoreImageProcessors() {
29283
31180
  let sharp;
29284
31181
  try {
29285
- const loaded = await importNative("sharp");
31182
+ const loaded = await importNative$1("sharp");
29286
31183
  sharp = loaded.default ?? loaded;
29287
31184
  } catch {
29288
31185
  throw new Error("restoreNode: Sharp is required to crop atlas images. Install sharp before restoring.");
@@ -29320,8 +31217,8 @@ async function createRestoreImageProcessors() {
29320
31217
  if (input.expectedWidth > 0 && input.expectedHeight > 0 && (info.width !== input.expectedWidth || info.height !== input.expectedHeight)) throw new Error(`restore: Cropped image size mismatch for ${targetPath}: expected ${input.expectedWidth}x${input.expectedHeight}, got ${info.width}x${info.height}`);
29321
31218
  return data;
29322
31219
  }
29323
- const fs = await importNative("node:fs/promises");
29324
- const path = await importNative("node:path");
31220
+ const fs = await importNative$1("node:fs/promises");
31221
+ const path = await importNative$1("node:path");
29325
31222
  return {
29326
31223
  extractImage,
29327
31224
  cropImage: async (input) => {
@@ -29340,6 +31237,70 @@ async function restoreNode(options) {
29340
31237
  });
29341
31238
  }
29342
31239
  //#endregion
31240
+ //#region ../functions/src/adapters/node/validate.ts
31241
+ const importNative = new Function("id", "return import(id)");
31242
+ function sourceName(resource) {
31243
+ return resource.sourcePath ?? resource.fileName ?? resource.file ?? resource.name;
31244
+ }
31245
+ async function validateProjectNode(projectPath) {
31246
+ const read = await new NodeIO().readProjectDetailed(projectPath, { hydrateResourceBytes: true });
31247
+ if (!read.document) return createProjectValidationReport(read.diagnostics, false);
31248
+ let project;
31249
+ try {
31250
+ project = liftDocumentToUamProject(read.document);
31251
+ } catch (error) {
31252
+ return createProjectValidationReport([...read.diagnostics, {
31253
+ severity: "error",
31254
+ code: "invalid_uam",
31255
+ path: "project",
31256
+ message: `Project cannot be represented as UAM: ${error instanceof Error ? error.message : String(error)}`,
31257
+ sourcePath: projectPath
31258
+ }], false);
31259
+ }
31260
+ const base = validateProject(project, {
31261
+ readDiagnostics: read.diagnostics,
31262
+ complete: read.complete,
31263
+ validateSources: true
31264
+ });
31265
+ let diagnostics = base.diagnostics;
31266
+ const knownCorruptPaths = new Set(base.diagnostics.filter((diagnostic) => diagnostic.code === "corrupt_source").map((diagnostic) => diagnostic.path));
31267
+ const images = project.packages.flatMap((pkg, packageIndex) => pkg.resources.map((resource, resourceIndex) => ({
31268
+ pkg,
31269
+ packageIndex,
31270
+ resource,
31271
+ resourceIndex
31272
+ })).filter(({ resource, packageIndex, resourceIndex }) => resource.kind === "image" && resource.sourceBytes instanceof Uint8Array && !knownCorruptPaths.has(`packages[${packageIndex}].resources[${resourceIndex}]`)));
31273
+ if (images.length === 0) return base;
31274
+ let sharp;
31275
+ try {
31276
+ const loaded = await importNative("sharp");
31277
+ sharp = loaded.default ?? loaded;
31278
+ } catch {
31279
+ return createProjectValidationReport([...base.diagnostics, {
31280
+ severity: "warning",
31281
+ code: "decode_capability_unavailable",
31282
+ path: "project",
31283
+ message: "Sharp is unavailable, so Node image decoding could not be completed."
31284
+ }], false);
31285
+ }
31286
+ const decodedPaths = new Set(images.map(({ packageIndex, resourceIndex }) => `packages[${packageIndex}].resources[${resourceIndex}]`));
31287
+ diagnostics = diagnostics.filter((diagnostic) => diagnostic.code !== "decode_capability_unavailable" || !decodedPaths.has(diagnostic.path));
31288
+ for (const { pkg, packageIndex, resource, resourceIndex } of images) try {
31289
+ await sharp(resource.sourceBytes).raw().toBuffer();
31290
+ } catch (error) {
31291
+ diagnostics.push({
31292
+ severity: "error",
31293
+ code: "corrupt_source",
31294
+ path: `packages[${packageIndex}].resources[${resourceIndex}]`,
31295
+ message: `Image source cannot be decoded: ${error instanceof Error ? error.message : String(error)}`,
31296
+ packageId: pkg.id,
31297
+ resourceId: resource.id,
31298
+ sourcePath: sourceName(resource)
31299
+ });
31300
+ }
31301
+ return createProjectValidationReport(diagnostics, read.complete && !diagnostics.some((diagnostic) => diagnostic.code === "decode_capability_unavailable"));
31302
+ }
31303
+ //#endregion
29343
31304
  //#region src/utils/project-type.ts
29344
31305
  function parseProjectType(value) {
29345
31306
  if (!value) return void 0;
@@ -29422,10 +31383,27 @@ function registerRestoreCommand(program) {
29422
31383
  });
29423
31384
  }
29424
31385
  //#endregion
31386
+ //#region src/commands/validate.ts
31387
+ function registerValidateCommand(program) {
31388
+ program.command("validate").description("Validate project structure, references, and source files").argument("<project-dir>", "Project root directory or .fairy file").option("--json", "Print the machine-readable validation report").action(async (projectDir, options) => {
31389
+ const fairyPath = await resolveFairyPath(projectDir);
31390
+ const report = await validateProjectNode(fairyPath);
31391
+ if (options.json) console.log(JSON.stringify(report, null, 2));
31392
+ else {
31393
+ console.log(`${report.status.toUpperCase()}: ${fairyPath}`);
31394
+ for (const diagnostic of report.diagnostics) {
31395
+ const source = diagnostic.sourcePath ? ` (${diagnostic.sourcePath})` : "";
31396
+ console.log(`${diagnostic.severity.toUpperCase()} ${diagnostic.code} ${diagnostic.path}${source}: ${diagnostic.message}`);
31397
+ }
31398
+ }
31399
+ process.exitCode = report.status === "valid" ? 0 : report.status === "invalid" ? 1 : 2;
31400
+ });
31401
+ }
31402
+ //#endregion
29425
31403
  //#region src/utils/package-version.ts
29426
31404
  const require$1 = createRequire(import.meta.url);
29427
31405
  function getInjectedPackageVersion() {
29428
- const version = "0.2.0";
31406
+ const version = "0.3.0-alpha.2";
29429
31407
  return typeof version === "string" && true ? version : null;
29430
31408
  }
29431
31409
  function readPackageVersion() {
@@ -29446,6 +31424,7 @@ function createProgram() {
29446
31424
  registerInspectCommand(program);
29447
31425
  registerPublishCommand(program);
29448
31426
  registerRestoreCommand(program);
31427
+ registerValidateCommand(program);
29449
31428
  registerBackendCapabilitiesCommand(program);
29450
31429
  program.addHelpText("after", [
29451
31430
  "",