@pixldocs/canvas-renderer 0.5.82 → 0.5.84

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/index.cjs CHANGED
@@ -494,29 +494,39 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
494
494
  const mode = group.layoutMode ?? "absolute";
495
495
  if (!isStackLayoutMode(mode)) return /* @__PURE__ */ new Map();
496
496
  const gap = group.stackSpacing ?? 8;
497
+ const padTop = group.paddingTop ?? 0;
498
+ const padLeft = group.paddingLeft ?? 0;
497
499
  const kids = group.children ?? [];
498
500
  const out = /* @__PURE__ */ new Map();
499
501
  if (isVerticalStackLayoutMode(mode)) {
500
- let prevBottom = 0;
502
+ let prevBottom = padTop;
503
+ let firstSeen = false;
501
504
  for (let i = 0; i < kids.length; i++) {
502
505
  const child = kids[i];
503
506
  const storedTop = getNodeTop(child);
504
507
  const storedLeft = getNodeLeft(child);
505
- const effectiveTop = i === 0 ? storedTop : prevBottom + gap + storedTop;
506
- out.set(child.id, { top: effectiveTop, left: storedLeft });
508
+ const mTop = child.marginTop ?? 0;
509
+ const mLeft = child.marginLeft ?? 0;
510
+ const effectiveTop = !firstSeen ? padTop + storedTop + mTop : prevBottom + gap + storedTop + mTop;
511
+ firstSeen = true;
512
+ out.set(child.id, { top: effectiveTop, left: padLeft + storedLeft + mLeft });
507
513
  const h = getNodeBounds(child, pageChildren).height;
508
- prevBottom = effectiveTop + h;
514
+ prevBottom = effectiveTop + h + (child.marginBottom ?? 0);
509
515
  }
510
516
  } else {
511
- let prevRight = 0;
517
+ let prevRight = padLeft;
518
+ let firstSeen = false;
512
519
  for (let i = 0; i < kids.length; i++) {
513
520
  const child = kids[i];
514
521
  const storedLeft = getNodeLeft(child);
515
522
  const storedTop = getNodeTop(child);
516
- const effectiveLeft = i === 0 ? storedLeft : prevRight + gap + storedLeft;
517
- out.set(child.id, { top: storedTop, left: effectiveLeft });
523
+ const mTop = child.marginTop ?? 0;
524
+ const mLeft = child.marginLeft ?? 0;
525
+ const effectiveLeft = !firstSeen ? padLeft + storedLeft + mLeft : prevRight + gap + storedLeft + mLeft;
526
+ firstSeen = true;
527
+ out.set(child.id, { top: padTop + storedTop + mTop, left: effectiveLeft });
518
528
  const w = getNodeBounds(child, pageChildren).width;
519
- prevRight = effectiveLeft + w;
529
+ prevRight = effectiveLeft + w + (child.marginRight ?? 0);
520
530
  }
521
531
  }
522
532
  return out;
@@ -541,6 +551,14 @@ function groupBoundsFromChildren(group, pageChildren, options) {
541
551
  maxX = Math.max(maxX, cl + b.width);
542
552
  maxY = Math.max(maxY, ct + b.height);
543
553
  }
554
+ if (isStack) {
555
+ const padRight = group.paddingRight ?? 0;
556
+ const padBottom = group.paddingBottom ?? 0;
557
+ return {
558
+ width: Math.max(1, maxX + padRight),
559
+ height: Math.max(1, maxY + padBottom)
560
+ };
561
+ }
544
562
  return {
545
563
  width: Math.max(1, maxX - minX),
546
564
  height: Math.max(1, maxY - minY)
@@ -603,7 +621,7 @@ function absoluteToStorePosition(absoluteLeft, absoluteTop, nodeId, pageChildren
603
621
  const prev = kids[idx - 1];
604
622
  const prevResolved = resolved.get(prev.id);
605
623
  const prevHeight = getNodeBounds(prev, pageChildren).height;
606
- const prevBottom = prevResolved ? prevResolved.top + prevHeight : 0;
624
+ const prevBottom = prevResolved ? prevResolved.top + prevHeight + (prev.marginBottom ?? 0) : 0;
607
625
  const storeTop = inParentTop - prevBottom - gap;
608
626
  return { left: storeLeft, top: Math.max(0, storeTop) };
609
627
  }
@@ -625,7 +643,7 @@ function reflowStackGroup(group, pageChildren, spacing) {
625
643
  const b = getNodeBounds(child, pageChildren);
626
644
  const currentTop = getNodeTop(child);
627
645
  const effectiveTop = i === 0 ? currentTop : prevBottom + gap;
628
- prevBottom = effectiveTop + b.height;
646
+ prevBottom = effectiveTop + b.height + (child.marginBottom ?? 0);
629
647
  if (i > 0) updates.set(child.id, { top: 0, left: firstLeft });
630
648
  }
631
649
  } else {
@@ -636,7 +654,7 @@ function reflowStackGroup(group, pageChildren, spacing) {
636
654
  const b = getNodeBounds(child, pageChildren);
637
655
  const currentLeft = getNodeLeft(child);
638
656
  const effectiveLeft = i === 0 ? currentLeft : prevRight + gap;
639
- prevRight = effectiveLeft + b.width;
657
+ prevRight = effectiveLeft + b.width + (child.marginRight ?? 0);
640
658
  if (i > 0) updates.set(child.id, { left: 0, top: firstTop });
641
659
  }
642
660
  }
@@ -788,7 +806,8 @@ const cloneCanvas = (canvas) => ({
788
806
  themeConfig: canvas.themeConfig ? {
789
807
  properties: canvas.themeConfig.properties.map((p) => ({ ...p })),
790
808
  variants: canvas.themeConfig.variants.map((v) => ({ ...v, values: { ...v.values } }))
791
- } : void 0
809
+ } : void 0,
810
+ pdfTextMode: canvas.pdfTextMode
792
811
  });
793
812
  const sameIdSet = (a, b) => {
794
813
  if (a.length !== b.length) return false;
@@ -1268,6 +1287,12 @@ const useEditorStore = zustand.create((set, get) => ({
1268
1287
  const committed = commitFromState(state, nextCanvas);
1269
1288
  return { canvas: nextCanvas, ...committed };
1270
1289
  }),
1290
+ setPdfTextMode: (mode) => set((state) => {
1291
+ if (state.canvas.pdfTextMode === mode) return {};
1292
+ const nextCanvas = { ...state.canvas, pdfTextMode: mode };
1293
+ const committed = commitFromState(state, nextCanvas);
1294
+ return { canvas: nextCanvas, ...committed };
1295
+ }),
1271
1296
  setZoom: (zoom) => set((state) => ({
1272
1297
  canvas: { ...state.canvas, zoom: Math.max(0.1, Math.min(10, zoom)) }
1273
1298
  })),
@@ -1671,7 +1696,7 @@ const useEditorStore = zustand.create((set, get) => ({
1671
1696
  const themeConfig = state.canvas.themeConfig ?? createEmptyThemeConfig();
1672
1697
  if (themeConfig.properties.some((p) => p.id === property.id)) return {};
1673
1698
  const updatedProperties = [...themeConfig.properties, property];
1674
- const updatedVariants = themeConfig.variants.map(
1699
+ const updatedVariants = property.linkedTo ? themeConfig.variants : themeConfig.variants.map(
1675
1700
  (v) => v.isDefault ? { ...v, values: { ...v.values, [property.id]: currentValue } } : v
1676
1701
  );
1677
1702
  const nextCanvas = {
@@ -1697,9 +1722,17 @@ const useEditorStore = zustand.create((set, get) => ({
1697
1722
  removeThemeProperty: (propertyId) => set((state) => {
1698
1723
  const themeConfig = state.canvas.themeConfig;
1699
1724
  if (!themeConfig) return {};
1700
- const updatedProperties = themeConfig.properties.filter((p) => p.id !== propertyId);
1725
+ const linkedChildren = themeConfig.properties.filter((p) => p.linkedTo === propertyId);
1726
+ const updatedProperties = themeConfig.properties.filter((p) => p.id !== propertyId).map((p) => p.linkedTo === propertyId ? { ...p, linkedTo: void 0 } : p);
1701
1727
  const updatedVariants = themeConfig.variants.map((v) => {
1702
- const { [propertyId]: _, ...rest } = v.values;
1728
+ const { [propertyId]: removedValue, ...rest } = v.values;
1729
+ if (linkedChildren.length && removedValue !== void 0) {
1730
+ const seeded = { ...rest };
1731
+ for (const child of linkedChildren) {
1732
+ if (seeded[child.id] === void 0) seeded[child.id] = removedValue;
1733
+ }
1734
+ return { ...v, values: seeded };
1735
+ }
1703
1736
  return { ...v, values: rest };
1704
1737
  });
1705
1738
  const nextCanvas = {
@@ -1773,7 +1806,7 @@ const useEditorStore = zustand.create((set, get) => ({
1773
1806
  const PAGE_BG_ID = "__pageBackground__";
1774
1807
  let updatedPages = [...state.canvas.pages];
1775
1808
  for (const prop of themeConfig.properties) {
1776
- const value = variant.values[prop.id];
1809
+ const value = variant.values[prop.linkedTo ?? prop.id];
1777
1810
  if (value === void 0) continue;
1778
1811
  if (prop.elementId === PAGE_BG_ID) {
1779
1812
  if (prop.targetProperty === "backgroundColor") {
@@ -1996,19 +2029,7 @@ const useEditorStore = zustand.create((set, get) => ({
1996
2029
  } else {
1997
2030
  newCollapsedSet.add(groupId);
1998
2031
  }
1999
- const currentPage = getCurrentPageFromCanvas(state.canvas);
2000
- let nextCanvas = state.canvas;
2001
- const group = findNodeById(currentPage.children, groupId);
2002
- if (group && isGroup(group)) {
2003
- nextCanvas = updateCurrentPageChildren(
2004
- nextCanvas,
2005
- (children) => updateNodeInTree(children, groupId, { collapsed: !isCollapsed })
2006
- );
2007
- }
2008
- return {
2009
- collapsedGroups: newCollapsedSet,
2010
- canvas: nextCanvas
2011
- };
2032
+ return { collapsedGroups: newCollapsedSet };
2012
2033
  }),
2013
2034
  // Convenience aliases
2014
2035
  groupElements: (ids, name) => get().groupNodes(ids, name),
@@ -2455,7 +2476,8 @@ const useEditorStore = zustand.create((set, get) => ({
2455
2476
  formBindingMode: config.formBindingMode,
2456
2477
  boundFormDefId: config.boundFormDefId,
2457
2478
  boundFormDefName: config.boundFormDefName,
2458
- themeConfig: config.themeConfig ?? void 0
2479
+ themeConfig: config.themeConfig ?? void 0,
2480
+ pdfTextMode: config.pdfTextMode ?? "selectable"
2459
2481
  };
2460
2482
  const committed = commitFromState(state, nextCanvas);
2461
2483
  const out = {
@@ -4922,7 +4944,9 @@ function extractTextBgConfig(element) {
4922
4944
  if (!Number.isFinite(n)) return void 0;
4923
4945
  return Math.max(0, Math.min(1, n));
4924
4946
  })(),
4925
- shadowAffectsBg: element.textShadowAffectsBg !== false
4947
+ shadowAffectsBg: element.textShadowAffectsBg !== false,
4948
+ shadowAffectsText: element.textShadowAffectsText !== false,
4949
+ fitToText: element.textBgFitToText === true
4926
4950
  };
4927
4951
  }
4928
4952
  function hasTextBackground(cfg) {
@@ -4978,10 +5002,6 @@ function applyTextBackground(obj, cfg) {
4978
5002
  const pR = Math.max(0, Number(bg.padRight ?? 0));
4979
5003
  const pB = Math.max(0, Number(bg.padBottom ?? 0));
4980
5004
  const pL = Math.max(0, Number(bg.padLeft ?? 0));
4981
- const x = -w / 2 - pL;
4982
- const y = -h / 2 - pT;
4983
- const bgW = w + pL + pR;
4984
- const bgH = h + pT + pB;
4985
5005
  ctx.save();
4986
5006
  const suppressShadowOnBg = bg.shadowAffectsBg === false;
4987
5007
  if (suppressShadowOnBg) {
@@ -4990,24 +5010,38 @@ function applyTextBackground(obj, cfg) {
4990
5010
  ctx.shadowOffsetX = 0;
4991
5011
  ctx.shadowOffsetY = 0;
4992
5012
  }
4993
- buildRoundedRectPath2D(
4994
- ctx,
4995
- x,
4996
- y,
4997
- bgW,
4998
- bgH,
4999
- bg.rxTL ?? 0,
5000
- bg.rxTR ?? 0,
5001
- bg.rxBR ?? 0,
5002
- bg.rxBL ?? 0
5003
- );
5004
5013
  const op = typeof bg.opacity === "number" ? Math.max(0, Math.min(1, bg.opacity)) : 1;
5005
5014
  if (op < 1) ctx.globalAlpha = (ctx.globalAlpha ?? 1) * op;
5006
5015
  ctx.fillStyle = bg.color;
5007
- ctx.fill();
5016
+ const rects = computeBgRects(this, w, h, pT, pR, pB, pL, !!bg.fitToText);
5017
+ for (const r of rects) {
5018
+ buildRoundedRectPath2D(
5019
+ ctx,
5020
+ r.x,
5021
+ r.y,
5022
+ r.w,
5023
+ r.h,
5024
+ bg.rxTL ?? 0,
5025
+ bg.rxTR ?? 0,
5026
+ bg.rxBR ?? 0,
5027
+ bg.rxBL ?? 0
5028
+ );
5029
+ ctx.fill();
5030
+ }
5031
+ ctx.restore();
5032
+ }
5033
+ const suppressShadowOnText = bg && bg.shadowAffectsText === false;
5034
+ if (suppressShadowOnText) {
5035
+ ctx.save();
5036
+ ctx.shadowColor = "transparent";
5037
+ ctx.shadowBlur = 0;
5038
+ ctx.shadowOffsetX = 0;
5039
+ ctx.shadowOffsetY = 0;
5040
+ originalRender(ctx);
5008
5041
  ctx.restore();
5042
+ } else {
5043
+ originalRender(ctx);
5009
5044
  }
5010
- originalRender(ctx);
5011
5045
  };
5012
5046
  const originalToObject = obj.toObject.bind(obj);
5013
5047
  obj.toObject = function(propertiesToInclude) {
@@ -5033,20 +5067,18 @@ function applyTextBackground(obj, cfg) {
5033
5067
  const pR = Math.max(0, Number((bg == null ? void 0 : bg.padRight) ?? 0));
5034
5068
  const pB = Math.max(0, Number((bg == null ? void 0 : bg.padBottom) ?? 0));
5035
5069
  const pL = Math.max(0, Number((bg == null ? void 0 : bg.padLeft) ?? 0));
5036
- const x = -w / 2 - pL;
5037
- const y = -h / 2 - pT;
5038
- const bgW = w + pL + pR;
5039
- const bgH = h + pT + pB;
5040
- const bgD = buildRoundedRectPathD(
5041
- x,
5042
- y,
5043
- bgW,
5044
- bgH,
5070
+ const fit = !!(bg == null ? void 0 : bg.fitToText);
5071
+ const rects = computeBgRects(this, w, h, pT, pR, pB, pL, fit);
5072
+ const bgD = rects.map((r) => buildRoundedRectPathD(
5073
+ r.x,
5074
+ r.y,
5075
+ r.w,
5076
+ r.h,
5045
5077
  (bg == null ? void 0 : bg.rxTL) ?? 0,
5046
5078
  (bg == null ? void 0 : bg.rxTR) ?? 0,
5047
5079
  (bg == null ? void 0 : bg.rxBR) ?? 0,
5048
5080
  (bg == null ? void 0 : bg.rxBL) ?? 0
5049
- );
5081
+ )).join(" ");
5050
5082
  const bgFill = (bg == null ? void 0 : bg.color) || "";
5051
5083
  const bgOpacity = typeof (bg == null ? void 0 : bg.opacity) === "number" ? Math.max(0, Math.min(1, bg.opacity)) : 1;
5052
5084
  const bgOpacityAttr = bgOpacity < 1 ? ` fill-opacity="${bgOpacity}"` : "";
@@ -5071,9 +5103,11 @@ function applyTextBackground(obj, cfg) {
5071
5103
  const shadowBgPath = `<path d="${bgD}" fill="${escapeXmlAttr(shadowColor)}" />`;
5072
5104
  bgShadowMarker = wrapShadow(shadowBgPath);
5073
5105
  }
5074
- const inner = extractGInnerMarkup(svg);
5075
- const recoloredText = recolorSvgFills(inner, shadowColor);
5076
- if (recoloredText) textShadowMarker = wrapShadow(recoloredText);
5106
+ if ((bg == null ? void 0 : bg.shadowAffectsText) !== false) {
5107
+ const inner = extractGInnerMarkup(svg);
5108
+ const recoloredText = recolorSvgFills(inner, shadowColor);
5109
+ if (recoloredText) textShadowMarker = wrapShadow(recoloredText);
5110
+ }
5077
5111
  }
5078
5112
  const openTagMatch = svg.match(/^\s*<g\b[^>]*>/);
5079
5113
  const inserted = bgShadowMarker + bgPath + textShadowMarker;
@@ -5124,6 +5158,74 @@ function buildRoundedRectPathD(x, y, w, h, rTL, rTR, rBR, rBL) {
5124
5158
  parts.push("Z");
5125
5159
  return parts.join(" ");
5126
5160
  }
5161
+ function computeBgRects(obj, w, h, pT, pR, pB, pL, fit) {
5162
+ var _a;
5163
+ if (!fit) {
5164
+ return [{
5165
+ x: -w / 2 - pL,
5166
+ y: -h / 2 - pT,
5167
+ w: w + pL + pR,
5168
+ h: h + pT + pB
5169
+ }];
5170
+ }
5171
+ const lines = (obj == null ? void 0 : obj._textLines) ?? [];
5172
+ if (!lines || lines.length === 0) {
5173
+ return [{
5174
+ x: -w / 2 - pL,
5175
+ y: -h / 2 - pT,
5176
+ w: w + pL + pR,
5177
+ h: h + pT + pB
5178
+ }];
5179
+ }
5180
+ const rects = [];
5181
+ const halfW = w / 2;
5182
+ const halfH = h / 2;
5183
+ const lineHeightRatio = Math.max(0.01, Number((obj == null ? void 0 : obj.lineHeight) ?? 1) || 1);
5184
+ let cursorY = -halfH;
5185
+ for (let i = 0; i < lines.length; i++) {
5186
+ let lineW = 0;
5187
+ let lineLeft = 0;
5188
+ let lineH = 0;
5189
+ try {
5190
+ lineW = obj.getLineWidth(i) || 0;
5191
+ } catch {
5192
+ lineW = 0;
5193
+ }
5194
+ try {
5195
+ lineLeft = ((_a = obj._getLineLeftOffset) == null ? void 0 : _a.call(obj, i)) ?? 0;
5196
+ } catch {
5197
+ lineLeft = 0;
5198
+ }
5199
+ try {
5200
+ lineH = obj.getHeightOfLine(i) || 0;
5201
+ } catch {
5202
+ lineH = 0;
5203
+ }
5204
+ const rawSlotH = i === lines.length - 1 ? lineH / lineHeightRatio : lineH;
5205
+ const usedH = cursorY + halfH;
5206
+ const slotH = Math.max(0, Math.min(rawSlotH, h - usedH));
5207
+ if (lineW <= 0 || slotH <= 0) {
5208
+ cursorY += slotH;
5209
+ continue;
5210
+ }
5211
+ rects.push({
5212
+ x: -halfW + lineLeft - pL,
5213
+ y: cursorY - pT,
5214
+ w: lineW + pL + pR,
5215
+ h: slotH + pT + pB
5216
+ });
5217
+ cursorY += slotH;
5218
+ }
5219
+ if (rects.length === 0) {
5220
+ return [{
5221
+ x: -w / 2 - pL,
5222
+ y: -h / 2 - pT,
5223
+ w: w + pL + pR,
5224
+ h: h + pT + pB
5225
+ }];
5226
+ }
5227
+ return rects;
5228
+ }
5127
5229
  function escapeXmlAttr(s) {
5128
5230
  return String(s).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
5129
5231
  }
@@ -8143,10 +8245,14 @@ const PageCanvas = react.forwardRef(
8143
8245
  tr: element.textBgRxTR ?? 0,
8144
8246
  br: element.textBgRxBR ?? 0,
8145
8247
  bl: element.textBgRxBL ?? 0,
8248
+ ft: element.textBgFitToText === true,
8249
+ bo: element.textBgOpacity ?? 1,
8146
8250
  sc: element.textShadowColor ?? null,
8147
8251
  sb: element.textShadowBlur ?? 0,
8148
8252
  sx: element.textShadowOffsetX ?? 0,
8149
- sy: element.textShadowOffsetY ?? 0
8253
+ sy: element.textShadowOffsetY ?? 0,
8254
+ st: element.textShadowAffectsText !== false,
8255
+ sa: element.textShadowAffectsBg !== false
8150
8256
  }) !== (existingObj.__lastTextBgShadowJson ?? "") || // CRITICAL: Detect gradient fill/stroke changes — serialise to JSON for deep comparison
8151
8257
  JSON.stringify(element.fillGradient || null) !== (existingObj.__lastFillGradientJson ?? "null") || JSON.stringify(element.strokeGradient || null) !== (existingObj.__lastStrokeGradientJson ?? "null");
8152
8258
  const forceApplyFromPanel = syncTriggeredByPanelRef.current;
@@ -9060,10 +9166,14 @@ const PageCanvas = react.forwardRef(
9060
9166
  tr: element.textBgRxTR ?? 0,
9061
9167
  br: element.textBgRxBR ?? 0,
9062
9168
  bl: element.textBgRxBL ?? 0,
9169
+ ft: element.textBgFitToText === true,
9170
+ bo: element.textBgOpacity ?? 1,
9063
9171
  sc: element.textShadowColor ?? null,
9064
9172
  sb: element.textShadowBlur ?? 0,
9065
9173
  sx: element.textShadowOffsetX ?? 0,
9066
- sy: element.textShadowOffsetY ?? 0
9174
+ sy: element.textShadowOffsetY ?? 0,
9175
+ st: element.textShadowAffectsText !== false,
9176
+ sa: element.textShadowAffectsBg !== false
9067
9177
  });
9068
9178
  obj.dirty = true;
9069
9179
  } catch (err) {
@@ -10186,7 +10296,8 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
10186
10296
  })),
10187
10297
  // Honor minEntries: 0 — start with no entries, user adds via "+ Add" button.
10188
10298
  initialEntryCount: minEntries,
10189
- parentId
10299
+ parentId,
10300
+ entryNameFieldKey: def.entryNameFieldKey
10190
10301
  };
10191
10302
  if (treeNodeId) section.treeNodeId = treeNodeId;
10192
10303
  sections.push(section);
@@ -10631,6 +10742,26 @@ function baseId(id) {
10631
10742
  const REPEATABLE_KEY_REGEX = /^field_(.+)_(\d+)_(.+)$/;
10632
10743
  const NESTED_REPEATABLE_KEY_REGEX = /^field_(.+)_(\d+)_field_(.+)_(\d+)_(.+)$/;
10633
10744
  const FORMDEF_CANONICAL_KEY_REGEX = /^field_.+_N_.+$/;
10745
+ function parseEntryRange(range, max) {
10746
+ if (!range || !range.trim()) return null;
10747
+ const out = /* @__PURE__ */ new Set();
10748
+ for (const partRaw of range.split(",")) {
10749
+ const part = partRaw.trim();
10750
+ if (!part) continue;
10751
+ if (/^\d+$/.test(part)) {
10752
+ const n = parseInt(part, 10);
10753
+ if (n >= 1 && n <= max) out.add(n);
10754
+ continue;
10755
+ }
10756
+ const m = /^(\d*)\s*-\s*(\d*)$/.exec(part);
10757
+ if (!m) continue;
10758
+ const start = m[1] === "" ? 1 : Math.max(1, parseInt(m[1], 10));
10759
+ const end = m[2] === "" ? max : Math.min(max, parseInt(m[2], 10));
10760
+ for (let i = start; i <= end; i++) out.add(i);
10761
+ }
10762
+ if (out.size === 0) return null;
10763
+ return Array.from(out).sort((a, b) => a - b);
10764
+ }
10634
10765
  function applyTextCase(text, textCase) {
10635
10766
  if (!textCase || textCase === "none") return text;
10636
10767
  switch (textCase) {
@@ -10709,13 +10840,19 @@ function findElementBySourceIdInSubtree(nodes, sourceId) {
10709
10840
  }
10710
10841
  return void 0;
10711
10842
  }
10712
- function findRepeatableElementBySourceId(pages, baseNodeId, oneBasedIndex, sourceElementId) {
10843
+ function findAllRepeatableElementsBySourceId(pages, baseNodeId, oneBasedIndex, sourceElementId, expectedEntriesPerOccurrence) {
10713
10844
  var _a;
10714
10845
  const groups = collectGroupsByBaseId(pages, baseNodeId);
10715
- const group = groups[oneBasedIndex - 1];
10716
- if (!group) return void 0;
10717
- if (!isGroup(group) || !((_a = group.children) == null ? void 0 : _a.length)) return void 0;
10718
- return findElementBySourceIdInSubtree(group.children, sourceElementId) ?? (group.__sourceId === sourceElementId ? group.id : void 0);
10846
+ if (!groups.length) return [];
10847
+ const N = Math.max(1, expectedEntriesPerOccurrence ?? groups.length);
10848
+ const out = [];
10849
+ for (let occStart = 0; occStart < groups.length; occStart += N) {
10850
+ const group = groups[occStart + (oneBasedIndex - 1)];
10851
+ if (!group || !isGroup(group) || !((_a = group.children) == null ? void 0 : _a.length)) continue;
10852
+ const found = findElementBySourceIdInSubtree(group.children, sourceElementId) ?? (group.__sourceId === sourceElementId ? group.id : void 0);
10853
+ if (found) out.push(found);
10854
+ }
10855
+ return out;
10719
10856
  }
10720
10857
  function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi, childBaseNodeId, childCi, sourceElementId) {
10721
10858
  var _a, _b;
@@ -10736,6 +10873,24 @@ function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi
10736
10873
  if (!childGroup || !isGroup(childGroup) || !((_b = childGroup.children) == null ? void 0 : _b.length)) return void 0;
10737
10874
  return findElementBySourceIdInSubtree(childGroup.children, sourceElementId) ?? (childGroup.__sourceId === sourceElementId ? childGroup.id : void 0);
10738
10875
  }
10876
+ function repeatableLabelKey(label) {
10877
+ return String(label ?? "").trim().toLowerCase();
10878
+ }
10879
+ function repeatableLabelSlug(label) {
10880
+ return repeatableLabelKey(label).replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
10881
+ }
10882
+ function addToSetMap(map, key, value) {
10883
+ if (!key || !value) return;
10884
+ const set = map.get(key);
10885
+ if (set) set.add(value);
10886
+ else map.set(key, /* @__PURE__ */ new Set([value]));
10887
+ }
10888
+ function getFieldKeyAliases(fieldId) {
10889
+ const aliases = /* @__PURE__ */ new Set([fieldId]);
10890
+ const canonicalParts = fieldId.split("_N_");
10891
+ if (canonicalParts.length > 1) aliases.add(canonicalParts[canonicalParts.length - 1]);
10892
+ return Array.from(aliases).filter(Boolean);
10893
+ }
10739
10894
  function idPrefix(node) {
10740
10895
  if (isGroup(node)) return "group";
10741
10896
  const t = node.type;
@@ -10789,7 +10944,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
10789
10944
  var _a2;
10790
10945
  return !!((_a2 = n.repeatableSection) == null ? void 0 : _a2.label);
10791
10946
  };
10792
- function walk(children, parentRepeatableBaseId, parentInfo) {
10947
+ function walk(children, parentRepeatableBaseId, parentInfo, parentRepeatableEntryIndex) {
10793
10948
  var _a2, _b;
10794
10949
  if (!Array.isArray(children)) return;
10795
10950
  for (let i = 0; i < children.length; i++) {
@@ -10803,7 +10958,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
10803
10958
  const childBaseFromMeta = child.__baseNodeId;
10804
10959
  const isMatch = schemaBaseIds.has(child.id) || schemaBaseIds.has(childBase) || childBaseFromMeta != null && schemaBaseIds.has(childBaseFromMeta);
10805
10960
  if (!isMatch) {
10806
- if (isGroup(child) && Array.isArray(child.children)) walk(child.children, parentRepeatableBaseId);
10961
+ if (isGroup(child) && Array.isArray(child.children)) walk(child.children, parentRepeatableBaseId, void 0, parentRepeatableEntryIndex);
10807
10962
  j++;
10808
10963
  continue;
10809
10964
  }
@@ -10826,17 +10981,22 @@ function findRepeatableByNodeIds(pages, nodeIds) {
10826
10981
  count,
10827
10982
  node: child,
10828
10983
  baseNodeId: childBaseFromMeta ?? childBase,
10829
- parentBaseNodeId: parentRepeatableBaseId
10984
+ parentBaseNodeId: parentRepeatableBaseId,
10985
+ parentEntryIndex: parentRepeatableEntryIndex
10830
10986
  });
10831
- if (isGroup(child) && Array.isArray(child.children)) walk(child.children, childBase);
10987
+ const childEntryIndex = child.__repeatableEntryIndex;
10988
+ if (isGroup(child) && Array.isArray(child.children)) walk(child.children, effectiveChildBase, void 0, childEntryIndex);
10832
10989
  j += count;
10833
10990
  }
10834
10991
  } else if (isGroup(node) && ((_b = node.children) == null ? void 0 : _b.length)) {
10835
10992
  const nodeBase = baseId(node.id);
10836
10993
  const selfMatch = schemaBaseIds.has(node.id) || schemaBaseIds.has(nodeBase) || node.__baseNodeId != null && schemaBaseIds.has(node.__baseNodeId);
10837
- if (selfMatch && hasRepeatableSection(node)) {
10994
+ const isSelfRepeatable = selfMatch && hasRepeatableSection(node);
10995
+ let matchedSelfBase;
10996
+ if (selfMatch) matchedSelfBase = node.__baseNodeId ?? nodeBase;
10997
+ if (isSelfRepeatable) {
10838
10998
  let count = 1;
10839
- const effectiveBase = node.__baseNodeId ?? nodeBase;
10999
+ const effectiveBase = matchedSelfBase ?? nodeBase;
10840
11000
  if (node.id !== nodeBase && node.id !== effectiveBase) {
10841
11001
  while (i + count < children.length) {
10842
11002
  const next = children[i + count];
@@ -10853,10 +11013,12 @@ function findRepeatableByNodeIds(pages, nodeIds) {
10853
11013
  count,
10854
11014
  node,
10855
11015
  baseNodeId: effectiveBase,
10856
- parentBaseNodeId: parentRepeatableBaseId
11016
+ parentBaseNodeId: parentRepeatableBaseId,
11017
+ parentEntryIndex: parentRepeatableEntryIndex
10857
11018
  });
10858
11019
  }
10859
- walk(node.children, parentRepeatableBaseId);
11020
+ const nodeEntryIndex = node.__repeatableEntryIndex;
11021
+ walk(node.children, matchedSelfBase ?? parentRepeatableBaseId, void 0, nodeEntryIndex ?? parentRepeatableEntryIndex);
10860
11022
  }
10861
11023
  }
10862
11024
  }
@@ -10915,7 +11077,7 @@ function getNestedRepeatableEntryCount(parentId, parentIndex, childId, formValue
10915
11077
  return Math.max(1, maxIndex);
10916
11078
  }
10917
11079
  function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap, repeatablePagesFromSchema) {
10918
- var _a, _b, _c, _d, _e, _f;
11080
+ var _a, _b, _c;
10919
11081
  const cloned = JSON.parse(JSON.stringify(config));
10920
11082
  if (!cloned.pages) return cloned;
10921
11083
  const dynamicFields = cloned.dynamicFields;
@@ -10965,17 +11127,56 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
10965
11127
  }
10966
11128
  const repeatableList = (repeatableSectionsFromSchema == null ? void 0 : repeatableSectionsFromSchema.length) ? repeatableSectionsFromSchema : getRepeatableFromConfig(pages);
10967
11129
  const nodeIds = repeatableList.map((r) => r.nodeId);
11130
+ const repeatableBasesByLabel = /* @__PURE__ */ new Map();
11131
+ for (const r of repeatableList) {
11132
+ const base = baseId(r.nodeId);
11133
+ addToSetMap(repeatableBasesByLabel, repeatableLabelKey(r.label), base);
11134
+ addToSetMap(repeatableBasesByLabel, repeatableLabelSlug(r.label), base);
11135
+ }
11136
+ const repeatableTokenToBaseIds = /* @__PURE__ */ new Map();
11137
+ for (const r of repeatableList) {
11138
+ const base = baseId(r.nodeId);
11139
+ const labelBases = /* @__PURE__ */ new Set([
11140
+ base,
11141
+ ...repeatableBasesByLabel.get(repeatableLabelKey(r.label)) ?? [],
11142
+ ...repeatableBasesByLabel.get(repeatableLabelSlug(r.label)) ?? []
11143
+ ]);
11144
+ for (const targetBase of labelBases) {
11145
+ addToSetMap(repeatableTokenToBaseIds, base, targetBase);
11146
+ addToSetMap(repeatableTokenToBaseIds, r.nodeId, targetBase);
11147
+ addToSetMap(repeatableTokenToBaseIds, repeatableLabelKey(r.label), targetBase);
11148
+ addToSetMap(repeatableTokenToBaseIds, repeatableLabelSlug(r.label), targetBase);
11149
+ }
11150
+ }
11151
+ const getRepeatableBaseIdsForToken = (token) => {
11152
+ const direct = repeatableTokenToBaseIds.get(token) ?? repeatableTokenToBaseIds.get(baseId(token));
11153
+ return direct ? Array.from(direct) : [baseId(token)];
11154
+ };
10968
11155
  const entryCountFromList = (baseNodeId) => {
10969
11156
  const item = repeatableList.find((r) => baseId(r.nodeId) === baseNodeId || r.nodeId === baseNodeId);
10970
11157
  return item == null ? void 0 : item.entryCount;
10971
11158
  };
11159
+ const entryFilterFromList = (baseNodeId) => {
11160
+ var _a2;
11161
+ const item = repeatableList.find((r) => baseId(r.nodeId) === baseNodeId || r.nodeId === baseNodeId);
11162
+ const filter = item == null ? void 0 : item.entryFilter;
11163
+ return (filter == null ? void 0 : filter.mode) === "range" && ((_a2 = filter.range) == null ? void 0 : _a2.trim()) ? filter : void 0;
11164
+ };
10972
11165
  const resolvedIdMap = /* @__PURE__ */ new Map();
11166
+ const addResolved = (key, id) => {
11167
+ const arr = resolvedIdMap.get(key);
11168
+ if (arr) {
11169
+ if (!arr.includes(id)) arr.push(id);
11170
+ } else resolvedIdMap.set(key, [id]);
11171
+ };
10973
11172
  const mappedNewIds = /* @__PURE__ */ new Set();
10974
11173
  const elementIdToFieldId = /* @__PURE__ */ new Map();
10975
11174
  if (dynamicFields == null ? void 0 : dynamicFields.length) {
10976
11175
  for (const f of dynamicFields) {
10977
- const elId = (_c = (_b = f.mappings) == null ? void 0 : _b[0]) == null ? void 0 : _c.elementId;
10978
- if (elId) elementIdToFieldId.set(elId, f.id);
11176
+ for (const m of f.mappings ?? []) {
11177
+ const elId = m == null ? void 0 : m.elementId;
11178
+ if (elId) elementIdToFieldId.set(elId, f.id);
11179
+ }
10979
11180
  }
10980
11181
  }
10981
11182
  const repeatableInfosFirst = findRepeatableByNodeIds(pages, nodeIds);
@@ -10988,37 +11189,90 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
10988
11189
  for (const r of nestedFirst) {
10989
11190
  if (r.parentBaseNodeId) nestedChildToParent.set(r.baseNodeId, r.parentBaseNodeId);
10990
11191
  }
11192
+ const getNestedBasePairs = (parentToken, childToken) => {
11193
+ const pairs = [];
11194
+ const seen = /* @__PURE__ */ new Set();
11195
+ for (const parentBaseId of getRepeatableBaseIdsForToken(parentToken)) {
11196
+ for (const childBaseId of getRepeatableBaseIdsForToken(childToken)) {
11197
+ const key = `${parentBaseId}::${childBaseId}`;
11198
+ if (seen.has(key)) continue;
11199
+ seen.add(key);
11200
+ pairs.push({ parentBaseId, childBaseId });
11201
+ }
11202
+ }
11203
+ return pairs.length ? pairs : [{ parentBaseId: baseId(parentToken), childBaseId: baseId(childToken) }];
11204
+ };
11205
+ const getNestedCountForBasePair = (parentBaseNodeId, parentIndex1Based, childBaseNodeId) => {
11206
+ let maxCount = 0;
11207
+ for (const { parentBaseId, childBaseId } of getNestedBasePairs(parentBaseNodeId, childBaseNodeId)) {
11208
+ const aliasKey = `${parentBaseId}_${parentIndex1Based}_${childBaseId}`;
11209
+ maxCount = Math.max(
11210
+ maxCount,
11211
+ (repeatableNestedEntryCounts == null ? void 0 : repeatableNestedEntryCounts[aliasKey]) ?? 0,
11212
+ getNestedRepeatableEntryCount(parentBaseId, parentIndex1Based, childBaseId, formValues)
11213
+ );
11214
+ }
11215
+ return Math.max(1, maxCount);
11216
+ };
10991
11217
  const phase1NewToOriginal = /* @__PURE__ */ new Map();
10992
- const topLevelByBase = /* @__PURE__ */ new Map();
11218
+ const entryCountByBase = /* @__PURE__ */ new Map();
11219
+ [...topLevel].sort((a, b) => {
11220
+ if (a.parentChildren !== b.parentChildren) return 0;
11221
+ return b.startIndex - a.startIndex;
11222
+ });
11223
+ const occByParent = /* @__PURE__ */ new Map();
10993
11224
  for (const r of topLevel) {
10994
- if (!topLevelByBase.has(r.baseNodeId)) topLevelByBase.set(r.baseNodeId, []);
10995
- topLevelByBase.get(r.baseNodeId).push(r);
10996
- }
10997
- for (const [, blocks] of topLevelByBase) {
10998
- const first = blocks[0];
10999
- const startIndex = Math.min(...blocks.map((b) => b.startIndex));
11000
- const endIndex = Math.max(...blocks.map((b) => b.startIndex + b.count));
11001
- const count = endIndex - startIndex;
11002
- const { parentChildren, node, baseNodeId } = first;
11225
+ if (!occByParent.has(r.parentChildren)) occByParent.set(r.parentChildren, []);
11226
+ occByParent.get(r.parentChildren).push(r);
11227
+ }
11228
+ const computeN = (baseNodeId, sampleNodeId) => {
11229
+ if (entryCountByBase.has(baseNodeId)) return entryCountByBase.get(baseNodeId);
11003
11230
  const countFromList = entryCountFromList(baseNodeId);
11004
- const countFromState = countFromList ?? (repeatableEntryCounts == null ? void 0 : repeatableEntryCounts[baseNodeId]) ?? (repeatableEntryCounts == null ? void 0 : repeatableEntryCounts[node.id]) ?? repeatableEntryCounts;
11231
+ const countFromState = countFromList ?? (repeatableEntryCounts == null ? void 0 : repeatableEntryCounts[baseNodeId]) ?? (repeatableEntryCounts == null ? void 0 : repeatableEntryCounts[sampleNodeId]) ?? repeatableEntryCounts;
11005
11232
  const N = Math.max(1, countFromState ?? getRepeatableEntryCount(baseNodeId, formValues));
11006
- const clones = [];
11007
- for (let i = 1; i <= N; i++) {
11008
- const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${baseNodeId}_e${i}`);
11009
- delete clone.repeatableSection;
11010
- clones.push(clone);
11011
- const newToOriginal = /* @__PURE__ */ new Map();
11012
- for (const [oldId, newId] of oldToNew) {
11013
- resolvedIdMap.set(`${baseNodeId}_${i}_${oldId}`, newId);
11014
- newToOriginal.set(newId, oldId);
11015
- const fieldId = elementIdToFieldId.get(oldId);
11016
- if (fieldId) resolvedIdMap.set(`${baseNodeId}_${i}_${fieldId}`, newId);
11017
- mappedNewIds.add(newId);
11018
- }
11019
- phase1NewToOriginal.set(`${baseNodeId}_${i}`, newToOriginal);
11020
- }
11021
- parentChildren.splice(startIndex, count, ...clones);
11233
+ entryCountByBase.set(baseNodeId, N);
11234
+ return N;
11235
+ };
11236
+ const occurrenceIndexByBase = /* @__PURE__ */ new Map();
11237
+ for (const r of topLevel) {
11238
+ const idx = (occurrenceIndexByBase.get(r.baseNodeId) ?? 0) + 1;
11239
+ occurrenceIndexByBase.set(r.baseNodeId, idx);
11240
+ r.__occurrenceIndex = idx;
11241
+ }
11242
+ for (const [parentChildren, blocks] of occByParent) {
11243
+ const sorted = [...blocks].sort((a, b) => b.startIndex - a.startIndex);
11244
+ for (const block of sorted) {
11245
+ const { node, baseNodeId, startIndex, count } = block;
11246
+ const occIdx = block.__occurrenceIndex ?? 1;
11247
+ const N = computeN(baseNodeId, node.id);
11248
+ const entryFilter = ((_b = node.repeatableSection) == null ? void 0 : _b.entryFilter) ?? entryFilterFromList(baseNodeId);
11249
+ let entryIndices;
11250
+ if (entryFilter && entryFilter.mode === "range" && entryFilter.range) {
11251
+ const parsed = parseEntryRange(entryFilter.range, N);
11252
+ entryIndices = parsed && parsed.length ? parsed : Array.from({ length: N }, (_, k) => k + 1);
11253
+ } else {
11254
+ entryIndices = Array.from({ length: N }, (_, k) => k + 1);
11255
+ }
11256
+ const clones = [];
11257
+ for (const i of entryIndices) {
11258
+ const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${baseNodeId}_o${occIdx}_e${i}`);
11259
+ clone.__repeatableEntryIndex = i;
11260
+ delete clone.repeatableSection;
11261
+ clones.push(clone);
11262
+ const newToOriginal = /* @__PURE__ */ new Map();
11263
+ for (const [oldId, newId] of oldToNew) {
11264
+ addResolved(`${baseNodeId}_${i}_${oldId}`, newId);
11265
+ newToOriginal.set(newId, oldId);
11266
+ const fieldId = elementIdToFieldId.get(oldId);
11267
+ if (fieldId) {
11268
+ for (const alias of getFieldKeyAliases(fieldId)) addResolved(`${baseNodeId}_${i}_${alias}`, newId);
11269
+ }
11270
+ mappedNewIds.add(newId);
11271
+ }
11272
+ phase1NewToOriginal.set(`${baseNodeId}_${i}`, newToOriginal);
11273
+ }
11274
+ parentChildren.splice(startIndex, count, ...clones);
11275
+ }
11022
11276
  }
11023
11277
  if (nestedChildToParent.size > 0) {
11024
11278
  const repeatableInfosSecond = findRepeatableByNodeIds(pages, nodeIds);
@@ -11031,25 +11285,41 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11031
11285
  for (const [childBaseNodeId, blocks] of byChildBase) {
11032
11286
  const parentBaseNodeId = nestedChildToParent.get(childBaseNodeId);
11033
11287
  blocks.forEach((block, parentIndex0) => {
11034
- const parentIndex1Based = parentIndex0 + 1;
11288
+ var _a2;
11289
+ const parentIndex1Based = block.parentEntryIndex ?? parentIndex0 + 1;
11035
11290
  const { parentChildren, startIndex, count, node, baseNodeId } = block;
11036
- const nestedKey = `${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}`;
11037
- const N = Math.max(
11038
- 1,
11039
- (repeatableNestedEntryCounts == null ? void 0 : repeatableNestedEntryCounts[nestedKey]) ?? getNestedRepeatableEntryCount(parentBaseNodeId, parentIndex1Based, baseNodeId, formValues)
11040
- );
11291
+ const N = getNestedCountForBasePair(parentBaseNodeId, parentIndex1Based, baseNodeId);
11041
11292
  const phase1Map = phase1NewToOriginal.get(`${parentBaseNodeId}_${parentIndex1Based}`);
11293
+ const nestedEntryFilter = ((_a2 = node.repeatableSection) == null ? void 0 : _a2.entryFilter) ?? entryFilterFromList(baseNodeId);
11294
+ let nestedEntryIndices;
11295
+ if (nestedEntryFilter && nestedEntryFilter.mode === "range" && nestedEntryFilter.range) {
11296
+ const parsed = parseEntryRange(nestedEntryFilter.range, N);
11297
+ nestedEntryIndices = parsed && parsed.length ? parsed : Array.from({ length: N }, (_, k) => k + 1);
11298
+ } else {
11299
+ nestedEntryIndices = Array.from({ length: N }, (_, k) => k + 1);
11300
+ }
11042
11301
  const clones = [];
11043
- for (let i = 1; i <= N; i++) {
11302
+ for (const i of nestedEntryIndices) {
11044
11303
  const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${parentBaseNodeId}_p${parentIndex1Based}_${baseNodeId}_e${i}`);
11045
11304
  delete clone.repeatableSection;
11046
11305
  clones.push(clone);
11047
11306
  for (const [oldId, newId] of oldToNew) {
11048
11307
  const originalId = (phase1Map == null ? void 0 : phase1Map.get(oldId)) ?? oldId;
11049
- resolvedIdMap.set(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${originalId}`, newId);
11050
- resolvedIdMap.set(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${oldId}`, newId);
11308
+ addResolved(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${originalId}`, newId);
11309
+ addResolved(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${oldId}`, newId);
11310
+ for (const { parentBaseId, childBaseId } of getNestedBasePairs(parentBaseNodeId, baseNodeId)) {
11311
+ addResolved(`${parentBaseId}_${parentIndex1Based}_${childBaseId}_${i}_${originalId}`, newId);
11312
+ addResolved(`${parentBaseId}_${parentIndex1Based}_${childBaseId}_${i}_${oldId}`, newId);
11313
+ }
11051
11314
  const fieldId = elementIdToFieldId.get(originalId) ?? elementIdToFieldId.get(oldId);
11052
- if (fieldId) resolvedIdMap.set(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${fieldId}`, newId);
11315
+ if (fieldId) {
11316
+ for (const alias of getFieldKeyAliases(fieldId)) {
11317
+ addResolved(`${parentBaseNodeId}_${parentIndex1Based}_${baseNodeId}_${i}_${alias}`, newId);
11318
+ for (const { parentBaseId, childBaseId } of getNestedBasePairs(parentBaseNodeId, baseNodeId)) {
11319
+ addResolved(`${parentBaseId}_${parentIndex1Based}_${childBaseId}_${i}_${alias}`, newId);
11320
+ }
11321
+ }
11322
+ }
11053
11323
  mappedNewIds.add(newId);
11054
11324
  }
11055
11325
  }
@@ -11057,7 +11327,9 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11057
11327
  });
11058
11328
  }
11059
11329
  }
11060
- cloned.__cloneIdMap = Object.fromEntries(resolvedIdMap);
11330
+ cloned.__cloneIdMap = Object.fromEntries(
11331
+ Array.from(resolvedIdMap.entries()).map(([k, v]) => [k, v.length === 1 ? v[0] : v])
11332
+ );
11061
11333
  cloned.__mappedElementIds = Array.from(mappedNewIds);
11062
11334
  const fieldLabelByKey = /* @__PURE__ */ new Map();
11063
11335
  const fieldTypeByKey = /* @__PURE__ */ new Map();
@@ -11200,10 +11472,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11200
11472
  }
11201
11473
  const byId = dynamicFields.find((f) => f.id === fieldId);
11202
11474
  if (byId) return byId;
11203
- const byElementId = dynamicFields.find((f) => {
11204
- var _a2, _b2;
11205
- return ((_b2 = (_a2 = f.mappings) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.elementId) === fieldId;
11206
- });
11475
+ const byElementId = dynamicFields.find((f) => (f.mappings ?? []).some((m) => (m == null ? void 0 : m.elementId) === fieldId));
11207
11476
  if (byElementId) return byElementId;
11208
11477
  const suffixMatch = dynamicFields.find((f) => {
11209
11478
  if (f.id.endsWith(`_N_${fieldId}`)) return true;
@@ -11219,39 +11488,36 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11219
11488
  const [, parentId, parentIndexStr, childId, childIndexStr, fieldId] = nestedMatch;
11220
11489
  const value = formValues[key];
11221
11490
  const field = getFieldForRepeatableKey(fieldId, key);
11222
- const mapping = (_d = field == null ? void 0 : field.mappings) == null ? void 0 : _d[0];
11223
- if (!mapping) continue;
11224
- const oldElementId = mapping.elementId;
11225
- const mapKeyByElement = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${oldElementId}`;
11226
- const mapKeyByField = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${fieldId}`;
11227
- let elementId = resolvedIdMap.get(mapKeyByElement) ?? resolvedIdMap.get(mapKeyByField);
11228
- if (!elementId) {
11229
- const mapKeyByElementBase = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${baseId(oldElementId)}`;
11230
- elementId = resolvedIdMap.get(mapKeyByElementBase);
11231
- }
11232
- if (!elementId) {
11233
- elementId = findNestedRepeatableElementBySourceId(
11234
- pages,
11235
- baseId(parentId),
11236
- parseInt(parentIndexStr, 10),
11237
- baseId(childId),
11238
- parseInt(childIndexStr, 10),
11239
- oldElementId
11240
- );
11241
- }
11242
- if (!elementId) {
11243
- elementId = findNestedRepeatableElementBySourceId(
11244
- pages,
11245
- baseId(parentId),
11246
- parseInt(parentIndexStr, 10),
11247
- baseId(childId),
11248
- parseInt(childIndexStr, 10),
11249
- baseId(oldElementId)
11250
- );
11491
+ for (const mapping of (field == null ? void 0 : field.mappings) ?? []) {
11492
+ const oldElementId = mapping.elementId;
11493
+ const mapKeyByElement = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${oldElementId}`;
11494
+ let elementIds = resolvedIdMap.get(mapKeyByElement);
11495
+ if (!elementIds || elementIds.length === 0) {
11496
+ const mapKeyByElementBase = `${baseId(parentId)}_${parentIndexStr}_${baseId(childId)}_${childIndexStr}_${baseId(oldElementId)}`;
11497
+ elementIds = resolvedIdMap.get(mapKeyByElementBase);
11498
+ }
11499
+ if (!elementIds || elementIds.length === 0) {
11500
+ const fallback = findNestedRepeatableElementBySourceId(
11501
+ pages,
11502
+ baseId(parentId),
11503
+ parseInt(parentIndexStr, 10),
11504
+ baseId(childId),
11505
+ parseInt(childIndexStr, 10),
11506
+ oldElementId
11507
+ ) ?? findNestedRepeatableElementBySourceId(
11508
+ pages,
11509
+ baseId(parentId),
11510
+ parseInt(parentIndexStr, 10),
11511
+ baseId(childId),
11512
+ parseInt(childIndexStr, 10),
11513
+ baseId(oldElementId)
11514
+ );
11515
+ if (fallback) elementIds = [fallback];
11516
+ }
11517
+ if (!elementIds || elementIds.length === 0) continue;
11518
+ const targetProperty = mapping.targetProperty || "text";
11519
+ for (const elementId of elementIds) applyValue(elementId, targetProperty, value, key);
11251
11520
  }
11252
- if (!elementId) continue;
11253
- const targetProperty = mapping.targetProperty || "text";
11254
- applyValue(elementId, targetProperty, value, key);
11255
11521
  }
11256
11522
  }
11257
11523
  }
@@ -11274,18 +11540,29 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11274
11540
  const [, nodeId, indexStr, fieldId] = match;
11275
11541
  const value = formValues[key];
11276
11542
  const field = getFieldForRepeatableKey(fieldId);
11277
- const mapping = (_e = field == null ? void 0 : field.mappings) == null ? void 0 : _e[0];
11278
- if (!mapping) continue;
11279
- const oldElementId = mapping.elementId;
11280
- const mapKeyByElement = `${baseId(nodeId)}_${indexStr}_${oldElementId}`;
11281
- const mapKeyByField = `${baseId(nodeId)}_${indexStr}_${fieldId}`;
11282
- let elementId = resolvedIdMap.get(mapKeyByElement) ?? resolvedIdMap.get(mapKeyByField);
11283
- if (!elementId) {
11284
- elementId = findRepeatableElementBySourceId(pages, baseId(nodeId), parseInt(indexStr, 10), oldElementId);
11543
+ for (const mapping of (field == null ? void 0 : field.mappings) ?? []) {
11544
+ const oldElementId = mapping.elementId;
11545
+ const elementIds = /* @__PURE__ */ new Set();
11546
+ for (const candidateBaseId of getRepeatableBaseIdsForToken(nodeId)) {
11547
+ const mapKeyByElement = `${candidateBaseId}_${indexStr}_${oldElementId}`;
11548
+ const foundByMap = resolvedIdMap.get(mapKeyByElement);
11549
+ for (const id of foundByMap ?? []) elementIds.add(id);
11550
+ if (!(foundByMap == null ? void 0 : foundByMap.length)) {
11551
+ const N = entryCountByBase.get(candidateBaseId);
11552
+ const found = findAllRepeatableElementsBySourceId(
11553
+ pages,
11554
+ candidateBaseId,
11555
+ parseInt(indexStr, 10),
11556
+ oldElementId,
11557
+ N
11558
+ );
11559
+ for (const id of found) elementIds.add(id);
11560
+ }
11561
+ }
11562
+ if (elementIds.size === 0) continue;
11563
+ const targetProperty = mapping.targetProperty || "text";
11564
+ for (const elementId of elementIds) applyValue(elementId, targetProperty, value, key);
11285
11565
  }
11286
- if (!elementId) continue;
11287
- const targetProperty = mapping.targetProperty || "text";
11288
- applyValue(elementId, targetProperty, value, key);
11289
11566
  }
11290
11567
  }
11291
11568
  const repeatableKeySet = new Set(
@@ -11338,7 +11615,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
11338
11615
  }
11339
11616
  }
11340
11617
  for (const page of pages) {
11341
- if ((_f = page.children) == null ? void 0 : _f.length) {
11618
+ if ((_c = page.children) == null ? void 0 : _c.length) {
11342
11619
  page.children = applyStackReflowToPageTree(page.children);
11343
11620
  }
11344
11621
  }
@@ -12296,7 +12573,8 @@ function applyThemeVariantToConfig(config, themeConfig, themeId) {
12296
12573
  const cloneIdMap = config.__cloneIdMap || {};
12297
12574
  const pageElements = result.pages.map((page) => flattenAll(page.children || []));
12298
12575
  for (const prop of themeConfig.properties) {
12299
- const value = variant ? (_d = variant.values) == null ? void 0 : _d[prop.id] : prop.defaultValue;
12576
+ const lookupId = prop.linkedTo || prop.id;
12577
+ const value = variant ? (_d = variant.values) == null ? void 0 : _d[lookupId] : prop.defaultValue;
12300
12578
  if (value === void 0) continue;
12301
12579
  if (prop.targetProperty === "backgroundColor" && prop.elementId === "__pageBackground__") {
12302
12580
  result.pages.forEach((p) => {
@@ -14115,6 +14393,7 @@ async function fetchTTFAsBase64(url) {
14115
14393
  if (!res.ok) return null;
14116
14394
  const buf = await res.arrayBuffer();
14117
14395
  const bytes = new Uint8Array(buf);
14396
+ if (!isJsPdfEmbeddableTrueType(bytes)) return null;
14118
14397
  let binary = "";
14119
14398
  for (let i = 0; i < bytes.length; i++) {
14120
14399
  binary += String.fromCharCode(bytes[i]);
@@ -14126,6 +14405,33 @@ async function fetchTTFAsBase64(url) {
14126
14405
  return null;
14127
14406
  }
14128
14407
  }
14408
+ function isJsPdfEmbeddableTrueType(bytes) {
14409
+ if (bytes.length < 12) return false;
14410
+ const signature = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3]);
14411
+ if (signature !== "\0\0\0" && signature !== "true") return false;
14412
+ const u16 = (offset) => bytes[offset] << 8 | bytes[offset + 1];
14413
+ const u32 = (offset) => (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
14414
+ const tableCount = u16(4);
14415
+ for (let i = 0; i < tableCount; i++) {
14416
+ const recordOffset = 12 + i * 16;
14417
+ if (recordOffset + 16 > bytes.length) return false;
14418
+ const tag = String.fromCharCode(bytes[recordOffset], bytes[recordOffset + 1], bytes[recordOffset + 2], bytes[recordOffset + 3]);
14419
+ if (tag !== "cmap") continue;
14420
+ const cmapOffset = u32(recordOffset + 8);
14421
+ const cmapLength = u32(recordOffset + 12);
14422
+ if (cmapOffset + Math.min(cmapLength, 4) > bytes.length) return false;
14423
+ const subtables = u16(cmapOffset + 2);
14424
+ for (let j = 0; j < subtables; j++) {
14425
+ const encOffset = cmapOffset + 4 + j * 8;
14426
+ if (encOffset + 8 > bytes.length) return false;
14427
+ const platform = u16(encOffset);
14428
+ const encoding = u16(encOffset + 2);
14429
+ if (platform === 0 || platform === 3 && (encoding === 1 || encoding === 10)) return true;
14430
+ }
14431
+ return false;
14432
+ }
14433
+ return false;
14434
+ }
14129
14435
  async function embedFont(pdf, fontName, weight, fontBaseUrl, isItalic = false) {
14130
14436
  const fontFiles = FONT_FILES[fontName];
14131
14437
  if (!fontFiles) return false;
@@ -15833,7 +16139,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
15833
16139
  }
15834
16140
  if (shouldOutlineText) {
15835
16141
  try {
15836
- const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-DHAXuVMF.cjs"));
16142
+ const { convertAllTextToPath } = await Promise.resolve().then(() => require("./svgTextToPath-CBcIgtk1.cjs"));
15837
16143
  pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
15838
16144
  try {
15839
16145
  dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");