@ohhwells/bridge 0.1.140 → 0.1.141

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.js CHANGED
@@ -5204,19 +5204,21 @@ function findIndexSegment(keys) {
5204
5204
  if (len < 2 || tokenLists.some((t) => t.length !== len)) return null;
5205
5205
  let position = -1;
5206
5206
  for (let p = 0; p < len; p++) {
5207
- const values = tokenLists.map((t) => t[p]);
5208
- const allSame = values.every((v) => v === values[0]);
5207
+ const values2 = tokenLists.map((t) => t[p]);
5208
+ const allSame = values2.every((v) => v === values2[0]);
5209
5209
  if (allSame) continue;
5210
- const allNumeric = values.every((v) => /^\d+$/.test(v));
5211
- if (!allNumeric || position !== -1) return null;
5210
+ if (position !== -1) return null;
5212
5211
  position = p;
5213
5212
  }
5214
5213
  if (position === -1) return null;
5214
+ const values = tokenLists.map((t) => t[position]);
5215
+ const numericCount = values.filter((v) => /^\d+$/.test(v)).length;
5216
+ if (numericCount !== 0 && numericCount !== values.length) return null;
5217
+ if (numericCount === 0 && position === len - 1) return null;
5215
5218
  const group = tokenLists[0].slice(0, position).join("-");
5216
5219
  if (!group) return null;
5217
- const indices = tokenLists.map((t) => parseInt(t[position], 10));
5218
- if (new Set(indices).size !== indices.length) return null;
5219
- return { position, group };
5220
+ if (new Set(values).size !== values.length) return null;
5221
+ return numericCount === values.length ? { position, group } : { position, group, slug: true };
5220
5222
  }
5221
5223
  function singleIndexSegment(key) {
5222
5224
  const tokens = baseKey(key).split("-");
@@ -5262,7 +5264,19 @@ function detectItemGroups(sectionEl) {
5262
5264
  list.push(m);
5263
5265
  byShape.set(shape, list);
5264
5266
  }
5265
- clusters.push(...Array.from(byShape.values()));
5267
+ const shaped = Array.from(byShape.values());
5268
+ clusters.push(...shaped.filter((c) => c.length >= 2));
5269
+ const singles = shaped.filter((c) => c.length === 1).map((c) => c[0]);
5270
+ const bySlugShape = /* @__PURE__ */ new Map();
5271
+ for (const m of singles) {
5272
+ const primary = primaryKey(keyedDescendants(m));
5273
+ const tokens = baseKey(primary ?? "").split("-");
5274
+ const slugShape = `${tokens.length}|${tokens[0]}|${tokens[tokens.length - 1]}`;
5275
+ const list = bySlugShape.get(slugShape) ?? [];
5276
+ list.push(m);
5277
+ bySlugShape.set(slugShape, list);
5278
+ }
5279
+ clusters.push(...Array.from(bySlugShape.values()));
5266
5280
  }
5267
5281
  for (const members of clusters) {
5268
5282
  const keyedPerMember = members.map((m) => keyedDescendants(m));
@@ -5273,11 +5287,28 @@ function detectItemGroups(sectionEl) {
5273
5287
  const dedupeKey = `${segment.group}`;
5274
5288
  if (seenParents.has(dedupeKey)) continue;
5275
5289
  seenParents.add(dedupeKey);
5276
- const items = members.map((el, i) => ({
5277
- el,
5278
- index: indexFromKey(primaries[i], segment.position),
5279
- keyed: keyedPerMember[i]
5280
- }));
5290
+ let items;
5291
+ if (segment.slug) {
5292
+ const tokens = members.map((_, i) => baseKey(primaries[i]).split("-")[segment.position]);
5293
+ let nextOriginal = 1;
5294
+ const indices = tokens.map((t) => {
5295
+ const cloneMatch = t.match(/^x(\d+)$/);
5296
+ return cloneMatch ? parseInt(cloneMatch[1], 10) : nextOriginal++;
5297
+ });
5298
+ if (new Set(indices).size !== indices.length) continue;
5299
+ items = members.map((el, i) => ({
5300
+ el,
5301
+ index: indices[i],
5302
+ keyed: keyedPerMember[i],
5303
+ slugToken: tokens[i]
5304
+ }));
5305
+ } else {
5306
+ items = members.map((el, i) => ({
5307
+ el,
5308
+ index: indexFromKey(primaries[i], segment.position),
5309
+ keyed: keyedPerMember[i]
5310
+ }));
5311
+ }
5281
5312
  groups.push({ group: segment.group, parent, nested: false, items });
5282
5313
  }
5283
5314
  }
@@ -5401,6 +5432,18 @@ function rekeyItemClone(clone, source, sibling, group, newIndex) {
5401
5432
  const delta = newIndex - source.index;
5402
5433
  const cloneKeyed = keyedDescendants(clone);
5403
5434
  const pairs = [];
5435
+ if (source.slugToken) {
5436
+ source.keyed.forEach((src, i) => {
5437
+ const target = cloneKeyed[i];
5438
+ if (!target || target.attr !== src.attr) return;
5439
+ const tokens = baseKey(src.key).split("-");
5440
+ if (!tokens.includes(source.slugToken)) return;
5441
+ const next = tokens.map((t) => t === source.slugToken ? `x${newIndex}` : t).join("-") + keySuffix(src.key);
5442
+ target.el.setAttribute(src.attr, next);
5443
+ pairs.push({ from: src.key, to: next });
5444
+ });
5445
+ return pairs;
5446
+ }
5404
5447
  source.keyed.forEach((src, i) => {
5405
5448
  const target = cloneKeyed[i];
5406
5449
  if (!target || target.attr !== src.attr) return;
@@ -5444,7 +5487,12 @@ function syncGroup(detected, state) {
5444
5487
  clone.setAttribute(ITEM_ATTR, `${detected.group}:${entry.index}`);
5445
5488
  rekeyItemClone(clone, source, sibling, detected.group, entry.index);
5446
5489
  source.el.insertAdjacentElement("afterend", clone);
5447
- byIndex.set(entry.index, { el: clone, index: entry.index, keyed: keyedDescendants(clone) });
5490
+ byIndex.set(entry.index, {
5491
+ el: clone,
5492
+ index: entry.index,
5493
+ keyed: keyedDescendants(clone),
5494
+ ...source.slugToken ? { slugToken: `x${entry.index}` } : {}
5495
+ });
5448
5496
  }
5449
5497
  const listed = state.items.map((e) => byIndex.get(e.index)?.el).filter((el) => !!el);
5450
5498
  let prev = null;
@@ -5546,9 +5594,16 @@ function applyItemOps(store, ops, currentContent) {
5546
5594
  const nodes = [];
5547
5595
  const added = [];
5548
5596
  let elements = syncGroup(detected, state);
5597
+ const sluggy = detected.items.some((item) => item.slugToken);
5598
+ const slugTokenOf = (index) => detected.items.find((item) => item.index === index)?.slugToken ?? (sluggy ? `x${index}` : void 0);
5549
5599
  for (const add of ops.add ?? []) {
5550
5600
  const sourceEl = elements.get(add.cloneOf);
5551
- const source = sourceEl ? { el: sourceEl, index: add.cloneOf, keyed: keyedDescendants(sourceEl) } : void 0;
5601
+ const source = sourceEl ? {
5602
+ el: sourceEl,
5603
+ index: add.cloneOf,
5604
+ keyed: keyedDescendants(sourceEl),
5605
+ ...slugTokenOf(add.cloneOf) ? { slugToken: slugTokenOf(add.cloneOf) } : {}
5606
+ } : void 0;
5552
5607
  if (!source) continue;
5553
5608
  const newIndex = Math.max(...state.items.map((e) => e.index), ...detected.items.map((i) => i.index)) + 1;
5554
5609
  const sibling = detected.items.find((item) => item.index !== add.cloneOf && !item.el.hasAttribute(ITEM_CLONE_ATTR)) ?? null;
@@ -5575,7 +5630,12 @@ function applyItemOps(store, ops, currentContent) {
5575
5630
  if (anchor) anchor.insertAdjacentElement("afterend", clone);
5576
5631
  else source.el.insertAdjacentElement("afterend", clone);
5577
5632
  elements.set(newIndex, clone);
5578
- detected.items.push({ el: clone, index: newIndex, keyed: cloneKeyed });
5633
+ detected.items.push({
5634
+ el: clone,
5635
+ index: newIndex,
5636
+ keyed: cloneKeyed,
5637
+ ...sluggy ? { slugToken: `x${newIndex}` } : {}
5638
+ });
5579
5639
  added.push(newIndex);
5580
5640
  elements = syncGroup(detected, state);
5581
5641
  }
@@ -6018,16 +6078,25 @@ function foldAlignIntoTrees(state, store) {
6018
6078
  nextTrees.set(id, fresh);
6019
6079
  return fresh;
6020
6080
  };
6081
+ const stripChildAligns = (node) => node.children ? {
6082
+ ...node,
6083
+ children: node.children.map((child) => {
6084
+ const { align: _dropped, ...rest } = child;
6085
+ return stripChildAligns(rest);
6086
+ })
6087
+ } : node;
6021
6088
  const nodes = {};
6022
6089
  for (const [key, override] of Object.entries(store.nodes)) {
6023
6090
  const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
6024
6091
  const tree = match ? treeFor(match[1]) : void 0;
6025
- const block = match && tree ? tree.rows[Number(match[2])]?.blocks[Number(match[3])] : void 0;
6026
- if (!block) {
6092
+ const row = match && tree ? tree.rows[Number(match[2])] : void 0;
6093
+ const blockIdx = match ? Number(match[3]) : -1;
6094
+ const block = row?.blocks[blockIdx];
6095
+ if (!row || !block) {
6027
6096
  nodes[key] = override;
6028
6097
  continue;
6029
6098
  }
6030
- block.align = override.align;
6099
+ row.blocks[blockIdx] = { ...stripChildAligns(block), align: override.align };
6031
6100
  const rest = { ...override };
6032
6101
  delete rest.align;
6033
6102
  if (Object.keys(rest).length > 0) nodes[key] = rest;
@@ -6040,7 +6109,7 @@ function foldAlignIntoTrees(state, store) {
6040
6109
  continue;
6041
6110
  }
6042
6111
  for (const row of tree.rows) {
6043
- for (const block of row.blocks) block.align = override.align;
6112
+ row.blocks = row.blocks.map((block) => ({ ...stripChildAligns(block), align: override.align }));
6044
6113
  }
6045
6114
  const rest = { ...override };
6046
6115
  delete rest.align;
@@ -7201,6 +7270,7 @@ var blockAlignStyle = (blockAlign) => blockAlign ? {
7201
7270
  alignItems: blockAlign === "left" ? "flex-start" : blockAlign === "right" ? "flex-end" : "center",
7202
7271
  textAlign: blockAlign
7203
7272
  } : {};
7273
+ var fullBleedBlock = (block) => block.type === "carousel" || block.type === "group" && str(block.slots?.layout) === "overlap";
7204
7274
  var featureLines = (value) => value.split(/\n|<br\s*\/?>/i).map((line) => line.trim()).filter(Boolean);
7205
7275
  var AI_MOBILE_CSS = [
7206
7276
  // Unscoped (applies at every viewport, not just mobile): re-enables pointer-events for the
@@ -9266,8 +9336,8 @@ function renderNode(node, ctx, path, ambientAlign) {
9266
9336
  // layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
9267
9337
  // scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
9268
9338
  // the full section width instead of reading at the usual content width.
9269
- /* @__PURE__ */ jsx("div", { style: { maxWidth: AI_TREE_TOKENS.sectionMaxWidth, margin: "0 auto", padding: "0 40px", width: "100%", boxSizing: "border-box" }, children: renderNode(child, ctx, `${path}.c${i}`, child.align ?? "center") })
9270
- ) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? "center" : void 0),
9339
+ /* @__PURE__ */ jsx("div", { style: { maxWidth: AI_TREE_TOKENS.sectionMaxWidth, margin: "0 auto", padding: "0 40px", width: "100%", boxSizing: "border-box" }, children: renderNode(child, ctx, `${path}.c${i}`, child.align ?? node.align ?? "center") })
9340
+ ) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? node.align ?? "center" : void 0),
9271
9341
  i === 0 && needsBaseScrim && /* @__PURE__ */ jsx(
9272
9342
  "div",
9273
9343
  {
@@ -9300,7 +9370,7 @@ function renderNode(node, ctx, path, ambientAlign) {
9300
9370
  // child otherwise stretches full-width (unchanged pre-existing behaviour).
9301
9371
  ...blockAlignStyle(child.align ?? ambientAlign)
9302
9372
  },
9303
- children: renderNode(child, ctx, `${path}.c${i}`, ambientAlign)
9373
+ children: renderNode(child, ctx, `${path}.c${i}`, node.align ?? ambientAlign)
9304
9374
  },
9305
9375
  i
9306
9376
  ));
@@ -9330,8 +9400,20 @@ function renderNode(node, ctx, path, ambientAlign) {
9330
9400
  }
9331
9401
  case "button":
9332
9402
  return /* @__PURE__ */ jsx(ButtonEl, { slots, ctx, path });
9333
- case "button-row":
9334
- return /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: AI_TREE_TOKENS.spacing6, justifyContent: "center" }, children: (node.children ?? []).map((child, i) => /* @__PURE__ */ jsx(ButtonEl, { slots: child.slots ?? {}, ctx, path: `${path}.c${i}` }, i)) });
9403
+ case "button-row": {
9404
+ const rowAlign = node.align ?? ambientAlign;
9405
+ return /* @__PURE__ */ jsx(
9406
+ "div",
9407
+ {
9408
+ style: {
9409
+ display: "flex",
9410
+ gap: AI_TREE_TOKENS.spacing6,
9411
+ justifyContent: rowAlign === "left" ? "flex-start" : rowAlign === "right" ? "flex-end" : "center"
9412
+ },
9413
+ children: (node.children ?? []).map((child, i) => /* @__PURE__ */ jsx(ButtonEl, { slots: child.slots ?? {}, ctx, path: `${path}.c${i}` }, i))
9414
+ }
9415
+ );
9416
+ }
9335
9417
  case "media":
9336
9418
  return /* @__PURE__ */ jsx(
9337
9419
  MediaBox,
@@ -9710,7 +9792,7 @@ function AiTreeRenderer({
9710
9792
  // its own horizontal `align`, which takes priority for that block.
9711
9793
  ...fillHeight ? { display: "grid" } : {},
9712
9794
  // Horizontal placement of the block's content within its column.
9713
- ...cellAlignStyle(block.align),
9795
+ ...fullBleedBlock(block) ? {} : cellAlignStyle(block.align),
9714
9796
  // space-between: each column becomes a flex column whose content spreads over
9715
9797
  // the full row height instead of clumping at the top.
9716
9798
  ...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
@@ -18344,10 +18426,23 @@ function setPricingCardStyle(tree, index, style) {
18344
18426
  });
18345
18427
  }
18346
18428
  function setPricingCardFeaturedTag(tree, index, on) {
18347
- return withPricingCard(tree, index, (target) => {
18429
+ return withPricingCollection(tree, (collection) => {
18430
+ const children = collection.children;
18431
+ if (index < 0 || index >= children.length) return false;
18432
+ if (on) {
18433
+ children.forEach((card, i) => {
18434
+ if (i === index) return;
18435
+ const prev2 = featuredOf(card);
18436
+ if (prev2.enabled !== true || badgeOf(prev2).length === 0) return;
18437
+ card.slots = card.slots ?? {};
18438
+ card.slots.featured = composeFeatured(pricingCardStyleOf(prev2), false, badgeOf(prev2));
18439
+ });
18440
+ }
18441
+ const target = children[index];
18442
+ target.slots = target.slots ?? {};
18348
18443
  const prev = featuredOf(target);
18349
- const style = pricingCardStyleOf(prev);
18350
- target.slots.featured = composeFeatured(style, on, badgeOf(prev));
18444
+ target.slots.featured = composeFeatured(pricingCardStyleOf(prev), on, badgeOf(prev));
18445
+ return true;
18351
18446
  });
18352
18447
  }
18353
18448
  function pricingCardStyleOf(featured) {
@@ -18597,25 +18692,40 @@ function ToolbarSeparator() {
18597
18692
  }
18598
18693
  function CardStyleMenu({
18599
18694
  value,
18600
- onChange
18695
+ onChange,
18696
+ disabled = false
18601
18697
  }) {
18602
18698
  const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
18699
+ const trigger = /* @__PURE__ */ jsxs11(
18700
+ "button",
18701
+ {
18702
+ type: "button",
18703
+ "aria-label": "Card style",
18704
+ disabled,
18705
+ className: cn(
18706
+ "inline-flex h-8 min-w-[110px] items-center gap-[7px] rounded-[6px] bg-transparent px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted data-[state=open]:bg-muted",
18707
+ disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
18708
+ ),
18709
+ children: [
18710
+ /* @__PURE__ */ jsx20(StyleSwatch, { style: current.value }),
18711
+ /* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
18712
+ /* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
18713
+ ]
18714
+ }
18715
+ );
18716
+ if (disabled) {
18717
+ return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
18718
+ /* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
18719
+ /* @__PURE__ */ jsxs11(Tooltip, { children: [
18720
+ /* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20("span", { className: "inline-flex", children: trigger }) }),
18721
+ /* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
18722
+ ] })
18723
+ ] });
18724
+ }
18603
18725
  return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
18604
18726
  /* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
18605
18727
  /* @__PURE__ */ jsxs11(DropdownMenu, { modal: false, children: [
18606
- /* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(
18607
- "button",
18608
- {
18609
- type: "button",
18610
- "aria-label": "Card style",
18611
- className: "inline-flex h-8 min-w-[110px] items-center gap-[7px] rounded-[6px] bg-transparent px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted data-[state=open]:bg-muted",
18612
- children: [
18613
- /* @__PURE__ */ jsx20(StyleSwatch, { style: current.value }),
18614
- /* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
18615
- /* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
18616
- ]
18617
- }
18618
- ) }),
18728
+ /* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children: trigger }),
18619
18729
  /* @__PURE__ */ jsx20(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
18620
18730
  const selected = style.value === value;
18621
18731
  return /* @__PURE__ */ jsxs11(
@@ -18679,23 +18789,35 @@ function PricingCardToolbar({
18679
18789
  mobile ? "flex-wrap justify-center" : "flex-nowrap"
18680
18790
  ),
18681
18791
  children: [
18682
- /* @__PURE__ */ jsx20(CardStyleMenu, { value: style, onChange: onSetStyle }),
18683
18792
  /* @__PURE__ */ jsxs11(Tooltip, { children: [
18684
18793
  /* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
18685
18794
  CustomToolbarButton,
18686
18795
  {
18687
18796
  type: "button",
18688
- "aria-label": featuredTag ? "Remove featured tag" : "Add featured tag",
18797
+ "aria-label": featuredTag ? "Unmark as featured" : "Mark as featured",
18689
18798
  "aria-pressed": featuredTag,
18690
- active: featuredTag,
18691
18799
  onClick: () => onSetFeaturedTag(!featuredTag),
18692
- className: "size-8",
18693
- children: /* @__PURE__ */ jsx20(Star2, { size: 16, fill: featuredTag ? "currentColor" : "none", style: { pointerEvents: "none" } })
18800
+ className: "group size-8",
18801
+ children: /* @__PURE__ */ jsx20(
18802
+ Star2,
18803
+ {
18804
+ size: 16,
18805
+ fill: "currentColor",
18806
+ strokeWidth: 0,
18807
+ className: cn(
18808
+ "transition-colors",
18809
+ featuredTag ? "text-[#f59e0b] group-hover:text-[#d97706]" : "text-[#d6d3d1] group-hover:text-[#fbbf24]"
18810
+ ),
18811
+ style: { pointerEvents: "none" }
18812
+ }
18813
+ )
18694
18814
  }
18695
18815
  ) }),
18696
- /* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Remove featured tag" : "Add featured tag" })
18816
+ /* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
18697
18817
  ] }),
18698
18818
  /* @__PURE__ */ jsx20(ToolbarSeparator, {}),
18819
+ /* @__PURE__ */ jsx20(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
18820
+ /* @__PURE__ */ jsx20(ToolbarSeparator, {}),
18699
18821
  /* @__PURE__ */ jsx20(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ jsx20(ButtonGlyph, {}) }),
18700
18822
  /* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ jsxs11("span", { className: "relative inline-flex", children: [
18701
18823
  /* @__PURE__ */ jsx20(ButtonGlyph, {}),
@@ -18838,7 +18960,12 @@ function AiPricingCardOverlay({
18838
18960
  index: active.index,
18839
18961
  pending,
18840
18962
  error,
18841
- onAddTier: () => runMutation(active.sectionId, addPricingTier),
18963
+ onAddTier: () => {
18964
+ const newIndex = pricingCardCount(activeEntry.tree);
18965
+ void runMutation(active.sectionId, addPricingTier).then((applied) => {
18966
+ if (applied) setActive({ sectionId: active.sectionId, index: newIndex });
18967
+ });
18968
+ },
18842
18969
  onRemoveTier: () => {
18843
18970
  void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
18844
18971
  (applied) => {
@@ -30251,9 +30378,10 @@ function OhhwellsBridge() {
30251
30378
  if (e.data?.type !== "ow:collect-section") return;
30252
30379
  const sectionId = e.data.sectionId;
30253
30380
  if (typeof sectionId !== "string" || !sectionId) return;
30254
- const sectionEl = document.querySelector(
30381
+ const foundEl = document.querySelector(
30255
30382
  `[data-ohw-section="${CSS.escape(sectionId)}"]`
30256
30383
  );
30384
+ const sectionEl = foundEl && !foundEl.hasAttribute("data-ohw-ai-template-hidden") && !foundEl.hasAttribute("data-ohw-ai-removed") && !foundEl.hasAttribute("data-ohw-ai-replaced-by") ? foundEl : null;
30257
30385
  const nodes = sectionEl ? collectEditableNodes(void 0, sectionEl).filter(
30258
30386
  (n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "video-setting"].includes(n.type)
30259
30387
  ).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })) : [];
@@ -30992,7 +31120,7 @@ function OhhwellsBridge() {
30992
31120
  postToParent2({
30993
31121
  type: "ow:ready",
30994
31122
  version: "1",
30995
- bridgeVersion: "0.1.139",
31123
+ bridgeVersion: "0.1.140",
30996
31124
  path: pathname,
30997
31125
  nodes: collectEditableNodes(editContentRef.current),
30998
31126
  sections
@@ -32207,6 +32335,7 @@ export {
32207
32335
  dropIndicatorVariants,
32208
32336
  ensureFooterTree,
32209
32337
  filterAvailablePages,
32338
+ foldAlignIntoTrees,
32210
32339
  getEditModeInitialState,
32211
32340
  insertFooterHours,
32212
32341
  isEditSessionActive,
@@ -32215,6 +32344,7 @@ export {
32215
32344
  isValidUrl,
32216
32345
  nextViableSlide,
32217
32346
  parseAiFooterState,
32347
+ parseAiSectionsState,
32218
32348
  parseTarget,
32219
32349
  removeFooterBlock,
32220
32350
  resolveFooterCopyright,