@bettercms-ai/types 1.15.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
File without changes
package/dist/index.d.ts CHANGED
@@ -65,6 +65,15 @@ interface BlockStyle {
65
65
  paddingBottom?: number;
66
66
  paddingSides?: number;
67
67
  contentWidth?: ContentWidthToken;
68
+ /**
69
+ * Where the constrained content column sits, when `contentWidth` constrains it.
70
+ *
71
+ * Split out of `align`, which still means text alignment and is still the fallback when this
72
+ * is unset — so everything written before the split renders byte-identically. The two were one
73
+ * token until anything MEASURED a section's text alignment: copying a source site's
74
+ * `text-align: left` would otherwise also shove its column to the page edge.
75
+ */
76
+ contentAlign?: AlignToken;
68
77
  fullHeight?: boolean;
69
78
  /** 0–100. */
70
79
  opacity?: number;
@@ -217,6 +226,12 @@ interface VideoProps {
217
226
  poster?: string;
218
227
  autoplay?: boolean;
219
228
  loop?: boolean;
229
+ /**
230
+ * What is said in the video (CPO-093). The block carries its own because its url may be a
231
+ * pasted provider link with no library asset to hang one from. Rendered as <details> after
232
+ * the player and published in the .md twin.
233
+ */
234
+ transcript?: string;
220
235
  }
221
236
  interface VideoBlock {
222
237
  type: "video";
@@ -564,6 +579,206 @@ declare function componentInstanceAddresses(instanceBlockId: string, props: read
564
579
  /** A CSS declaration object (key → value) usable as a React `style` prop, or undefined when empty. */
565
580
  declare function blockStyleToCss(style: BlockStyle | undefined): Record<string, string | number> | undefined;
566
581
 
582
+ /**
583
+ * ContentModel — the structured content model (schema) for a workspace.
584
+ * Defines which content fields are available for authors to fill in.
585
+ */
586
+ interface ContentModel {
587
+ id: string;
588
+ workspaceId: string;
589
+ name: string;
590
+ description?: string;
591
+ /** 'block' models hold no entries — they are instantiable only inside a `modular` field. */
592
+ kind?: ContentModelKind;
593
+ fields: ContentModelField[];
594
+ /** Authoring-only field grouping for the schema builder. Never affects the API shape. */
595
+ fieldsets?: Fieldset[];
596
+ createdAt: string;
597
+ updatedAt: string;
598
+ }
599
+ /**
600
+ * Canonical field types. Nesting lives on `array` via `config.zones`
601
+ * (see {@link ArrayZoneConfig}): `group`/`repeater` are accepted as legacy input
602
+ * by the API but normalized to `array` + zones on write, so stored/delivered
603
+ * content never contains them.
604
+ */
605
+ type ContentModelFieldType = "text" | "richtext" | "document" | "image" | "boolean" | "number" | "select" | "reference" | "multi-reference" | "multiReference" | "array" | "date" | "datetime" | "longtext" | "slug" | "email" | "phone" | "link" | "color" | "json" | "file" | "component-ref" | "modular" | "sections" | "location";
606
+ type ContentModelKind = "model" | "block";
607
+ /** A named, UI-only grouping of a model's fields. Order is the array index. */
608
+ interface Fieldset {
609
+ id: string;
610
+ name: string;
611
+ /** One line shown under the card title in the editor. Editor-only. */
612
+ description?: string;
613
+ }
614
+ /**
615
+ * Nested-content config for an `array` field. A zone holds ordinary fields, and a
616
+ * zone field may itself be an `array` with its own zones, so nesting is recursive
617
+ * to any depth.
618
+ * - `nonRepeatable` — a single fixed block of fields (former `group`).
619
+ * - `repeatable` — a repeating list of field-objects (former `repeater`).
620
+ * Mutually exclusive with the primitive form (`config.itemType`).
621
+ */
622
+ interface ArrayZoneConfig {
623
+ nonRepeatable?: ContentModelField[];
624
+ repeatable?: {
625
+ fields: ContentModelField[];
626
+ minItems?: number;
627
+ maxItems?: number;
628
+ };
629
+ }
630
+ /** Per-type config for a field (the typed shape behind the loose `config` bag). */
631
+ interface FieldConfig {
632
+ /** primitive array: list of scalars */
633
+ itemType?: "text" | "number" | "date";
634
+ /** nested array: zoned fields (recursive) */
635
+ zones?: ArrayZoneConfig;
636
+ /** reference / multi-reference */
637
+ contentModelId?: string;
638
+ min?: number;
639
+ max?: number;
640
+ /** date / datetime */
641
+ includeTime?: boolean;
642
+ /** modular: SLUGS of the kind='block' models this field accepts. Non-empty. */
643
+ blockSlugs?: string[];
644
+ /** modular: bounds on how many block instances the field may hold. */
645
+ minItems?: number;
646
+ maxItems?: number;
647
+ /**
648
+ * sections: SLUGS of the sections an author may insert into this zone.
649
+ *
650
+ * Deliberately NOT named `blockSlugs`. That key means "kind='block' content models" and is
651
+ * read by ModularField; these are section-registry slugs resolved from a different place.
652
+ * One key meaning two things is how `blockModels`/`blockSlugs` already drifted apart in the
653
+ * dashboard — a distinct name costs nothing and cannot be confused at a call site.
654
+ *
655
+ * ⚠ ABSENT ≠ EMPTY:
656
+ * absent → UNRESTRICTED, every registry section may be inserted
657
+ * [] → DENY ALL, a deliberate empty restriction
658
+ * [a, b] → only those
659
+ * `[]` means DENY here to match `components.allowed_on` (migration 0190), so two adjacent
660
+ * allow-lists never disagree about what empty means.
661
+ *
662
+ * Absent rather than "all current slugs" because the registry GROWS — it is fed by repo
663
+ * pushes and project components, so materializing today's slugs at field-creation time would
664
+ * silently exclude every section shipped afterwards.
665
+ *
666
+ * NOT READ DIRECTLY. Insertability is this list INTERSECTED with the component's `allowedOn`
667
+ * (where that section may be placed), computed by one resolver so the two cannot drift.
668
+ *
669
+ * Enforced on NEW picks only. Narrowing the list later must never invalidate sections an
670
+ * author already placed, the same rule modular's blockSlugs and component-ref's allowlist
671
+ * follow.
672
+ */
673
+ allowedSections?: string[];
674
+ /** Durable project-local authored Zone mode. Legacy zones omit this key. */
675
+ mode?: "authored-v2";
676
+ /** Durable Zone id. Present when `mode` is `authored-v2`. */
677
+ zoneId?: string;
678
+ /** Explicit migration acknowledgement while the legacy allowlist remains readable. */
679
+ legacyResolved?: boolean;
680
+ legacyMappings?: Record<string, string>;
681
+ [key: string]: unknown;
682
+ }
683
+ /**
684
+ * Where a field renders in the entry editor.
685
+ *
686
+ * AUTHORING ONLY — this has no delivery or storage effect. It does not change the
687
+ * shape of `data`, is not read by any renderer in @bettercms-ai/next or /astro, and
688
+ * cannot move a value onto or off a published page. It decides one thing: where the
689
+ * control sits while somebody is writing.
690
+ *
691
+ * Granularity is REGION-level, never interleaved between body blocks: the canvas is
692
+ * `[hero slots] → [free block flow] → [inline fields] → [panel fields in the drawer]`.
693
+ * A field cannot be positioned "between two paragraphs" — there is no coordinate space
694
+ * for that, and inventing one would mean mounting form controls inside the Lexical tree.
695
+ *
696
+ * - `cover` / `title` / `excerpt` / `body` — the four hero slots, rendered unlabelled
697
+ * and typographically native. SCHEMA-LEVEL ONLY: a per-entry override may never
698
+ * claim one, or one author's click renders anonymous 40px text over anonymous text
699
+ * on that entry alone.
700
+ * - `inline` — in the canvas, below the block flow, labelled.
701
+ * - `panel` — in the drawer.
702
+ *
703
+ * ABSENT is meaningful and is the default for every model that predates this: the
704
+ * editor falls back to its title-gated heuristic. Only an explicit value promotes a
705
+ * field past that gate.
706
+ */
707
+ type ContentModelFieldPlacement = "cover" | "title" | "excerpt" | "body" | "inline" | "panel";
708
+ interface ContentModelField {
709
+ key: string;
710
+ label: string;
711
+ type: ContentModelFieldType;
712
+ required?: boolean;
713
+ /**
714
+ * No two entries of the model may hold the same value (trimmed, case-insensitive). On a
715
+ * repeater child, every row of every entry at that path. Scalar types only.
716
+ */
717
+ unique?: boolean;
718
+ defaultValue?: unknown;
719
+ options?: string[];
720
+ /** Per-type config. For `array`: either `itemType` (primitive) or `zones` (nested). */
721
+ config?: FieldConfig | null;
722
+ /**
723
+ * Which fieldset this field renders under in the schema builder. Authoring-only: it is
724
+ * never delivered and cannot move a value — see {@link Fieldset}.
725
+ */
726
+ fieldsetId?: string;
727
+ /**
728
+ * Authoring-only editor placement. See {@link ContentModelFieldPlacement}.
729
+ * Field ORDER is the array index — there is deliberately no `order` property.
730
+ */
731
+ placement?: ContentModelFieldPlacement;
732
+ /**
733
+ * Authoring chrome — how the field PRESENTS in the editor. Never delivered, never read by a
734
+ * renderer, and never able to move a value; the same contract as {@link placement}.
735
+ *
736
+ * A SIBLING of `config`, not a member of it: `config` is per-type and strict on several
737
+ * types, and the normalizer rebuilds it wholesale for every nesting field — so a `config.ui`
738
+ * survives on leaves and vanishes on exactly the fields `preview` is for.
739
+ *
740
+ * `preview.title` / `preview.media` name a CHILD FIELD KEY of this field (validated on
741
+ * write). Still no `order`: order is the array index, per the note on {@link placement}.
742
+ */
743
+ ui?: ContentModelFieldUi;
744
+ }
745
+ /** @see ContentModelField.ui */
746
+ interface ContentModelFieldUi {
747
+ /** Start this nesting field's panel collapsed. Absent ≡ the editor's own default. */
748
+ collapsed?: boolean;
749
+ /** How one item of a nesting field summarises itself when collapsed. Keys, not values. */
750
+ preview?: {
751
+ /** Child field key whose value titles the row. */
752
+ title?: string;
753
+ /** Child field key whose value is the row's thumbnail. Type is not constrained. */
754
+ media?: string;
755
+ };
756
+ /**
757
+ * How the ITEMS of a nesting field are arranged. ABSENT ≡ `"list"` — every field stored
758
+ * before this key existed means `"list"`, so a reader must treat undefined as list and never
759
+ * as "unset, pick something".
760
+ *
761
+ * Same placement rule as {@link ContentModelFieldUi.preview}: nesting fields only.
762
+ */
763
+ layout?: "list" | "grid" | "table";
764
+ /**
765
+ * Whether the items of a list may be dragged. ABSENT ≡ `true`, for the same reason — nothing
766
+ * stored today carries it, and everything stored today is reorderable.
767
+ *
768
+ * `false` LOCKS the order: a "three steps" band, a semantic nav, a timeline. Valid only where
769
+ * there is a list (a repeatable zone, a `repeater`, or `modular`), so a reader that honours it
770
+ * must disable the sortable behaviour, not just hide the grip — a hidden grip still reorders
771
+ * from the keyboard.
772
+ */
773
+ reorderable?: boolean;
774
+ }
775
+ /**
776
+ * A field inside an array zone — identical to a top-level {@link ContentModelField}.
777
+ * Kept as a named alias so consumers can express "zone field" intent; recursion
778
+ * (an array zone field with its own `config.zones`) is supported.
779
+ */
780
+ type ZoneField = ContentModelField;
781
+
567
782
  /**
568
783
  * Generated from lucide-react@1.8.0 dynamic icon names.
569
784
  * Legacy CamelCase identifiers remain valid for existing Layout documents.
@@ -971,6 +1186,20 @@ interface ComponentPropDef {
971
1186
  */
972
1187
  type: "text" | "richtext" | "image" | "url" | "boolean" | "number" | "select" | "group" | "table" | "slot";
973
1188
  defaultValue?: unknown;
1189
+ /**
1190
+ * EDITOR HINTS (playbook §12). Stored in the props JSON, so no migration.
1191
+ *
1192
+ * 🔴 `required` IS NOT ENFORCED AT WRITE TIME, deliberately. Nothing on the write path
1193
+ * refuses an override that omits a required prop — a placement saves either way — because
1194
+ * the alternative is a component definition that can retroactively make already-saved pages
1195
+ * unsaveable. It is a marker the dashboard renders and `get_site_composition` counts, which
1196
+ * is the honest shape: the receipt names what is missing instead of the write refusing it.
1197
+ */
1198
+ required?: boolean;
1199
+ /** Hint shown under the control, muted. */
1200
+ helpText?: string;
1201
+ /** Ghost text inside a text-ish control. */
1202
+ placeholder?: string;
974
1203
  /** Per-type settings; the save schema enforces that each is present on the type needing it. */
975
1204
  config?: {
976
1205
  /** `slot` — a pick allowlist. */
@@ -984,6 +1213,19 @@ interface ComponentPropDef {
984
1213
  max?: number;
985
1214
  step?: number;
986
1215
  } & Record<string, unknown>;
1216
+ /**
1217
+ * AUTHORING CHROME — the same object a content-model FIELD carries ({@link ContentModelFieldUi}),
1218
+ * deliberately: an agent that has learned `ui` once has learned it on both lanes.
1219
+ *
1220
+ * A SIBLING of `config`, not a member of it. `config` is a loose bag, so a `config.ui` already
1221
+ * survived the write — and that is the problem this key fixes: surviving is not declared, and
1222
+ * an undeclared prop is a typo that saves cleanly and renders as nothing.
1223
+ *
1224
+ * WHERE EACH KEY IS LEGAL differs from the field lane, because the vocabulary does:
1225
+ * `preview`/`layout` on `group`, `table` and `slot`; `reorderable` on `table` ALONE, the only
1226
+ * prop type whose value is a list. The save schema refuses the rest with the valid set named.
1227
+ */
1228
+ ui?: ContentModelFieldUi;
987
1229
  }
988
1230
  /** One field inside a `group` prop or a `table` row. Recursive, capped at 3 levels deep. */
989
1231
  interface ComponentSubField {
@@ -992,6 +1234,10 @@ interface ComponentSubField {
992
1234
  /** No `slot`: a nested component instance belongs on the prop itself, not inside a row. */
993
1235
  type: Exclude<ComponentPropDef["type"], "slot">;
994
1236
  defaultValue?: unknown;
1237
+ /** The same editor hints as the prop above, one level down. @see ComponentPropDef */
1238
+ required?: boolean;
1239
+ helpText?: string;
1240
+ placeholder?: string;
995
1241
  options?: string[];
996
1242
  /** CANONICAL. A nested `group`/`table`'s own sub-shape. */
997
1243
  fields?: ComponentSubField[];
@@ -1106,157 +1352,6 @@ interface ContentEntry {
1106
1352
  updatedAt: string;
1107
1353
  }
1108
1354
 
1109
- /**
1110
- * ContentModel — the structured content model (schema) for a workspace.
1111
- * Defines which content fields are available for authors to fill in.
1112
- */
1113
- interface ContentModel {
1114
- id: string;
1115
- workspaceId: string;
1116
- name: string;
1117
- description?: string;
1118
- /** 'block' models hold no entries — they are instantiable only inside a `modular` field. */
1119
- kind?: ContentModelKind;
1120
- fields: ContentModelField[];
1121
- /** Authoring-only field grouping for the schema builder. Never affects the API shape. */
1122
- fieldsets?: Fieldset[];
1123
- createdAt: string;
1124
- updatedAt: string;
1125
- }
1126
- /**
1127
- * Canonical field types. Nesting lives on `array` via `config.zones`
1128
- * (see {@link ArrayZoneConfig}): `group`/`repeater` are accepted as legacy input
1129
- * by the API but normalized to `array` + zones on write, so stored/delivered
1130
- * content never contains them.
1131
- */
1132
- type ContentModelFieldType = "text" | "richtext" | "document" | "image" | "boolean" | "number" | "select" | "reference" | "multi-reference" | "multiReference" | "array" | "date" | "datetime" | "longtext" | "slug" | "email" | "phone" | "link" | "color" | "json" | "file" | "component-ref" | "modular" | "sections" | "location";
1133
- type ContentModelKind = "model" | "block";
1134
- /** A named, UI-only grouping of a model's fields. Order is the array index. */
1135
- interface Fieldset {
1136
- id: string;
1137
- name: string;
1138
- }
1139
- /**
1140
- * Nested-content config for an `array` field. A zone holds ordinary fields, and a
1141
- * zone field may itself be an `array` with its own zones, so nesting is recursive
1142
- * to any depth.
1143
- * - `nonRepeatable` — a single fixed block of fields (former `group`).
1144
- * - `repeatable` — a repeating list of field-objects (former `repeater`).
1145
- * Mutually exclusive with the primitive form (`config.itemType`).
1146
- */
1147
- interface ArrayZoneConfig {
1148
- nonRepeatable?: ContentModelField[];
1149
- repeatable?: {
1150
- fields: ContentModelField[];
1151
- minItems?: number;
1152
- maxItems?: number;
1153
- };
1154
- }
1155
- /** Per-type config for a field (the typed shape behind the loose `config` bag). */
1156
- interface FieldConfig {
1157
- /** primitive array: list of scalars */
1158
- itemType?: "text" | "number" | "date";
1159
- /** nested array: zoned fields (recursive) */
1160
- zones?: ArrayZoneConfig;
1161
- /** reference / multi-reference */
1162
- contentModelId?: string;
1163
- min?: number;
1164
- max?: number;
1165
- /** date / datetime */
1166
- includeTime?: boolean;
1167
- /** modular: SLUGS of the kind='block' models this field accepts. Non-empty. */
1168
- blockSlugs?: string[];
1169
- /** modular: bounds on how many block instances the field may hold. */
1170
- minItems?: number;
1171
- maxItems?: number;
1172
- /**
1173
- * sections: SLUGS of the sections an author may insert into this zone.
1174
- *
1175
- * Deliberately NOT named `blockSlugs`. That key means "kind='block' content models" and is
1176
- * read by ModularField; these are section-registry slugs resolved from a different place.
1177
- * One key meaning two things is how `blockModels`/`blockSlugs` already drifted apart in the
1178
- * dashboard — a distinct name costs nothing and cannot be confused at a call site.
1179
- *
1180
- * ⚠ ABSENT ≠ EMPTY:
1181
- * absent → UNRESTRICTED, every registry section may be inserted
1182
- * [] → DENY ALL, a deliberate empty restriction
1183
- * [a, b] → only those
1184
- * `[]` means DENY here to match `components.allowed_on` (migration 0190), so two adjacent
1185
- * allow-lists never disagree about what empty means.
1186
- *
1187
- * Absent rather than "all current slugs" because the registry GROWS — it is fed by repo
1188
- * pushes and project components, so materializing today's slugs at field-creation time would
1189
- * silently exclude every section shipped afterwards.
1190
- *
1191
- * NOT READ DIRECTLY. Insertability is this list INTERSECTED with the component's `allowedOn`
1192
- * (where that section may be placed), computed by one resolver so the two cannot drift.
1193
- *
1194
- * Enforced on NEW picks only. Narrowing the list later must never invalidate sections an
1195
- * author already placed, the same rule modular's blockSlugs and component-ref's allowlist
1196
- * follow.
1197
- */
1198
- allowedSections?: string[];
1199
- /** Durable project-local authored Zone mode. Legacy zones omit this key. */
1200
- mode?: "authored-v2";
1201
- /** Durable Zone id. Present when `mode` is `authored-v2`. */
1202
- zoneId?: string;
1203
- /** Explicit migration acknowledgement while the legacy allowlist remains readable. */
1204
- legacyResolved?: boolean;
1205
- legacyMappings?: Record<string, string>;
1206
- [key: string]: unknown;
1207
- }
1208
- /**
1209
- * Where a field renders in the entry editor.
1210
- *
1211
- * AUTHORING ONLY — this has no delivery or storage effect. It does not change the
1212
- * shape of `data`, is not read by any renderer in @bettercms-ai/next or /astro, and
1213
- * cannot move a value onto or off a published page. It decides one thing: where the
1214
- * control sits while somebody is writing.
1215
- *
1216
- * Granularity is REGION-level, never interleaved between body blocks: the canvas is
1217
- * `[hero slots] → [free block flow] → [inline fields] → [panel fields in the drawer]`.
1218
- * A field cannot be positioned "between two paragraphs" — there is no coordinate space
1219
- * for that, and inventing one would mean mounting form controls inside the Lexical tree.
1220
- *
1221
- * - `cover` / `title` / `excerpt` / `body` — the four hero slots, rendered unlabelled
1222
- * and typographically native. SCHEMA-LEVEL ONLY: a per-entry override may never
1223
- * claim one, or one author's click renders anonymous 40px text over anonymous text
1224
- * on that entry alone.
1225
- * - `inline` — in the canvas, below the block flow, labelled.
1226
- * - `panel` — in the drawer.
1227
- *
1228
- * ABSENT is meaningful and is the default for every model that predates this: the
1229
- * editor falls back to its title-gated heuristic. Only an explicit value promotes a
1230
- * field past that gate.
1231
- */
1232
- type ContentModelFieldPlacement = "cover" | "title" | "excerpt" | "body" | "inline" | "panel";
1233
- interface ContentModelField {
1234
- key: string;
1235
- label: string;
1236
- type: ContentModelFieldType;
1237
- required?: boolean;
1238
- defaultValue?: unknown;
1239
- options?: string[];
1240
- /** Per-type config. For `array`: either `itemType` (primitive) or `zones` (nested). */
1241
- config?: FieldConfig | null;
1242
- /**
1243
- * Which fieldset this field renders under in the schema builder. Authoring-only: it is
1244
- * never delivered and cannot move a value — see {@link Fieldset}.
1245
- */
1246
- fieldsetId?: string;
1247
- /**
1248
- * Authoring-only editor placement. See {@link ContentModelFieldPlacement}.
1249
- * Field ORDER is the array index — there is deliberately no `order` property.
1250
- */
1251
- placement?: ContentModelFieldPlacement;
1252
- }
1253
- /**
1254
- * A field inside an array zone — identical to a top-level {@link ContentModelField}.
1255
- * Kept as a named alias so consumers can express "zone field" intent; recursion
1256
- * (an array zone field with its own `config.zones`) is supported.
1257
- */
1258
- type ZoneField = ContentModelField;
1259
-
1260
1355
  /**
1261
1356
  * MediaAsset — a file uploaded to the CMS media library.
1262
1357
  */
@@ -1272,10 +1367,40 @@ interface MediaAsset {
1272
1367
  width?: number;
1273
1368
  height?: number;
1274
1369
  altText?: string;
1370
+ /**
1371
+ * Video/audio only: what is said in the recording (CPO-093). Stored once on the asset and
1372
+ * resolved into every file value that references it. null/absent = nobody has written one.
1373
+ */
1374
+ transcript?: string | null;
1375
+ /**
1376
+ * RESERVED (CPO-093 §2) — caption/subtitle tracks for the player (WCAG 1.2.2). Not rendered,
1377
+ * not writable and not returned yet; the shape is fixed now so the follow-up is additive.
1378
+ */
1379
+ captions?: MediaCaptionTrack[];
1275
1380
  isActive: boolean;
1276
1381
  createdAt: string;
1277
1382
  updatedAt: string;
1278
1383
  }
1384
+ /** RESERVED — one `.vtt` track. See MediaAsset.captions. */
1385
+ interface MediaCaptionTrack {
1386
+ lang: string;
1387
+ label: string;
1388
+ url: string;
1389
+ kind: "captions" | "subtitles";
1390
+ default?: boolean;
1391
+ }
1392
+ /**
1393
+ * A `file` (or `image`) field value as the delivery API returns it. `transcript` is the
1394
+ * RESOLVED value — the referenced video/audio asset's own — so a client never follows the asset
1395
+ * to find it. Present only when the asset is video or audio and has one.
1396
+ */
1397
+ interface MediaFieldValue {
1398
+ id?: string;
1399
+ url: string;
1400
+ name?: string;
1401
+ altText?: string | null;
1402
+ transcript?: string;
1403
+ }
1279
1404
 
1280
1405
  /**
1281
1406
  * Delivery API response shapes — the read surface consumed by framework
@@ -1292,6 +1417,13 @@ interface DeliveryEntry<T = Record<string, unknown>> {
1292
1417
  publishedAt: string | null;
1293
1418
  updatedAt: string | null;
1294
1419
  data: T;
1420
+ /**
1421
+ * The entry's SEO, ready for `<head>`: its collection template's meta and JSON-LD with
1422
+ * `{{field}}` tokens already resolved for this entry, the entry's own values merged over it
1423
+ * field by field, and an empty title/description auto-filled from its content. Feed it to
1424
+ * `resolveSeo(entrySeoInput(entry), siteDefaults)`; there is no token work left to do.
1425
+ */
1426
+ seo?: DeliveryEntrySeo;
1295
1427
  /** Hydrated reference fields, present when `depth >= 1`. */
1296
1428
  _hydration?: Record<string, DeliveryEntry | DeliveryEntry[]>;
1297
1429
  _meta?: {
@@ -1342,6 +1474,12 @@ interface PageMetaJson {
1342
1474
  };
1343
1475
  schema?: Record<string, unknown> | Array<Record<string, unknown>>;
1344
1476
  }
1477
+ /** `DeliveryEntry.seo`: the page meta shape plus the entry's flat title, description and noindex. */
1478
+ interface DeliveryEntrySeo extends PageMetaJson {
1479
+ metaTitle?: string;
1480
+ metaDescription?: string;
1481
+ noindex?: boolean;
1482
+ }
1345
1483
  /**
1346
1484
  * Site-level SEO defaults a headless consumer passes to `resolveSeo`/`buildMetadata`
1347
1485
  * so per-page meta layers over project-wide fallbacks (mirrors the server renderer's
@@ -1579,4 +1717,4 @@ type DeepReadonly<T> = T extends Function ? T : T extends object ? {
1579
1717
  */
1580
1718
  type AssertEqual<L, R> = [L] extends [R] ? ([R] extends [L] ? true : false) : false;
1581
1719
 
1582
- export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, BLOCK_BINDINGS, type BetterCMSErrorCode, type BindingKind, type BlockBinding, type BlockStyle, type BlockType, type ButtonBlock, type ButtonProps, type CanonicalInputDefinition, type CollectionBlock, type CollectionProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentPropDef, type ComponentProps, type ComponentSubField, type ComponentVariantGroup, type Content, type ContentBlock, type ContentEntry, type ContentModel, type ContentModelField, type ContentModelFieldType, type ContentPageResult, type ContentResponse, type DeepReadonly, type DeliveredLayout, type DeliveryComponent, type DeliveryEntry, type DeliveryList, type DeliveryPage, type ExpandedBinding, FOOTER_SECTION_ID, type FieldConfig, type FontSizeToken, type FooterBlock, type FooterColumn, type FooterProps, type Form, type FormBlock, type FormField, type FormProps, type FormSubmission, type HeadingBlock, type HeadingProps, type ImageBlock, type ImageProps, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, type LayoutComponentItem, type LayoutDataDocument, type LayoutFieldDefinition, type LayoutFieldItem, type LayoutFieldType, type LayoutScalarFieldType, type LayoutSection, type LayoutSectionIcon, type LayoutSectionItem, type LayoutStructureDocument, type LayoutZone, type ManagementLayoutCommand, type MediaAsset, NAVIGATION_SECTION_ID, type NavLink, type NavbarBlock, type NavbarProps, PAGE_CONTENT_ANCHOR_ID, type Page, type PageLayoutOverrideDataDocument, type PageLayoutOverrideDocument, type PageLayoutOverrideState, type PageLayoutOverrideStructureDocument, type PageLayoutSectionOverride, type PageLayoutSectionStructureOverride, type PageMetaJson, type PageOnlyLayoutSection, type PageSectionPlacement, type PaginatedResult, type Perspective, type PortableTextDocument, type PortableTextNode, type RadiusToken, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, SECTION_DOCTRINE, type SectionBlock, type SectionProps, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SpaceToken, type SpacerBlock, type SpacerProps, type TabItem, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type VariantInputMapping, type VideoBlock, type VideoProps, type WeightToken, type Workspace, type ZoneField, blockStyleToCss, componentInstanceAddresses, componentPropTargetKey, expandBlockBindings, formatPropsAttribute, getBlockType, isBlock, parsePropsAttribute, readPath };
1720
+ export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, BLOCK_BINDINGS, type BetterCMSErrorCode, type BgToken, type BindingKind, type BlockBinding, type BlockStyle, type BlockType, type ButtonBlock, type ButtonProps, type CanonicalInputDefinition, type CollectionBlock, type CollectionProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentPropDef, type ComponentProps, type ComponentSubField, type ComponentVariantGroup, type Content, type ContentBlock, type ContentEntry, type ContentModel, type ContentModelField, type ContentModelFieldType, type ContentModelFieldUi, type ContentPageResult, type ContentResponse, type ContentWidthToken, type CornerToken, type DeepReadonly, type DeliveredLayout, type DeliveryComponent, type DeliveryEntry, type DeliveryEntrySeo, type DeliveryList, type DeliveryPage, type ExpandedBinding, FOOTER_SECTION_ID, type FieldConfig, type FontSizeToken, type FooterBlock, type FooterColumn, type FooterProps, type Form, type FormBlock, type FormField, type FormProps, type FormSubmission, type HeadingBlock, type HeadingProps, type ImageBlock, type ImageProps, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, type LayoutComponentItem, type LayoutDataDocument, type LayoutFieldDefinition, type LayoutFieldItem, type LayoutFieldType, type LayoutScalarFieldType, type LayoutSection, type LayoutSectionIcon, type LayoutSectionItem, type LayoutStructureDocument, type LayoutZone, type ManagementLayoutCommand, type MediaAsset, type MediaCaptionTrack, type MediaFieldValue, NAVIGATION_SECTION_ID, type NavLink, type NavbarBlock, type NavbarProps, PAGE_CONTENT_ANCHOR_ID, type Page, type PageLayoutOverrideDataDocument, type PageLayoutOverrideDocument, type PageLayoutOverrideState, type PageLayoutOverrideStructureDocument, type PageLayoutSectionOverride, type PageLayoutSectionStructureOverride, type PageMetaJson, type PageOnlyLayoutSection, type PageSectionPlacement, type PaginatedResult, type Perspective, type PortableTextDocument, type PortableTextNode, type RadiusToken, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, SECTION_DOCTRINE, type SectionBlock, type SectionProps, type ShadowToken, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SpaceToken, type SpacerBlock, type SpacerProps, type TabItem, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type ThemeToken, type VariantInputMapping, type VideoBlock, type VideoProps, type WeightToken, type Workspace, type ZoneField, blockStyleToCss, componentInstanceAddresses, componentPropTargetKey, expandBlockBindings, formatPropsAttribute, getBlockType, isBlock, parsePropsAttribute, readPath };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/block.ts","../src/block-bindings.ts","../src/blockStyle.ts","../src/component.ts","../src/layout-lucide-icons.ts","../src/layout.ts"],"sourcesContent":["/**\n * ContentBlock — a discriminated union of all CMS block types.\n * Each block has a `type` discriminator and a `props` object\n * whose shape matches the block type.\n */\n\n// ── Block style (FLO-264) ──────────────────────────────────────────────────────\n// A uniform, BOUNDED set of design tokens any block may carry (sibling to `props`).\n// Tokens map to fixed CSS values in the renderer (`styleTokensToCss`) so styling\n// reaches the live site WITHOUT arbitrary CSS. Additive + fully optional.\n\nexport type SpaceToken = \"none\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type ColorToken = \"none\" | \"white\" | \"black\" | \"muted\" | \"mutedBg\" | \"primary\" | \"accent\";\nexport type AlignToken = \"left\" | \"center\" | \"right\";\nexport type FontSizeToken = \"sm\" | \"base\" | \"lg\" | \"xl\" | \"2xl\";\nexport type WeightToken = \"normal\" | \"medium\" | \"semibold\" | \"bold\";\nexport type RadiusToken = \"none\" | \"sm\" | \"md\" | \"lg\" | \"full\";\n\n// Section design (task 4) — the per-instance design a section carries on the page.\nexport type ThemeToken = \"inherit\" | \"light\" | \"dark\";\nexport type BgToken = \"none\" | \"surface\" | \"muted\" | \"accent\" | \"dark\" | \"custom\";\nexport type ContentWidthToken = \"narrow\" | \"default\" | \"wide\" | \"full\";\nexport type CornerToken = \"0\" | \"s\" | \"m\" | \"l\" | \"xl\" | \"2xl\";\nexport type ShadowToken = \"0\" | \"s\" | \"m\" | \"l\" | \"xl\";\n\nexport interface BlockStyle {\n // Legacy token set (FLO-264). Where these overlap the section fields below\n // (background, radius, padding), the section field WINS in the renderer.\n paddingY?: SpaceToken;\n paddingX?: SpaceToken;\n marginTop?: SpaceToken;\n marginBottom?: SpaceToken;\n background?: ColorToken;\n textColor?: ColorToken;\n align?: AlignToken;\n fontSize?: FontSizeToken;\n weight?: WeightToken;\n radius?: RadiusToken;\n\n // Section design (task 4).\n theme?: ThemeToken;\n bg?: BgToken;\n /** Only read when `bg === \"custom\"`. Hex only. */\n bgCustom?: string;\n /** Padding sliders, in px (0–240). */\n paddingTop?: number;\n paddingBottom?: number;\n paddingSides?: number;\n contentWidth?: ContentWidthToken;\n fullHeight?: boolean;\n /** 0–100. */\n opacity?: number;\n corner?: CornerToken;\n shadow?: ShadowToken;\n borderTop?: boolean;\n borderBottom?: boolean;\n /** 🔴 The one free-form string. MUST go through `safeCssUrl()` before reaching CSS. */\n bgImage?: string;\n}\n\n// ── Heading ──────────────────────────────────────────────────────────────────\n\nexport interface HeadingProps {\n text: string;\n level?: 1 | 2 | 3;\n}\n\nexport interface HeadingBlock {\n type: \"heading\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: HeadingProps;\n}\n\n// ── Text ─────────────────────────────────────────────────────────────────────\n\nexport interface TextProps {\n html: string;\n}\n\nexport interface TextBlock {\n type: \"text\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: TextProps;\n}\n\n/**\n * A rich-text block: the same HTML payload as `text`, authored through a real editor.\n *\n * WHY A SEPARATE TYPE RATHER THAN CHANGING `text`. Every `text` block already on a live page\n * holds an HTML string that the delivery renderer injects as-is. Repurposing that type would\n * mean migrating published content, and getting it wrong renders visible markup to visitors.\n * A new type costs nothing at rest and leaves existing pages untouched.\n *\n * The payload is deliberately IDENTICAL to TextProps (an HTML string) so the two are\n * interchangeable at the renderer: delivery treats them the same, and the difference is\n * entirely in how an author edits them — `text` is a plain field, `richtext` gets the\n * formatting surface.\n */\n/**\n * A Portable Text node — the structured form of rich text.\n *\n * Kept alongside `html` rather than replacing it, so nothing already published moves. The\n * structure exists because an HTML string cannot carry INTENT: a colour is a hex with no\n * notion of which brand token produced it, an embedded component is a div with no reference\n * to resolve, and neither can be read back by tooling. Nodes can carry all of that.\n */\nexport interface PortableTextNode {\n _type: string;\n _key?: string;\n /** Block style — \"normal\", \"h2\", \"blockquote\". */\n style?: string;\n text?: string;\n children?: PortableTextNode[];\n /** Marks on a span: \"strong\", \"em\", or a token reference like \"color:brand-accent\". */\n marks?: string[];\n /** An embedded component or reference resolves through these. */\n schemaKey?: string;\n _ref?: string;\n fields?: Record<string, unknown>;\n}\n\nexport interface PortableTextDocument {\n version: 1;\n content: PortableTextNode[];\n}\n\nexport interface RichTextProps {\n /**\n * The RENDERED CACHE. Delivery reads this, so the fast path stays a string interpolation\n * and every page published before `content` existed keeps rendering byte-identically.\n */\n html: string;\n /**\n * The SOURCE OF TRUTH, when present — `content` always wins over `html`.\n *\n * Optional on purpose: this is the same envelope the field values already use\n * (`{ format, value, html }`), where `html` is likewise derived. Any writer that sets\n * `html` alone on a block that HAS `content` must delete `content` in the same write, or\n * the stale string silently shadows the newer structure.\n */\n content?: PortableTextDocument;\n}\n\nexport interface RichTextBlock {\n type: \"richtext\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: RichTextProps;\n}\n\n// ── Image ────────────────────────────────────────────────────────────────────\n\nexport interface ImageProps {\n src: string;\n alt: string;\n width?: number;\n height?: number;\n caption?: string;\n}\n\nexport interface ImageBlock {\n type: \"image\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: ImageProps;\n}\n\n// ── Button ───────────────────────────────────────────────────────────────────\n\nexport interface ButtonProps {\n text: string;\n href: string;\n variant?: \"primary\" | \"secondary\";\n}\n\nexport interface ButtonBlock {\n type: \"button\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: ButtonProps;\n}\n\n// ── Spacer ───────────────────────────────────────────────────────────────────\n\nexport interface SpacerProps {\n height: number; // in px\n}\n\nexport interface SpacerBlock {\n type: \"spacer\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: SpacerProps;\n}\n\n// ── Columns ───────────────────────────────────────────────────────────────────\n\nexport interface ColumnsProps {\n columns: ContentBlock[][]; // array of column slots, each slot is an array of blocks\n gap?: number; // in px\n}\n\nexport interface ColumnsBlock {\n type: \"columns\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: ColumnsProps;\n}\n\n// ── Video ────────────────────────────────────────────────────────────────────\n\nexport interface VideoProps {\n url: string;\n poster?: string;\n autoplay?: boolean;\n loop?: boolean;\n}\n\nexport interface VideoBlock {\n type: \"video\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: VideoProps;\n}\n\n// ── Form ─────────────────────────────────────────────────────────────────────\n\nexport interface FormProps {\n formId: string; // references forms.id (a nanoid). Resolved against delivered forms at render time.\n}\n\nexport interface FormBlock {\n type: \"form\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: FormProps;\n}\n\n// ── Section (recursive container) ──────────────────────────────────────────────\n\nexport interface SectionProps {\n children: ContentBlock[];\n background?: string;\n paddingY?: number; // in px\n maxWidth?: number; // in px\n}\n\nexport interface SectionBlock {\n type: \"section\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: SectionProps;\n}\n\n// ── Navbar ─────────────────────────────────────────────────────────────────────\n\nexport interface NavLink {\n label: string;\n href: string;\n}\n\nexport interface NavbarProps {\n logo?: { src: string; alt: string; href?: string };\n logoAlt?: string;\n links: NavLink[];\n mobileMenu?: boolean;\n cta?: { text: string; href: string };\n}\n\nexport interface NavbarBlock {\n type: \"navbar\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: NavbarProps;\n}\n\n// ── Footer ─────────────────────────────────────────────────────────────────────\n\nexport interface FooterColumn {\n heading?: string;\n links: NavLink[];\n}\n\nexport interface FooterProps {\n columns: FooterColumn[];\n copyright?: string;\n}\n\nexport interface FooterBlock {\n type: \"footer\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: FooterProps;\n}\n\n// ── Slider / Carousel (recursive container, client-hydrated) ────────────────────\n\nexport interface SlideItem {\n id: string;\n children: ContentBlock[];\n}\n\nexport interface SliderProps {\n slides: SlideItem[];\n autoplay?: boolean;\n interval?: number; // in ms\n loop?: boolean;\n}\n\nexport interface SliderBlock {\n type: \"slider\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: SliderProps;\n}\n\n// ── Tabs (recursive container, client-hydrated) ─────────────────────────────────\n\nexport interface TabItem {\n id: string;\n label: string;\n children: ContentBlock[];\n}\n\nexport interface TabsProps {\n tabs: TabItem[];\n}\n\nexport interface TabsBlock {\n type: \"tabs\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: TabsProps;\n}\n\n// ── Component instance (Webflow-style reusable symbol) ──────────────────────────\n// References a reusable component by id. `overrides` maps a component prop key\n// (declared in the component's `props[]` allowlist) to a value, applied to the\n// component's block tree at render time. Resolved against delivered components.\n\nexport interface ComponentProps {\n componentId: string;\n overrides?: Record<string, unknown>;\n /** Phase A: the page field group this placement renders (its copy + bindings live there). */\n bind?: string;\n /**\n * Phase B: where each override's copy CAME FROM — `{ <propKey>: \"<page field path>\" }`.\n *\n * Written when a placement takes ownership of its copy (`bind` is deleted at the same moment),\n * and it is not decoration:\n * - the COVERAGE METER counts a block-lane declaration\n * (`data-bcms-block=\"<id>\"` + `data-bcms-field=\"<id>__overrides.<propKey>\"`) as bound for\n * the page path named here, so a converted page does not read as a site that lost its\n * bindings;\n * - it is how the componentize lane still recognises WHICH GROUP an instance renders once\n * `bind` is gone — without it a second run would mint a second instance for the same band.\n * A `table` prop names its repeater's path (`faq.items`); every row path under it is that one\n * declaration's, because the prop holds every row.\n */\n source?: Record<string, string>;\n}\n\nexport interface ComponentBlock {\n type: \"component\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: ComponentProps;\n}\n\n// ── Collection (the entries of the page this block sits on) ─────────────────────\n//\n// LANE-AWARE, and that is the whole idea. A dynamic page's `blockJson` is BOTH what\n// `/blog` renders and the template interpolated into every `/blog/<slug>`. One array\n// cannot be an index and a post layout — unless the one block that differs between them\n// knows which lane it is in. The route supplies that (see CollectionCtx in render-page.ts):\n//\n// /blog → this block renders a card per published entry\n// /blog/my-post → this block renders THAT entry's detail; every other block in the\n// array is interpolated with {{placeholders}} exactly as before\n//\n// So no second template column, no migration, and a page without a collection block\n// behaves byte-identically to before.\n//\n// Scope is IMPLIED, never configured: a collection lists the entries of the page it sits\n// on, which is precisely the set whose detail URLs are /<thisPage>/<slug>. There is no\n// model picker because there is no other correct answer.\n\nexport interface CollectionProps {\n /** Component rendered once per entry, interpolated with {{field}} and {{url}}. Omit for a built-in card. */\n cardComponentId?: string;\n /** Component rendered for the single entry on a detail URL. Omit to fall back to the generic field layout. */\n detailComponentId?: string;\n /** Built-in card only. Defaults to \"title\" / no excerpt. */\n titleField?: string;\n excerptField?: string;\n /** Max cards to render. Defaults to 20. */\n limit?: number;\n /** \"newest\" (default) reverses the reader's created_at ordering. */\n order?: \"newest\" | \"oldest\";\n emptyText?: string;\n}\n\nexport interface CollectionBlock {\n type: \"collection\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: CollectionProps;\n}\n\n// ── Union ─────────────────────────────────────────────────────────────────────\n\nexport type ContentBlock =\n | CollectionBlock\n | HeadingBlock\n | TextBlock\n | RichTextBlock\n | ImageBlock\n | ButtonBlock\n | SpacerBlock\n | ColumnsBlock\n | VideoBlock\n | FormBlock\n | SectionBlock\n | NavbarBlock\n | FooterBlock\n | SliderBlock\n | TabsBlock\n | ComponentBlock;\n\n/** Literal union of all block type discriminators. */\nexport type BlockType = ContentBlock[\"type\"];\n\n/**\n * Type guard — narrows an unknown block to `ContentBlock`.\n *\n * @example\n * const block = maybeBlock as unknown;\n * if (isBlock(block)) {\n * // block is ContentBlock here\n * }\n */\nexport function isBlock(value: unknown): value is ContentBlock {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n typeof (value as Record<string, unknown>)[\"type\"] === \"string\"\n );\n}\n\n/**\n * Extract the `type` discriminator from a block, or `null` if not a block.\n *\n * @example\n * const block = { type: \"heading\", id: \"1\", props: { text: \"Hi\" } };\n * getBlockType(block); // \"heading\"\n * getBlockType({ not: \"a block\" }); // null\n */\nexport function getBlockType(value: unknown): BlockType | null {\n if (isBlock(value)) return value.type;\n return null;\n}\n","/**\n * The ONE declaration of which block props the Visual Editor can address.\n *\n * Four renderers stamp `data-bcms-field` — the hosted renderer, the Next SDK, the Astro SDK\n * and (for minting keys rather than markup) the dashboard's `buildBlockPageDoc`. Until this\n * file existed each carried its own hand-written list, they disagreed by two props, and the\n * dashboard's copy said so in a comment while having nothing to enforce it. A block listed in\n * one and missing from another does not error: it simply never binds, or it binds to a node\n * that resolves to no field. Both failures are silent, which is why they survived.\n *\n * This file is the declaration. The renderers remain the implementation — only they know which\n * ELEMENT carries a value — and `block-binding-coverage.test.ts` asserts the two agree.\n *\n * ── Two kinds of address, because an element is not an attribute ────────────────────────────\n *\n * `data-bcms-field` addresses ONE element. That is enough for a heading's text or an image's\n * src, and not enough for an image's `alt`: the `<img>` already carries a binding, and an\n * element cannot hold two. Entries that name an `attr` are therefore emitted on a SECOND\n * attribute, `data-bcms-props`, whose grammar is:\n *\n * <address>|<kind>|<domAttribute>[;<address>|<kind>|<domAttribute>]*\n *\n * No JSON, because the values are already constrained: an address is grammar A\n * (`[A-Za-z0-9_$-]`, `.`, `[n]`), and kinds and attributes are plain identifiers. A split on\n * two characters parses it, in any language, with no escaping.\n *\n * ── Path templates ──────────────────────────────────────────────────────────────────────────\n *\n * `[]` marks an array the renderer walks. `expandBlockBindings` substitutes real indices from a\n * block's actual props, so `links[].label` on a three-link navbar yields three concrete\n * addresses and on an empty one yields none. `parseFieldPath`/`setFieldPath` in the dashboard\n * have handled N indices since FLO-949; the cap was in what the renderer offered, not in what\n * the writer could persist.\n */\nimport type { ContentBlock, BlockType } from \"./block.js\";\n\n/**\n * How the editor paints a value, and whether it may take a caret.\n *\n * `text`/`richtext` are inline-editable. `image` selects and swaps through the media picker.\n * `url` never takes a caret — a URL typed onto the page has nowhere to report a malformed\n * value — so it is edited in the element toolbar. `array` is a repeater slot: selectable and\n * locatable, edited in the dock.\n */\nexport type BindingKind = \"text\" | \"richtext\" | \"image\" | \"url\" | \"number\" | \"array\";\n\nexport interface BlockBinding {\n /** Path template in grammar A, relative to the block's `props`. `[]` = an array to walk. */\n readonly path: string;\n readonly kind: BindingKind;\n /**\n * The DOM attribute this value lives in, when it is not the element's own text or `src`.\n * Present ⇒ the renderer emits it on `data-bcms-props`, never on `data-bcms-field`.\n */\n readonly attr?: string;\n}\n\n/**\n * Props deliberately absent, and still absent for the original reason:\n *\n * `spacer.height`, `columns.gap`, `section.background` and every `style` token — design, not\n * content. They are edited in the Design accordion, where a slider can express a bounded\n * range that free typing on the page cannot.\n *\n * `text.html` when Portable Text is present — `html` is a cache derived from `content`, so\n * advertising it would persist an ignored sibling and the next frame would read as a revert.\n * The renderer suppresses it; the expander cannot see `content`, so the branch stays there.\n *\n * `component.overrides.*` — instance-scoped, so it cannot be a static template. The renderer\n * derives those addresses per instance from the definition's declared props.\n */\nexport const BLOCK_BINDINGS: Partial<Record<BlockType, readonly BlockBinding[]>> = {\n heading: [{ path: \"text\", kind: \"text\" }],\n text: [{ path: \"html\", kind: \"richtext\" }],\n richtext: [{ path: \"html\", kind: \"richtext\" }],\n image: [\n { path: \"src\", kind: \"image\" },\n { path: \"caption\", kind: \"text\" },\n { path: \"alt\", kind: \"text\", attr: \"alt\" },\n ],\n button: [\n { path: \"text\", kind: \"text\" },\n { path: \"href\", kind: \"url\", attr: \"href\" },\n ],\n video: [\n { path: \"url\", kind: \"url\", attr: \"src\" },\n { path: \"poster\", kind: \"url\", attr: \"poster\" },\n ],\n navbar: [\n { path: \"logo.src\", kind: \"image\" },\n { path: \"logo.alt\", kind: \"text\", attr: \"alt\" },\n { path: \"links[].label\", kind: \"text\" },\n { path: \"links[].href\", kind: \"url\", attr: \"href\" },\n { path: \"cta.text\", kind: \"text\" },\n { path: \"cta.href\", kind: \"url\", attr: \"href\" },\n ],\n footer: [\n { path: \"copyright\", kind: \"text\" },\n { path: \"columns[].heading\", kind: \"text\" },\n { path: \"columns[].links[].label\", kind: \"text\" },\n { path: \"columns[].links[].href\", kind: \"url\", attr: \"href\" },\n ],\n tabs: [{ path: \"tabs[].label\", kind: \"text\" }],\n};\n\n/** One concrete, writable address on one block. */\nexport interface ExpandedBinding extends BlockBinding {\n /** The template with every `[]` replaced by a real index, e.g. `links[2].href`. */\n readonly path: string;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n\n/**\n * Read a grammar-A path — dotted object keys and zero or more `[n]` indices.\n *\n * Positional, exactly like the dashboard's `parseFieldPath`: a dotted segment is always an\n * object key and a bracketed one always an index, so `links.0` reads the string key \"0\" and\n * misses, rather than being quietly treated as `links[0]`. Any miss returns undefined; nothing\n * here throws, because a template that does not resolve must yield no address, not an error.\n *\n * EXPORTED because a second reader of this grammar now exists: `@bettercms-ai/convert` commits a\n * build-time helper into a customer's repository, and that helper must resolve a path exactly the\n * way the editor does or a converted template renders a fallback where a value exists. The helper\n * itself carries an inlined copy (it lands in a repo where our packages do not exist) and a parity\n * test pins the copy to this original.\n */\nexport function readPath(root: unknown, path: string): unknown {\n let cursor: unknown = root;\n for (const segment of path.split(\".\")) {\n if (!segment) return undefined;\n const key = segment.replace(/\\[\\d+\\]/g, \"\");\n if (key) {\n if (!isRecord(cursor)) return undefined;\n cursor = cursor[key];\n }\n for (const index of segment.matchAll(/\\[(\\d+)\\]/g)) {\n if (!Array.isArray(cursor)) return undefined;\n cursor = cursor[Number(index[1])];\n }\n }\n return cursor;\n}\n\n/** Substitute the FIRST `[]` with every real index, then recurse for any deeper array. */\nfunction expandTemplate(binding: BlockBinding, props: unknown, path: string): ExpandedBinding[] {\n const at = path.indexOf(\"[]\");\n if (at < 0) return [{ ...binding, path }];\n\n const head = path.slice(0, at);\n const tail = path.slice(at + 2);\n const array = readPath(props, head);\n if (!Array.isArray(array)) return [];\n\n return array.flatMap((_item, index) =>\n expandTemplate(binding, props, `${head}[${index}]${tail}`),\n );\n}\n\n/**\n * Every concrete address a block actually offers right now.\n *\n * Array templates expand against the array's real length, so an address is only ever minted\n * for an element that exists. That is the load-bearing property: `setFieldPath` refuses to\n * fabricate an array member, so an address for `links[3]` on a two-link navbar would be a\n * binding the writer rejects — the \"advertises an edit that silently fails\" failure this whole\n * grammar exists to avoid.\n *\n * A prop whose KEY is absent does NOT expand, and that is not a nicety. `setFieldPath` refuses\n * to create a final key unless `createMissingObjects` is set, which only component overrides\n * pass — so an address for a key the block does not carry is a write the editor would reject.\n * An empty string still expands: `\"\"` is a value, and clearing a heading must not make it\n * uneditable.\n */\nexport function expandBlockBindings(block: ContentBlock): ExpandedBinding[] {\n const declared = BLOCK_BINDINGS[block.type];\n if (!declared) return [];\n const props = (block as { props?: unknown }).props;\n if (!isRecord(props)) return [];\n return declared\n .flatMap((binding) => expandTemplate(binding, props, binding.path))\n .filter((binding) => readPath(props, binding.path) !== undefined);\n}\n\n/** The `data-bcms-props` value for a block's attribute bindings, or \"\" when it has none. */\nexport function formatPropsAttribute(\n entries: readonly { address: string; kind: BindingKind; attr: string }[],\n): string {\n return entries.map((e) => `${e.address}|${e.kind}|${e.attr}`).join(\";\");\n}\n\n/** Parse a `data-bcms-props` value. Malformed entries are dropped, never guessed at. */\nexport function parsePropsAttribute(\n value: string | null | undefined,\n): { address: string; kind: BindingKind; attr: string }[] {\n if (!value) return [];\n return value\n .split(\";\")\n .map((entry) => entry.split(\"|\"))\n .filter((parts): parts is [string, BindingKind, string] => parts.length === 3 && parts.every(Boolean))\n .map(([address, kind, attr]) => ({ address, kind, attr }));\n}\n\n/** The shape of a declared component prop this module needs: where it points, and its key. */\ninterface PropTarget {\n key?: string;\n target?: { blockId?: string; path?: string };\n}\n\n/**\n * `<defBlockId>__<prop>` → `<instanceBlockId>__overrides.<propKey>`, for one placed component.\n *\n * Shared by every renderer, because the mapping is a property of the DEFINITION and not of any\n * one output format. A component's block ids belong to the definition and are shared by every\n * instance of it, so `<defBlockId>__text` addresses no instance's value — which is why component\n * subtrees used to render unannotated, and why the SDKs (which never had that suppression)\n * stamped definition-scoped addresses that resolve to no field and, on a component placed twice,\n * collide into a duplicate that drops BOTH copies.\n *\n * The definition already states the mapping in `props[].target`. This only re-keys that\n * statement into the address the editor writes through. Nothing is inferred: a prop with no\n * target produces no entry, so it keeps its dock control and stays uneditable on the canvas,\n * which is the truthful outcome rather than a broken one.\n */\n/**\n * The definition-scoped key a declared prop POINTS AT — `<defBlockId>__<path>`, the same\n * grammar `expandBlockBindings` produces for a block's own bindings.\n *\n * Exported so the \"which leaves does no prop reach?\" check and the address minter below read\n * the key from ONE place. They ask opposite questions of the same mapping, and two spellings\n * of `.replace(/^props\\./, \"\")` is precisely how a leaf ends up counted as bound by one and\n * unbound by the other. Null when the prop declares no target — which is the honest answer:\n * such a prop reaches nothing.\n */\nexport function componentPropTargetKey(prop: PropTarget | undefined): string | null {\n if (!prop?.key || !prop.target?.blockId) return null;\n return `${prop.target.blockId}__${String(prop.target.path ?? \"\").replace(/^props\\./, \"\")}`;\n}\n\nexport function componentInstanceAddresses(\n instanceBlockId: string,\n props: readonly PropTarget[] | undefined,\n): Map<string, string> {\n const out = new Map<string, string>();\n for (const prop of props ?? []) {\n if (!prop?.key || !prop.target?.blockId) continue;\n const from = componentPropTargetKey(prop)!;\n // Two props aimed at one target would make the address ambiguous; first declaration wins\n // and the duplicate is dropped rather than silently overwriting it.\n if (!out.has(from)) out.set(from, `${instanceBlockId}__overrides.${prop.key}`);\n }\n return out;\n}\n","/**\n * FLO-264 — bounded block-style tokens → CSS. Framework-agnostic (returns a plain\n * declaration object, no React types) so every renderer shares ONE mapping: the\n * headless @bettercms-ai/next adapter, @bettercms-ai/ui, and (string form) the hosted\n * render-page.ts. Unknown tokens are dropped — closed set, no arbitrary CSS.\n */\nimport type { BlockStyle } from \"./block.js\";\n\nconst SPACE_PX: Record<string, string> = { none: \"0\", xs: \"4px\", sm: \"8px\", md: \"16px\", lg: \"32px\", xl: \"64px\" };\nconst FONT_SIZE_REM: Record<string, string> = { sm: \"0.875rem\", base: \"1rem\", lg: \"1.25rem\", xl: \"1.5rem\", \"2xl\": \"2rem\" };\nconst WEIGHT: Record<string, number> = { normal: 400, medium: 500, semibold: 600, bold: 700 };\nconst RADIUS_PX: Record<string, string> = { none: \"0\", sm: \"4px\", md: \"8px\", lg: \"16px\", full: \"9999px\" };\nconst COLOR_HEX: Record<string, string> = { white: \"#ffffff\", black: \"#111111\", muted: \"#6b7280\", mutedBg: \"#f3f4f6\", primary: \"#111111\", accent: \"#4f46e5\" };\n\n/** A CSS declaration object (key → value) usable as a React `style` prop, or undefined when empty. */\nexport function blockStyleToCss(style: BlockStyle | undefined): Record<string, string | number> | undefined {\n if (!style || typeof style !== \"object\") return undefined;\n const s = style as Record<string, string>;\n const css: Record<string, string | number> = {};\n if (s.paddingY && SPACE_PX[s.paddingY] != null) { css.paddingTop = SPACE_PX[s.paddingY]!; css.paddingBottom = SPACE_PX[s.paddingY]!; }\n if (s.paddingX && SPACE_PX[s.paddingX] != null) { css.paddingLeft = SPACE_PX[s.paddingX]!; css.paddingRight = SPACE_PX[s.paddingX]!; }\n if (s.marginTop && SPACE_PX[s.marginTop] != null) css.marginTop = SPACE_PX[s.marginTop]!;\n if (s.marginBottom && SPACE_PX[s.marginBottom] != null) css.marginBottom = SPACE_PX[s.marginBottom]!;\n if (s.background && COLOR_HEX[s.background]) css.background = COLOR_HEX[s.background]!;\n if (s.textColor && COLOR_HEX[s.textColor]) css.color = COLOR_HEX[s.textColor]!;\n if (s.align === \"left\" || s.align === \"center\" || s.align === \"right\") css.textAlign = s.align;\n if (s.fontSize && FONT_SIZE_REM[s.fontSize]) css.fontSize = FONT_SIZE_REM[s.fontSize]!;\n if (s.weight && WEIGHT[s.weight] != null) css.fontWeight = WEIGHT[s.weight]!;\n if (s.radius && RADIUS_PX[s.radius] != null) css.borderRadius = RADIUS_PX[s.radius]!;\n return Object.keys(css).length ? css : undefined;\n}\n","/**\n * Component — a reusable, Webflow-style block tree (a \"symbol\").\n *\n * A component is authored once and placed across pages via `component` blocks\n * (see `ComponentBlock` in `./block.ts`). Its definition lives in `blockJson`;\n * `props` declares a flat allowlist of values an instance may override.\n */\nimport type { ContentBlock } from \"./block.js\";\nimport type { VariantInputMapping } from \"./layout.js\";\n\n/**\n * The category a component belongs to (drives library grouping + icons). The first eight\n * are structural (what the component IS); the last four are the \"Add a section\" library\n * tabs (where it appears). One varchar column, not a PG enum — widening is code-only.\n */\n/**\n * 🔴 THE STRUCTURE DOCTRINE — one sentence, one home, spliced into every surface that builds a page.\n *\n * It lives HERE, beside the component contract it describes, because there are THREE places that teach\n * an agent how to build a page and they drifted apart:\n * • `packages/mcp/src/tools.ts` — the MCP tool descriptions (external agents)\n * • `src/lib/ai/agent.ts` — the in-product Studio Agent's system prompt\n * • `packages/mcp/src/prompts.ts` — the authoring playbook, which a tool call does not carry\n *\n * Only the playbook explained sections. `create_page` taught the SCHEMA axis in detail (\"each visual\n * section becomes a nested field\") and said nothing about STRUCTURE; the Studio Agent's prompt named\n * \"pages & reusable components (structure/layout)\" without ever mentioning `sectionType`.\n *\n * Measured consequence, production 2026-08-18: project `acme` has three components, ALL with\n * `section_type = (none)`, and its home page is 18 loose top-level blocks with ZERO sections. Every\n * generated page came out flat, so the visual editor's section lane — outline, name, move, duplicate,\n * delete, variant swap — had nothing to attach to. The editor was faithfully showing pages that were\n * never built out of sections.\n *\n * A constant rather than three paraphrases, because updating some of them is exactly how this happened.\n */\nexport const SECTION_DOCTRINE =\n \"STRUCTURE (separate from schema): a page is composed of SECTIONS. NEVER build a page out of loose top-level heading/text/image/button/spacer blocks — they cannot be moved, duplicated or swapped as a unit, the visual editor cannot outline or name them, and every one of them becomes its own section in the editor. A hero of a headline, a lede and two CTAs is ONE section, not four. TWO SHAPES, and the choice is about REUSE. (1) A band that appears on more than one page, or that needs layout variants, is a COMPONENT with a `sectionType` — see create_component. Components sharing a `sectionType` are that section's VARIANTS (one Hero: 'Centered' for the home page and 'Two-column' for about, same prop keys so a swap keeps the content). This is also the only shape the editor's 'Add a section' picker can insert, and the only one that gets a family name and a variant switcher. (2) A genuinely one-off band on a single page is a `section` BLOCK whose `props.children` hold its blocks. THE TRADEOFF, stated in the present tense because it is real today: inside a component, ONLY the leaves a declared prop TARGETS are click-to-edit on the canvas — each declared prop's `target` is re-keyed to that PLACEMENT's own override address, so editing it changes this page and not the shared definition. A prop with no `target` still SHOWS as a dock control, but its override reaches no rendered slot, so editing it changes nothing on the page. Copy that no prop points at is worse still: no binding and no control, unreachable from click-to-edit AND from the dock, changeable only by editing the component definition, which rewrites every page that places it. A `section` block's children stay click-to-edit unconditionally. So when you choose a component, DECLARE A PROP — WITH A `target` — for every string, link and image a marketer will ever touch; a component with un-propped editable copy is the defect, not the component. In the dock an unset prop shows EMPTY and inherits the definition's default, so set props explicitly when you want the current copy visible there. Do not hand-write a band's JSON: start from a built-in section blueprint (list_components returns locked `builtin:*` blueprints with no projectId — hero-centered, hero-split, feature-grid-three, cta-banner and nine more), each already rooted in a `section` block with its editable leaves declared as props. INLINE its blockJson as a `section` block for a one-off band; for a recurring band, materialize the blueprint with create_component so it becomes project-scoped before implementation validation, Output or publication. Direct `builtin:*` component references exist only for legacy delivery compatibility. Two consecutive call-to-action buttons are two sibling `button` blocks inside the same section — never a `columns` block, which is a `repeat(N,1fr)` grid and would stretch each CTA to half the container. Buttons are inline-level and flow side by side on their own.\";\n\nexport type ComponentCategory =\n | \"navbar\"\n | \"footer\"\n | \"button\"\n | \"section\"\n | \"slider\"\n | \"tabs\"\n | \"form\"\n | \"custom\"\n | \"hero\"\n | \"content\"\n | \"social-proof\"\n | \"conversion\";\n\n/**\n * A single overridable field on a component. `target` points at the block + JSON\n * path inside `blockJson` the override writes to (e.g. blockId \"cta\", path\n * \"props.text\"). Keeping overrides a declared allowlist (not arbitrary nested\n * rewrites) keeps instance data small and the contract explicit.\n */\nexport interface ComponentPropDef {\n key: string;\n label: string;\n target: { blockId: string; path: string };\n /**\n * `slot` holds ONE nested component instance — the component-level twin of the\n * content-model field type `component-ref` (see content-model.ts), named differently for\n * the same reason that one is: `component` already means a BLOCK type. Its value is\n * `{ componentId, overrides }` and its `target.path` is `props`, so filling a slot writes\n * that object over an empty `component` block's props.\n *\n * On a PAGE a slot fill is a LIVE reference; a published ENTRY freezes it (resolveDeep).\n */\n /**\n * The EDITOR contract, not a storage one: `applyOverrides` writes the value at\n * `target.path` whatever its shape, so `type` decides which control the inspector renders\n * and what shape that control produces (FLO-1020).\n *\n * number → a number (heading.level, columns.count)\n * select → one string from `config.options`\n * group → an object keyed by `config.fields`\n * table → an array of such objects (slider.slides)\n *\n * `reference` is absent on purpose: nothing resolves a content-entry id at component render\n * time, so such a prop would save cleanly and render as nothing.\n */\n type: \"text\" | \"richtext\" | \"image\" | \"url\" | \"boolean\" | \"number\" | \"select\" | \"group\" | \"table\" | \"slot\";\n defaultValue?: unknown;\n /** Per-type settings; the save schema enforces that each is present on the type needing it. */\n config?: {\n /** `slot` — a pick allowlist. */\n componentIds?: string[];\n /** `select` — the choices. Required, and a default must be one of them. */\n options?: string[];\n /** `group` / `table` — the sub-shape, nestable to 3 levels. */\n fields?: ComponentSubField[];\n /** `number` — bounds for the control. */\n min?: number;\n max?: number;\n step?: number;\n } & Record<string, unknown>;\n}\n\n/** One field inside a `group` prop or a `table` row. Recursive, capped at 3 levels deep. */\nexport interface ComponentSubField {\n key: string;\n label: string;\n /** No `slot`: a nested component instance belongs on the prop itself, not inside a row. */\n type: Exclude<ComponentPropDef[\"type\"], \"slot\">;\n defaultValue?: unknown;\n options?: string[];\n /** CANONICAL. A nested `group`/`table`'s own sub-shape. */\n fields?: ComponentSubField[];\n /**\n * A READ-ONLY MIRROR of `options`/`fields`, in the shape `ComponentPropDef` puts them in.\n *\n * 🔴 WHY A SECOND COPY EXISTS AT ALL. A `group`/`table` PROP declares its sub-shape under\n * `config.fields`; a sub-field of one declares its own under a bare `fields`. So a consumer\n * walking a nested table has to switch shape after the first level, and the componentize lane's\n * repo half (`@bettercms-ai/convert --componentize`) walks exactly that — it reads one node\n * shape at every depth. Mirroring the sub-shape here lets it, without the CMS having to\n * describe a nested table differently from a top-level one.\n *\n * `fields` is the authority. The save schema REFUSES a node whose mirror disagrees with it\n * (`componentPropDefSchema`), because two copies that may drift are worse than one awkward\n * shape — an editor that rewrote `fields` alone would leave a stale row description behind.\n */\n config?: { fields?: ComponentSubField[]; options?: string[] } & Record<string, unknown>;\n}\n\n/** The value a `slot` prop holds — the draft half of a `component-ref`, deliberately. */\nexport interface SlotValue {\n componentId: string;\n overrides?: Record<string, unknown>;\n}\n\n/**\n * A component is a DRAFT until published; only the published copy reaches a visitor.\n * Mirrors pages and entries. See migration 0186_component_draft_live_split.sql.\n */\nexport type ComponentStatus = \"draft\" | \"published\";\n\n/**\n * Archive state (FLO-1012), deliberately SEPARATE from `ComponentStatus`.\n *\n * Archive takes a component out of the working set — hidden from the components list by\n * default, not offered in the visual editor's insert surfaces — while every existing usage\n * keeps serving. It is not unpublish (which pulls the live copy and re-bakes every page that\n * embeds it) and it is not delete.\n *\n * It is a timestamp rather than a third `status` value because a component can be published\n * AND archived; collapsing the two would lose the bit restore has to put back.\n */\n\nexport interface Component {\n id: string;\n workspaceId: string;\n projectId?: string | null;\n name: string;\n slug: string;\n category: ComponentCategory;\n /**\n * Section library: the family this component is a LAYOUT of, e.g. \"Hero\". `name` is the\n * layout label (\"Centered\"), so components sharing a sectionType are selectable variants\n * of one section. Null/absent = an ordinary component, not shown in the section library.\n */\n sectionType?: string | null;\n /** First-class variant family membership; exact workspace/project scope is enforced in DB. */\n variantGroupId?: string | null;\n variantInputMappings?: VariantInputMapping[];\n /** Placement governance: `*`, `slug:<page-slug>`, and/or `type:<page-type>`. */\n allowedOn: string[];\n description?: string | null;\n /** The DRAFT definition. Every builder/autosave/import write path targets these two. */\n blockJson: ContentBlock[];\n props: ComponentPropDef[];\n status: ComponentStatus;\n /** When it left the working set, or null/absent while active. @see ComponentStatus */\n archivedAt?: string | Date | null;\n /** Derived from `archivedAt`, so a client never has to know the column. */\n archived?: boolean;\n /**\n * The LIVE snapshot get_components_by_handle() serves. Null until the first publish.\n * Returned by GET-one (the Compare view needs it), omitted from list rows for payload.\n */\n publishedBlockJson?: ContentBlock[] | null;\n publishedProps?: ComponentPropDef[] | null;\n publishedAt?: string | null; // ISO 8601\n /**\n * Computed in SQL on list/get, never stored:\n * status='published' AND (blockJson or props has diverged from its published copy).\n * An exact jsonb compare, so it self-clears when an edit is reverted.\n */\n pendingChanges?: boolean;\n thumbnail?: string | null;\n createdAt: string; // ISO 8601\n updatedAt: string; // ISO 8601\n}\n\n/**\n * Public/delivery projection — the fields a renderer needs to resolve instances.\n *\n * DELIBERATELY UNCHANGED by the 0186 draft/live split: delivery aliases\n * publishedBlockJson -> blockJson, so every already-deployed site and every\n * bcms-content.json on disk keeps a byte-identical wire shape. Do not add `status` here —\n * delivery only ever returns published rows, so it would always be the same constant.\n */\nexport interface DeliveryComponent {\n id: string;\n name: string;\n slug: string;\n category: ComponentCategory;\n sectionType?: string | null;\n blockJson: ContentBlock[];\n props: ComponentPropDef[];\n}\n","/**\n * Generated from lucide-react@1.8.0 dynamic icon names.\n * Legacy CamelCase identifiers remain valid for existing Layout documents.\n */\nexport const LAYOUT_SECTION_ICONS: readonly string[] = Object.freeze([\n \"LayoutPanelTop\",\n \"PanelTop\",\n \"PanelBottom\",\n \"Menu\",\n \"Navigation\",\n \"Megaphone\",\n \"GalleryHorizontal\",\n \"Rows3\",\n \"Grid2X2\",\n \"FileText\",\n \"Link\",\n \"Contact\",\n \"BadgeInfo\",\n \"Sparkles\",\n \"a-arrow-down\",\n \"a-arrow-up\",\n \"a-large-small\",\n \"accessibility\",\n \"activity\",\n \"air-vent\",\n \"airplay\",\n \"alarm-clock-check\",\n \"alarm-check\",\n \"alarm-clock-minus\",\n \"alarm-minus\",\n \"alarm-clock-off\",\n \"alarm-clock-plus\",\n \"alarm-plus\",\n \"alarm-clock\",\n \"alarm-smoke\",\n \"album\",\n \"align-center-horizontal\",\n \"align-center-vertical\",\n \"align-end-horizontal\",\n \"align-end-vertical\",\n \"align-horizontal-distribute-center\",\n \"align-horizontal-distribute-end\",\n \"align-horizontal-distribute-start\",\n \"align-horizontal-justify-center\",\n \"align-horizontal-justify-end\",\n \"align-horizontal-justify-start\",\n \"align-horizontal-space-around\",\n \"align-horizontal-space-between\",\n \"align-start-horizontal\",\n \"align-start-vertical\",\n \"align-vertical-distribute-center\",\n \"align-vertical-distribute-end\",\n \"align-vertical-distribute-start\",\n \"align-vertical-justify-center\",\n \"align-vertical-justify-end\",\n \"align-vertical-justify-start\",\n \"align-vertical-space-around\",\n \"align-vertical-space-between\",\n \"ambulance\",\n \"ampersand\",\n \"ampersands\",\n \"amphora\",\n \"anchor\",\n \"angry\",\n \"annoyed\",\n \"antenna\",\n \"anvil\",\n \"aperture\",\n \"app-window-mac\",\n \"app-window\",\n \"apple\",\n \"archive-restore\",\n \"archive-x\",\n \"archive\",\n \"armchair\",\n \"arrow-big-down-dash\",\n \"arrow-big-down\",\n \"arrow-big-left-dash\",\n \"arrow-big-left\",\n \"arrow-big-right-dash\",\n \"arrow-big-right\",\n \"arrow-big-up-dash\",\n \"arrow-big-up\",\n \"arrow-down-0-1\",\n \"arrow-down-01\",\n \"arrow-down-1-0\",\n \"arrow-down-10\",\n \"arrow-down-a-z\",\n \"arrow-down-az\",\n \"arrow-down-from-line\",\n \"arrow-down-left\",\n \"arrow-down-narrow-wide\",\n \"arrow-down-right\",\n \"arrow-down-to-dot\",\n \"arrow-down-to-line\",\n \"arrow-down-up\",\n \"arrow-down-wide-narrow\",\n \"sort-desc\",\n \"arrow-down-z-a\",\n \"arrow-down-za\",\n \"arrow-down\",\n \"arrow-left-from-line\",\n \"arrow-left-right\",\n \"arrow-left-to-line\",\n \"arrow-left\",\n \"arrow-right-from-line\",\n \"arrow-right-left\",\n \"arrow-right-to-line\",\n \"arrow-right\",\n \"arrow-up-0-1\",\n \"arrow-up-01\",\n \"arrow-up-1-0\",\n \"arrow-up-10\",\n \"arrow-up-a-z\",\n \"arrow-up-az\",\n \"arrow-up-down\",\n \"arrow-up-from-dot\",\n \"arrow-up-from-line\",\n \"arrow-up-left\",\n \"arrow-up-narrow-wide\",\n \"sort-asc\",\n \"arrow-up-right\",\n \"arrow-up-to-line\",\n \"arrow-up-wide-narrow\",\n \"arrow-up-z-a\",\n \"arrow-up-za\",\n \"arrow-up\",\n \"arrows-up-from-line\",\n \"asterisk\",\n \"at-sign\",\n \"atom\",\n \"audio-lines\",\n \"audio-waveform\",\n \"award\",\n \"axe\",\n \"axis-3d\",\n \"axis-3-d\",\n \"baby\",\n \"backpack\",\n \"badge-alert\",\n \"badge-cent\",\n \"badge-check\",\n \"verified\",\n \"badge-dollar-sign\",\n \"badge-euro\",\n \"badge-indian-rupee\",\n \"badge-info\",\n \"badge-japanese-yen\",\n \"badge-minus\",\n \"badge-percent\",\n \"badge-plus\",\n \"badge-pound-sterling\",\n \"badge-question-mark\",\n \"badge-help\",\n \"badge-russian-ruble\",\n \"badge-swiss-franc\",\n \"badge-turkish-lira\",\n \"badge-x\",\n \"badge\",\n \"baggage-claim\",\n \"balloon\",\n \"ban\",\n \"banana\",\n \"bandage\",\n \"banknote-arrow-down\",\n \"banknote-arrow-up\",\n \"banknote-x\",\n \"banknote\",\n \"barcode\",\n \"barrel\",\n \"baseline\",\n \"bath\",\n \"battery-charging\",\n \"battery-full\",\n \"battery-low\",\n \"battery-medium\",\n \"battery-plus\",\n \"battery-warning\",\n \"battery\",\n \"beaker\",\n \"bean-off\",\n \"bean\",\n \"bed-double\",\n \"bed-single\",\n \"bed\",\n \"beef-off\",\n \"beef\",\n \"beer-off\",\n \"beer\",\n \"bell-dot\",\n \"bell-electric\",\n \"bell-minus\",\n \"bell-off\",\n \"bell-plus\",\n \"bell-ring\",\n \"bell\",\n \"between-horizontal-end\",\n \"between-horizonal-end\",\n \"between-horizontal-start\",\n \"between-horizonal-start\",\n \"between-vertical-end\",\n \"between-vertical-start\",\n \"biceps-flexed\",\n \"bike\",\n \"binary\",\n \"binoculars\",\n \"biohazard\",\n \"bird\",\n \"birdhouse\",\n \"bitcoin\",\n \"blend\",\n \"blinds\",\n \"blocks\",\n \"bluetooth-connected\",\n \"bluetooth-off\",\n \"bluetooth-searching\",\n \"bluetooth\",\n \"bold\",\n \"bolt\",\n \"bomb\",\n \"bone\",\n \"book-a\",\n \"book-alert\",\n \"book-audio\",\n \"book-check\",\n \"book-copy\",\n \"book-dashed\",\n \"book-template\",\n \"book-down\",\n \"book-headphones\",\n \"book-heart\",\n \"book-image\",\n \"book-key\",\n \"book-lock\",\n \"book-marked\",\n \"book-minus\",\n \"book-open-check\",\n \"book-open-text\",\n \"book-open\",\n \"book-plus\",\n \"book-search\",\n \"book-text\",\n \"book-type\",\n \"book-up-2\",\n \"book-up\",\n \"book-user\",\n \"book-x\",\n \"book\",\n \"bookmark-check\",\n \"bookmark-minus\",\n \"bookmark-off\",\n \"bookmark-plus\",\n \"bookmark-x\",\n \"bookmark\",\n \"boom-box\",\n \"bot-message-square\",\n \"bot-off\",\n \"bot\",\n \"bottle-wine\",\n \"bow-arrow\",\n \"box\",\n \"boxes\",\n \"braces\",\n \"curly-braces\",\n \"brackets\",\n \"brain-circuit\",\n \"brain-cog\",\n \"brain\",\n \"brick-wall-fire\",\n \"brick-wall-shield\",\n \"brick-wall\",\n \"briefcase-business\",\n \"briefcase-conveyor-belt\",\n \"briefcase-medical\",\n \"briefcase\",\n \"bring-to-front\",\n \"brush-cleaning\",\n \"brush\",\n \"bubbles\",\n \"bug-off\",\n \"bug-play\",\n \"bug\",\n \"building-2\",\n \"building\",\n \"bus-front\",\n \"bus\",\n \"cable-car\",\n \"cable\",\n \"cake-slice\",\n \"cake\",\n \"calculator\",\n \"calendar-1\",\n \"calendar-arrow-down\",\n \"calendar-arrow-up\",\n \"calendar-check-2\",\n \"calendar-check\",\n \"calendar-clock\",\n \"calendar-cog\",\n \"calendar-days\",\n \"calendar-fold\",\n \"calendar-heart\",\n \"calendar-minus-2\",\n \"calendar-minus\",\n \"calendar-off\",\n \"calendar-plus-2\",\n \"calendar-plus\",\n \"calendar-range\",\n \"calendar-search\",\n \"calendar-sync\",\n \"calendar-x-2\",\n \"calendar-x\",\n \"calendar\",\n \"calendars\",\n \"camera-off\",\n \"camera\",\n \"candy-cane\",\n \"candy-off\",\n \"candy\",\n \"cannabis-off\",\n \"cannabis\",\n \"captions-off\",\n \"captions\",\n \"subtitles\",\n \"car-front\",\n \"car-taxi-front\",\n \"car\",\n \"caravan\",\n \"card-sim\",\n \"carrot\",\n \"case-lower\",\n \"case-sensitive\",\n \"case-upper\",\n \"cassette-tape\",\n \"cast\",\n \"castle\",\n \"cat\",\n \"cctv-off\",\n \"cctv\",\n \"chart-area\",\n \"area-chart\",\n \"chart-bar-big\",\n \"bar-chart-horizontal-big\",\n \"chart-bar-decreasing\",\n \"chart-bar-increasing\",\n \"chart-bar-stacked\",\n \"chart-bar\",\n \"bar-chart-horizontal\",\n \"chart-candlestick\",\n \"candlestick-chart\",\n \"chart-column-big\",\n \"bar-chart-big\",\n \"chart-column-decreasing\",\n \"chart-column-increasing\",\n \"bar-chart-4\",\n \"chart-column-stacked\",\n \"chart-column\",\n \"bar-chart-3\",\n \"chart-gantt\",\n \"chart-line\",\n \"line-chart\",\n \"chart-network\",\n \"chart-no-axes-column-decreasing\",\n \"chart-no-axes-column-increasing\",\n \"bar-chart\",\n \"chart-no-axes-column\",\n \"bar-chart-2\",\n \"chart-no-axes-combined\",\n \"chart-no-axes-gantt\",\n \"gantt-chart\",\n \"chart-pie\",\n \"pie-chart\",\n \"chart-scatter\",\n \"scatter-chart\",\n \"chart-spline\",\n \"check-check\",\n \"check-line\",\n \"check\",\n \"chef-hat\",\n \"cherry\",\n \"chess-bishop\",\n \"chess-king\",\n \"chess-knight\",\n \"chess-pawn\",\n \"chess-queen\",\n \"chess-rook\",\n \"chevron-down\",\n \"chevron-first\",\n \"chevron-last\",\n \"chevron-left\",\n \"chevron-right\",\n \"chevron-up\",\n \"chevrons-down-up\",\n \"chevrons-down\",\n \"chevrons-left-right-ellipsis\",\n \"chevrons-left-right\",\n \"chevrons-left\",\n \"chevrons-right-left\",\n \"chevrons-right\",\n \"chevrons-up-down\",\n \"chevrons-up\",\n \"church\",\n \"cigarette-off\",\n \"cigarette\",\n \"circle-alert\",\n \"alert-circle\",\n \"circle-arrow-down\",\n \"arrow-down-circle\",\n \"circle-arrow-left\",\n \"arrow-left-circle\",\n \"circle-arrow-out-down-left\",\n \"arrow-down-left-from-circle\",\n \"circle-arrow-out-down-right\",\n \"arrow-down-right-from-circle\",\n \"circle-arrow-out-up-left\",\n \"arrow-up-left-from-circle\",\n \"circle-arrow-out-up-right\",\n \"arrow-up-right-from-circle\",\n \"circle-arrow-right\",\n \"arrow-right-circle\",\n \"circle-arrow-up\",\n \"arrow-up-circle\",\n \"circle-check-big\",\n \"check-circle\",\n \"circle-check\",\n \"check-circle-2\",\n \"circle-chevron-down\",\n \"chevron-down-circle\",\n \"circle-chevron-left\",\n \"chevron-left-circle\",\n \"circle-chevron-right\",\n \"chevron-right-circle\",\n \"circle-chevron-up\",\n \"chevron-up-circle\",\n \"circle-dashed\",\n \"circle-divide\",\n \"divide-circle\",\n \"circle-dollar-sign\",\n \"circle-dot-dashed\",\n \"circle-dot\",\n \"circle-ellipsis\",\n \"circle-equal\",\n \"circle-fading-arrow-up\",\n \"circle-fading-plus\",\n \"circle-gauge\",\n \"gauge-circle\",\n \"circle-minus\",\n \"minus-circle\",\n \"circle-off\",\n \"circle-parking-off\",\n \"parking-circle-off\",\n \"circle-parking\",\n \"parking-circle\",\n \"circle-pause\",\n \"pause-circle\",\n \"circle-percent\",\n \"percent-circle\",\n \"circle-pile\",\n \"circle-play\",\n \"play-circle\",\n \"circle-plus\",\n \"plus-circle\",\n \"circle-pound-sterling\",\n \"circle-power\",\n \"power-circle\",\n \"circle-question-mark\",\n \"help-circle\",\n \"circle-help\",\n \"circle-slash-2\",\n \"circle-slashed\",\n \"circle-slash\",\n \"circle-small\",\n \"circle-star\",\n \"circle-stop\",\n \"stop-circle\",\n \"circle-user-round\",\n \"user-circle-2\",\n \"circle-user\",\n \"user-circle\",\n \"circle-x\",\n \"x-circle\",\n \"circle\",\n \"circuit-board\",\n \"citrus\",\n \"clapperboard\",\n \"clipboard-check\",\n \"clipboard-clock\",\n \"clipboard-copy\",\n \"clipboard-list\",\n \"clipboard-minus\",\n \"clipboard-paste\",\n \"clipboard-pen-line\",\n \"clipboard-signature\",\n \"clipboard-pen\",\n \"clipboard-edit\",\n \"clipboard-plus\",\n \"clipboard-type\",\n \"clipboard-x\",\n \"clipboard\",\n \"clock-1\",\n \"clock-10\",\n \"clock-11\",\n \"clock-12\",\n \"clock-2\",\n \"clock-3\",\n \"clock-4\",\n \"clock-5\",\n \"clock-6\",\n \"clock-7\",\n \"clock-8\",\n \"clock-9\",\n \"clock-alert\",\n \"clock-arrow-down\",\n \"clock-arrow-up\",\n \"clock-check\",\n \"clock-fading\",\n \"clock-plus\",\n \"clock\",\n \"closed-caption\",\n \"cloud-alert\",\n \"cloud-backup\",\n \"cloud-check\",\n \"cloud-cog\",\n \"cloud-download\",\n \"download-cloud\",\n \"cloud-drizzle\",\n \"cloud-fog\",\n \"cloud-hail\",\n \"cloud-lightning\",\n \"cloud-moon-rain\",\n \"cloud-moon\",\n \"cloud-off\",\n \"cloud-rain-wind\",\n \"cloud-rain\",\n \"cloud-snow\",\n \"cloud-sun-rain\",\n \"cloud-sun\",\n \"cloud-sync\",\n \"cloud-upload\",\n \"upload-cloud\",\n \"cloud\",\n \"cloudy\",\n \"clover\",\n \"club\",\n \"code-xml\",\n \"code-2\",\n \"code\",\n \"coffee\",\n \"cog\",\n \"coins\",\n \"columns-2\",\n \"columns\",\n \"columns-3-cog\",\n \"columns-settings\",\n \"table-config\",\n \"columns-3\",\n \"panels-left-right\",\n \"columns-4\",\n \"combine\",\n \"command\",\n \"compass\",\n \"component\",\n \"computer\",\n \"concierge-bell\",\n \"cone\",\n \"construction\",\n \"contact-round\",\n \"contact-2\",\n \"contact\",\n \"container\",\n \"contrast\",\n \"cookie\",\n \"cooking-pot\",\n \"copy-check\",\n \"copy-minus\",\n \"copy-plus\",\n \"copy-slash\",\n \"copy-x\",\n \"copy\",\n \"copyleft\",\n \"copyright\",\n \"corner-down-left\",\n \"corner-down-right\",\n \"corner-left-down\",\n \"corner-left-up\",\n \"corner-right-down\",\n \"corner-right-up\",\n \"corner-up-left\",\n \"corner-up-right\",\n \"cpu\",\n \"creative-commons\",\n \"credit-card\",\n \"croissant\",\n \"crop\",\n \"cross\",\n \"crosshair\",\n \"crown\",\n \"cuboid\",\n \"cup-soda\",\n \"currency\",\n \"cylinder\",\n \"dam\",\n \"database-backup\",\n \"database-search\",\n \"database-zap\",\n \"database\",\n \"decimals-arrow-left\",\n \"decimals-arrow-right\",\n \"delete\",\n \"dessert\",\n \"diameter\",\n \"diamond-minus\",\n \"diamond-percent\",\n \"percent-diamond\",\n \"diamond-plus\",\n \"diamond\",\n \"dice-1\",\n \"dice-2\",\n \"dice-3\",\n \"dice-4\",\n \"dice-5\",\n \"dice-6\",\n \"dices\",\n \"diff\",\n \"disc-2\",\n \"disc-3\",\n \"disc-album\",\n \"disc\",\n \"divide\",\n \"dna-off\",\n \"dna\",\n \"dock\",\n \"dog\",\n \"dollar-sign\",\n \"donut\",\n \"door-closed-locked\",\n \"door-closed\",\n \"door-open\",\n \"dot\",\n \"download\",\n \"drafting-compass\",\n \"drama\",\n \"drill\",\n \"drone\",\n \"droplet-off\",\n \"droplet\",\n \"droplets\",\n \"drum\",\n \"drumstick\",\n \"dumbbell\",\n \"ear-off\",\n \"ear\",\n \"earth-lock\",\n \"earth\",\n \"globe-2\",\n \"eclipse\",\n \"egg-fried\",\n \"egg-off\",\n \"egg\",\n \"ellipse\",\n \"ellipsis-vertical\",\n \"more-vertical\",\n \"ellipsis\",\n \"more-horizontal\",\n \"equal-approximately\",\n \"equal-not\",\n \"equal\",\n \"eraser\",\n \"ethernet-port\",\n \"euro\",\n \"ev-charger\",\n \"expand\",\n \"external-link\",\n \"eye-closed\",\n \"eye-off\",\n \"eye\",\n \"factory\",\n \"fan\",\n \"fast-forward\",\n \"feather\",\n \"fence\",\n \"ferris-wheel\",\n \"file-archive\",\n \"file-axis-3d\",\n \"file-axis-3-d\",\n \"file-badge\",\n \"file-badge-2\",\n \"file-box\",\n \"file-braces-corner\",\n \"file-json-2\",\n \"file-braces\",\n \"file-json\",\n \"file-chart-column-increasing\",\n \"file-bar-chart\",\n \"file-chart-column\",\n \"file-bar-chart-2\",\n \"file-chart-line\",\n \"file-line-chart\",\n \"file-chart-pie\",\n \"file-pie-chart\",\n \"file-check-corner\",\n \"file-check-2\",\n \"file-check\",\n \"file-clock\",\n \"file-code-corner\",\n \"file-code-2\",\n \"file-code\",\n \"file-cog\",\n \"file-cog-2\",\n \"file-diff\",\n \"file-digit\",\n \"file-down\",\n \"file-exclamation-point\",\n \"file-warning\",\n \"file-headphone\",\n \"file-audio\",\n \"file-audio-2\",\n \"file-heart\",\n \"file-image\",\n \"file-input\",\n \"file-key\",\n \"file-key-2\",\n \"file-lock\",\n \"file-lock-2\",\n \"file-minus-corner\",\n \"file-minus-2\",\n \"file-minus\",\n \"file-music\",\n \"file-output\",\n \"file-pen-line\",\n \"file-signature\",\n \"file-pen\",\n \"file-edit\",\n \"file-play\",\n \"file-video\",\n \"file-plus-corner\",\n \"file-plus-2\",\n \"file-plus\",\n \"file-question-mark\",\n \"file-question\",\n \"file-scan\",\n \"file-search-corner\",\n \"file-search-2\",\n \"file-search\",\n \"file-signal\",\n \"file-volume-2\",\n \"file-sliders\",\n \"file-spreadsheet\",\n \"file-stack\",\n \"file-symlink\",\n \"file-terminal\",\n \"file-text\",\n \"file-type-corner\",\n \"file-type-2\",\n \"file-type\",\n \"file-up\",\n \"file-user\",\n \"file-video-camera\",\n \"file-video-2\",\n \"file-volume\",\n \"file-x-corner\",\n \"file-x-2\",\n \"file-x\",\n \"file\",\n \"files\",\n \"film\",\n \"fingerprint-pattern\",\n \"fingerprint\",\n \"fire-extinguisher\",\n \"fish-off\",\n \"fish-symbol\",\n \"fish\",\n \"fishing-hook\",\n \"fishing-rod\",\n \"flag-off\",\n \"flag-triangle-left\",\n \"flag-triangle-right\",\n \"flag\",\n \"flame-kindling\",\n \"flame\",\n \"flashlight-off\",\n \"flashlight\",\n \"flask-conical-off\",\n \"flask-conical\",\n \"flask-round\",\n \"flip-horizontal-2\",\n \"flip-vertical-2\",\n \"flower-2\",\n \"flower\",\n \"focus\",\n \"fold-horizontal\",\n \"fold-vertical\",\n \"folder-archive\",\n \"folder-check\",\n \"folder-clock\",\n \"folder-closed\",\n \"folder-code\",\n \"folder-cog\",\n \"folder-cog-2\",\n \"folder-dot\",\n \"folder-down\",\n \"folder-git-2\",\n \"folder-git\",\n \"folder-heart\",\n \"folder-input\",\n \"folder-kanban\",\n \"folder-key\",\n \"folder-lock\",\n \"folder-minus\",\n \"folder-open-dot\",\n \"folder-open\",\n \"folder-output\",\n \"folder-pen\",\n \"folder-edit\",\n \"folder-plus\",\n \"folder-root\",\n \"folder-search-2\",\n \"folder-search\",\n \"folder-symlink\",\n \"folder-sync\",\n \"folder-tree\",\n \"folder-up\",\n \"folder-x\",\n \"folder\",\n \"folders\",\n \"footprints\",\n \"forklift\",\n \"form\",\n \"forward\",\n \"frame\",\n \"frown\",\n \"fuel\",\n \"fullscreen\",\n \"funnel-plus\",\n \"funnel-x\",\n \"filter-x\",\n \"funnel\",\n \"filter\",\n \"gallery-horizontal-end\",\n \"gallery-horizontal\",\n \"gallery-thumbnails\",\n \"gallery-vertical-end\",\n \"gallery-vertical\",\n \"gamepad-2\",\n \"gamepad-directional\",\n \"gamepad\",\n \"gauge\",\n \"gavel\",\n \"gem\",\n \"georgian-lari\",\n \"ghost\",\n \"gift\",\n \"git-branch-minus\",\n \"git-branch-plus\",\n \"git-branch\",\n \"git-commit-horizontal\",\n \"git-commit\",\n \"git-commit-vertical\",\n \"git-compare-arrows\",\n \"git-compare\",\n \"git-fork\",\n \"git-graph\",\n \"git-merge-conflict\",\n \"git-merge\",\n \"git-pull-request-arrow\",\n \"git-pull-request-closed\",\n \"git-pull-request-create-arrow\",\n \"git-pull-request-create\",\n \"git-pull-request-draft\",\n \"git-pull-request\",\n \"glass-water\",\n \"glasses\",\n \"globe-lock\",\n \"globe-off\",\n \"globe-x\",\n \"globe\",\n \"goal\",\n \"gpu\",\n \"graduation-cap\",\n \"grape\",\n \"grid-2x2-check\",\n \"grid-2-x-2-check\",\n \"grid-2x2-plus\",\n \"grid-2-x-2-plus\",\n \"grid-2x2-x\",\n \"grid-2-x-2-x\",\n \"grid-2x2\",\n \"grid-2-x-2\",\n \"grid-3x2\",\n \"grid-3x3\",\n \"grid\",\n \"grid-3-x-3\",\n \"grip-horizontal\",\n \"grip-vertical\",\n \"grip\",\n \"group\",\n \"guitar\",\n \"ham\",\n \"hamburger\",\n \"hammer\",\n \"hand-coins\",\n \"hand-fist\",\n \"hand-grab\",\n \"grab\",\n \"hand-heart\",\n \"hand-helping\",\n \"helping-hand\",\n \"hand-metal\",\n \"hand-platter\",\n \"hand\",\n \"handbag\",\n \"handshake\",\n \"hard-drive-download\",\n \"hard-drive-upload\",\n \"hard-drive\",\n \"hard-hat\",\n \"hash\",\n \"hat-glasses\",\n \"haze\",\n \"hd\",\n \"hdmi-port\",\n \"heading-1\",\n \"heading-2\",\n \"heading-3\",\n \"heading-4\",\n \"heading-5\",\n \"heading-6\",\n \"heading\",\n \"headphone-off\",\n \"headphones\",\n \"headset\",\n \"heart-crack\",\n \"heart-handshake\",\n \"heart-minus\",\n \"heart-off\",\n \"heart-plus\",\n \"heart-pulse\",\n \"heart\",\n \"heater\",\n \"helicopter\",\n \"hexagon\",\n \"highlighter\",\n \"history\",\n \"hop-off\",\n \"hop\",\n \"hospital\",\n \"hotel\",\n \"hourglass\",\n \"house-heart\",\n \"house-plug\",\n \"house-plus\",\n \"house-wifi\",\n \"house\",\n \"home\",\n \"ice-cream-bowl\",\n \"ice-cream-2\",\n \"ice-cream-cone\",\n \"ice-cream\",\n \"id-card-lanyard\",\n \"id-card\",\n \"image-down\",\n \"image-minus\",\n \"image-off\",\n \"image-play\",\n \"image-plus\",\n \"image-up\",\n \"image-upscale\",\n \"image\",\n \"images\",\n \"import\",\n \"inbox\",\n \"indian-rupee\",\n \"infinity\",\n \"info\",\n \"inspection-panel\",\n \"italic\",\n \"iteration-ccw\",\n \"iteration-cw\",\n \"japanese-yen\",\n \"joystick\",\n \"kanban\",\n \"kayak\",\n \"key-round\",\n \"key-square\",\n \"key\",\n \"keyboard-music\",\n \"keyboard-off\",\n \"keyboard\",\n \"lamp-ceiling\",\n \"lamp-desk\",\n \"lamp-floor\",\n \"lamp-wall-down\",\n \"lamp-wall-up\",\n \"lamp\",\n \"land-plot\",\n \"landmark\",\n \"languages\",\n \"laptop-minimal-check\",\n \"laptop-minimal\",\n \"laptop-2\",\n \"laptop\",\n \"lasso-select\",\n \"lasso\",\n \"laugh\",\n \"layers-2\",\n \"layers-plus\",\n \"layers\",\n \"layers-3\",\n \"layout-dashboard\",\n \"layout-grid\",\n \"layout-list\",\n \"layout-panel-left\",\n \"layout-panel-top\",\n \"layout-template\",\n \"leaf\",\n \"leafy-green\",\n \"lectern\",\n \"lens-concave\",\n \"lens-convex\",\n \"library-big\",\n \"library\",\n \"life-buoy\",\n \"ligature\",\n \"lightbulb-off\",\n \"lightbulb\",\n \"line-dot-right-horizontal\",\n \"line-squiggle\",\n \"line-style\",\n \"link-2-off\",\n \"link-2\",\n \"link\",\n \"list-check\",\n \"list-checks\",\n \"list-chevrons-down-up\",\n \"list-chevrons-up-down\",\n \"list-collapse\",\n \"list-end\",\n \"list-filter-plus\",\n \"list-filter\",\n \"list-indent-decrease\",\n \"outdent\",\n \"indent-decrease\",\n \"list-indent-increase\",\n \"indent\",\n \"indent-increase\",\n \"list-minus\",\n \"list-music\",\n \"list-ordered\",\n \"list-plus\",\n \"list-restart\",\n \"list-start\",\n \"list-todo\",\n \"list-tree\",\n \"list-video\",\n \"list-x\",\n \"list\",\n \"loader-circle\",\n \"loader-2\",\n \"loader-pinwheel\",\n \"loader\",\n \"locate-fixed\",\n \"locate-off\",\n \"locate\",\n \"lock-keyhole-open\",\n \"unlock-keyhole\",\n \"lock-keyhole\",\n \"lock-open\",\n \"unlock\",\n \"lock\",\n \"log-in\",\n \"log-out\",\n \"logs\",\n \"lollipop\",\n \"luggage\",\n \"magnet\",\n \"mail-check\",\n \"mail-minus\",\n \"mail-open\",\n \"mail-plus\",\n \"mail-question-mark\",\n \"mail-question\",\n \"mail-search\",\n \"mail-warning\",\n \"mail-x\",\n \"mail\",\n \"mailbox\",\n \"mails\",\n \"map-minus\",\n \"map-pin-check-inside\",\n \"map-pin-check\",\n \"map-pin-house\",\n \"map-pin-minus-inside\",\n \"map-pin-minus\",\n \"map-pin-off\",\n \"map-pin-pen\",\n \"location-edit\",\n \"map-pin-plus-inside\",\n \"map-pin-plus\",\n \"map-pin-search\",\n \"map-pin-x-inside\",\n \"map-pin-x\",\n \"map-pin\",\n \"map-pinned\",\n \"map-plus\",\n \"map\",\n \"mars-stroke\",\n \"mars\",\n \"martini\",\n \"maximize-2\",\n \"maximize\",\n \"medal\",\n \"megaphone-off\",\n \"megaphone\",\n \"meh\",\n \"memory-stick\",\n \"menu\",\n \"merge\",\n \"message-circle-check\",\n \"message-circle-code\",\n \"message-circle-dashed\",\n \"message-circle-heart\",\n \"message-circle-more\",\n \"message-circle-off\",\n \"message-circle-plus\",\n \"message-circle-question-mark\",\n \"message-circle-question\",\n \"message-circle-reply\",\n \"message-circle-warning\",\n \"message-circle-x\",\n \"message-circle\",\n \"message-square-check\",\n \"message-square-code\",\n \"message-square-dashed\",\n \"message-square-diff\",\n \"message-square-dot\",\n \"message-square-heart\",\n \"message-square-lock\",\n \"message-square-more\",\n \"message-square-off\",\n \"message-square-plus\",\n \"message-square-quote\",\n \"message-square-reply\",\n \"message-square-share\",\n \"message-square-text\",\n \"message-square-warning\",\n \"message-square-x\",\n \"message-square\",\n \"messages-square\",\n \"metronome\",\n \"mic-off\",\n \"mic-vocal\",\n \"mic-2\",\n \"mic\",\n \"microchip\",\n \"microscope\",\n \"microwave\",\n \"milestone\",\n \"milk-off\",\n \"milk\",\n \"minimize-2\",\n \"minimize\",\n \"minus\",\n \"mirror-rectangular\",\n \"mirror-round\",\n \"monitor-check\",\n \"monitor-cloud\",\n \"monitor-cog\",\n \"monitor-dot\",\n \"monitor-down\",\n \"monitor-off\",\n \"monitor-pause\",\n \"monitor-play\",\n \"monitor-smartphone\",\n \"monitor-speaker\",\n \"monitor-stop\",\n \"monitor-up\",\n \"monitor-x\",\n \"monitor\",\n \"moon-star\",\n \"moon\",\n \"motorbike\",\n \"mountain-snow\",\n \"mountain\",\n \"mouse-left\",\n \"mouse-off\",\n \"mouse-pointer-2-off\",\n \"mouse-pointer-2\",\n \"mouse-pointer-ban\",\n \"mouse-pointer-click\",\n \"mouse-pointer\",\n \"mouse-right\",\n \"mouse\",\n \"move-3d\",\n \"move-3-d\",\n \"move-diagonal-2\",\n \"move-diagonal\",\n \"move-down-left\",\n \"move-down-right\",\n \"move-down\",\n \"move-horizontal\",\n \"move-left\",\n \"move-right\",\n \"move-up-left\",\n \"move-up-right\",\n \"move-up\",\n \"move-vertical\",\n \"move\",\n \"music-2\",\n \"music-3\",\n \"music-4\",\n \"music\",\n \"navigation-2-off\",\n \"navigation-2\",\n \"navigation-off\",\n \"navigation\",\n \"network\",\n \"newspaper\",\n \"nfc\",\n \"non-binary\",\n \"notebook-pen\",\n \"notebook-tabs\",\n \"notebook-text\",\n \"notebook\",\n \"notepad-text-dashed\",\n \"notepad-text\",\n \"nut-off\",\n \"nut\",\n \"octagon-alert\",\n \"alert-octagon\",\n \"octagon-minus\",\n \"octagon-pause\",\n \"pause-octagon\",\n \"octagon-x\",\n \"x-octagon\",\n \"octagon\",\n \"omega\",\n \"option\",\n \"orbit\",\n \"origami\",\n \"package-2\",\n \"package-check\",\n \"package-minus\",\n \"package-open\",\n \"package-plus\",\n \"package-search\",\n \"package-x\",\n \"package\",\n \"paint-bucket\",\n \"paint-roller\",\n \"paintbrush-vertical\",\n \"paintbrush-2\",\n \"paintbrush\",\n \"palette\",\n \"panda\",\n \"panel-bottom-close\",\n \"panel-bottom-dashed\",\n \"panel-bottom-inactive\",\n \"panel-bottom-open\",\n \"panel-bottom\",\n \"panel-left-close\",\n \"sidebar-close\",\n \"panel-left-dashed\",\n \"panel-left-inactive\",\n \"panel-left-open\",\n \"sidebar-open\",\n \"panel-left-right-dashed\",\n \"panel-left\",\n \"sidebar\",\n \"panel-right-close\",\n \"panel-right-dashed\",\n \"panel-right-inactive\",\n \"panel-right-open\",\n \"panel-right\",\n \"panel-top-bottom-dashed\",\n \"panel-top-close\",\n \"panel-top-dashed\",\n \"panel-top-inactive\",\n \"panel-top-open\",\n \"panel-top\",\n \"panels-left-bottom\",\n \"panels-right-bottom\",\n \"panels-top-left\",\n \"layout\",\n \"paperclip\",\n \"parentheses\",\n \"parking-meter\",\n \"party-popper\",\n \"pause\",\n \"paw-print\",\n \"pc-case\",\n \"pen-line\",\n \"edit-3\",\n \"pen-off\",\n \"pen-tool\",\n \"pen\",\n \"edit-2\",\n \"pencil-line\",\n \"pencil-off\",\n \"pencil-ruler\",\n \"pencil\",\n \"pentagon\",\n \"percent\",\n \"person-standing\",\n \"philippine-peso\",\n \"phone-call\",\n \"phone-forwarded\",\n \"phone-incoming\",\n \"phone-missed\",\n \"phone-off\",\n \"phone-outgoing\",\n \"phone\",\n \"pi\",\n \"piano\",\n \"pickaxe\",\n \"picture-in-picture-2\",\n \"picture-in-picture\",\n \"piggy-bank\",\n \"pilcrow-left\",\n \"pilcrow-right\",\n \"pilcrow\",\n \"pill-bottle\",\n \"pill\",\n \"pin-off\",\n \"pin\",\n \"pipette\",\n \"pizza\",\n \"plane-landing\",\n \"plane-takeoff\",\n \"plane\",\n \"play\",\n \"plug-2\",\n \"plug-zap\",\n \"plug-zap-2\",\n \"plug\",\n \"plus\",\n \"pocket-knife\",\n \"podcast\",\n \"pointer-off\",\n \"pointer\",\n \"popcorn\",\n \"popsicle\",\n \"pound-sterling\",\n \"power-off\",\n \"power\",\n \"presentation\",\n \"printer-check\",\n \"printer-x\",\n \"printer\",\n \"projector\",\n \"proportions\",\n \"puzzle\",\n \"pyramid\",\n \"qr-code\",\n \"quote\",\n \"rabbit\",\n \"radar\",\n \"radiation\",\n \"radical\",\n \"radio-off\",\n \"radio-receiver\",\n \"radio-tower\",\n \"radio\",\n \"radius\",\n \"rainbow\",\n \"rat\",\n \"ratio\",\n \"receipt-cent\",\n \"receipt-euro\",\n \"receipt-indian-rupee\",\n \"receipt-japanese-yen\",\n \"receipt-pound-sterling\",\n \"receipt-russian-ruble\",\n \"receipt-swiss-franc\",\n \"receipt-text\",\n \"receipt-turkish-lira\",\n \"receipt\",\n \"rectangle-circle\",\n \"rectangle-ellipsis\",\n \"form-input\",\n \"rectangle-goggles\",\n \"rectangle-horizontal\",\n \"rectangle-vertical\",\n \"recycle\",\n \"redo-2\",\n \"redo-dot\",\n \"redo\",\n \"refresh-ccw-dot\",\n \"refresh-ccw\",\n \"refresh-cw-off\",\n \"refresh-cw\",\n \"refrigerator\",\n \"regex\",\n \"remove-formatting\",\n \"repeat-1\",\n \"repeat-2\",\n \"repeat\",\n \"replace-all\",\n \"replace\",\n \"reply-all\",\n \"reply\",\n \"rewind\",\n \"ribbon\",\n \"road\",\n \"rocket\",\n \"rocking-chair\",\n \"roller-coaster\",\n \"rose\",\n \"rotate-3d\",\n \"rotate-3-d\",\n \"rotate-ccw-key\",\n \"rotate-ccw-square\",\n \"rotate-ccw\",\n \"rotate-cw-square\",\n \"rotate-cw\",\n \"route-off\",\n \"route\",\n \"router\",\n \"rows-2\",\n \"rows\",\n \"rows-3\",\n \"panels-top-bottom\",\n \"rows-4\",\n \"rss\",\n \"ruler-dimension-line\",\n \"ruler\",\n \"russian-ruble\",\n \"sailboat\",\n \"salad\",\n \"sandwich\",\n \"satellite-dish\",\n \"satellite\",\n \"saudi-riyal\",\n \"save-all\",\n \"save-off\",\n \"save\",\n \"scale-3d\",\n \"scale-3-d\",\n \"scale\",\n \"scaling\",\n \"scan-barcode\",\n \"scan-eye\",\n \"scan-face\",\n \"scan-heart\",\n \"scan-line\",\n \"scan-qr-code\",\n \"scan-search\",\n \"scan-text\",\n \"scan\",\n \"school\",\n \"scissors-line-dashed\",\n \"scissors\",\n \"scooter\",\n \"screen-share-off\",\n \"screen-share\",\n \"scroll-text\",\n \"scroll\",\n \"search-alert\",\n \"search-check\",\n \"search-code\",\n \"search-slash\",\n \"search-x\",\n \"search\",\n \"section\",\n \"send-horizontal\",\n \"send-horizonal\",\n \"send-to-back\",\n \"send\",\n \"separator-horizontal\",\n \"separator-vertical\",\n \"server-cog\",\n \"server-crash\",\n \"server-off\",\n \"server\",\n \"settings-2\",\n \"settings\",\n \"shapes\",\n \"share-2\",\n \"share\",\n \"sheet\",\n \"shell\",\n \"shelving-unit\",\n \"shield-alert\",\n \"shield-ban\",\n \"shield-check\",\n \"shield-cog-corner\",\n \"shield-cog\",\n \"shield-ellipsis\",\n \"shield-half\",\n \"shield-minus\",\n \"shield-off\",\n \"shield-plus\",\n \"shield-question-mark\",\n \"shield-question\",\n \"shield-user\",\n \"shield-x\",\n \"shield-close\",\n \"shield\",\n \"ship-wheel\",\n \"ship\",\n \"shirt\",\n \"shopping-bag\",\n \"shopping-basket\",\n \"shopping-cart\",\n \"shovel\",\n \"shower-head\",\n \"shredder\",\n \"shrimp\",\n \"shrink\",\n \"shrub\",\n \"shuffle\",\n \"sigma\",\n \"signal-high\",\n \"signal-low\",\n \"signal-medium\",\n \"signal-zero\",\n \"signal\",\n \"signature\",\n \"signpost-big\",\n \"signpost\",\n \"siren\",\n \"skip-back\",\n \"skip-forward\",\n \"skull\",\n \"slash\",\n \"slice\",\n \"sliders-horizontal\",\n \"sliders-vertical\",\n \"sliders\",\n \"smartphone-charging\",\n \"smartphone-nfc\",\n \"smartphone\",\n \"smile-plus\",\n \"smile\",\n \"snail\",\n \"snowflake\",\n \"soap-dispenser-droplet\",\n \"sofa\",\n \"solar-panel\",\n \"soup\",\n \"space\",\n \"spade\",\n \"sparkle\",\n \"sparkles\",\n \"stars\",\n \"speaker\",\n \"speech\",\n \"spell-check-2\",\n \"spell-check\",\n \"spline-pointer\",\n \"spline\",\n \"split\",\n \"spool\",\n \"sport-shoe\",\n \"spotlight\",\n \"spray-can\",\n \"sprout\",\n \"square-activity\",\n \"activity-square\",\n \"square-arrow-down-left\",\n \"arrow-down-left-square\",\n \"square-arrow-down-right\",\n \"arrow-down-right-square\",\n \"square-arrow-down\",\n \"arrow-down-square\",\n \"square-arrow-left\",\n \"arrow-left-square\",\n \"square-arrow-out-down-left\",\n \"arrow-down-left-from-square\",\n \"square-arrow-out-down-right\",\n \"arrow-down-right-from-square\",\n \"square-arrow-out-up-left\",\n \"arrow-up-left-from-square\",\n \"square-arrow-out-up-right\",\n \"arrow-up-right-from-square\",\n \"square-arrow-right-enter\",\n \"square-arrow-right-exit\",\n \"square-arrow-right\",\n \"arrow-right-square\",\n \"square-arrow-up-left\",\n \"arrow-up-left-square\",\n \"square-arrow-up-right\",\n \"arrow-up-right-square\",\n \"square-arrow-up\",\n \"arrow-up-square\",\n \"square-asterisk\",\n \"asterisk-square\",\n \"square-bottom-dashed-scissors\",\n \"scissors-square-dashed-bottom\",\n \"square-centerline-dashed-horizontal\",\n \"flip-horizontal\",\n \"square-centerline-dashed-vertical\",\n \"flip-vertical\",\n \"square-chart-gantt\",\n \"gantt-chart-square\",\n \"square-gantt-chart\",\n \"square-check-big\",\n \"check-square\",\n \"square-check\",\n \"check-square-2\",\n \"square-chevron-down\",\n \"chevron-down-square\",\n \"square-chevron-left\",\n \"chevron-left-square\",\n \"square-chevron-right\",\n \"chevron-right-square\",\n \"square-chevron-up\",\n \"chevron-up-square\",\n \"square-code\",\n \"code-square\",\n \"square-dashed-bottom-code\",\n \"square-dashed-bottom\",\n \"square-dashed-kanban\",\n \"kanban-square-dashed\",\n \"square-dashed-mouse-pointer\",\n \"mouse-pointer-square-dashed\",\n \"square-dashed-text\",\n \"text-selection\",\n \"text-select\",\n \"square-dashed-top-solid\",\n \"square-dashed\",\n \"box-select\",\n \"square-divide\",\n \"divide-square\",\n \"square-dot\",\n \"dot-square\",\n \"square-equal\",\n \"equal-square\",\n \"square-function\",\n \"function-square\",\n \"square-kanban\",\n \"kanban-square\",\n \"square-library\",\n \"library-square\",\n \"square-m\",\n \"m-square\",\n \"square-menu\",\n \"menu-square\",\n \"square-minus\",\n \"minus-square\",\n \"square-mouse-pointer\",\n \"inspect\",\n \"square-parking-off\",\n \"parking-square-off\",\n \"square-parking\",\n \"parking-square\",\n \"square-pause\",\n \"square-pen\",\n \"pen-box\",\n \"edit\",\n \"pen-square\",\n \"square-percent\",\n \"percent-square\",\n \"square-pi\",\n \"pi-square\",\n \"square-pilcrow\",\n \"pilcrow-square\",\n \"square-play\",\n \"play-square\",\n \"square-plus\",\n \"plus-square\",\n \"square-power\",\n \"power-square\",\n \"square-radical\",\n \"square-round-corner\",\n \"square-scissors\",\n \"scissors-square\",\n \"square-sigma\",\n \"sigma-square\",\n \"square-slash\",\n \"slash-square\",\n \"square-split-horizontal\",\n \"split-square-horizontal\",\n \"square-split-vertical\",\n \"split-square-vertical\",\n \"square-square\",\n \"square-stack\",\n \"square-star\",\n \"square-stop\",\n \"square-terminal\",\n \"terminal-square\",\n \"square-user-round\",\n \"user-square-2\",\n \"square-user\",\n \"user-square\",\n \"square-x\",\n \"x-square\",\n \"square\",\n \"squares-exclude\",\n \"squares-intersect\",\n \"squares-subtract\",\n \"squares-unite\",\n \"squircle-dashed\",\n \"squircle\",\n \"squirrel\",\n \"stamp\",\n \"star-half\",\n \"star-off\",\n \"star\",\n \"step-back\",\n \"step-forward\",\n \"stethoscope\",\n \"sticker\",\n \"sticky-note\",\n \"stone\",\n \"store\",\n \"stretch-horizontal\",\n \"stretch-vertical\",\n \"strikethrough\",\n \"subscript\",\n \"sun-dim\",\n \"sun-medium\",\n \"sun-moon\",\n \"sun-snow\",\n \"sun\",\n \"sunrise\",\n \"sunset\",\n \"superscript\",\n \"swatch-book\",\n \"swiss-franc\",\n \"switch-camera\",\n \"sword\",\n \"swords\",\n \"syringe\",\n \"table-2\",\n \"table-cells-merge\",\n \"table-cells-split\",\n \"table-columns-split\",\n \"table-of-contents\",\n \"table-properties\",\n \"table-rows-split\",\n \"table\",\n \"tablet-smartphone\",\n \"tablet\",\n \"tablets\",\n \"tag\",\n \"tags\",\n \"tally-1\",\n \"tally-2\",\n \"tally-3\",\n \"tally-4\",\n \"tally-5\",\n \"tangent\",\n \"target\",\n \"telescope\",\n \"tent-tree\",\n \"tent\",\n \"terminal\",\n \"test-tube-diagonal\",\n \"test-tube-2\",\n \"test-tube\",\n \"test-tubes\",\n \"text-align-center\",\n \"align-center\",\n \"text-align-end\",\n \"align-right\",\n \"text-align-justify\",\n \"align-justify\",\n \"text-align-start\",\n \"text\",\n \"align-left\",\n \"text-cursor-input\",\n \"text-cursor\",\n \"text-initial\",\n \"letter-text\",\n \"text-quote\",\n \"text-search\",\n \"text-wrap\",\n \"wrap-text\",\n \"theater\",\n \"thermometer-snowflake\",\n \"thermometer-sun\",\n \"thermometer\",\n \"thumbs-down\",\n \"thumbs-up\",\n \"ticket-check\",\n \"ticket-minus\",\n \"ticket-percent\",\n \"ticket-plus\",\n \"ticket-slash\",\n \"ticket-x\",\n \"ticket\",\n \"tickets-plane\",\n \"tickets\",\n \"timer-off\",\n \"timer-reset\",\n \"timer\",\n \"toggle-left\",\n \"toggle-right\",\n \"toilet\",\n \"tool-case\",\n \"toolbox\",\n \"tornado\",\n \"torus\",\n \"touchpad-off\",\n \"touchpad\",\n \"towel-rack\",\n \"tower-control\",\n \"toy-brick\",\n \"tractor\",\n \"traffic-cone\",\n \"train-front-tunnel\",\n \"train-front\",\n \"train-track\",\n \"tram-front\",\n \"train\",\n \"transgender\",\n \"trash-2\",\n \"trash\",\n \"tree-deciduous\",\n \"tree-palm\",\n \"palmtree\",\n \"tree-pine\",\n \"trees\",\n \"trending-down\",\n \"trending-up-down\",\n \"trending-up\",\n \"triangle-alert\",\n \"alert-triangle\",\n \"triangle-dashed\",\n \"triangle-right\",\n \"triangle\",\n \"trophy\",\n \"truck-electric\",\n \"truck\",\n \"turkish-lira\",\n \"turntable\",\n \"turtle\",\n \"tv-minimal-play\",\n \"tv-minimal\",\n \"tv-2\",\n \"tv\",\n \"type-outline\",\n \"type\",\n \"umbrella-off\",\n \"umbrella\",\n \"underline\",\n \"undo-2\",\n \"undo-dot\",\n \"undo\",\n \"unfold-horizontal\",\n \"unfold-vertical\",\n \"ungroup\",\n \"university\",\n \"school-2\",\n \"unlink-2\",\n \"unlink\",\n \"unplug\",\n \"upload\",\n \"usb\",\n \"user-check\",\n \"user-cog\",\n \"user-key\",\n \"user-lock\",\n \"user-minus\",\n \"user-pen\",\n \"user-plus\",\n \"user-round-check\",\n \"user-check-2\",\n \"user-round-cog\",\n \"user-cog-2\",\n \"user-round-key\",\n \"user-round-minus\",\n \"user-minus-2\",\n \"user-round-pen\",\n \"user-round-plus\",\n \"user-plus-2\",\n \"user-round-search\",\n \"user-round-x\",\n \"user-x-2\",\n \"user-round\",\n \"user-2\",\n \"user-search\",\n \"user-star\",\n \"user-x\",\n \"user\",\n \"users-round\",\n \"users-2\",\n \"users\",\n \"utensils-crossed\",\n \"fork-knife-crossed\",\n \"utensils\",\n \"fork-knife\",\n \"utility-pole\",\n \"van\",\n \"variable\",\n \"vault\",\n \"vector-square\",\n \"vegan\",\n \"venetian-mask\",\n \"venus-and-mars\",\n \"venus\",\n \"vibrate-off\",\n \"vibrate\",\n \"video-off\",\n \"video\",\n \"videotape\",\n \"view\",\n \"voicemail\",\n \"volleyball\",\n \"volume-1\",\n \"volume-2\",\n \"volume-off\",\n \"volume-x\",\n \"volume\",\n \"vote\",\n \"wallet-cards\",\n \"wallet-minimal\",\n \"wallet-2\",\n \"wallet\",\n \"wallpaper\",\n \"wand-sparkles\",\n \"wand-2\",\n \"wand\",\n \"warehouse\",\n \"washing-machine\",\n \"watch\",\n \"waves-arrow-down\",\n \"waves-arrow-up\",\n \"waves-ladder\",\n \"waves\",\n \"waypoints\",\n \"webcam\",\n \"webhook-off\",\n \"webhook\",\n \"weight-tilde\",\n \"weight\",\n \"wheat-off\",\n \"wheat\",\n \"whole-word\",\n \"wifi-cog\",\n \"wifi-high\",\n \"wifi-low\",\n \"wifi-off\",\n \"wifi-pen\",\n \"wifi-sync\",\n \"wifi-zero\",\n \"wifi\",\n \"wind-arrow-down\",\n \"wind\",\n \"wine-off\",\n \"wine\",\n \"workflow\",\n \"worm\",\n \"wrench\",\n \"x-line-top\",\n \"x\",\n \"zap-off\",\n \"zap\",\n \"zodiac-aquarius\",\n \"zodiac-aries\",\n \"zodiac-cancer\",\n \"zodiac-capricorn\",\n \"zodiac-gemini\",\n \"zodiac-leo\",\n \"zodiac-libra\",\n \"zodiac-ophiuchus\",\n \"zodiac-pisces\",\n \"zodiac-sagittarius\",\n \"zodiac-scorpio\",\n \"zodiac-taurus\",\n \"zodiac-virgo\",\n \"zoom-in\",\n \"zoom-out\",\n]);\n\nexport const LAYOUT_SECTION_ICON_SET: ReadonlySet<string> = new Set(LAYOUT_SECTION_ICONS);\nexport type LayoutSectionIcon = string;\n","/** Stable identifiers used by every project and page layout document. */\nexport const PAGE_CONTENT_ANCHOR_ID = \"page-content\" as const;\nexport const NAVIGATION_SECTION_ID = \"navigation\" as const;\nexport const FOOTER_SECTION_ID = \"footer\" as const;\n\n/** Locked transport/validation set shared by authoring surfaces and the server. */\nexport {\n LAYOUT_SECTION_ICONS,\n LAYOUT_SECTION_ICON_SET,\n type LayoutSectionIcon,\n} from \"./layout-lucide-icons.js\";\nimport type { LayoutSectionIcon } from \"./layout-lucide-icons.js\";\n\nexport type LayoutZone = \"above-page-content\" | \"below-page-content\";\nexport type ReservedLayoutSection = \"navigation\" | \"footer\";\n\nexport type LayoutScalarFieldType =\n | \"text\"\n | \"longtext\"\n | \"richtext\"\n | \"number\"\n | \"toggle\"\n | \"date\"\n | \"image\"\n | \"file\"\n | \"link\"\n | \"email\"\n | \"phone\"\n | \"select\"\n | \"color\"\n | \"json\"\n | \"reference\"\n | \"multi-reference\";\n\nexport type LayoutFieldType = LayoutScalarFieldType | \"group\" | \"repeater\";\n\n/** A recursive, stable-ID field contract shared by Sections and variant inputs. */\nexport interface LayoutFieldDefinition {\n id: string;\n slug: string;\n label: string;\n type: LayoutFieldType;\n required?: boolean;\n defaultValue?: unknown;\n config?: {\n options?: Array<{ label: string; value: string }>;\n referenceModelId?: string;\n minItems?: number;\n maxItems?: number;\n } & Record<string, unknown>;\n /** Required for group/repeater; forbidden for scalar fields. */\n fields?: LayoutFieldDefinition[];\n}\n\n/** The canonical public input contract all variants in a group implement. */\nexport type CanonicalInputDefinition = LayoutFieldDefinition;\n\n/** Maps one canonical input onto one or more internal component prop paths. */\nexport interface VariantInputMapping {\n inputId: string;\n targets: Array<{ blockId: string; path: string }>;\n}\n\nexport interface ComponentVariantGroup {\n id: string;\n workspaceId: string;\n projectId?: string | null;\n name: string;\n slug: string;\n canonicalInputs: CanonicalInputDefinition[];\n status: \"draft\" | \"published\";\n}\n\nexport interface LayoutFieldItem {\n id: string;\n kind: \"field\";\n fieldId: string;\n}\n\nexport interface LayoutComponentItem {\n id: string;\n kind: \"component\";\n componentId: string;\n variantGroupId?: string;\n bindings: Array<{ inputId: string; fieldId: string }>;\n literalValues?: Record<string, unknown>;\n}\n\nexport type LayoutSectionItem = LayoutFieldItem | LayoutComponentItem;\n\nexport interface LayoutSection {\n id: string;\n name: string;\n slug: string;\n icon: string;\n zone: LayoutZone;\n orderKey: string;\n reserved?: ReservedLayoutSection;\n fields: LayoutFieldDefinition[];\n items: LayoutSectionItem[];\n}\n\nexport interface LayoutStructureDocument {\n version: 1;\n pageContentAnchor: { id: typeof PAGE_CONTENT_ANCHOR_ID };\n sections: LayoutSection[];\n}\n\nexport interface LayoutDataDocument {\n version: 1;\n sections: Record<string, { fields: Record<string, unknown> }>;\n}\n\nexport type PageLayoutOverrideState =\n | \"inherit\"\n | \"override-content\"\n | \"customize-structure\"\n | \"disable\";\n\nexport interface PageSectionPlacement {\n zone: LayoutZone;\n afterSectionId?: string;\n beforeSectionId?: string;\n localOrderKey: string;\n}\n\nexport type PageLayoutSectionOverride =\n | { sectionId: string; state: \"inherit\" }\n | { sectionId: string; state: \"override-content\"; values: Record<string, unknown> }\n | {\n sectionId: string;\n state: \"customize-structure\";\n section: LayoutSection;\n data: { fields: Record<string, unknown> };\n /** Retained when the inherited Section is later deleted. */\n placement: PageSectionPlacement;\n }\n | { sectionId: string; state: \"disable\" };\n\nexport interface PageOnlyLayoutSection {\n section: LayoutSection;\n data: { fields: Record<string, unknown> };\n placement: PageSectionPlacement;\n}\n\nexport type PageLayoutSectionStructureOverride =\n | { sectionId: string; state: \"inherit\" }\n | { sectionId: string; state: \"override-content\" }\n | { sectionId: string; state: \"customize-structure\"; section: LayoutSection; placement: PageSectionPlacement }\n | { sectionId: string; state: \"disable\" };\n\n/** Persisted in pages.layout_override_structure_json. */\nexport interface PageLayoutOverrideStructureDocument {\n version: 1;\n sections: PageLayoutSectionStructureOverride[];\n pageOnlySections: Array<{ section: LayoutSection; placement: PageSectionPlacement }>;\n}\n\n/** Persisted independently so values can be patched without rewriting structure. */\nexport interface PageLayoutOverrideDataDocument {\n version: 1;\n sections: Record<string, { fields: Record<string, unknown> }>;\n pageOnlySections: Record<string, { fields: Record<string, unknown> }>;\n}\n\n/** Canonical in-memory form consumed by the pure resolver. */\nexport interface PageLayoutOverrideDocument {\n version: 1;\n sections: PageLayoutSectionOverride[];\n pageOnlySections: PageOnlyLayoutSection[];\n}\n\n/** Canonical, discriminated Management/MCP authoring transport. Authority is derived from type. */\nexport type ManagementLayoutCommand =\n | { type: \"set-section-values\"; sectionId: string; values: Record<string, unknown> }\n | { type: \"set-field-value\"; sectionId: string; fieldId: string; value: unknown }\n | { type: \"add-component\"; sectionId: string; componentId: string; variantGroupId?: string; bindings?: LayoutComponentItem[\"bindings\"]; literalValues?: Record<string, unknown> }\n | { type: \"remove-item\"; sectionId: string; itemId: string }\n | { type: \"move-component\"; sectionId: string; itemId: string; index: number }\n | { type: \"move-item\"; sectionId: string; itemId: string; index: number }\n | { type: \"swap-component-variant\"; sectionId: string; itemId: string; componentId: string }\n | { type: \"set-page-state\"; sectionId: string; state: PageLayoutOverrideState | \"reset\" }\n | { type: \"set-section-state\"; sectionId: string; state: PageLayoutOverrideState | \"reset\" }\n | { type: \"add-section\"; name: string; icon: LayoutSectionIcon; zone: \"before_page\" | \"after_page\" }\n | { type: \"restore-section\"; section: LayoutSection; data: { fields: Record<string, unknown> }; placement?: PageSectionPlacement }\n | { type: \"update-section\"; sectionId: string; name?: string; icon?: LayoutSectionIcon; slug?: string; zone?: LayoutZone; orderKey?: string }\n | { type: \"remove-section\"; sectionId: string }\n | { type: \"move-section\"; sectionId: string; afterId?: string | null; beforeId?: string | null }\n | { type: \"add-field\"; sectionId: string; parentFieldId?: string; field?: LayoutFieldDefinition; fieldType?: LayoutFieldType }\n | { type: \"update-field\"; sectionId: string; fieldId: string; patch: Partial<Omit<LayoutFieldDefinition, \"id\">> }\n | { type: \"remove-field\"; sectionId: string; fieldId: string }\n | { type: \"move-field\"; sectionId: string; itemId: string; index: number }\n | { type: \"set-bindings\"; sectionId: string; itemId: string; bindings: LayoutComponentItem[\"bindings\"]; literalValues?: Record<string, unknown> };\n\nexport type ResolvedLayoutNode =\n | { kind: \"page-content\"; id: typeof PAGE_CONTENT_ANCHOR_ID }\n | {\n kind: \"section\";\n id: string;\n section: LayoutSection;\n data: { fields: Record<string, unknown> };\n source: \"inherit\" | \"override-content\" | \"customize-structure\" | \"page-only\" | \"detached\";\n };\n\nexport interface DeliveredLayout {\n version: 1;\n nodes: Array<\n | { kind: \"page-content\"; id: typeof PAGE_CONTENT_ANCHOR_ID }\n | { kind: \"section\"; id: string; slug: string; name: string; source: Extract<ResolvedLayoutNode, { kind: \"section\" }>[\"source\"] }\n >;\n sections: Record<string, {\n id: string;\n slug: string;\n name: string;\n fields: Record<string, unknown>;\n items: Array<\n | { id: string; kind: \"field\"; fieldId: string; value: unknown }\n | {\n id: string;\n kind: \"component\";\n componentId: string;\n variantGroupId?: string;\n canonicalInputs: CanonicalInputDefinition[];\n bindings: LayoutComponentItem[\"bindings\"];\n canonicalValues: Record<string, unknown>;\n resolvedProps: Record<string, unknown>;\n /**\n * `prop.key` → canonical `inputId` — the relation `resolvedProps` consumes and throws\n * away (`output[prop.key] = canonicalValues[mapping.inputId]`).\n *\n * Without it a renderer holds a component prop key and NO address: `logoAlt`/`links`/\n * `cta` are the component's own bare keys, and nothing relates them back to the layout\n * field a write must land on. With it the chain closes — `prop.key` → `inputId` →\n * (`bindings`, already delivered above) → `fieldId` → `set-field-value(sectionId,\n * fieldId)`. That is what makes global chrome click-to-edit (FLO-1179).\n *\n * Additive and always present (`{}` when the item has no variant mappings), so an\n * older consumer that ignores it is byte-identical to before.\n */\n propInputs: Record<string, string>;\n blocks: unknown[];\n }\n >;\n }>;\n}\n"],"mappings":";AA2dO,SAAS,QAAQ,OAAuC;AAC7D,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,OAAQ,MAAkC,MAAM,MAAM;AAE1D;AAUO,SAAS,aAAa,OAAkC;AAC7D,MAAI,QAAQ,KAAK,EAAG,QAAO,MAAM;AACjC,SAAO;AACT;;;ACxaO,IAAM,iBAAsE;AAAA,EACjF,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,EACxC,MAAM,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,CAAC;AAAA,EACzC,UAAU,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,CAAC;AAAA,EAC7C,OAAO;AAAA,IACL,EAAE,MAAM,OAAO,MAAM,QAAQ;AAAA,IAC7B,EAAE,MAAM,WAAW,MAAM,OAAO;AAAA,IAChC,EAAE,MAAM,OAAO,MAAM,QAAQ,MAAM,MAAM;AAAA,EAC3C;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,QAAQ,MAAM,OAAO;AAAA,IAC7B,EAAE,MAAM,QAAQ,MAAM,OAAO,MAAM,OAAO;AAAA,EAC5C;AAAA,EACA,OAAO;AAAA,IACL,EAAE,MAAM,OAAO,MAAM,OAAO,MAAM,MAAM;AAAA,IACxC,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM,SAAS;AAAA,EAChD;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,YAAY,MAAM,QAAQ;AAAA,IAClC,EAAE,MAAM,YAAY,MAAM,QAAQ,MAAM,MAAM;AAAA,IAC9C,EAAE,MAAM,iBAAiB,MAAM,OAAO;AAAA,IACtC,EAAE,MAAM,gBAAgB,MAAM,OAAO,MAAM,OAAO;AAAA,IAClD,EAAE,MAAM,YAAY,MAAM,OAAO;AAAA,IACjC,EAAE,MAAM,YAAY,MAAM,OAAO,MAAM,OAAO;AAAA,EAChD;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,aAAa,MAAM,OAAO;AAAA,IAClC,EAAE,MAAM,qBAAqB,MAAM,OAAO;AAAA,IAC1C,EAAE,MAAM,2BAA2B,MAAM,OAAO;AAAA,IAChD,EAAE,MAAM,0BAA0B,MAAM,OAAO,MAAM,OAAO;AAAA,EAC9D;AAAA,EACA,MAAM,CAAC,EAAE,MAAM,gBAAgB,MAAM,OAAO,CAAC;AAC/C;AAQA,IAAM,WAAW,CAAC,MAChB,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAgBlD,SAAS,SAAS,MAAe,MAAuB;AAC7D,MAAI,SAAkB;AACtB,aAAW,WAAW,KAAK,MAAM,GAAG,GAAG;AACrC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,MAAM,QAAQ,QAAQ,YAAY,EAAE;AAC1C,QAAI,KAAK;AACP,UAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAC9B,eAAS,OAAO,GAAG;AAAA,IACrB;AACA,eAAW,SAAS,QAAQ,SAAS,YAAY,GAAG;AAClD,UAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO;AACnC,eAAS,OAAO,OAAO,MAAM,CAAC,CAAC,CAAC;AAAA,IAClC;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,eAAe,SAAuB,OAAgB,MAAiC;AAC9F,QAAM,KAAK,KAAK,QAAQ,IAAI;AAC5B,MAAI,KAAK,EAAG,QAAO,CAAC,EAAE,GAAG,SAAS,KAAK,CAAC;AAExC,QAAM,OAAO,KAAK,MAAM,GAAG,EAAE;AAC7B,QAAM,OAAO,KAAK,MAAM,KAAK,CAAC;AAC9B,QAAM,QAAQ,SAAS,OAAO,IAAI;AAClC,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AAEnC,SAAO,MAAM;AAAA,IAAQ,CAAC,OAAO,UAC3B,eAAe,SAAS,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE;AAAA,EAC3D;AACF;AAiBO,SAAS,oBAAoB,OAAwC;AAC1E,QAAM,WAAW,eAAe,MAAM,IAAI;AAC1C,MAAI,CAAC,SAAU,QAAO,CAAC;AACvB,QAAM,QAAS,MAA8B;AAC7C,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO,CAAC;AAC9B,SAAO,SACJ,QAAQ,CAAC,YAAY,eAAe,SAAS,OAAO,QAAQ,IAAI,CAAC,EACjE,OAAO,CAAC,YAAY,SAAS,OAAO,QAAQ,IAAI,MAAM,MAAS;AACpE;AAGO,SAAS,qBACd,SACQ;AACR,SAAO,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO,IAAI,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,GAAG;AACxE;AAGO,SAAS,oBACd,OACwD;AACxD,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO,MACJ,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,MAAM,GAAG,CAAC,EAC/B,OAAO,CAAC,UAAkD,MAAM,WAAW,KAAK,MAAM,MAAM,OAAO,CAAC,EACpG,IAAI,CAAC,CAAC,SAAS,MAAM,IAAI,OAAO,EAAE,SAAS,MAAM,KAAK,EAAE;AAC7D;AAiCO,SAAS,uBAAuB,MAA6C;AAClF,MAAI,CAAC,MAAM,OAAO,CAAC,KAAK,QAAQ,QAAS,QAAO;AAChD,SAAO,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,KAAK,OAAO,QAAQ,EAAE,EAAE,QAAQ,YAAY,EAAE,CAAC;AAC1F;AAEO,SAAS,2BACd,iBACA,OACqB;AACrB,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,QAAQ,SAAS,CAAC,GAAG;AAC9B,QAAI,CAAC,MAAM,OAAO,CAAC,KAAK,QAAQ,QAAS;AACzC,UAAM,OAAO,uBAAuB,IAAI;AAGxC,QAAI,CAAC,IAAI,IAAI,IAAI,EAAG,KAAI,IAAI,MAAM,GAAG,eAAe,eAAe,KAAK,GAAG,EAAE;AAAA,EAC/E;AACA,SAAO;AACT;;;ACrPA,IAAM,WAAmC,EAAE,MAAM,KAAK,IAAI,OAAO,IAAI,OAAO,IAAI,QAAQ,IAAI,QAAQ,IAAI,OAAO;AAC/G,IAAM,gBAAwC,EAAE,IAAI,YAAY,MAAM,QAAQ,IAAI,WAAW,IAAI,UAAU,OAAO,OAAO;AACzH,IAAM,SAAiC,EAAE,QAAQ,KAAK,QAAQ,KAAK,UAAU,KAAK,MAAM,IAAI;AAC5F,IAAM,YAAoC,EAAE,MAAM,KAAK,IAAI,OAAO,IAAI,OAAO,IAAI,QAAQ,MAAM,SAAS;AACxG,IAAM,YAAoC,EAAE,OAAO,WAAW,OAAO,WAAW,OAAO,WAAW,SAAS,WAAW,SAAS,WAAW,QAAQ,UAAU;AAGrJ,SAAS,gBAAgB,OAA4E;AAC1G,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,IAAI;AACV,QAAM,MAAuC,CAAC;AAC9C,MAAI,EAAE,YAAY,SAAS,EAAE,QAAQ,KAAK,MAAM;AAAE,QAAI,aAAa,SAAS,EAAE,QAAQ;AAAI,QAAI,gBAAgB,SAAS,EAAE,QAAQ;AAAA,EAAI;AACrI,MAAI,EAAE,YAAY,SAAS,EAAE,QAAQ,KAAK,MAAM;AAAE,QAAI,cAAc,SAAS,EAAE,QAAQ;AAAI,QAAI,eAAe,SAAS,EAAE,QAAQ;AAAA,EAAI;AACrI,MAAI,EAAE,aAAa,SAAS,EAAE,SAAS,KAAK,KAAM,KAAI,YAAY,SAAS,EAAE,SAAS;AACtF,MAAI,EAAE,gBAAgB,SAAS,EAAE,YAAY,KAAK,KAAM,KAAI,eAAe,SAAS,EAAE,YAAY;AAClG,MAAI,EAAE,cAAc,UAAU,EAAE,UAAU,EAAG,KAAI,aAAa,UAAU,EAAE,UAAU;AACpF,MAAI,EAAE,aAAa,UAAU,EAAE,SAAS,EAAG,KAAI,QAAQ,UAAU,EAAE,SAAS;AAC5E,MAAI,EAAE,UAAU,UAAU,EAAE,UAAU,YAAY,EAAE,UAAU,QAAS,KAAI,YAAY,EAAE;AACzF,MAAI,EAAE,YAAY,cAAc,EAAE,QAAQ,EAAG,KAAI,WAAW,cAAc,EAAE,QAAQ;AACpF,MAAI,EAAE,UAAU,OAAO,EAAE,MAAM,KAAK,KAAM,KAAI,aAAa,OAAO,EAAE,MAAM;AAC1E,MAAI,EAAE,UAAU,UAAU,EAAE,MAAM,KAAK,KAAM,KAAI,eAAe,UAAU,EAAE,MAAM;AAClF,SAAO,OAAO,KAAK,GAAG,EAAE,SAAS,MAAM;AACzC;;;ACMO,IAAM,mBACX;;;ACjCK,IAAM,uBAA0C,OAAO,OAAO;AAAA,EACnE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,0BAA+C,IAAI,IAAI,oBAAoB;;;AC36DjF,IAAM,yBAAyB;AAC/B,IAAM,wBAAwB;AAC9B,IAAM,oBAAoB;","names":[]}
1
+ {"version":3,"sources":["../src/block.ts","../src/block-bindings.ts","../src/blockStyle.ts","../src/component.ts","../src/layout-lucide-icons.ts","../src/layout.ts"],"sourcesContent":["/**\n * ContentBlock — a discriminated union of all CMS block types.\n * Each block has a `type` discriminator and a `props` object\n * whose shape matches the block type.\n */\n\n// ── Block style (FLO-264) ──────────────────────────────────────────────────────\n// A uniform, BOUNDED set of design tokens any block may carry (sibling to `props`).\n// Tokens map to fixed CSS values in the renderer (`styleTokensToCss`) so styling\n// reaches the live site WITHOUT arbitrary CSS. Additive + fully optional.\n\nexport type SpaceToken = \"none\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type ColorToken = \"none\" | \"white\" | \"black\" | \"muted\" | \"mutedBg\" | \"primary\" | \"accent\";\nexport type AlignToken = \"left\" | \"center\" | \"right\";\nexport type FontSizeToken = \"sm\" | \"base\" | \"lg\" | \"xl\" | \"2xl\";\nexport type WeightToken = \"normal\" | \"medium\" | \"semibold\" | \"bold\";\nexport type RadiusToken = \"none\" | \"sm\" | \"md\" | \"lg\" | \"full\";\n\n// Section design (task 4) — the per-instance design a section carries on the page.\nexport type ThemeToken = \"inherit\" | \"light\" | \"dark\";\nexport type BgToken = \"none\" | \"surface\" | \"muted\" | \"accent\" | \"dark\" | \"custom\";\nexport type ContentWidthToken = \"narrow\" | \"default\" | \"wide\" | \"full\";\nexport type CornerToken = \"0\" | \"s\" | \"m\" | \"l\" | \"xl\" | \"2xl\";\nexport type ShadowToken = \"0\" | \"s\" | \"m\" | \"l\" | \"xl\";\n\nexport interface BlockStyle {\n // Legacy token set (FLO-264). Where these overlap the section fields below\n // (background, radius, padding), the section field WINS in the renderer.\n paddingY?: SpaceToken;\n paddingX?: SpaceToken;\n marginTop?: SpaceToken;\n marginBottom?: SpaceToken;\n background?: ColorToken;\n textColor?: ColorToken;\n align?: AlignToken;\n fontSize?: FontSizeToken;\n weight?: WeightToken;\n radius?: RadiusToken;\n\n // Section design (task 4).\n theme?: ThemeToken;\n bg?: BgToken;\n /** Only read when `bg === \"custom\"`. Hex only. */\n bgCustom?: string;\n /** Padding sliders, in px (0–240). */\n paddingTop?: number;\n paddingBottom?: number;\n paddingSides?: number;\n contentWidth?: ContentWidthToken;\n /**\n * Where the constrained content column sits, when `contentWidth` constrains it.\n *\n * Split out of `align`, which still means text alignment and is still the fallback when this\n * is unset — so everything written before the split renders byte-identically. The two were one\n * token until anything MEASURED a section's text alignment: copying a source site's\n * `text-align: left` would otherwise also shove its column to the page edge.\n */\n contentAlign?: AlignToken;\n fullHeight?: boolean;\n /** 0–100. */\n opacity?: number;\n corner?: CornerToken;\n shadow?: ShadowToken;\n borderTop?: boolean;\n borderBottom?: boolean;\n /** 🔴 The one free-form string. MUST go through `safeCssUrl()` before reaching CSS. */\n bgImage?: string;\n}\n\n// ── Heading ──────────────────────────────────────────────────────────────────\n\nexport interface HeadingProps {\n text: string;\n level?: 1 | 2 | 3;\n}\n\nexport interface HeadingBlock {\n type: \"heading\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: HeadingProps;\n}\n\n// ── Text ─────────────────────────────────────────────────────────────────────\n\nexport interface TextProps {\n html: string;\n}\n\nexport interface TextBlock {\n type: \"text\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: TextProps;\n}\n\n/**\n * A rich-text block: the same HTML payload as `text`, authored through a real editor.\n *\n * WHY A SEPARATE TYPE RATHER THAN CHANGING `text`. Every `text` block already on a live page\n * holds an HTML string that the delivery renderer injects as-is. Repurposing that type would\n * mean migrating published content, and getting it wrong renders visible markup to visitors.\n * A new type costs nothing at rest and leaves existing pages untouched.\n *\n * The payload is deliberately IDENTICAL to TextProps (an HTML string) so the two are\n * interchangeable at the renderer: delivery treats them the same, and the difference is\n * entirely in how an author edits them — `text` is a plain field, `richtext` gets the\n * formatting surface.\n */\n/**\n * A Portable Text node — the structured form of rich text.\n *\n * Kept alongside `html` rather than replacing it, so nothing already published moves. The\n * structure exists because an HTML string cannot carry INTENT: a colour is a hex with no\n * notion of which brand token produced it, an embedded component is a div with no reference\n * to resolve, and neither can be read back by tooling. Nodes can carry all of that.\n */\nexport interface PortableTextNode {\n _type: string;\n _key?: string;\n /** Block style — \"normal\", \"h2\", \"blockquote\". */\n style?: string;\n text?: string;\n children?: PortableTextNode[];\n /** Marks on a span: \"strong\", \"em\", or a token reference like \"color:brand-accent\". */\n marks?: string[];\n /** An embedded component or reference resolves through these. */\n schemaKey?: string;\n _ref?: string;\n fields?: Record<string, unknown>;\n}\n\nexport interface PortableTextDocument {\n version: 1;\n content: PortableTextNode[];\n}\n\nexport interface RichTextProps {\n /**\n * The RENDERED CACHE. Delivery reads this, so the fast path stays a string interpolation\n * and every page published before `content` existed keeps rendering byte-identically.\n */\n html: string;\n /**\n * The SOURCE OF TRUTH, when present — `content` always wins over `html`.\n *\n * Optional on purpose: this is the same envelope the field values already use\n * (`{ format, value, html }`), where `html` is likewise derived. Any writer that sets\n * `html` alone on a block that HAS `content` must delete `content` in the same write, or\n * the stale string silently shadows the newer structure.\n */\n content?: PortableTextDocument;\n}\n\nexport interface RichTextBlock {\n type: \"richtext\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: RichTextProps;\n}\n\n// ── Image ────────────────────────────────────────────────────────────────────\n\nexport interface ImageProps {\n src: string;\n alt: string;\n width?: number;\n height?: number;\n caption?: string;\n}\n\nexport interface ImageBlock {\n type: \"image\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: ImageProps;\n}\n\n// ── Button ───────────────────────────────────────────────────────────────────\n\nexport interface ButtonProps {\n text: string;\n href: string;\n variant?: \"primary\" | \"secondary\";\n}\n\nexport interface ButtonBlock {\n type: \"button\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: ButtonProps;\n}\n\n// ── Spacer ───────────────────────────────────────────────────────────────────\n\nexport interface SpacerProps {\n height: number; // in px\n}\n\nexport interface SpacerBlock {\n type: \"spacer\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: SpacerProps;\n}\n\n// ── Columns ───────────────────────────────────────────────────────────────────\n\nexport interface ColumnsProps {\n columns: ContentBlock[][]; // array of column slots, each slot is an array of blocks\n gap?: number; // in px\n}\n\nexport interface ColumnsBlock {\n type: \"columns\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: ColumnsProps;\n}\n\n// ── Video ────────────────────────────────────────────────────────────────────\n\nexport interface VideoProps {\n url: string;\n poster?: string;\n autoplay?: boolean;\n loop?: boolean;\n /**\n * What is said in the video (CPO-093). The block carries its own because its url may be a\n * pasted provider link with no library asset to hang one from. Rendered as <details> after\n * the player and published in the .md twin.\n */\n transcript?: string;\n}\n\nexport interface VideoBlock {\n type: \"video\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: VideoProps;\n}\n\n// ── Form ─────────────────────────────────────────────────────────────────────\n\nexport interface FormProps {\n formId: string; // references forms.id (a nanoid). Resolved against delivered forms at render time.\n}\n\nexport interface FormBlock {\n type: \"form\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: FormProps;\n}\n\n// ── Section (recursive container) ──────────────────────────────────────────────\n\nexport interface SectionProps {\n children: ContentBlock[];\n background?: string;\n paddingY?: number; // in px\n maxWidth?: number; // in px\n}\n\nexport interface SectionBlock {\n type: \"section\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: SectionProps;\n}\n\n// ── Navbar ─────────────────────────────────────────────────────────────────────\n\nexport interface NavLink {\n label: string;\n href: string;\n}\n\nexport interface NavbarProps {\n logo?: { src: string; alt: string; href?: string };\n logoAlt?: string;\n links: NavLink[];\n mobileMenu?: boolean;\n cta?: { text: string; href: string };\n}\n\nexport interface NavbarBlock {\n type: \"navbar\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: NavbarProps;\n}\n\n// ── Footer ─────────────────────────────────────────────────────────────────────\n\nexport interface FooterColumn {\n heading?: string;\n links: NavLink[];\n}\n\nexport interface FooterProps {\n columns: FooterColumn[];\n copyright?: string;\n}\n\nexport interface FooterBlock {\n type: \"footer\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: FooterProps;\n}\n\n// ── Slider / Carousel (recursive container, client-hydrated) ────────────────────\n\nexport interface SlideItem {\n id: string;\n children: ContentBlock[];\n}\n\nexport interface SliderProps {\n slides: SlideItem[];\n autoplay?: boolean;\n interval?: number; // in ms\n loop?: boolean;\n}\n\nexport interface SliderBlock {\n type: \"slider\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: SliderProps;\n}\n\n// ── Tabs (recursive container, client-hydrated) ─────────────────────────────────\n\nexport interface TabItem {\n id: string;\n label: string;\n children: ContentBlock[];\n}\n\nexport interface TabsProps {\n tabs: TabItem[];\n}\n\nexport interface TabsBlock {\n type: \"tabs\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: TabsProps;\n}\n\n// ── Component instance (Webflow-style reusable symbol) ──────────────────────────\n// References a reusable component by id. `overrides` maps a component prop key\n// (declared in the component's `props[]` allowlist) to a value, applied to the\n// component's block tree at render time. Resolved against delivered components.\n\nexport interface ComponentProps {\n componentId: string;\n overrides?: Record<string, unknown>;\n /** Phase A: the page field group this placement renders (its copy + bindings live there). */\n bind?: string;\n /**\n * Phase B: where each override's copy CAME FROM — `{ <propKey>: \"<page field path>\" }`.\n *\n * Written when a placement takes ownership of its copy (`bind` is deleted at the same moment),\n * and it is not decoration:\n * - the COVERAGE METER counts a block-lane declaration\n * (`data-bcms-block=\"<id>\"` + `data-bcms-field=\"<id>__overrides.<propKey>\"`) as bound for\n * the page path named here, so a converted page does not read as a site that lost its\n * bindings;\n * - it is how the componentize lane still recognises WHICH GROUP an instance renders once\n * `bind` is gone — without it a second run would mint a second instance for the same band.\n * A `table` prop names its repeater's path (`faq.items`); every row path under it is that one\n * declaration's, because the prop holds every row.\n */\n source?: Record<string, string>;\n}\n\nexport interface ComponentBlock {\n type: \"component\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: ComponentProps;\n}\n\n// ── Collection (the entries of the page this block sits on) ─────────────────────\n//\n// LANE-AWARE, and that is the whole idea. A dynamic page's `blockJson` is BOTH what\n// `/blog` renders and the template interpolated into every `/blog/<slug>`. One array\n// cannot be an index and a post layout — unless the one block that differs between them\n// knows which lane it is in. The route supplies that (see CollectionCtx in render-page.ts):\n//\n// /blog → this block renders a card per published entry\n// /blog/my-post → this block renders THAT entry's detail; every other block in the\n// array is interpolated with {{placeholders}} exactly as before\n//\n// So no second template column, no migration, and a page without a collection block\n// behaves byte-identically to before.\n//\n// Scope is IMPLIED, never configured: a collection lists the entries of the page it sits\n// on, which is precisely the set whose detail URLs are /<thisPage>/<slug>. There is no\n// model picker because there is no other correct answer.\n\nexport interface CollectionProps {\n /** Component rendered once per entry, interpolated with {{field}} and {{url}}. Omit for a built-in card. */\n cardComponentId?: string;\n /** Component rendered for the single entry on a detail URL. Omit to fall back to the generic field layout. */\n detailComponentId?: string;\n /** Built-in card only. Defaults to \"title\" / no excerpt. */\n titleField?: string;\n excerptField?: string;\n /** Max cards to render. Defaults to 20. */\n limit?: number;\n /** \"newest\" (default) reverses the reader's created_at ordering. */\n order?: \"newest\" | \"oldest\";\n emptyText?: string;\n}\n\nexport interface CollectionBlock {\n type: \"collection\";\n id: string;\n style?: BlockStyle;\n /** Editor-facing display name for this block's dock card. Not rendered. */\n label?: string;\n props: CollectionProps;\n}\n\n// ── Union ─────────────────────────────────────────────────────────────────────\n\nexport type ContentBlock =\n | CollectionBlock\n | HeadingBlock\n | TextBlock\n | RichTextBlock\n | ImageBlock\n | ButtonBlock\n | SpacerBlock\n | ColumnsBlock\n | VideoBlock\n | FormBlock\n | SectionBlock\n | NavbarBlock\n | FooterBlock\n | SliderBlock\n | TabsBlock\n | ComponentBlock;\n\n/** Literal union of all block type discriminators. */\nexport type BlockType = ContentBlock[\"type\"];\n\n/**\n * Type guard — narrows an unknown block to `ContentBlock`.\n *\n * @example\n * const block = maybeBlock as unknown;\n * if (isBlock(block)) {\n * // block is ContentBlock here\n * }\n */\nexport function isBlock(value: unknown): value is ContentBlock {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n typeof (value as Record<string, unknown>)[\"type\"] === \"string\"\n );\n}\n\n/**\n * Extract the `type` discriminator from a block, or `null` if not a block.\n *\n * @example\n * const block = { type: \"heading\", id: \"1\", props: { text: \"Hi\" } };\n * getBlockType(block); // \"heading\"\n * getBlockType({ not: \"a block\" }); // null\n */\nexport function getBlockType(value: unknown): BlockType | null {\n if (isBlock(value)) return value.type;\n return null;\n}\n","/**\n * The ONE declaration of which block props the Visual Editor can address.\n *\n * Four renderers stamp `data-bcms-field` — the hosted renderer, the Next SDK, the Astro SDK\n * and (for minting keys rather than markup) the dashboard's `buildBlockPageDoc`. Until this\n * file existed each carried its own hand-written list, they disagreed by two props, and the\n * dashboard's copy said so in a comment while having nothing to enforce it. A block listed in\n * one and missing from another does not error: it simply never binds, or it binds to a node\n * that resolves to no field. Both failures are silent, which is why they survived.\n *\n * This file is the declaration. The renderers remain the implementation — only they know which\n * ELEMENT carries a value — and `block-binding-coverage.test.ts` asserts the two agree.\n *\n * ── Two kinds of address, because an element is not an attribute ────────────────────────────\n *\n * `data-bcms-field` addresses ONE element. That is enough for a heading's text or an image's\n * src, and not enough for an image's `alt`: the `<img>` already carries a binding, and an\n * element cannot hold two. Entries that name an `attr` are therefore emitted on a SECOND\n * attribute, `data-bcms-props`, whose grammar is:\n *\n * <address>|<kind>|<domAttribute>[;<address>|<kind>|<domAttribute>]*\n *\n * No JSON, because the values are already constrained: an address is grammar A\n * (`[A-Za-z0-9_$-]`, `.`, `[n]`), and kinds and attributes are plain identifiers. A split on\n * two characters parses it, in any language, with no escaping.\n *\n * ── Path templates ──────────────────────────────────────────────────────────────────────────\n *\n * `[]` marks an array the renderer walks. `expandBlockBindings` substitutes real indices from a\n * block's actual props, so `links[].label` on a three-link navbar yields three concrete\n * addresses and on an empty one yields none. `parseFieldPath`/`setFieldPath` in the dashboard\n * have handled N indices since FLO-949; the cap was in what the renderer offered, not in what\n * the writer could persist.\n */\nimport type { ContentBlock, BlockType } from \"./block.js\";\n\n/**\n * How the editor paints a value, and whether it may take a caret.\n *\n * `text`/`richtext` are inline-editable. `image` selects and swaps through the media picker.\n * `url` never takes a caret — a URL typed onto the page has nowhere to report a malformed\n * value — so it is edited in the element toolbar. `array` is a repeater slot: selectable and\n * locatable, edited in the dock.\n */\nexport type BindingKind = \"text\" | \"richtext\" | \"image\" | \"url\" | \"number\" | \"array\";\n\nexport interface BlockBinding {\n /** Path template in grammar A, relative to the block's `props`. `[]` = an array to walk. */\n readonly path: string;\n readonly kind: BindingKind;\n /**\n * The DOM attribute this value lives in, when it is not the element's own text or `src`.\n * Present ⇒ the renderer emits it on `data-bcms-props`, never on `data-bcms-field`.\n */\n readonly attr?: string;\n}\n\n/**\n * Props deliberately absent, and still absent for the original reason:\n *\n * `spacer.height`, `columns.gap`, `section.background` and every `style` token — design, not\n * content. They are edited in the Design accordion, where a slider can express a bounded\n * range that free typing on the page cannot.\n *\n * `text.html` when Portable Text is present — `html` is a cache derived from `content`, so\n * advertising it would persist an ignored sibling and the next frame would read as a revert.\n * The renderer suppresses it; the expander cannot see `content`, so the branch stays there.\n *\n * `component.overrides.*` — instance-scoped, so it cannot be a static template. The renderer\n * derives those addresses per instance from the definition's declared props.\n */\nexport const BLOCK_BINDINGS: Partial<Record<BlockType, readonly BlockBinding[]>> = {\n heading: [{ path: \"text\", kind: \"text\" }],\n text: [{ path: \"html\", kind: \"richtext\" }],\n richtext: [{ path: \"html\", kind: \"richtext\" }],\n image: [\n { path: \"src\", kind: \"image\" },\n { path: \"caption\", kind: \"text\" },\n { path: \"alt\", kind: \"text\", attr: \"alt\" },\n ],\n button: [\n { path: \"text\", kind: \"text\" },\n { path: \"href\", kind: \"url\", attr: \"href\" },\n ],\n video: [\n { path: \"url\", kind: \"url\", attr: \"src\" },\n { path: \"poster\", kind: \"url\", attr: \"poster\" },\n ],\n navbar: [\n { path: \"logo.src\", kind: \"image\" },\n { path: \"logo.alt\", kind: \"text\", attr: \"alt\" },\n { path: \"links[].label\", kind: \"text\" },\n { path: \"links[].href\", kind: \"url\", attr: \"href\" },\n { path: \"cta.text\", kind: \"text\" },\n { path: \"cta.href\", kind: \"url\", attr: \"href\" },\n ],\n footer: [\n { path: \"copyright\", kind: \"text\" },\n { path: \"columns[].heading\", kind: \"text\" },\n { path: \"columns[].links[].label\", kind: \"text\" },\n { path: \"columns[].links[].href\", kind: \"url\", attr: \"href\" },\n ],\n tabs: [{ path: \"tabs[].label\", kind: \"text\" }],\n};\n\n/** One concrete, writable address on one block. */\nexport interface ExpandedBinding extends BlockBinding {\n /** The template with every `[]` replaced by a real index, e.g. `links[2].href`. */\n readonly path: string;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n\n/**\n * Read a grammar-A path — dotted object keys and zero or more `[n]` indices.\n *\n * Positional, exactly like the dashboard's `parseFieldPath`: a dotted segment is always an\n * object key and a bracketed one always an index, so `links.0` reads the string key \"0\" and\n * misses, rather than being quietly treated as `links[0]`. Any miss returns undefined; nothing\n * here throws, because a template that does not resolve must yield no address, not an error.\n *\n * EXPORTED because a second reader of this grammar now exists: `@bettercms-ai/convert` commits a\n * build-time helper into a customer's repository, and that helper must resolve a path exactly the\n * way the editor does or a converted template renders a fallback where a value exists. The helper\n * itself carries an inlined copy (it lands in a repo where our packages do not exist) and a parity\n * test pins the copy to this original.\n */\nexport function readPath(root: unknown, path: string): unknown {\n let cursor: unknown = root;\n for (const segment of path.split(\".\")) {\n if (!segment) return undefined;\n const key = segment.replace(/\\[\\d+\\]/g, \"\");\n if (key) {\n if (!isRecord(cursor)) return undefined;\n cursor = cursor[key];\n }\n for (const index of segment.matchAll(/\\[(\\d+)\\]/g)) {\n if (!Array.isArray(cursor)) return undefined;\n cursor = cursor[Number(index[1])];\n }\n }\n return cursor;\n}\n\n/** Substitute the FIRST `[]` with every real index, then recurse for any deeper array. */\nfunction expandTemplate(binding: BlockBinding, props: unknown, path: string): ExpandedBinding[] {\n const at = path.indexOf(\"[]\");\n if (at < 0) return [{ ...binding, path }];\n\n const head = path.slice(0, at);\n const tail = path.slice(at + 2);\n const array = readPath(props, head);\n if (!Array.isArray(array)) return [];\n\n return array.flatMap((_item, index) =>\n expandTemplate(binding, props, `${head}[${index}]${tail}`),\n );\n}\n\n/**\n * Every concrete address a block actually offers right now.\n *\n * Array templates expand against the array's real length, so an address is only ever minted\n * for an element that exists. That is the load-bearing property: `setFieldPath` refuses to\n * fabricate an array member, so an address for `links[3]` on a two-link navbar would be a\n * binding the writer rejects — the \"advertises an edit that silently fails\" failure this whole\n * grammar exists to avoid.\n *\n * A prop whose KEY is absent does NOT expand, and that is not a nicety. `setFieldPath` refuses\n * to create a final key unless `createMissingObjects` is set, which only component overrides\n * pass — so an address for a key the block does not carry is a write the editor would reject.\n * An empty string still expands: `\"\"` is a value, and clearing a heading must not make it\n * uneditable.\n */\nexport function expandBlockBindings(block: ContentBlock): ExpandedBinding[] {\n const declared = BLOCK_BINDINGS[block.type];\n if (!declared) return [];\n const props = (block as { props?: unknown }).props;\n if (!isRecord(props)) return [];\n return declared\n .flatMap((binding) => expandTemplate(binding, props, binding.path))\n .filter((binding) => readPath(props, binding.path) !== undefined);\n}\n\n/** The `data-bcms-props` value for a block's attribute bindings, or \"\" when it has none. */\nexport function formatPropsAttribute(\n entries: readonly { address: string; kind: BindingKind; attr: string }[],\n): string {\n return entries.map((e) => `${e.address}|${e.kind}|${e.attr}`).join(\";\");\n}\n\n/** Parse a `data-bcms-props` value. Malformed entries are dropped, never guessed at. */\nexport function parsePropsAttribute(\n value: string | null | undefined,\n): { address: string; kind: BindingKind; attr: string }[] {\n if (!value) return [];\n return value\n .split(\";\")\n .map((entry) => entry.split(\"|\"))\n .filter((parts): parts is [string, BindingKind, string] => parts.length === 3 && parts.every(Boolean))\n .map(([address, kind, attr]) => ({ address, kind, attr }));\n}\n\n/** The shape of a declared component prop this module needs: where it points, and its key. */\ninterface PropTarget {\n key?: string;\n target?: { blockId?: string; path?: string };\n}\n\n/**\n * `<defBlockId>__<prop>` → `<instanceBlockId>__overrides.<propKey>`, for one placed component.\n *\n * Shared by every renderer, because the mapping is a property of the DEFINITION and not of any\n * one output format. A component's block ids belong to the definition and are shared by every\n * instance of it, so `<defBlockId>__text` addresses no instance's value — which is why component\n * subtrees used to render unannotated, and why the SDKs (which never had that suppression)\n * stamped definition-scoped addresses that resolve to no field and, on a component placed twice,\n * collide into a duplicate that drops BOTH copies.\n *\n * The definition already states the mapping in `props[].target`. This only re-keys that\n * statement into the address the editor writes through. Nothing is inferred: a prop with no\n * target produces no entry, so it keeps its dock control and stays uneditable on the canvas,\n * which is the truthful outcome rather than a broken one.\n */\n/**\n * The definition-scoped key a declared prop POINTS AT — `<defBlockId>__<path>`, the same\n * grammar `expandBlockBindings` produces for a block's own bindings.\n *\n * Exported so the \"which leaves does no prop reach?\" check and the address minter below read\n * the key from ONE place. They ask opposite questions of the same mapping, and two spellings\n * of `.replace(/^props\\./, \"\")` is precisely how a leaf ends up counted as bound by one and\n * unbound by the other. Null when the prop declares no target — which is the honest answer:\n * such a prop reaches nothing.\n */\nexport function componentPropTargetKey(prop: PropTarget | undefined): string | null {\n if (!prop?.key || !prop.target?.blockId) return null;\n return `${prop.target.blockId}__${String(prop.target.path ?? \"\").replace(/^props\\./, \"\")}`;\n}\n\nexport function componentInstanceAddresses(\n instanceBlockId: string,\n props: readonly PropTarget[] | undefined,\n): Map<string, string> {\n const out = new Map<string, string>();\n for (const prop of props ?? []) {\n if (!prop?.key || !prop.target?.blockId) continue;\n const from = componentPropTargetKey(prop)!;\n // Two props aimed at one target would make the address ambiguous; first declaration wins\n // and the duplicate is dropped rather than silently overwriting it.\n if (!out.has(from)) out.set(from, `${instanceBlockId}__overrides.${prop.key}`);\n }\n return out;\n}\n","/**\n * FLO-264 — bounded block-style tokens → CSS. Framework-agnostic (returns a plain\n * declaration object, no React types) so every renderer shares ONE mapping: the\n * headless @bettercms-ai/next adapter, @bettercms-ai/ui, and (string form) the hosted\n * render-page.ts. Unknown tokens are dropped — closed set, no arbitrary CSS.\n */\nimport type { BlockStyle } from \"./block.js\";\n\nconst SPACE_PX: Record<string, string> = { none: \"0\", xs: \"4px\", sm: \"8px\", md: \"16px\", lg: \"32px\", xl: \"64px\" };\nconst FONT_SIZE_REM: Record<string, string> = { sm: \"0.875rem\", base: \"1rem\", lg: \"1.25rem\", xl: \"1.5rem\", \"2xl\": \"2rem\" };\nconst WEIGHT: Record<string, number> = { normal: 400, medium: 500, semibold: 600, bold: 700 };\nconst RADIUS_PX: Record<string, string> = { none: \"0\", sm: \"4px\", md: \"8px\", lg: \"16px\", full: \"9999px\" };\nconst COLOR_HEX: Record<string, string> = { white: \"#ffffff\", black: \"#111111\", muted: \"#6b7280\", mutedBg: \"#f3f4f6\", primary: \"#111111\", accent: \"#4f46e5\" };\n\n/** A CSS declaration object (key → value) usable as a React `style` prop, or undefined when empty. */\nexport function blockStyleToCss(style: BlockStyle | undefined): Record<string, string | number> | undefined {\n if (!style || typeof style !== \"object\") return undefined;\n const s = style as Record<string, string>;\n const css: Record<string, string | number> = {};\n if (s.paddingY && SPACE_PX[s.paddingY] != null) { css.paddingTop = SPACE_PX[s.paddingY]!; css.paddingBottom = SPACE_PX[s.paddingY]!; }\n if (s.paddingX && SPACE_PX[s.paddingX] != null) { css.paddingLeft = SPACE_PX[s.paddingX]!; css.paddingRight = SPACE_PX[s.paddingX]!; }\n if (s.marginTop && SPACE_PX[s.marginTop] != null) css.marginTop = SPACE_PX[s.marginTop]!;\n if (s.marginBottom && SPACE_PX[s.marginBottom] != null) css.marginBottom = SPACE_PX[s.marginBottom]!;\n if (s.background && COLOR_HEX[s.background]) css.background = COLOR_HEX[s.background]!;\n if (s.textColor && COLOR_HEX[s.textColor]) css.color = COLOR_HEX[s.textColor]!;\n if (s.align === \"left\" || s.align === \"center\" || s.align === \"right\") css.textAlign = s.align;\n if (s.fontSize && FONT_SIZE_REM[s.fontSize]) css.fontSize = FONT_SIZE_REM[s.fontSize]!;\n if (s.weight && WEIGHT[s.weight] != null) css.fontWeight = WEIGHT[s.weight]!;\n if (s.radius && RADIUS_PX[s.radius] != null) css.borderRadius = RADIUS_PX[s.radius]!;\n return Object.keys(css).length ? css : undefined;\n}\n","/**\n * Component — a reusable, Webflow-style block tree (a \"symbol\").\n *\n * A component is authored once and placed across pages via `component` blocks\n * (see `ComponentBlock` in `./block.ts`). Its definition lives in `blockJson`;\n * `props` declares a flat allowlist of values an instance may override.\n */\nimport type { ContentBlock } from \"./block.js\";\nimport type { ContentModelFieldUi } from \"./content-model.js\";\nimport type { VariantInputMapping } from \"./layout.js\";\n\n/**\n * The category a component belongs to (drives library grouping + icons). The first eight\n * are structural (what the component IS); the last four are the \"Add a section\" library\n * tabs (where it appears). One varchar column, not a PG enum — widening is code-only.\n */\n/**\n * 🔴 THE STRUCTURE DOCTRINE — one sentence, one home, spliced into every surface that builds a page.\n *\n * It lives HERE, beside the component contract it describes, because there are THREE places that teach\n * an agent how to build a page and they drifted apart:\n * • `packages/mcp/src/tools.ts` — the MCP tool descriptions (external agents)\n * • `src/lib/ai/agent.ts` — the in-product Studio Agent's system prompt\n * • `packages/mcp/src/prompts.ts` — the authoring playbook, which a tool call does not carry\n *\n * Only the playbook explained sections. `create_page` taught the SCHEMA axis in detail (\"each visual\n * section becomes a nested field\") and said nothing about STRUCTURE; the Studio Agent's prompt named\n * \"pages & reusable components (structure/layout)\" without ever mentioning `sectionType`.\n *\n * Measured consequence, production 2026-08-18: project `acme` has three components, ALL with\n * `section_type = (none)`, and its home page is 18 loose top-level blocks with ZERO sections. Every\n * generated page came out flat, so the visual editor's section lane — outline, name, move, duplicate,\n * delete, variant swap — had nothing to attach to. The editor was faithfully showing pages that were\n * never built out of sections.\n *\n * A constant rather than three paraphrases, because updating some of them is exactly how this happened.\n */\nexport const SECTION_DOCTRINE =\n \"STRUCTURE (separate from schema): a page is composed of SECTIONS. NEVER build a page out of loose top-level heading/text/image/button/spacer blocks — they cannot be moved, duplicated or swapped as a unit, the visual editor cannot outline or name them, and every one of them becomes its own section in the editor. A hero of a headline, a lede and two CTAs is ONE section, not four. TWO SHAPES, and the choice is about REUSE. (1) A band that appears on more than one page, or that needs layout variants, is a COMPONENT with a `sectionType` — see create_component. Components sharing a `sectionType` are that section's VARIANTS (one Hero: 'Centered' for the home page and 'Two-column' for about, same prop keys so a swap keeps the content). This is also the only shape the editor's 'Add a section' picker can insert, and the only one that gets a family name and a variant switcher. (2) A genuinely one-off band on a single page is a `section` BLOCK whose `props.children` hold its blocks. THE TRADEOFF, stated in the present tense because it is real today: inside a component, ONLY the leaves a declared prop TARGETS are click-to-edit on the canvas — each declared prop's `target` is re-keyed to that PLACEMENT's own override address, so editing it changes this page and not the shared definition. A prop with no `target` still SHOWS as a dock control, but its override reaches no rendered slot, so editing it changes nothing on the page. Copy that no prop points at is worse still: no binding and no control, unreachable from click-to-edit AND from the dock, changeable only by editing the component definition, which rewrites every page that places it. A `section` block's children stay click-to-edit unconditionally. So when you choose a component, DECLARE A PROP — WITH A `target` — for every string, link and image a marketer will ever touch; a component with un-propped editable copy is the defect, not the component. In the dock an unset prop shows EMPTY and inherits the definition's default, so set props explicitly when you want the current copy visible there. Do not hand-write a band's JSON: start from a built-in section blueprint (list_components returns locked `builtin:*` blueprints with no projectId — hero-centered, hero-split, feature-grid-three, cta-banner and nine more), each already rooted in a `section` block with its editable leaves declared as props. INLINE its blockJson as a `section` block for a one-off band; for a recurring band, materialize the blueprint with create_component so it becomes project-scoped before implementation validation, Output or publication. Direct `builtin:*` component references exist only for legacy delivery compatibility. Two consecutive call-to-action buttons are two sibling `button` blocks inside the same section — never a `columns` block, which is a `repeat(N,1fr)` grid and would stretch each CTA to half the container. Buttons are inline-level and flow side by side on their own.\";\n\nexport type ComponentCategory =\n | \"navbar\"\n | \"footer\"\n | \"button\"\n | \"section\"\n | \"slider\"\n | \"tabs\"\n | \"form\"\n | \"custom\"\n | \"hero\"\n | \"content\"\n | \"social-proof\"\n | \"conversion\";\n\n/**\n * A single overridable field on a component. `target` points at the block + JSON\n * path inside `blockJson` the override writes to (e.g. blockId \"cta\", path\n * \"props.text\"). Keeping overrides a declared allowlist (not arbitrary nested\n * rewrites) keeps instance data small and the contract explicit.\n */\nexport interface ComponentPropDef {\n key: string;\n label: string;\n target: { blockId: string; path: string };\n /**\n * `slot` holds ONE nested component instance — the component-level twin of the\n * content-model field type `component-ref` (see content-model.ts), named differently for\n * the same reason that one is: `component` already means a BLOCK type. Its value is\n * `{ componentId, overrides }` and its `target.path` is `props`, so filling a slot writes\n * that object over an empty `component` block's props.\n *\n * On a PAGE a slot fill is a LIVE reference; a published ENTRY freezes it (resolveDeep).\n */\n /**\n * The EDITOR contract, not a storage one: `applyOverrides` writes the value at\n * `target.path` whatever its shape, so `type` decides which control the inspector renders\n * and what shape that control produces (FLO-1020).\n *\n * number → a number (heading.level, columns.count)\n * select → one string from `config.options`\n * group → an object keyed by `config.fields`\n * table → an array of such objects (slider.slides)\n *\n * `reference` is absent on purpose: nothing resolves a content-entry id at component render\n * time, so such a prop would save cleanly and render as nothing.\n */\n type: \"text\" | \"richtext\" | \"image\" | \"url\" | \"boolean\" | \"number\" | \"select\" | \"group\" | \"table\" | \"slot\";\n defaultValue?: unknown;\n /**\n * EDITOR HINTS (playbook §12). Stored in the props JSON, so no migration.\n *\n * 🔴 `required` IS NOT ENFORCED AT WRITE TIME, deliberately. Nothing on the write path\n * refuses an override that omits a required prop — a placement saves either way — because\n * the alternative is a component definition that can retroactively make already-saved pages\n * unsaveable. It is a marker the dashboard renders and `get_site_composition` counts, which\n * is the honest shape: the receipt names what is missing instead of the write refusing it.\n */\n required?: boolean;\n /** Hint shown under the control, muted. */\n helpText?: string;\n /** Ghost text inside a text-ish control. */\n placeholder?: string;\n /** Per-type settings; the save schema enforces that each is present on the type needing it. */\n config?: {\n /** `slot` — a pick allowlist. */\n componentIds?: string[];\n /** `select` — the choices. Required, and a default must be one of them. */\n options?: string[];\n /** `group` / `table` — the sub-shape, nestable to 3 levels. */\n fields?: ComponentSubField[];\n /** `number` — bounds for the control. */\n min?: number;\n max?: number;\n step?: number;\n } & Record<string, unknown>;\n /**\n * AUTHORING CHROME — the same object a content-model FIELD carries ({@link ContentModelFieldUi}),\n * deliberately: an agent that has learned `ui` once has learned it on both lanes.\n *\n * A SIBLING of `config`, not a member of it. `config` is a loose bag, so a `config.ui` already\n * survived the write — and that is the problem this key fixes: surviving is not declared, and\n * an undeclared prop is a typo that saves cleanly and renders as nothing.\n *\n * WHERE EACH KEY IS LEGAL differs from the field lane, because the vocabulary does:\n * `preview`/`layout` on `group`, `table` and `slot`; `reorderable` on `table` ALONE, the only\n * prop type whose value is a list. The save schema refuses the rest with the valid set named.\n */\n ui?: ContentModelFieldUi;\n}\n\n/** One field inside a `group` prop or a `table` row. Recursive, capped at 3 levels deep. */\nexport interface ComponentSubField {\n key: string;\n label: string;\n /** No `slot`: a nested component instance belongs on the prop itself, not inside a row. */\n type: Exclude<ComponentPropDef[\"type\"], \"slot\">;\n defaultValue?: unknown;\n /** The same editor hints as the prop above, one level down. @see ComponentPropDef */\n required?: boolean;\n helpText?: string;\n placeholder?: string;\n options?: string[];\n /** CANONICAL. A nested `group`/`table`'s own sub-shape. */\n fields?: ComponentSubField[];\n /**\n * A READ-ONLY MIRROR of `options`/`fields`, in the shape `ComponentPropDef` puts them in.\n *\n * 🔴 WHY A SECOND COPY EXISTS AT ALL. A `group`/`table` PROP declares its sub-shape under\n * `config.fields`; a sub-field of one declares its own under a bare `fields`. So a consumer\n * walking a nested table has to switch shape after the first level, and the componentize lane's\n * repo half (`@bettercms-ai/convert --componentize`) walks exactly that — it reads one node\n * shape at every depth. Mirroring the sub-shape here lets it, without the CMS having to\n * describe a nested table differently from a top-level one.\n *\n * `fields` is the authority. The save schema REFUSES a node whose mirror disagrees with it\n * (`componentPropDefSchema`), because two copies that may drift are worse than one awkward\n * shape — an editor that rewrote `fields` alone would leave a stale row description behind.\n */\n config?: { fields?: ComponentSubField[]; options?: string[] } & Record<string, unknown>;\n}\n\n/** The value a `slot` prop holds — the draft half of a `component-ref`, deliberately. */\nexport interface SlotValue {\n componentId: string;\n overrides?: Record<string, unknown>;\n}\n\n/**\n * A component is a DRAFT until published; only the published copy reaches a visitor.\n * Mirrors pages and entries. See migration 0186_component_draft_live_split.sql.\n */\nexport type ComponentStatus = \"draft\" | \"published\";\n\n/**\n * Archive state (FLO-1012), deliberately SEPARATE from `ComponentStatus`.\n *\n * Archive takes a component out of the working set — hidden from the components list by\n * default, not offered in the visual editor's insert surfaces — while every existing usage\n * keeps serving. It is not unpublish (which pulls the live copy and re-bakes every page that\n * embeds it) and it is not delete.\n *\n * It is a timestamp rather than a third `status` value because a component can be published\n * AND archived; collapsing the two would lose the bit restore has to put back.\n */\n\nexport interface Component {\n id: string;\n workspaceId: string;\n projectId?: string | null;\n name: string;\n slug: string;\n category: ComponentCategory;\n /**\n * Section library: the family this component is a LAYOUT of, e.g. \"Hero\". `name` is the\n * layout label (\"Centered\"), so components sharing a sectionType are selectable variants\n * of one section. Null/absent = an ordinary component, not shown in the section library.\n */\n sectionType?: string | null;\n /** First-class variant family membership; exact workspace/project scope is enforced in DB. */\n variantGroupId?: string | null;\n variantInputMappings?: VariantInputMapping[];\n /** Placement governance: `*`, `slug:<page-slug>`, and/or `type:<page-type>`. */\n allowedOn: string[];\n description?: string | null;\n /** The DRAFT definition. Every builder/autosave/import write path targets these two. */\n blockJson: ContentBlock[];\n props: ComponentPropDef[];\n status: ComponentStatus;\n /** When it left the working set, or null/absent while active. @see ComponentStatus */\n archivedAt?: string | Date | null;\n /** Derived from `archivedAt`, so a client never has to know the column. */\n archived?: boolean;\n /**\n * The LIVE snapshot get_components_by_handle() serves. Null until the first publish.\n * Returned by GET-one (the Compare view needs it), omitted from list rows for payload.\n */\n publishedBlockJson?: ContentBlock[] | null;\n publishedProps?: ComponentPropDef[] | null;\n publishedAt?: string | null; // ISO 8601\n /**\n * Computed in SQL on list/get, never stored:\n * status='published' AND (blockJson or props has diverged from its published copy).\n * An exact jsonb compare, so it self-clears when an edit is reverted.\n */\n pendingChanges?: boolean;\n thumbnail?: string | null;\n createdAt: string; // ISO 8601\n updatedAt: string; // ISO 8601\n}\n\n/**\n * Public/delivery projection — the fields a renderer needs to resolve instances.\n *\n * DELIBERATELY UNCHANGED by the 0186 draft/live split: delivery aliases\n * publishedBlockJson -> blockJson, so every already-deployed site and every\n * bcms-content.json on disk keeps a byte-identical wire shape. Do not add `status` here —\n * delivery only ever returns published rows, so it would always be the same constant.\n */\nexport interface DeliveryComponent {\n id: string;\n name: string;\n slug: string;\n category: ComponentCategory;\n sectionType?: string | null;\n blockJson: ContentBlock[];\n props: ComponentPropDef[];\n}\n","/**\n * Generated from lucide-react@1.8.0 dynamic icon names.\n * Legacy CamelCase identifiers remain valid for existing Layout documents.\n */\nexport const LAYOUT_SECTION_ICONS: readonly string[] = Object.freeze([\n \"LayoutPanelTop\",\n \"PanelTop\",\n \"PanelBottom\",\n \"Menu\",\n \"Navigation\",\n \"Megaphone\",\n \"GalleryHorizontal\",\n \"Rows3\",\n \"Grid2X2\",\n \"FileText\",\n \"Link\",\n \"Contact\",\n \"BadgeInfo\",\n \"Sparkles\",\n \"a-arrow-down\",\n \"a-arrow-up\",\n \"a-large-small\",\n \"accessibility\",\n \"activity\",\n \"air-vent\",\n \"airplay\",\n \"alarm-clock-check\",\n \"alarm-check\",\n \"alarm-clock-minus\",\n \"alarm-minus\",\n \"alarm-clock-off\",\n \"alarm-clock-plus\",\n \"alarm-plus\",\n \"alarm-clock\",\n \"alarm-smoke\",\n \"album\",\n \"align-center-horizontal\",\n \"align-center-vertical\",\n \"align-end-horizontal\",\n \"align-end-vertical\",\n \"align-horizontal-distribute-center\",\n \"align-horizontal-distribute-end\",\n \"align-horizontal-distribute-start\",\n \"align-horizontal-justify-center\",\n \"align-horizontal-justify-end\",\n \"align-horizontal-justify-start\",\n \"align-horizontal-space-around\",\n \"align-horizontal-space-between\",\n \"align-start-horizontal\",\n \"align-start-vertical\",\n \"align-vertical-distribute-center\",\n \"align-vertical-distribute-end\",\n \"align-vertical-distribute-start\",\n \"align-vertical-justify-center\",\n \"align-vertical-justify-end\",\n \"align-vertical-justify-start\",\n \"align-vertical-space-around\",\n \"align-vertical-space-between\",\n \"ambulance\",\n \"ampersand\",\n \"ampersands\",\n \"amphora\",\n \"anchor\",\n \"angry\",\n \"annoyed\",\n \"antenna\",\n \"anvil\",\n \"aperture\",\n \"app-window-mac\",\n \"app-window\",\n \"apple\",\n \"archive-restore\",\n \"archive-x\",\n \"archive\",\n \"armchair\",\n \"arrow-big-down-dash\",\n \"arrow-big-down\",\n \"arrow-big-left-dash\",\n \"arrow-big-left\",\n \"arrow-big-right-dash\",\n \"arrow-big-right\",\n \"arrow-big-up-dash\",\n \"arrow-big-up\",\n \"arrow-down-0-1\",\n \"arrow-down-01\",\n \"arrow-down-1-0\",\n \"arrow-down-10\",\n \"arrow-down-a-z\",\n \"arrow-down-az\",\n \"arrow-down-from-line\",\n \"arrow-down-left\",\n \"arrow-down-narrow-wide\",\n \"arrow-down-right\",\n \"arrow-down-to-dot\",\n \"arrow-down-to-line\",\n \"arrow-down-up\",\n \"arrow-down-wide-narrow\",\n \"sort-desc\",\n \"arrow-down-z-a\",\n \"arrow-down-za\",\n \"arrow-down\",\n \"arrow-left-from-line\",\n \"arrow-left-right\",\n \"arrow-left-to-line\",\n \"arrow-left\",\n \"arrow-right-from-line\",\n \"arrow-right-left\",\n \"arrow-right-to-line\",\n \"arrow-right\",\n \"arrow-up-0-1\",\n \"arrow-up-01\",\n \"arrow-up-1-0\",\n \"arrow-up-10\",\n \"arrow-up-a-z\",\n \"arrow-up-az\",\n \"arrow-up-down\",\n \"arrow-up-from-dot\",\n \"arrow-up-from-line\",\n \"arrow-up-left\",\n \"arrow-up-narrow-wide\",\n \"sort-asc\",\n \"arrow-up-right\",\n \"arrow-up-to-line\",\n \"arrow-up-wide-narrow\",\n \"arrow-up-z-a\",\n \"arrow-up-za\",\n \"arrow-up\",\n \"arrows-up-from-line\",\n \"asterisk\",\n \"at-sign\",\n \"atom\",\n \"audio-lines\",\n \"audio-waveform\",\n \"award\",\n \"axe\",\n \"axis-3d\",\n \"axis-3-d\",\n \"baby\",\n \"backpack\",\n \"badge-alert\",\n \"badge-cent\",\n \"badge-check\",\n \"verified\",\n \"badge-dollar-sign\",\n \"badge-euro\",\n \"badge-indian-rupee\",\n \"badge-info\",\n \"badge-japanese-yen\",\n \"badge-minus\",\n \"badge-percent\",\n \"badge-plus\",\n \"badge-pound-sterling\",\n \"badge-question-mark\",\n \"badge-help\",\n \"badge-russian-ruble\",\n \"badge-swiss-franc\",\n \"badge-turkish-lira\",\n \"badge-x\",\n \"badge\",\n \"baggage-claim\",\n \"balloon\",\n \"ban\",\n \"banana\",\n \"bandage\",\n \"banknote-arrow-down\",\n \"banknote-arrow-up\",\n \"banknote-x\",\n \"banknote\",\n \"barcode\",\n \"barrel\",\n \"baseline\",\n \"bath\",\n \"battery-charging\",\n \"battery-full\",\n \"battery-low\",\n \"battery-medium\",\n \"battery-plus\",\n \"battery-warning\",\n \"battery\",\n \"beaker\",\n \"bean-off\",\n \"bean\",\n \"bed-double\",\n \"bed-single\",\n \"bed\",\n \"beef-off\",\n \"beef\",\n \"beer-off\",\n \"beer\",\n \"bell-dot\",\n \"bell-electric\",\n \"bell-minus\",\n \"bell-off\",\n \"bell-plus\",\n \"bell-ring\",\n \"bell\",\n \"between-horizontal-end\",\n \"between-horizonal-end\",\n \"between-horizontal-start\",\n \"between-horizonal-start\",\n \"between-vertical-end\",\n \"between-vertical-start\",\n \"biceps-flexed\",\n \"bike\",\n \"binary\",\n \"binoculars\",\n \"biohazard\",\n \"bird\",\n \"birdhouse\",\n \"bitcoin\",\n \"blend\",\n \"blinds\",\n \"blocks\",\n \"bluetooth-connected\",\n \"bluetooth-off\",\n \"bluetooth-searching\",\n \"bluetooth\",\n \"bold\",\n \"bolt\",\n \"bomb\",\n \"bone\",\n \"book-a\",\n \"book-alert\",\n \"book-audio\",\n \"book-check\",\n \"book-copy\",\n \"book-dashed\",\n \"book-template\",\n \"book-down\",\n \"book-headphones\",\n \"book-heart\",\n \"book-image\",\n \"book-key\",\n \"book-lock\",\n \"book-marked\",\n \"book-minus\",\n \"book-open-check\",\n \"book-open-text\",\n \"book-open\",\n \"book-plus\",\n \"book-search\",\n \"book-text\",\n \"book-type\",\n \"book-up-2\",\n \"book-up\",\n \"book-user\",\n \"book-x\",\n \"book\",\n \"bookmark-check\",\n \"bookmark-minus\",\n \"bookmark-off\",\n \"bookmark-plus\",\n \"bookmark-x\",\n \"bookmark\",\n \"boom-box\",\n \"bot-message-square\",\n \"bot-off\",\n \"bot\",\n \"bottle-wine\",\n \"bow-arrow\",\n \"box\",\n \"boxes\",\n \"braces\",\n \"curly-braces\",\n \"brackets\",\n \"brain-circuit\",\n \"brain-cog\",\n \"brain\",\n \"brick-wall-fire\",\n \"brick-wall-shield\",\n \"brick-wall\",\n \"briefcase-business\",\n \"briefcase-conveyor-belt\",\n \"briefcase-medical\",\n \"briefcase\",\n \"bring-to-front\",\n \"brush-cleaning\",\n \"brush\",\n \"bubbles\",\n \"bug-off\",\n \"bug-play\",\n \"bug\",\n \"building-2\",\n \"building\",\n \"bus-front\",\n \"bus\",\n \"cable-car\",\n \"cable\",\n \"cake-slice\",\n \"cake\",\n \"calculator\",\n \"calendar-1\",\n \"calendar-arrow-down\",\n \"calendar-arrow-up\",\n \"calendar-check-2\",\n \"calendar-check\",\n \"calendar-clock\",\n \"calendar-cog\",\n \"calendar-days\",\n \"calendar-fold\",\n \"calendar-heart\",\n \"calendar-minus-2\",\n \"calendar-minus\",\n \"calendar-off\",\n \"calendar-plus-2\",\n \"calendar-plus\",\n \"calendar-range\",\n \"calendar-search\",\n \"calendar-sync\",\n \"calendar-x-2\",\n \"calendar-x\",\n \"calendar\",\n \"calendars\",\n \"camera-off\",\n \"camera\",\n \"candy-cane\",\n \"candy-off\",\n \"candy\",\n \"cannabis-off\",\n \"cannabis\",\n \"captions-off\",\n \"captions\",\n \"subtitles\",\n \"car-front\",\n \"car-taxi-front\",\n \"car\",\n \"caravan\",\n \"card-sim\",\n \"carrot\",\n \"case-lower\",\n \"case-sensitive\",\n \"case-upper\",\n \"cassette-tape\",\n \"cast\",\n \"castle\",\n \"cat\",\n \"cctv-off\",\n \"cctv\",\n \"chart-area\",\n \"area-chart\",\n \"chart-bar-big\",\n \"bar-chart-horizontal-big\",\n \"chart-bar-decreasing\",\n \"chart-bar-increasing\",\n \"chart-bar-stacked\",\n \"chart-bar\",\n \"bar-chart-horizontal\",\n \"chart-candlestick\",\n \"candlestick-chart\",\n \"chart-column-big\",\n \"bar-chart-big\",\n \"chart-column-decreasing\",\n \"chart-column-increasing\",\n \"bar-chart-4\",\n \"chart-column-stacked\",\n \"chart-column\",\n \"bar-chart-3\",\n \"chart-gantt\",\n \"chart-line\",\n \"line-chart\",\n \"chart-network\",\n \"chart-no-axes-column-decreasing\",\n \"chart-no-axes-column-increasing\",\n \"bar-chart\",\n \"chart-no-axes-column\",\n \"bar-chart-2\",\n \"chart-no-axes-combined\",\n \"chart-no-axes-gantt\",\n \"gantt-chart\",\n \"chart-pie\",\n \"pie-chart\",\n \"chart-scatter\",\n \"scatter-chart\",\n \"chart-spline\",\n \"check-check\",\n \"check-line\",\n \"check\",\n \"chef-hat\",\n \"cherry\",\n \"chess-bishop\",\n \"chess-king\",\n \"chess-knight\",\n \"chess-pawn\",\n \"chess-queen\",\n \"chess-rook\",\n \"chevron-down\",\n \"chevron-first\",\n \"chevron-last\",\n \"chevron-left\",\n \"chevron-right\",\n \"chevron-up\",\n \"chevrons-down-up\",\n \"chevrons-down\",\n \"chevrons-left-right-ellipsis\",\n \"chevrons-left-right\",\n \"chevrons-left\",\n \"chevrons-right-left\",\n \"chevrons-right\",\n \"chevrons-up-down\",\n \"chevrons-up\",\n \"church\",\n \"cigarette-off\",\n \"cigarette\",\n \"circle-alert\",\n \"alert-circle\",\n \"circle-arrow-down\",\n \"arrow-down-circle\",\n \"circle-arrow-left\",\n \"arrow-left-circle\",\n \"circle-arrow-out-down-left\",\n \"arrow-down-left-from-circle\",\n \"circle-arrow-out-down-right\",\n \"arrow-down-right-from-circle\",\n \"circle-arrow-out-up-left\",\n \"arrow-up-left-from-circle\",\n \"circle-arrow-out-up-right\",\n \"arrow-up-right-from-circle\",\n \"circle-arrow-right\",\n \"arrow-right-circle\",\n \"circle-arrow-up\",\n \"arrow-up-circle\",\n \"circle-check-big\",\n \"check-circle\",\n \"circle-check\",\n \"check-circle-2\",\n \"circle-chevron-down\",\n \"chevron-down-circle\",\n \"circle-chevron-left\",\n \"chevron-left-circle\",\n \"circle-chevron-right\",\n \"chevron-right-circle\",\n \"circle-chevron-up\",\n \"chevron-up-circle\",\n \"circle-dashed\",\n \"circle-divide\",\n \"divide-circle\",\n \"circle-dollar-sign\",\n \"circle-dot-dashed\",\n \"circle-dot\",\n \"circle-ellipsis\",\n \"circle-equal\",\n \"circle-fading-arrow-up\",\n \"circle-fading-plus\",\n \"circle-gauge\",\n \"gauge-circle\",\n \"circle-minus\",\n \"minus-circle\",\n \"circle-off\",\n \"circle-parking-off\",\n \"parking-circle-off\",\n \"circle-parking\",\n \"parking-circle\",\n \"circle-pause\",\n \"pause-circle\",\n \"circle-percent\",\n \"percent-circle\",\n \"circle-pile\",\n \"circle-play\",\n \"play-circle\",\n \"circle-plus\",\n \"plus-circle\",\n \"circle-pound-sterling\",\n \"circle-power\",\n \"power-circle\",\n \"circle-question-mark\",\n \"help-circle\",\n \"circle-help\",\n \"circle-slash-2\",\n \"circle-slashed\",\n \"circle-slash\",\n \"circle-small\",\n \"circle-star\",\n \"circle-stop\",\n \"stop-circle\",\n \"circle-user-round\",\n \"user-circle-2\",\n \"circle-user\",\n \"user-circle\",\n \"circle-x\",\n \"x-circle\",\n \"circle\",\n \"circuit-board\",\n \"citrus\",\n \"clapperboard\",\n \"clipboard-check\",\n \"clipboard-clock\",\n \"clipboard-copy\",\n \"clipboard-list\",\n \"clipboard-minus\",\n \"clipboard-paste\",\n \"clipboard-pen-line\",\n \"clipboard-signature\",\n \"clipboard-pen\",\n \"clipboard-edit\",\n \"clipboard-plus\",\n \"clipboard-type\",\n \"clipboard-x\",\n \"clipboard\",\n \"clock-1\",\n \"clock-10\",\n \"clock-11\",\n \"clock-12\",\n \"clock-2\",\n \"clock-3\",\n \"clock-4\",\n \"clock-5\",\n \"clock-6\",\n \"clock-7\",\n \"clock-8\",\n \"clock-9\",\n \"clock-alert\",\n \"clock-arrow-down\",\n \"clock-arrow-up\",\n \"clock-check\",\n \"clock-fading\",\n \"clock-plus\",\n \"clock\",\n \"closed-caption\",\n \"cloud-alert\",\n \"cloud-backup\",\n \"cloud-check\",\n \"cloud-cog\",\n \"cloud-download\",\n \"download-cloud\",\n \"cloud-drizzle\",\n \"cloud-fog\",\n \"cloud-hail\",\n \"cloud-lightning\",\n \"cloud-moon-rain\",\n \"cloud-moon\",\n \"cloud-off\",\n \"cloud-rain-wind\",\n \"cloud-rain\",\n \"cloud-snow\",\n \"cloud-sun-rain\",\n \"cloud-sun\",\n \"cloud-sync\",\n \"cloud-upload\",\n \"upload-cloud\",\n \"cloud\",\n \"cloudy\",\n \"clover\",\n \"club\",\n \"code-xml\",\n \"code-2\",\n \"code\",\n \"coffee\",\n \"cog\",\n \"coins\",\n \"columns-2\",\n \"columns\",\n \"columns-3-cog\",\n \"columns-settings\",\n \"table-config\",\n \"columns-3\",\n \"panels-left-right\",\n \"columns-4\",\n \"combine\",\n \"command\",\n \"compass\",\n \"component\",\n \"computer\",\n \"concierge-bell\",\n \"cone\",\n \"construction\",\n \"contact-round\",\n \"contact-2\",\n \"contact\",\n \"container\",\n \"contrast\",\n \"cookie\",\n \"cooking-pot\",\n \"copy-check\",\n \"copy-minus\",\n \"copy-plus\",\n \"copy-slash\",\n \"copy-x\",\n \"copy\",\n \"copyleft\",\n \"copyright\",\n \"corner-down-left\",\n \"corner-down-right\",\n \"corner-left-down\",\n \"corner-left-up\",\n \"corner-right-down\",\n \"corner-right-up\",\n \"corner-up-left\",\n \"corner-up-right\",\n \"cpu\",\n \"creative-commons\",\n \"credit-card\",\n \"croissant\",\n \"crop\",\n \"cross\",\n \"crosshair\",\n \"crown\",\n \"cuboid\",\n \"cup-soda\",\n \"currency\",\n \"cylinder\",\n \"dam\",\n \"database-backup\",\n \"database-search\",\n \"database-zap\",\n \"database\",\n \"decimals-arrow-left\",\n \"decimals-arrow-right\",\n \"delete\",\n \"dessert\",\n \"diameter\",\n \"diamond-minus\",\n \"diamond-percent\",\n \"percent-diamond\",\n \"diamond-plus\",\n \"diamond\",\n \"dice-1\",\n \"dice-2\",\n \"dice-3\",\n \"dice-4\",\n \"dice-5\",\n \"dice-6\",\n \"dices\",\n \"diff\",\n \"disc-2\",\n \"disc-3\",\n \"disc-album\",\n \"disc\",\n \"divide\",\n \"dna-off\",\n \"dna\",\n \"dock\",\n \"dog\",\n \"dollar-sign\",\n \"donut\",\n \"door-closed-locked\",\n \"door-closed\",\n \"door-open\",\n \"dot\",\n \"download\",\n \"drafting-compass\",\n \"drama\",\n \"drill\",\n \"drone\",\n \"droplet-off\",\n \"droplet\",\n \"droplets\",\n \"drum\",\n \"drumstick\",\n \"dumbbell\",\n \"ear-off\",\n \"ear\",\n \"earth-lock\",\n \"earth\",\n \"globe-2\",\n \"eclipse\",\n \"egg-fried\",\n \"egg-off\",\n \"egg\",\n \"ellipse\",\n \"ellipsis-vertical\",\n \"more-vertical\",\n \"ellipsis\",\n \"more-horizontal\",\n \"equal-approximately\",\n \"equal-not\",\n \"equal\",\n \"eraser\",\n \"ethernet-port\",\n \"euro\",\n \"ev-charger\",\n \"expand\",\n \"external-link\",\n \"eye-closed\",\n \"eye-off\",\n \"eye\",\n \"factory\",\n \"fan\",\n \"fast-forward\",\n \"feather\",\n \"fence\",\n \"ferris-wheel\",\n \"file-archive\",\n \"file-axis-3d\",\n \"file-axis-3-d\",\n \"file-badge\",\n \"file-badge-2\",\n \"file-box\",\n \"file-braces-corner\",\n \"file-json-2\",\n \"file-braces\",\n \"file-json\",\n \"file-chart-column-increasing\",\n \"file-bar-chart\",\n \"file-chart-column\",\n \"file-bar-chart-2\",\n \"file-chart-line\",\n \"file-line-chart\",\n \"file-chart-pie\",\n \"file-pie-chart\",\n \"file-check-corner\",\n \"file-check-2\",\n \"file-check\",\n \"file-clock\",\n \"file-code-corner\",\n \"file-code-2\",\n \"file-code\",\n \"file-cog\",\n \"file-cog-2\",\n \"file-diff\",\n \"file-digit\",\n \"file-down\",\n \"file-exclamation-point\",\n \"file-warning\",\n \"file-headphone\",\n \"file-audio\",\n \"file-audio-2\",\n \"file-heart\",\n \"file-image\",\n \"file-input\",\n \"file-key\",\n \"file-key-2\",\n \"file-lock\",\n \"file-lock-2\",\n \"file-minus-corner\",\n \"file-minus-2\",\n \"file-minus\",\n \"file-music\",\n \"file-output\",\n \"file-pen-line\",\n \"file-signature\",\n \"file-pen\",\n \"file-edit\",\n \"file-play\",\n \"file-video\",\n \"file-plus-corner\",\n \"file-plus-2\",\n \"file-plus\",\n \"file-question-mark\",\n \"file-question\",\n \"file-scan\",\n \"file-search-corner\",\n \"file-search-2\",\n \"file-search\",\n \"file-signal\",\n \"file-volume-2\",\n \"file-sliders\",\n \"file-spreadsheet\",\n \"file-stack\",\n \"file-symlink\",\n \"file-terminal\",\n \"file-text\",\n \"file-type-corner\",\n \"file-type-2\",\n \"file-type\",\n \"file-up\",\n \"file-user\",\n \"file-video-camera\",\n \"file-video-2\",\n \"file-volume\",\n \"file-x-corner\",\n \"file-x-2\",\n \"file-x\",\n \"file\",\n \"files\",\n \"film\",\n \"fingerprint-pattern\",\n \"fingerprint\",\n \"fire-extinguisher\",\n \"fish-off\",\n \"fish-symbol\",\n \"fish\",\n \"fishing-hook\",\n \"fishing-rod\",\n \"flag-off\",\n \"flag-triangle-left\",\n \"flag-triangle-right\",\n \"flag\",\n \"flame-kindling\",\n \"flame\",\n \"flashlight-off\",\n \"flashlight\",\n \"flask-conical-off\",\n \"flask-conical\",\n \"flask-round\",\n \"flip-horizontal-2\",\n \"flip-vertical-2\",\n \"flower-2\",\n \"flower\",\n \"focus\",\n \"fold-horizontal\",\n \"fold-vertical\",\n \"folder-archive\",\n \"folder-check\",\n \"folder-clock\",\n \"folder-closed\",\n \"folder-code\",\n \"folder-cog\",\n \"folder-cog-2\",\n \"folder-dot\",\n \"folder-down\",\n \"folder-git-2\",\n \"folder-git\",\n \"folder-heart\",\n \"folder-input\",\n \"folder-kanban\",\n \"folder-key\",\n \"folder-lock\",\n \"folder-minus\",\n \"folder-open-dot\",\n \"folder-open\",\n \"folder-output\",\n \"folder-pen\",\n \"folder-edit\",\n \"folder-plus\",\n \"folder-root\",\n \"folder-search-2\",\n \"folder-search\",\n \"folder-symlink\",\n \"folder-sync\",\n \"folder-tree\",\n \"folder-up\",\n \"folder-x\",\n \"folder\",\n \"folders\",\n \"footprints\",\n \"forklift\",\n \"form\",\n \"forward\",\n \"frame\",\n \"frown\",\n \"fuel\",\n \"fullscreen\",\n \"funnel-plus\",\n \"funnel-x\",\n \"filter-x\",\n \"funnel\",\n \"filter\",\n \"gallery-horizontal-end\",\n \"gallery-horizontal\",\n \"gallery-thumbnails\",\n \"gallery-vertical-end\",\n \"gallery-vertical\",\n \"gamepad-2\",\n \"gamepad-directional\",\n \"gamepad\",\n \"gauge\",\n \"gavel\",\n \"gem\",\n \"georgian-lari\",\n \"ghost\",\n \"gift\",\n \"git-branch-minus\",\n \"git-branch-plus\",\n \"git-branch\",\n \"git-commit-horizontal\",\n \"git-commit\",\n \"git-commit-vertical\",\n \"git-compare-arrows\",\n \"git-compare\",\n \"git-fork\",\n \"git-graph\",\n \"git-merge-conflict\",\n \"git-merge\",\n \"git-pull-request-arrow\",\n \"git-pull-request-closed\",\n \"git-pull-request-create-arrow\",\n \"git-pull-request-create\",\n \"git-pull-request-draft\",\n \"git-pull-request\",\n \"glass-water\",\n \"glasses\",\n \"globe-lock\",\n \"globe-off\",\n \"globe-x\",\n \"globe\",\n \"goal\",\n \"gpu\",\n \"graduation-cap\",\n \"grape\",\n \"grid-2x2-check\",\n \"grid-2-x-2-check\",\n \"grid-2x2-plus\",\n \"grid-2-x-2-plus\",\n \"grid-2x2-x\",\n \"grid-2-x-2-x\",\n \"grid-2x2\",\n \"grid-2-x-2\",\n \"grid-3x2\",\n \"grid-3x3\",\n \"grid\",\n \"grid-3-x-3\",\n \"grip-horizontal\",\n \"grip-vertical\",\n \"grip\",\n \"group\",\n \"guitar\",\n \"ham\",\n \"hamburger\",\n \"hammer\",\n \"hand-coins\",\n \"hand-fist\",\n \"hand-grab\",\n \"grab\",\n \"hand-heart\",\n \"hand-helping\",\n \"helping-hand\",\n \"hand-metal\",\n \"hand-platter\",\n \"hand\",\n \"handbag\",\n \"handshake\",\n \"hard-drive-download\",\n \"hard-drive-upload\",\n \"hard-drive\",\n \"hard-hat\",\n \"hash\",\n \"hat-glasses\",\n \"haze\",\n \"hd\",\n \"hdmi-port\",\n \"heading-1\",\n \"heading-2\",\n \"heading-3\",\n \"heading-4\",\n \"heading-5\",\n \"heading-6\",\n \"heading\",\n \"headphone-off\",\n \"headphones\",\n \"headset\",\n \"heart-crack\",\n \"heart-handshake\",\n \"heart-minus\",\n \"heart-off\",\n \"heart-plus\",\n \"heart-pulse\",\n \"heart\",\n \"heater\",\n \"helicopter\",\n \"hexagon\",\n \"highlighter\",\n \"history\",\n \"hop-off\",\n \"hop\",\n \"hospital\",\n \"hotel\",\n \"hourglass\",\n \"house-heart\",\n \"house-plug\",\n \"house-plus\",\n \"house-wifi\",\n \"house\",\n \"home\",\n \"ice-cream-bowl\",\n \"ice-cream-2\",\n \"ice-cream-cone\",\n \"ice-cream\",\n \"id-card-lanyard\",\n \"id-card\",\n \"image-down\",\n \"image-minus\",\n \"image-off\",\n \"image-play\",\n \"image-plus\",\n \"image-up\",\n \"image-upscale\",\n \"image\",\n \"images\",\n \"import\",\n \"inbox\",\n \"indian-rupee\",\n \"infinity\",\n \"info\",\n \"inspection-panel\",\n \"italic\",\n \"iteration-ccw\",\n \"iteration-cw\",\n \"japanese-yen\",\n \"joystick\",\n \"kanban\",\n \"kayak\",\n \"key-round\",\n \"key-square\",\n \"key\",\n \"keyboard-music\",\n \"keyboard-off\",\n \"keyboard\",\n \"lamp-ceiling\",\n \"lamp-desk\",\n \"lamp-floor\",\n \"lamp-wall-down\",\n \"lamp-wall-up\",\n \"lamp\",\n \"land-plot\",\n \"landmark\",\n \"languages\",\n \"laptop-minimal-check\",\n \"laptop-minimal\",\n \"laptop-2\",\n \"laptop\",\n \"lasso-select\",\n \"lasso\",\n \"laugh\",\n \"layers-2\",\n \"layers-plus\",\n \"layers\",\n \"layers-3\",\n \"layout-dashboard\",\n \"layout-grid\",\n \"layout-list\",\n \"layout-panel-left\",\n \"layout-panel-top\",\n \"layout-template\",\n \"leaf\",\n \"leafy-green\",\n \"lectern\",\n \"lens-concave\",\n \"lens-convex\",\n \"library-big\",\n \"library\",\n \"life-buoy\",\n \"ligature\",\n \"lightbulb-off\",\n \"lightbulb\",\n \"line-dot-right-horizontal\",\n \"line-squiggle\",\n \"line-style\",\n \"link-2-off\",\n \"link-2\",\n \"link\",\n \"list-check\",\n \"list-checks\",\n \"list-chevrons-down-up\",\n \"list-chevrons-up-down\",\n \"list-collapse\",\n \"list-end\",\n \"list-filter-plus\",\n \"list-filter\",\n \"list-indent-decrease\",\n \"outdent\",\n \"indent-decrease\",\n \"list-indent-increase\",\n \"indent\",\n \"indent-increase\",\n \"list-minus\",\n \"list-music\",\n \"list-ordered\",\n \"list-plus\",\n \"list-restart\",\n \"list-start\",\n \"list-todo\",\n \"list-tree\",\n \"list-video\",\n \"list-x\",\n \"list\",\n \"loader-circle\",\n \"loader-2\",\n \"loader-pinwheel\",\n \"loader\",\n \"locate-fixed\",\n \"locate-off\",\n \"locate\",\n \"lock-keyhole-open\",\n \"unlock-keyhole\",\n \"lock-keyhole\",\n \"lock-open\",\n \"unlock\",\n \"lock\",\n \"log-in\",\n \"log-out\",\n \"logs\",\n \"lollipop\",\n \"luggage\",\n \"magnet\",\n \"mail-check\",\n \"mail-minus\",\n \"mail-open\",\n \"mail-plus\",\n \"mail-question-mark\",\n \"mail-question\",\n \"mail-search\",\n \"mail-warning\",\n \"mail-x\",\n \"mail\",\n \"mailbox\",\n \"mails\",\n \"map-minus\",\n \"map-pin-check-inside\",\n \"map-pin-check\",\n \"map-pin-house\",\n \"map-pin-minus-inside\",\n \"map-pin-minus\",\n \"map-pin-off\",\n \"map-pin-pen\",\n \"location-edit\",\n \"map-pin-plus-inside\",\n \"map-pin-plus\",\n \"map-pin-search\",\n \"map-pin-x-inside\",\n \"map-pin-x\",\n \"map-pin\",\n \"map-pinned\",\n \"map-plus\",\n \"map\",\n \"mars-stroke\",\n \"mars\",\n \"martini\",\n \"maximize-2\",\n \"maximize\",\n \"medal\",\n \"megaphone-off\",\n \"megaphone\",\n \"meh\",\n \"memory-stick\",\n \"menu\",\n \"merge\",\n \"message-circle-check\",\n \"message-circle-code\",\n \"message-circle-dashed\",\n \"message-circle-heart\",\n \"message-circle-more\",\n \"message-circle-off\",\n \"message-circle-plus\",\n \"message-circle-question-mark\",\n \"message-circle-question\",\n \"message-circle-reply\",\n \"message-circle-warning\",\n \"message-circle-x\",\n \"message-circle\",\n \"message-square-check\",\n \"message-square-code\",\n \"message-square-dashed\",\n \"message-square-diff\",\n \"message-square-dot\",\n \"message-square-heart\",\n \"message-square-lock\",\n \"message-square-more\",\n \"message-square-off\",\n \"message-square-plus\",\n \"message-square-quote\",\n \"message-square-reply\",\n \"message-square-share\",\n \"message-square-text\",\n \"message-square-warning\",\n \"message-square-x\",\n \"message-square\",\n \"messages-square\",\n \"metronome\",\n \"mic-off\",\n \"mic-vocal\",\n \"mic-2\",\n \"mic\",\n \"microchip\",\n \"microscope\",\n \"microwave\",\n \"milestone\",\n \"milk-off\",\n \"milk\",\n \"minimize-2\",\n \"minimize\",\n \"minus\",\n \"mirror-rectangular\",\n \"mirror-round\",\n \"monitor-check\",\n \"monitor-cloud\",\n \"monitor-cog\",\n \"monitor-dot\",\n \"monitor-down\",\n \"monitor-off\",\n \"monitor-pause\",\n \"monitor-play\",\n \"monitor-smartphone\",\n \"monitor-speaker\",\n \"monitor-stop\",\n \"monitor-up\",\n \"monitor-x\",\n \"monitor\",\n \"moon-star\",\n \"moon\",\n \"motorbike\",\n \"mountain-snow\",\n \"mountain\",\n \"mouse-left\",\n \"mouse-off\",\n \"mouse-pointer-2-off\",\n \"mouse-pointer-2\",\n \"mouse-pointer-ban\",\n \"mouse-pointer-click\",\n \"mouse-pointer\",\n \"mouse-right\",\n \"mouse\",\n \"move-3d\",\n \"move-3-d\",\n \"move-diagonal-2\",\n \"move-diagonal\",\n \"move-down-left\",\n \"move-down-right\",\n \"move-down\",\n \"move-horizontal\",\n \"move-left\",\n \"move-right\",\n \"move-up-left\",\n \"move-up-right\",\n \"move-up\",\n \"move-vertical\",\n \"move\",\n \"music-2\",\n \"music-3\",\n \"music-4\",\n \"music\",\n \"navigation-2-off\",\n \"navigation-2\",\n \"navigation-off\",\n \"navigation\",\n \"network\",\n \"newspaper\",\n \"nfc\",\n \"non-binary\",\n \"notebook-pen\",\n \"notebook-tabs\",\n \"notebook-text\",\n \"notebook\",\n \"notepad-text-dashed\",\n \"notepad-text\",\n \"nut-off\",\n \"nut\",\n \"octagon-alert\",\n \"alert-octagon\",\n \"octagon-minus\",\n \"octagon-pause\",\n \"pause-octagon\",\n \"octagon-x\",\n \"x-octagon\",\n \"octagon\",\n \"omega\",\n \"option\",\n \"orbit\",\n \"origami\",\n \"package-2\",\n \"package-check\",\n \"package-minus\",\n \"package-open\",\n \"package-plus\",\n \"package-search\",\n \"package-x\",\n \"package\",\n \"paint-bucket\",\n \"paint-roller\",\n \"paintbrush-vertical\",\n \"paintbrush-2\",\n \"paintbrush\",\n \"palette\",\n \"panda\",\n \"panel-bottom-close\",\n \"panel-bottom-dashed\",\n \"panel-bottom-inactive\",\n \"panel-bottom-open\",\n \"panel-bottom\",\n \"panel-left-close\",\n \"sidebar-close\",\n \"panel-left-dashed\",\n \"panel-left-inactive\",\n \"panel-left-open\",\n \"sidebar-open\",\n \"panel-left-right-dashed\",\n \"panel-left\",\n \"sidebar\",\n \"panel-right-close\",\n \"panel-right-dashed\",\n \"panel-right-inactive\",\n \"panel-right-open\",\n \"panel-right\",\n \"panel-top-bottom-dashed\",\n \"panel-top-close\",\n \"panel-top-dashed\",\n \"panel-top-inactive\",\n \"panel-top-open\",\n \"panel-top\",\n \"panels-left-bottom\",\n \"panels-right-bottom\",\n \"panels-top-left\",\n \"layout\",\n \"paperclip\",\n \"parentheses\",\n \"parking-meter\",\n \"party-popper\",\n \"pause\",\n \"paw-print\",\n \"pc-case\",\n \"pen-line\",\n \"edit-3\",\n \"pen-off\",\n \"pen-tool\",\n \"pen\",\n \"edit-2\",\n \"pencil-line\",\n \"pencil-off\",\n \"pencil-ruler\",\n \"pencil\",\n \"pentagon\",\n \"percent\",\n \"person-standing\",\n \"philippine-peso\",\n \"phone-call\",\n \"phone-forwarded\",\n \"phone-incoming\",\n \"phone-missed\",\n \"phone-off\",\n \"phone-outgoing\",\n \"phone\",\n \"pi\",\n \"piano\",\n \"pickaxe\",\n \"picture-in-picture-2\",\n \"picture-in-picture\",\n \"piggy-bank\",\n \"pilcrow-left\",\n \"pilcrow-right\",\n \"pilcrow\",\n \"pill-bottle\",\n \"pill\",\n \"pin-off\",\n \"pin\",\n \"pipette\",\n \"pizza\",\n \"plane-landing\",\n \"plane-takeoff\",\n \"plane\",\n \"play\",\n \"plug-2\",\n \"plug-zap\",\n \"plug-zap-2\",\n \"plug\",\n \"plus\",\n \"pocket-knife\",\n \"podcast\",\n \"pointer-off\",\n \"pointer\",\n \"popcorn\",\n \"popsicle\",\n \"pound-sterling\",\n \"power-off\",\n \"power\",\n \"presentation\",\n \"printer-check\",\n \"printer-x\",\n \"printer\",\n \"projector\",\n \"proportions\",\n \"puzzle\",\n \"pyramid\",\n \"qr-code\",\n \"quote\",\n \"rabbit\",\n \"radar\",\n \"radiation\",\n \"radical\",\n \"radio-off\",\n \"radio-receiver\",\n \"radio-tower\",\n \"radio\",\n \"radius\",\n \"rainbow\",\n \"rat\",\n \"ratio\",\n \"receipt-cent\",\n \"receipt-euro\",\n \"receipt-indian-rupee\",\n \"receipt-japanese-yen\",\n \"receipt-pound-sterling\",\n \"receipt-russian-ruble\",\n \"receipt-swiss-franc\",\n \"receipt-text\",\n \"receipt-turkish-lira\",\n \"receipt\",\n \"rectangle-circle\",\n \"rectangle-ellipsis\",\n \"form-input\",\n \"rectangle-goggles\",\n \"rectangle-horizontal\",\n \"rectangle-vertical\",\n \"recycle\",\n \"redo-2\",\n \"redo-dot\",\n \"redo\",\n \"refresh-ccw-dot\",\n \"refresh-ccw\",\n \"refresh-cw-off\",\n \"refresh-cw\",\n \"refrigerator\",\n \"regex\",\n \"remove-formatting\",\n \"repeat-1\",\n \"repeat-2\",\n \"repeat\",\n \"replace-all\",\n \"replace\",\n \"reply-all\",\n \"reply\",\n \"rewind\",\n \"ribbon\",\n \"road\",\n \"rocket\",\n \"rocking-chair\",\n \"roller-coaster\",\n \"rose\",\n \"rotate-3d\",\n \"rotate-3-d\",\n \"rotate-ccw-key\",\n \"rotate-ccw-square\",\n \"rotate-ccw\",\n \"rotate-cw-square\",\n \"rotate-cw\",\n \"route-off\",\n \"route\",\n \"router\",\n \"rows-2\",\n \"rows\",\n \"rows-3\",\n \"panels-top-bottom\",\n \"rows-4\",\n \"rss\",\n \"ruler-dimension-line\",\n \"ruler\",\n \"russian-ruble\",\n \"sailboat\",\n \"salad\",\n \"sandwich\",\n \"satellite-dish\",\n \"satellite\",\n \"saudi-riyal\",\n \"save-all\",\n \"save-off\",\n \"save\",\n \"scale-3d\",\n \"scale-3-d\",\n \"scale\",\n \"scaling\",\n \"scan-barcode\",\n \"scan-eye\",\n \"scan-face\",\n \"scan-heart\",\n \"scan-line\",\n \"scan-qr-code\",\n \"scan-search\",\n \"scan-text\",\n \"scan\",\n \"school\",\n \"scissors-line-dashed\",\n \"scissors\",\n \"scooter\",\n \"screen-share-off\",\n \"screen-share\",\n \"scroll-text\",\n \"scroll\",\n \"search-alert\",\n \"search-check\",\n \"search-code\",\n \"search-slash\",\n \"search-x\",\n \"search\",\n \"section\",\n \"send-horizontal\",\n \"send-horizonal\",\n \"send-to-back\",\n \"send\",\n \"separator-horizontal\",\n \"separator-vertical\",\n \"server-cog\",\n \"server-crash\",\n \"server-off\",\n \"server\",\n \"settings-2\",\n \"settings\",\n \"shapes\",\n \"share-2\",\n \"share\",\n \"sheet\",\n \"shell\",\n \"shelving-unit\",\n \"shield-alert\",\n \"shield-ban\",\n \"shield-check\",\n \"shield-cog-corner\",\n \"shield-cog\",\n \"shield-ellipsis\",\n \"shield-half\",\n \"shield-minus\",\n \"shield-off\",\n \"shield-plus\",\n \"shield-question-mark\",\n \"shield-question\",\n \"shield-user\",\n \"shield-x\",\n \"shield-close\",\n \"shield\",\n \"ship-wheel\",\n \"ship\",\n \"shirt\",\n \"shopping-bag\",\n \"shopping-basket\",\n \"shopping-cart\",\n \"shovel\",\n \"shower-head\",\n \"shredder\",\n \"shrimp\",\n \"shrink\",\n \"shrub\",\n \"shuffle\",\n \"sigma\",\n \"signal-high\",\n \"signal-low\",\n \"signal-medium\",\n \"signal-zero\",\n \"signal\",\n \"signature\",\n \"signpost-big\",\n \"signpost\",\n \"siren\",\n \"skip-back\",\n \"skip-forward\",\n \"skull\",\n \"slash\",\n \"slice\",\n \"sliders-horizontal\",\n \"sliders-vertical\",\n \"sliders\",\n \"smartphone-charging\",\n \"smartphone-nfc\",\n \"smartphone\",\n \"smile-plus\",\n \"smile\",\n \"snail\",\n \"snowflake\",\n \"soap-dispenser-droplet\",\n \"sofa\",\n \"solar-panel\",\n \"soup\",\n \"space\",\n \"spade\",\n \"sparkle\",\n \"sparkles\",\n \"stars\",\n \"speaker\",\n \"speech\",\n \"spell-check-2\",\n \"spell-check\",\n \"spline-pointer\",\n \"spline\",\n \"split\",\n \"spool\",\n \"sport-shoe\",\n \"spotlight\",\n \"spray-can\",\n \"sprout\",\n \"square-activity\",\n \"activity-square\",\n \"square-arrow-down-left\",\n \"arrow-down-left-square\",\n \"square-arrow-down-right\",\n \"arrow-down-right-square\",\n \"square-arrow-down\",\n \"arrow-down-square\",\n \"square-arrow-left\",\n \"arrow-left-square\",\n \"square-arrow-out-down-left\",\n \"arrow-down-left-from-square\",\n \"square-arrow-out-down-right\",\n \"arrow-down-right-from-square\",\n \"square-arrow-out-up-left\",\n \"arrow-up-left-from-square\",\n \"square-arrow-out-up-right\",\n \"arrow-up-right-from-square\",\n \"square-arrow-right-enter\",\n \"square-arrow-right-exit\",\n \"square-arrow-right\",\n \"arrow-right-square\",\n \"square-arrow-up-left\",\n \"arrow-up-left-square\",\n \"square-arrow-up-right\",\n \"arrow-up-right-square\",\n \"square-arrow-up\",\n \"arrow-up-square\",\n \"square-asterisk\",\n \"asterisk-square\",\n \"square-bottom-dashed-scissors\",\n \"scissors-square-dashed-bottom\",\n \"square-centerline-dashed-horizontal\",\n \"flip-horizontal\",\n \"square-centerline-dashed-vertical\",\n \"flip-vertical\",\n \"square-chart-gantt\",\n \"gantt-chart-square\",\n \"square-gantt-chart\",\n \"square-check-big\",\n \"check-square\",\n \"square-check\",\n \"check-square-2\",\n \"square-chevron-down\",\n \"chevron-down-square\",\n \"square-chevron-left\",\n \"chevron-left-square\",\n \"square-chevron-right\",\n \"chevron-right-square\",\n \"square-chevron-up\",\n \"chevron-up-square\",\n \"square-code\",\n \"code-square\",\n \"square-dashed-bottom-code\",\n \"square-dashed-bottom\",\n \"square-dashed-kanban\",\n \"kanban-square-dashed\",\n \"square-dashed-mouse-pointer\",\n \"mouse-pointer-square-dashed\",\n \"square-dashed-text\",\n \"text-selection\",\n \"text-select\",\n \"square-dashed-top-solid\",\n \"square-dashed\",\n \"box-select\",\n \"square-divide\",\n \"divide-square\",\n \"square-dot\",\n \"dot-square\",\n \"square-equal\",\n \"equal-square\",\n \"square-function\",\n \"function-square\",\n \"square-kanban\",\n \"kanban-square\",\n \"square-library\",\n \"library-square\",\n \"square-m\",\n \"m-square\",\n \"square-menu\",\n \"menu-square\",\n \"square-minus\",\n \"minus-square\",\n \"square-mouse-pointer\",\n \"inspect\",\n \"square-parking-off\",\n \"parking-square-off\",\n \"square-parking\",\n \"parking-square\",\n \"square-pause\",\n \"square-pen\",\n \"pen-box\",\n \"edit\",\n \"pen-square\",\n \"square-percent\",\n \"percent-square\",\n \"square-pi\",\n \"pi-square\",\n \"square-pilcrow\",\n \"pilcrow-square\",\n \"square-play\",\n \"play-square\",\n \"square-plus\",\n \"plus-square\",\n \"square-power\",\n \"power-square\",\n \"square-radical\",\n \"square-round-corner\",\n \"square-scissors\",\n \"scissors-square\",\n \"square-sigma\",\n \"sigma-square\",\n \"square-slash\",\n \"slash-square\",\n \"square-split-horizontal\",\n \"split-square-horizontal\",\n \"square-split-vertical\",\n \"split-square-vertical\",\n \"square-square\",\n \"square-stack\",\n \"square-star\",\n \"square-stop\",\n \"square-terminal\",\n \"terminal-square\",\n \"square-user-round\",\n \"user-square-2\",\n \"square-user\",\n \"user-square\",\n \"square-x\",\n \"x-square\",\n \"square\",\n \"squares-exclude\",\n \"squares-intersect\",\n \"squares-subtract\",\n \"squares-unite\",\n \"squircle-dashed\",\n \"squircle\",\n \"squirrel\",\n \"stamp\",\n \"star-half\",\n \"star-off\",\n \"star\",\n \"step-back\",\n \"step-forward\",\n \"stethoscope\",\n \"sticker\",\n \"sticky-note\",\n \"stone\",\n \"store\",\n \"stretch-horizontal\",\n \"stretch-vertical\",\n \"strikethrough\",\n \"subscript\",\n \"sun-dim\",\n \"sun-medium\",\n \"sun-moon\",\n \"sun-snow\",\n \"sun\",\n \"sunrise\",\n \"sunset\",\n \"superscript\",\n \"swatch-book\",\n \"swiss-franc\",\n \"switch-camera\",\n \"sword\",\n \"swords\",\n \"syringe\",\n \"table-2\",\n \"table-cells-merge\",\n \"table-cells-split\",\n \"table-columns-split\",\n \"table-of-contents\",\n \"table-properties\",\n \"table-rows-split\",\n \"table\",\n \"tablet-smartphone\",\n \"tablet\",\n \"tablets\",\n \"tag\",\n \"tags\",\n \"tally-1\",\n \"tally-2\",\n \"tally-3\",\n \"tally-4\",\n \"tally-5\",\n \"tangent\",\n \"target\",\n \"telescope\",\n \"tent-tree\",\n \"tent\",\n \"terminal\",\n \"test-tube-diagonal\",\n \"test-tube-2\",\n \"test-tube\",\n \"test-tubes\",\n \"text-align-center\",\n \"align-center\",\n \"text-align-end\",\n \"align-right\",\n \"text-align-justify\",\n \"align-justify\",\n \"text-align-start\",\n \"text\",\n \"align-left\",\n \"text-cursor-input\",\n \"text-cursor\",\n \"text-initial\",\n \"letter-text\",\n \"text-quote\",\n \"text-search\",\n \"text-wrap\",\n \"wrap-text\",\n \"theater\",\n \"thermometer-snowflake\",\n \"thermometer-sun\",\n \"thermometer\",\n \"thumbs-down\",\n \"thumbs-up\",\n \"ticket-check\",\n \"ticket-minus\",\n \"ticket-percent\",\n \"ticket-plus\",\n \"ticket-slash\",\n \"ticket-x\",\n \"ticket\",\n \"tickets-plane\",\n \"tickets\",\n \"timer-off\",\n \"timer-reset\",\n \"timer\",\n \"toggle-left\",\n \"toggle-right\",\n \"toilet\",\n \"tool-case\",\n \"toolbox\",\n \"tornado\",\n \"torus\",\n \"touchpad-off\",\n \"touchpad\",\n \"towel-rack\",\n \"tower-control\",\n \"toy-brick\",\n \"tractor\",\n \"traffic-cone\",\n \"train-front-tunnel\",\n \"train-front\",\n \"train-track\",\n \"tram-front\",\n \"train\",\n \"transgender\",\n \"trash-2\",\n \"trash\",\n \"tree-deciduous\",\n \"tree-palm\",\n \"palmtree\",\n \"tree-pine\",\n \"trees\",\n \"trending-down\",\n \"trending-up-down\",\n \"trending-up\",\n \"triangle-alert\",\n \"alert-triangle\",\n \"triangle-dashed\",\n \"triangle-right\",\n \"triangle\",\n \"trophy\",\n \"truck-electric\",\n \"truck\",\n \"turkish-lira\",\n \"turntable\",\n \"turtle\",\n \"tv-minimal-play\",\n \"tv-minimal\",\n \"tv-2\",\n \"tv\",\n \"type-outline\",\n \"type\",\n \"umbrella-off\",\n \"umbrella\",\n \"underline\",\n \"undo-2\",\n \"undo-dot\",\n \"undo\",\n \"unfold-horizontal\",\n \"unfold-vertical\",\n \"ungroup\",\n \"university\",\n \"school-2\",\n \"unlink-2\",\n \"unlink\",\n \"unplug\",\n \"upload\",\n \"usb\",\n \"user-check\",\n \"user-cog\",\n \"user-key\",\n \"user-lock\",\n \"user-minus\",\n \"user-pen\",\n \"user-plus\",\n \"user-round-check\",\n \"user-check-2\",\n \"user-round-cog\",\n \"user-cog-2\",\n \"user-round-key\",\n \"user-round-minus\",\n \"user-minus-2\",\n \"user-round-pen\",\n \"user-round-plus\",\n \"user-plus-2\",\n \"user-round-search\",\n \"user-round-x\",\n \"user-x-2\",\n \"user-round\",\n \"user-2\",\n \"user-search\",\n \"user-star\",\n \"user-x\",\n \"user\",\n \"users-round\",\n \"users-2\",\n \"users\",\n \"utensils-crossed\",\n \"fork-knife-crossed\",\n \"utensils\",\n \"fork-knife\",\n \"utility-pole\",\n \"van\",\n \"variable\",\n \"vault\",\n \"vector-square\",\n \"vegan\",\n \"venetian-mask\",\n \"venus-and-mars\",\n \"venus\",\n \"vibrate-off\",\n \"vibrate\",\n \"video-off\",\n \"video\",\n \"videotape\",\n \"view\",\n \"voicemail\",\n \"volleyball\",\n \"volume-1\",\n \"volume-2\",\n \"volume-off\",\n \"volume-x\",\n \"volume\",\n \"vote\",\n \"wallet-cards\",\n \"wallet-minimal\",\n \"wallet-2\",\n \"wallet\",\n \"wallpaper\",\n \"wand-sparkles\",\n \"wand-2\",\n \"wand\",\n \"warehouse\",\n \"washing-machine\",\n \"watch\",\n \"waves-arrow-down\",\n \"waves-arrow-up\",\n \"waves-ladder\",\n \"waves\",\n \"waypoints\",\n \"webcam\",\n \"webhook-off\",\n \"webhook\",\n \"weight-tilde\",\n \"weight\",\n \"wheat-off\",\n \"wheat\",\n \"whole-word\",\n \"wifi-cog\",\n \"wifi-high\",\n \"wifi-low\",\n \"wifi-off\",\n \"wifi-pen\",\n \"wifi-sync\",\n \"wifi-zero\",\n \"wifi\",\n \"wind-arrow-down\",\n \"wind\",\n \"wine-off\",\n \"wine\",\n \"workflow\",\n \"worm\",\n \"wrench\",\n \"x-line-top\",\n \"x\",\n \"zap-off\",\n \"zap\",\n \"zodiac-aquarius\",\n \"zodiac-aries\",\n \"zodiac-cancer\",\n \"zodiac-capricorn\",\n \"zodiac-gemini\",\n \"zodiac-leo\",\n \"zodiac-libra\",\n \"zodiac-ophiuchus\",\n \"zodiac-pisces\",\n \"zodiac-sagittarius\",\n \"zodiac-scorpio\",\n \"zodiac-taurus\",\n \"zodiac-virgo\",\n \"zoom-in\",\n \"zoom-out\",\n]);\n\nexport const LAYOUT_SECTION_ICON_SET: ReadonlySet<string> = new Set(LAYOUT_SECTION_ICONS);\nexport type LayoutSectionIcon = string;\n","/** Stable identifiers used by every project and page layout document. */\nexport const PAGE_CONTENT_ANCHOR_ID = \"page-content\" as const;\nexport const NAVIGATION_SECTION_ID = \"navigation\" as const;\nexport const FOOTER_SECTION_ID = \"footer\" as const;\n\n/** Locked transport/validation set shared by authoring surfaces and the server. */\nexport {\n LAYOUT_SECTION_ICONS,\n LAYOUT_SECTION_ICON_SET,\n type LayoutSectionIcon,\n} from \"./layout-lucide-icons.js\";\nimport type { LayoutSectionIcon } from \"./layout-lucide-icons.js\";\n\nexport type LayoutZone = \"above-page-content\" | \"below-page-content\";\nexport type ReservedLayoutSection = \"navigation\" | \"footer\";\n\nexport type LayoutScalarFieldType =\n | \"text\"\n | \"longtext\"\n | \"richtext\"\n | \"number\"\n | \"toggle\"\n | \"date\"\n | \"image\"\n | \"file\"\n | \"link\"\n | \"email\"\n | \"phone\"\n | \"select\"\n | \"color\"\n | \"json\"\n | \"reference\"\n | \"multi-reference\";\n\nexport type LayoutFieldType = LayoutScalarFieldType | \"group\" | \"repeater\";\n\n/** A recursive, stable-ID field contract shared by Sections and variant inputs. */\nexport interface LayoutFieldDefinition {\n id: string;\n slug: string;\n label: string;\n type: LayoutFieldType;\n required?: boolean;\n defaultValue?: unknown;\n config?: {\n options?: Array<{ label: string; value: string }>;\n referenceModelId?: string;\n minItems?: number;\n maxItems?: number;\n } & Record<string, unknown>;\n /** Required for group/repeater; forbidden for scalar fields. */\n fields?: LayoutFieldDefinition[];\n}\n\n/** The canonical public input contract all variants in a group implement. */\nexport type CanonicalInputDefinition = LayoutFieldDefinition;\n\n/** Maps one canonical input onto one or more internal component prop paths. */\nexport interface VariantInputMapping {\n inputId: string;\n targets: Array<{ blockId: string; path: string }>;\n}\n\nexport interface ComponentVariantGroup {\n id: string;\n workspaceId: string;\n projectId?: string | null;\n name: string;\n slug: string;\n canonicalInputs: CanonicalInputDefinition[];\n status: \"draft\" | \"published\";\n}\n\nexport interface LayoutFieldItem {\n id: string;\n kind: \"field\";\n fieldId: string;\n}\n\nexport interface LayoutComponentItem {\n id: string;\n kind: \"component\";\n componentId: string;\n variantGroupId?: string;\n bindings: Array<{ inputId: string; fieldId: string }>;\n literalValues?: Record<string, unknown>;\n}\n\nexport type LayoutSectionItem = LayoutFieldItem | LayoutComponentItem;\n\nexport interface LayoutSection {\n id: string;\n name: string;\n slug: string;\n icon: string;\n zone: LayoutZone;\n orderKey: string;\n reserved?: ReservedLayoutSection;\n fields: LayoutFieldDefinition[];\n items: LayoutSectionItem[];\n}\n\nexport interface LayoutStructureDocument {\n version: 1;\n pageContentAnchor: { id: typeof PAGE_CONTENT_ANCHOR_ID };\n sections: LayoutSection[];\n}\n\nexport interface LayoutDataDocument {\n version: 1;\n sections: Record<string, { fields: Record<string, unknown> }>;\n}\n\nexport type PageLayoutOverrideState =\n | \"inherit\"\n | \"override-content\"\n | \"customize-structure\"\n | \"disable\";\n\nexport interface PageSectionPlacement {\n zone: LayoutZone;\n afterSectionId?: string;\n beforeSectionId?: string;\n localOrderKey: string;\n}\n\nexport type PageLayoutSectionOverride =\n | { sectionId: string; state: \"inherit\" }\n | { sectionId: string; state: \"override-content\"; values: Record<string, unknown> }\n | {\n sectionId: string;\n state: \"customize-structure\";\n section: LayoutSection;\n data: { fields: Record<string, unknown> };\n /** Retained when the inherited Section is later deleted. */\n placement: PageSectionPlacement;\n }\n | { sectionId: string; state: \"disable\" };\n\nexport interface PageOnlyLayoutSection {\n section: LayoutSection;\n data: { fields: Record<string, unknown> };\n placement: PageSectionPlacement;\n}\n\nexport type PageLayoutSectionStructureOverride =\n | { sectionId: string; state: \"inherit\" }\n | { sectionId: string; state: \"override-content\" }\n | { sectionId: string; state: \"customize-structure\"; section: LayoutSection; placement: PageSectionPlacement }\n | { sectionId: string; state: \"disable\" };\n\n/** Persisted in pages.layout_override_structure_json. */\nexport interface PageLayoutOverrideStructureDocument {\n version: 1;\n sections: PageLayoutSectionStructureOverride[];\n pageOnlySections: Array<{ section: LayoutSection; placement: PageSectionPlacement }>;\n}\n\n/** Persisted independently so values can be patched without rewriting structure. */\nexport interface PageLayoutOverrideDataDocument {\n version: 1;\n sections: Record<string, { fields: Record<string, unknown> }>;\n pageOnlySections: Record<string, { fields: Record<string, unknown> }>;\n}\n\n/** Canonical in-memory form consumed by the pure resolver. */\nexport interface PageLayoutOverrideDocument {\n version: 1;\n sections: PageLayoutSectionOverride[];\n pageOnlySections: PageOnlyLayoutSection[];\n}\n\n/** Canonical, discriminated Management/MCP authoring transport. Authority is derived from type. */\nexport type ManagementLayoutCommand =\n | { type: \"set-section-values\"; sectionId: string; values: Record<string, unknown> }\n | { type: \"set-field-value\"; sectionId: string; fieldId: string; value: unknown }\n | { type: \"add-component\"; sectionId: string; componentId: string; variantGroupId?: string; bindings?: LayoutComponentItem[\"bindings\"]; literalValues?: Record<string, unknown> }\n | { type: \"remove-item\"; sectionId: string; itemId: string }\n | { type: \"move-component\"; sectionId: string; itemId: string; index: number }\n | { type: \"move-item\"; sectionId: string; itemId: string; index: number }\n | { type: \"swap-component-variant\"; sectionId: string; itemId: string; componentId: string }\n | { type: \"set-page-state\"; sectionId: string; state: PageLayoutOverrideState | \"reset\" }\n | { type: \"set-section-state\"; sectionId: string; state: PageLayoutOverrideState | \"reset\" }\n | { type: \"add-section\"; name: string; icon: LayoutSectionIcon; zone: \"before_page\" | \"after_page\" }\n | { type: \"restore-section\"; section: LayoutSection; data: { fields: Record<string, unknown> }; placement?: PageSectionPlacement }\n | { type: \"update-section\"; sectionId: string; name?: string; icon?: LayoutSectionIcon; slug?: string; zone?: LayoutZone; orderKey?: string }\n | { type: \"remove-section\"; sectionId: string }\n | { type: \"move-section\"; sectionId: string; afterId?: string | null; beforeId?: string | null }\n | { type: \"add-field\"; sectionId: string; parentFieldId?: string; field?: LayoutFieldDefinition; fieldType?: LayoutFieldType }\n | { type: \"update-field\"; sectionId: string; fieldId: string; patch: Partial<Omit<LayoutFieldDefinition, \"id\">> }\n | { type: \"remove-field\"; sectionId: string; fieldId: string }\n | { type: \"move-field\"; sectionId: string; itemId: string; index: number }\n | { type: \"set-bindings\"; sectionId: string; itemId: string; bindings: LayoutComponentItem[\"bindings\"]; literalValues?: Record<string, unknown> };\n\nexport type ResolvedLayoutNode =\n | { kind: \"page-content\"; id: typeof PAGE_CONTENT_ANCHOR_ID }\n | {\n kind: \"section\";\n id: string;\n section: LayoutSection;\n data: { fields: Record<string, unknown> };\n source: \"inherit\" | \"override-content\" | \"customize-structure\" | \"page-only\" | \"detached\";\n };\n\nexport interface DeliveredLayout {\n version: 1;\n nodes: Array<\n | { kind: \"page-content\"; id: typeof PAGE_CONTENT_ANCHOR_ID }\n | { kind: \"section\"; id: string; slug: string; name: string; source: Extract<ResolvedLayoutNode, { kind: \"section\" }>[\"source\"] }\n >;\n sections: Record<string, {\n id: string;\n slug: string;\n name: string;\n fields: Record<string, unknown>;\n items: Array<\n | { id: string; kind: \"field\"; fieldId: string; value: unknown }\n | {\n id: string;\n kind: \"component\";\n componentId: string;\n variantGroupId?: string;\n canonicalInputs: CanonicalInputDefinition[];\n bindings: LayoutComponentItem[\"bindings\"];\n canonicalValues: Record<string, unknown>;\n resolvedProps: Record<string, unknown>;\n /**\n * `prop.key` → canonical `inputId` — the relation `resolvedProps` consumes and throws\n * away (`output[prop.key] = canonicalValues[mapping.inputId]`).\n *\n * Without it a renderer holds a component prop key and NO address: `logoAlt`/`links`/\n * `cta` are the component's own bare keys, and nothing relates them back to the layout\n * field a write must land on. With it the chain closes — `prop.key` → `inputId` →\n * (`bindings`, already delivered above) → `fieldId` → `set-field-value(sectionId,\n * fieldId)`. That is what makes global chrome click-to-edit (FLO-1179).\n *\n * Additive and always present (`{}` when the item has no variant mappings), so an\n * older consumer that ignores it is byte-identical to before.\n */\n propInputs: Record<string, string>;\n blocks: unknown[];\n }\n >;\n }>;\n}\n"],"mappings":";AA0eO,SAAS,QAAQ,OAAuC;AAC7D,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,OAAQ,MAAkC,MAAM,MAAM;AAE1D;AAUO,SAAS,aAAa,OAAkC;AAC7D,MAAI,QAAQ,KAAK,EAAG,QAAO,MAAM;AACjC,SAAO;AACT;;;ACvbO,IAAM,iBAAsE;AAAA,EACjF,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,EACxC,MAAM,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,CAAC;AAAA,EACzC,UAAU,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,CAAC;AAAA,EAC7C,OAAO;AAAA,IACL,EAAE,MAAM,OAAO,MAAM,QAAQ;AAAA,IAC7B,EAAE,MAAM,WAAW,MAAM,OAAO;AAAA,IAChC,EAAE,MAAM,OAAO,MAAM,QAAQ,MAAM,MAAM;AAAA,EAC3C;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,QAAQ,MAAM,OAAO;AAAA,IAC7B,EAAE,MAAM,QAAQ,MAAM,OAAO,MAAM,OAAO;AAAA,EAC5C;AAAA,EACA,OAAO;AAAA,IACL,EAAE,MAAM,OAAO,MAAM,OAAO,MAAM,MAAM;AAAA,IACxC,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM,SAAS;AAAA,EAChD;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,YAAY,MAAM,QAAQ;AAAA,IAClC,EAAE,MAAM,YAAY,MAAM,QAAQ,MAAM,MAAM;AAAA,IAC9C,EAAE,MAAM,iBAAiB,MAAM,OAAO;AAAA,IACtC,EAAE,MAAM,gBAAgB,MAAM,OAAO,MAAM,OAAO;AAAA,IAClD,EAAE,MAAM,YAAY,MAAM,OAAO;AAAA,IACjC,EAAE,MAAM,YAAY,MAAM,OAAO,MAAM,OAAO;AAAA,EAChD;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,aAAa,MAAM,OAAO;AAAA,IAClC,EAAE,MAAM,qBAAqB,MAAM,OAAO;AAAA,IAC1C,EAAE,MAAM,2BAA2B,MAAM,OAAO;AAAA,IAChD,EAAE,MAAM,0BAA0B,MAAM,OAAO,MAAM,OAAO;AAAA,EAC9D;AAAA,EACA,MAAM,CAAC,EAAE,MAAM,gBAAgB,MAAM,OAAO,CAAC;AAC/C;AAQA,IAAM,WAAW,CAAC,MAChB,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAgBlD,SAAS,SAAS,MAAe,MAAuB;AAC7D,MAAI,SAAkB;AACtB,aAAW,WAAW,KAAK,MAAM,GAAG,GAAG;AACrC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,MAAM,QAAQ,QAAQ,YAAY,EAAE;AAC1C,QAAI,KAAK;AACP,UAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAC9B,eAAS,OAAO,GAAG;AAAA,IACrB;AACA,eAAW,SAAS,QAAQ,SAAS,YAAY,GAAG;AAClD,UAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO;AACnC,eAAS,OAAO,OAAO,MAAM,CAAC,CAAC,CAAC;AAAA,IAClC;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,eAAe,SAAuB,OAAgB,MAAiC;AAC9F,QAAM,KAAK,KAAK,QAAQ,IAAI;AAC5B,MAAI,KAAK,EAAG,QAAO,CAAC,EAAE,GAAG,SAAS,KAAK,CAAC;AAExC,QAAM,OAAO,KAAK,MAAM,GAAG,EAAE;AAC7B,QAAM,OAAO,KAAK,MAAM,KAAK,CAAC;AAC9B,QAAM,QAAQ,SAAS,OAAO,IAAI;AAClC,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AAEnC,SAAO,MAAM;AAAA,IAAQ,CAAC,OAAO,UAC3B,eAAe,SAAS,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE;AAAA,EAC3D;AACF;AAiBO,SAAS,oBAAoB,OAAwC;AAC1E,QAAM,WAAW,eAAe,MAAM,IAAI;AAC1C,MAAI,CAAC,SAAU,QAAO,CAAC;AACvB,QAAM,QAAS,MAA8B;AAC7C,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO,CAAC;AAC9B,SAAO,SACJ,QAAQ,CAAC,YAAY,eAAe,SAAS,OAAO,QAAQ,IAAI,CAAC,EACjE,OAAO,CAAC,YAAY,SAAS,OAAO,QAAQ,IAAI,MAAM,MAAS;AACpE;AAGO,SAAS,qBACd,SACQ;AACR,SAAO,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO,IAAI,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,GAAG;AACxE;AAGO,SAAS,oBACd,OACwD;AACxD,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO,MACJ,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,MAAM,GAAG,CAAC,EAC/B,OAAO,CAAC,UAAkD,MAAM,WAAW,KAAK,MAAM,MAAM,OAAO,CAAC,EACpG,IAAI,CAAC,CAAC,SAAS,MAAM,IAAI,OAAO,EAAE,SAAS,MAAM,KAAK,EAAE;AAC7D;AAiCO,SAAS,uBAAuB,MAA6C;AAClF,MAAI,CAAC,MAAM,OAAO,CAAC,KAAK,QAAQ,QAAS,QAAO;AAChD,SAAO,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,KAAK,OAAO,QAAQ,EAAE,EAAE,QAAQ,YAAY,EAAE,CAAC;AAC1F;AAEO,SAAS,2BACd,iBACA,OACqB;AACrB,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,QAAQ,SAAS,CAAC,GAAG;AAC9B,QAAI,CAAC,MAAM,OAAO,CAAC,KAAK,QAAQ,QAAS;AACzC,UAAM,OAAO,uBAAuB,IAAI;AAGxC,QAAI,CAAC,IAAI,IAAI,IAAI,EAAG,KAAI,IAAI,MAAM,GAAG,eAAe,eAAe,KAAK,GAAG,EAAE;AAAA,EAC/E;AACA,SAAO;AACT;;;ACrPA,IAAM,WAAmC,EAAE,MAAM,KAAK,IAAI,OAAO,IAAI,OAAO,IAAI,QAAQ,IAAI,QAAQ,IAAI,OAAO;AAC/G,IAAM,gBAAwC,EAAE,IAAI,YAAY,MAAM,QAAQ,IAAI,WAAW,IAAI,UAAU,OAAO,OAAO;AACzH,IAAM,SAAiC,EAAE,QAAQ,KAAK,QAAQ,KAAK,UAAU,KAAK,MAAM,IAAI;AAC5F,IAAM,YAAoC,EAAE,MAAM,KAAK,IAAI,OAAO,IAAI,OAAO,IAAI,QAAQ,MAAM,SAAS;AACxG,IAAM,YAAoC,EAAE,OAAO,WAAW,OAAO,WAAW,OAAO,WAAW,SAAS,WAAW,SAAS,WAAW,QAAQ,UAAU;AAGrJ,SAAS,gBAAgB,OAA4E;AAC1G,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,IAAI;AACV,QAAM,MAAuC,CAAC;AAC9C,MAAI,EAAE,YAAY,SAAS,EAAE,QAAQ,KAAK,MAAM;AAAE,QAAI,aAAa,SAAS,EAAE,QAAQ;AAAI,QAAI,gBAAgB,SAAS,EAAE,QAAQ;AAAA,EAAI;AACrI,MAAI,EAAE,YAAY,SAAS,EAAE,QAAQ,KAAK,MAAM;AAAE,QAAI,cAAc,SAAS,EAAE,QAAQ;AAAI,QAAI,eAAe,SAAS,EAAE,QAAQ;AAAA,EAAI;AACrI,MAAI,EAAE,aAAa,SAAS,EAAE,SAAS,KAAK,KAAM,KAAI,YAAY,SAAS,EAAE,SAAS;AACtF,MAAI,EAAE,gBAAgB,SAAS,EAAE,YAAY,KAAK,KAAM,KAAI,eAAe,SAAS,EAAE,YAAY;AAClG,MAAI,EAAE,cAAc,UAAU,EAAE,UAAU,EAAG,KAAI,aAAa,UAAU,EAAE,UAAU;AACpF,MAAI,EAAE,aAAa,UAAU,EAAE,SAAS,EAAG,KAAI,QAAQ,UAAU,EAAE,SAAS;AAC5E,MAAI,EAAE,UAAU,UAAU,EAAE,UAAU,YAAY,EAAE,UAAU,QAAS,KAAI,YAAY,EAAE;AACzF,MAAI,EAAE,YAAY,cAAc,EAAE,QAAQ,EAAG,KAAI,WAAW,cAAc,EAAE,QAAQ;AACpF,MAAI,EAAE,UAAU,OAAO,EAAE,MAAM,KAAK,KAAM,KAAI,aAAa,OAAO,EAAE,MAAM;AAC1E,MAAI,EAAE,UAAU,UAAU,EAAE,MAAM,KAAK,KAAM,KAAI,eAAe,UAAU,EAAE,MAAM;AAClF,SAAO,OAAO,KAAK,GAAG,EAAE,SAAS,MAAM;AACzC;;;ACOO,IAAM,mBACX;;;AClCK,IAAM,uBAA0C,OAAO,OAAO;AAAA,EACnE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,0BAA+C,IAAI,IAAI,oBAAoB;;;AC36DjF,IAAM,yBAAyB;AAC/B,IAAM,wBAAwB;AAC9B,IAAM,oBAAoB;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bettercms-ai/types",
3
- "version": "1.15.0",
3
+ "version": "1.17.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",