@artinstack/migrator 0.1.12 → 0.1.13
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 +2 -1
- package/dist/{bundle-CysqqLij.d.ts → bundle-BgoXkWMy.d.ts} +1 -1
- package/dist/{chunk-MUFGDYGI.js → chunk-373TTCG7.js} +11 -1
- package/dist/chunk-373TTCG7.js.map +1 -0
- package/dist/{chunk-J7EUSPEA.js → chunk-4XZK55RW.js} +172 -2
- package/dist/chunk-4XZK55RW.js.map +1 -0
- package/dist/{chunk-Q44KGFIH.js → chunk-53VXTXGM.js} +74 -5
- package/dist/chunk-53VXTXGM.js.map +1 -0
- package/dist/{chunk-VRRYN6NS.js → chunk-5TRCJONX.js} +3 -3
- package/dist/{chunk-QFJXNEXG.js → chunk-HUSXCKPI.js} +4 -2
- package/dist/{chunk-QFJXNEXG.js.map → chunk-HUSXCKPI.js.map} +1 -1
- package/dist/{chunk-PFUXPS7A.js → chunk-PD5AZX3B.js} +1 -1
- package/dist/chunk-PD5AZX3B.js.map +1 -0
- package/dist/{chunk-WCAHVNWW.js → chunk-VQ5HKNYP.js} +13 -3
- package/dist/chunk-VQ5HKNYP.js.map +1 -0
- package/dist/cli/index.js +5 -5
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -7
- package/dist/normalizer/index.d.ts +100 -4
- package/dist/normalizer/index.js +2 -2
- package/dist/sinks/index.d.ts +2 -2
- package/dist/sinks/index.js +3 -3
- package/dist/transformers/index.d.ts +1 -1
- package/dist/transformers/index.js +3 -3
- package/dist/{types-CLNmloya.d.ts → types-Bicgdp4Z.d.ts} +13 -1
- package/package.json +1 -1
- package/dist/chunk-J7EUSPEA.js.map +0 -1
- package/dist/chunk-MUFGDYGI.js.map +0 -1
- package/dist/chunk-PFUXPS7A.js.map +0 -1
- package/dist/chunk-Q44KGFIH.js.map +0 -1
- package/dist/chunk-WCAHVNWW.js.map +0 -1
- /package/dist/{chunk-VRRYN6NS.js.map → chunk-5TRCJONX.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { i as MigrationCursor, E as EntityKey,
|
|
2
|
-
export { A as AdapterContext, h as EntityType, M as MigrationAdapter, g as MigrationPlatform, b as NormalizedAsset, j as NormalizedAssetExif, d as NormalizedCategory, f as NormalizedEntity, a as NormalizedPage, c as NormalizedPortfolio, N as NormalizedPost, e as NormalizedTag, k as PublishStatus, S as SourceMetadata, V as ValidationIssue, W as WxrImportSummary,
|
|
3
|
-
import { E as EntityBundle } from '../bundle-
|
|
4
|
-
export { B as BundleCounts, b as bundleCounts, c as collectEntities, e as emptyBundle } from '../bundle-
|
|
1
|
+
import { i as MigrationCursor, E as EntityKey, l as PortfolioMediaLink, n as ValidationResult } from '../types-Bicgdp4Z.js';
|
|
2
|
+
export { A as AdapterContext, h as EntityType, M as MigrationAdapter, g as MigrationPlatform, b as NormalizedAsset, j as NormalizedAssetExif, d as NormalizedCategory, f as NormalizedEntity, a as NormalizedPage, c as NormalizedPortfolio, N as NormalizedPost, e as NormalizedTag, P as PageHeroSliderHint, k as PageLayoutHints, m as PublishStatus, S as SourceMetadata, V as ValidationIssue, W as WxrImportSummary, o as entityKey } from '../types-Bicgdp4Z.js';
|
|
3
|
+
import { E as EntityBundle } from '../bundle-BgoXkWMy.js';
|
|
4
|
+
export { B as BundleCounts, b as bundleCounts, c as collectEntities, e as emptyBundle } from '../bundle-BgoXkWMy.js';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
7
|
/** Portable entity state for resume / idempotency (not Directus field names). */
|
|
@@ -149,6 +149,38 @@ declare const normalizedPageSchema: z.ZodObject<{
|
|
|
149
149
|
contentCss: z.ZodOptional<z.ZodString>;
|
|
150
150
|
isHomePage: z.ZodOptional<z.ZodBoolean>;
|
|
151
151
|
isPortfolioPage: z.ZodOptional<z.ZodBoolean>;
|
|
152
|
+
layoutHints: z.ZodOptional<z.ZodObject<{
|
|
153
|
+
heroSlider: z.ZodOptional<z.ZodObject<{
|
|
154
|
+
plugin: z.ZodEnum<["revslider", "masterslider"]>;
|
|
155
|
+
alias: z.ZodString;
|
|
156
|
+
slidertitle: z.ZodOptional<z.ZodString>;
|
|
157
|
+
source: z.ZodOptional<z.ZodEnum<["meta-shortcode", "meta-slider-field", "tatsu-json"]>>;
|
|
158
|
+
}, "strip", z.ZodTypeAny, {
|
|
159
|
+
plugin: "revslider" | "masterslider";
|
|
160
|
+
alias: string;
|
|
161
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
162
|
+
slidertitle?: string | undefined;
|
|
163
|
+
}, {
|
|
164
|
+
plugin: "revslider" | "masterslider";
|
|
165
|
+
alias: string;
|
|
166
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
167
|
+
slidertitle?: string | undefined;
|
|
168
|
+
}>>;
|
|
169
|
+
}, "strip", z.ZodTypeAny, {
|
|
170
|
+
heroSlider?: {
|
|
171
|
+
plugin: "revslider" | "masterslider";
|
|
172
|
+
alias: string;
|
|
173
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
174
|
+
slidertitle?: string | undefined;
|
|
175
|
+
} | undefined;
|
|
176
|
+
}, {
|
|
177
|
+
heroSlider?: {
|
|
178
|
+
plugin: "revslider" | "masterslider";
|
|
179
|
+
alias: string;
|
|
180
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
181
|
+
slidertitle?: string | undefined;
|
|
182
|
+
} | undefined;
|
|
183
|
+
}>>;
|
|
152
184
|
status: z.ZodEnum<["draft", "published", "archived"]>;
|
|
153
185
|
seoTitle: z.ZodOptional<z.ZodString>;
|
|
154
186
|
seoDescription: z.ZodOptional<z.ZodString>;
|
|
@@ -171,6 +203,14 @@ declare const normalizedPageSchema: z.ZodObject<{
|
|
|
171
203
|
contentCss?: string | undefined;
|
|
172
204
|
isHomePage?: boolean | undefined;
|
|
173
205
|
isPortfolioPage?: boolean | undefined;
|
|
206
|
+
layoutHints?: {
|
|
207
|
+
heroSlider?: {
|
|
208
|
+
plugin: "revslider" | "masterslider";
|
|
209
|
+
alias: string;
|
|
210
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
211
|
+
slidertitle?: string | undefined;
|
|
212
|
+
} | undefined;
|
|
213
|
+
} | undefined;
|
|
174
214
|
}, {
|
|
175
215
|
type: "page";
|
|
176
216
|
status: "draft" | "published" | "archived";
|
|
@@ -190,6 +230,14 @@ declare const normalizedPageSchema: z.ZodObject<{
|
|
|
190
230
|
contentCss?: string | undefined;
|
|
191
231
|
isHomePage?: boolean | undefined;
|
|
192
232
|
isPortfolioPage?: boolean | undefined;
|
|
233
|
+
layoutHints?: {
|
|
234
|
+
heroSlider?: {
|
|
235
|
+
plugin: "revslider" | "masterslider";
|
|
236
|
+
alias: string;
|
|
237
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
238
|
+
slidertitle?: string | undefined;
|
|
239
|
+
} | undefined;
|
|
240
|
+
} | undefined;
|
|
193
241
|
}>;
|
|
194
242
|
declare const normalizedAssetExifSchema: z.ZodObject<{
|
|
195
243
|
iso: z.ZodOptional<z.ZodNumber>;
|
|
@@ -561,6 +609,38 @@ declare const normalizedEntitySchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
561
609
|
contentCss: z.ZodOptional<z.ZodString>;
|
|
562
610
|
isHomePage: z.ZodOptional<z.ZodBoolean>;
|
|
563
611
|
isPortfolioPage: z.ZodOptional<z.ZodBoolean>;
|
|
612
|
+
layoutHints: z.ZodOptional<z.ZodObject<{
|
|
613
|
+
heroSlider: z.ZodOptional<z.ZodObject<{
|
|
614
|
+
plugin: z.ZodEnum<["revslider", "masterslider"]>;
|
|
615
|
+
alias: z.ZodString;
|
|
616
|
+
slidertitle: z.ZodOptional<z.ZodString>;
|
|
617
|
+
source: z.ZodOptional<z.ZodEnum<["meta-shortcode", "meta-slider-field", "tatsu-json"]>>;
|
|
618
|
+
}, "strip", z.ZodTypeAny, {
|
|
619
|
+
plugin: "revslider" | "masterslider";
|
|
620
|
+
alias: string;
|
|
621
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
622
|
+
slidertitle?: string | undefined;
|
|
623
|
+
}, {
|
|
624
|
+
plugin: "revslider" | "masterslider";
|
|
625
|
+
alias: string;
|
|
626
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
627
|
+
slidertitle?: string | undefined;
|
|
628
|
+
}>>;
|
|
629
|
+
}, "strip", z.ZodTypeAny, {
|
|
630
|
+
heroSlider?: {
|
|
631
|
+
plugin: "revslider" | "masterslider";
|
|
632
|
+
alias: string;
|
|
633
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
634
|
+
slidertitle?: string | undefined;
|
|
635
|
+
} | undefined;
|
|
636
|
+
}, {
|
|
637
|
+
heroSlider?: {
|
|
638
|
+
plugin: "revslider" | "masterslider";
|
|
639
|
+
alias: string;
|
|
640
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
641
|
+
slidertitle?: string | undefined;
|
|
642
|
+
} | undefined;
|
|
643
|
+
}>>;
|
|
564
644
|
status: z.ZodEnum<["draft", "published", "archived"]>;
|
|
565
645
|
seoTitle: z.ZodOptional<z.ZodString>;
|
|
566
646
|
seoDescription: z.ZodOptional<z.ZodString>;
|
|
@@ -583,6 +663,14 @@ declare const normalizedEntitySchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
583
663
|
contentCss?: string | undefined;
|
|
584
664
|
isHomePage?: boolean | undefined;
|
|
585
665
|
isPortfolioPage?: boolean | undefined;
|
|
666
|
+
layoutHints?: {
|
|
667
|
+
heroSlider?: {
|
|
668
|
+
plugin: "revslider" | "masterslider";
|
|
669
|
+
alias: string;
|
|
670
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
671
|
+
slidertitle?: string | undefined;
|
|
672
|
+
} | undefined;
|
|
673
|
+
} | undefined;
|
|
586
674
|
}, {
|
|
587
675
|
type: "page";
|
|
588
676
|
status: "draft" | "published" | "archived";
|
|
@@ -602,6 +690,14 @@ declare const normalizedEntitySchema: z.ZodDiscriminatedUnion<"type", [z.ZodObje
|
|
|
602
690
|
contentCss?: string | undefined;
|
|
603
691
|
isHomePage?: boolean | undefined;
|
|
604
692
|
isPortfolioPage?: boolean | undefined;
|
|
693
|
+
layoutHints?: {
|
|
694
|
+
heroSlider?: {
|
|
695
|
+
plugin: "revslider" | "masterslider";
|
|
696
|
+
alias: string;
|
|
697
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json" | undefined;
|
|
698
|
+
slidertitle?: string | undefined;
|
|
699
|
+
} | undefined;
|
|
700
|
+
} | undefined;
|
|
605
701
|
}>, z.ZodObject<{
|
|
606
702
|
type: z.ZodLiteral<"asset">;
|
|
607
703
|
source: z.ZodObject<{
|
package/dist/normalizer/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
validateNormalizedPortfolio,
|
|
16
16
|
validateNormalizedPost,
|
|
17
17
|
validateNormalizedTag
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-373TTCG7.js";
|
|
19
19
|
import {
|
|
20
20
|
buildPortfolioMediaLinks,
|
|
21
21
|
bundleCounts,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
entityKey,
|
|
25
25
|
isTerminalState,
|
|
26
26
|
shouldProcessEntity
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-PD5AZX3B.js";
|
|
28
28
|
export {
|
|
29
29
|
buildPortfolioMediaLinks,
|
|
30
30
|
bundleCounts,
|
package/dist/sinks/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { d as NormalizedCategory, e as NormalizedTag, b as NormalizedAsset, c as NormalizedPortfolio, N as NormalizedPost, a as NormalizedPage,
|
|
1
|
+
import { d as NormalizedCategory, e as NormalizedTag, b as NormalizedAsset, c as NormalizedPortfolio, N as NormalizedPost, a as NormalizedPage, l as PortfolioMediaLink, E as EntityKey, f as NormalizedEntity, g as MigrationPlatform, W as WxrImportSummary, M as MigrationAdapter } from '../types-Bicgdp4Z.js';
|
|
2
2
|
import { Readable } from 'node:stream';
|
|
3
3
|
import { a as RewriteInlineImagesOptions } from '../rewrite-inline-images-BsgSquzV.js';
|
|
4
4
|
export { b as RewriteInlineImagesResult, r as rewriteInlineImages } from '../rewrite-inline-images-BsgSquzV.js';
|
|
5
|
-
import { E as EntityBundle } from '../bundle-
|
|
5
|
+
import { E as EntityBundle } from '../bundle-BgoXkWMy.js';
|
|
6
6
|
import '../media-urls-u49RCyPn.js';
|
|
7
7
|
|
|
8
8
|
interface CreatePostResult {
|
package/dist/sinks/index.js
CHANGED
|
@@ -20,11 +20,11 @@ import {
|
|
|
20
20
|
staleUrlsFromEstimate,
|
|
21
21
|
summarizeAssetDiscovery,
|
|
22
22
|
writeFilesystemExport
|
|
23
|
-
} from "../chunk-
|
|
24
|
-
import "../chunk-
|
|
23
|
+
} from "../chunk-5TRCJONX.js";
|
|
24
|
+
import "../chunk-PD5AZX3B.js";
|
|
25
25
|
import {
|
|
26
26
|
rewriteInlineImages
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-HUSXCKPI.js";
|
|
28
28
|
import "../chunk-XRCF73DA.js";
|
|
29
29
|
import "../chunk-S4GMDRGX.js";
|
|
30
30
|
export {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { n as ValidationResult } from '../types-Bicgdp4Z.js';
|
|
3
3
|
export { R as RewriteInlineImageRef, a as RewriteInlineImagesOptions, b as RewriteInlineImagesResult, S as StampMigrationMediaRefsOptions, U as UploadedAssetRef, r as rewriteInlineImages, s as stampMigrationMediaRefs } from '../rewrite-inline-images-BsgSquzV.js';
|
|
4
4
|
export { d as buildMigrationMediaUrlIndex } from '../media-urls-u49RCyPn.js';
|
|
5
5
|
|
|
@@ -11,12 +11,12 @@ import {
|
|
|
11
11
|
tiptapNodeSchema,
|
|
12
12
|
validateGrapesProjectSnapshot,
|
|
13
13
|
validateTiptapDoc
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
} from "../chunk-VQ5HKNYP.js";
|
|
15
|
+
import "../chunk-4XZK55RW.js";
|
|
16
16
|
import {
|
|
17
17
|
rewriteInlineImages,
|
|
18
18
|
stampMigrationMediaRefs
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-HUSXCKPI.js";
|
|
20
20
|
import {
|
|
21
21
|
buildMigrationMediaUrlIndex
|
|
22
22
|
} from "../chunk-S4GMDRGX.js";
|
|
@@ -29,6 +29,17 @@ interface NormalizedPost {
|
|
|
29
29
|
seoTitle?: string;
|
|
30
30
|
seoDescription?: string;
|
|
31
31
|
}
|
|
32
|
+
/** RevSlider / MasterSlider reference from theme hero meta (OSS-27) — alias only, no slide payloads in WXR. */
|
|
33
|
+
interface PageHeroSliderHint {
|
|
34
|
+
plugin: "revslider" | "masterslider";
|
|
35
|
+
alias: string;
|
|
36
|
+
slidertitle?: string;
|
|
37
|
+
source?: "meta-shortcode" | "meta-slider-field" | "tatsu-json";
|
|
38
|
+
}
|
|
39
|
+
/** Non-body layout signals for host promotion (theme chrome, hero slots, …). */
|
|
40
|
+
interface PageLayoutHints {
|
|
41
|
+
heroSlider?: PageHeroSliderHint;
|
|
42
|
+
}
|
|
32
43
|
/** Canonical page DTO — raw HTML snapshot. */
|
|
33
44
|
interface NormalizedPage {
|
|
34
45
|
type: "page";
|
|
@@ -41,6 +52,7 @@ interface NormalizedPage {
|
|
|
41
52
|
isHomePage?: boolean;
|
|
42
53
|
/** Site portfolio listing shell (distinct from portfolio CPT singles). */
|
|
43
54
|
isPortfolioPage?: boolean;
|
|
55
|
+
layoutHints?: PageLayoutHints;
|
|
44
56
|
status: PublishStatus;
|
|
45
57
|
seoTitle?: string;
|
|
46
58
|
seoDescription?: string;
|
|
@@ -148,4 +160,4 @@ interface EntityKey {
|
|
|
148
160
|
}
|
|
149
161
|
declare function entityKey(entity: NormalizedEntity, platform: MigrationPlatform): EntityKey;
|
|
150
162
|
|
|
151
|
-
export { type AdapterContext as A, type EntityKey as E, type MigrationAdapter as M, type NormalizedPost as N, type
|
|
163
|
+
export { type AdapterContext as A, type EntityKey as E, type MigrationAdapter as M, type NormalizedPost as N, type PageHeroSliderHint as P, type SourceMetadata as S, type ValidationIssue as V, type WxrImportSummary as W, type NormalizedPage as a, type NormalizedAsset as b, type NormalizedPortfolio as c, type NormalizedCategory as d, type NormalizedTag as e, type NormalizedEntity as f, type MigrationPlatform as g, type EntityType as h, type MigrationCursor as i, type NormalizedAssetExif as j, type PageLayoutHints as k, type PortfolioMediaLink as l, type PublishStatus as m, type ValidationResult as n, entityKey as o };
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parsers/wordpress/builders/flatten.ts"],"sourcesContent":["import { normalizeAssetUrl } from \"../../../lib/media-urls.js\";\nimport type {\n BuilderIconImageRule,\n BuilderPlaceholderRule,\n BuilderTextRule,\n BuilderThemeConfig,\n BuilderUrlRule,\n BuilderWrapperRule,\n FractionalLayoutMap,\n ExtendedPrefixedLayoutMap,\n PrefixedLayoutMap,\n StructuralLayoutMap,\n TextHtmlTag,\n BuilderHtmlTag,\n} from \"./registry.js\";\nimport {\n WORDPRESS_BUILDER_REGISTRY,\n WORDPRESS_WIDGET_REGISTRY,\n WP_WIDGET_PLACEHOLDER,\n type WordPressWidgetRegistry,\n} from \"./registry.js\";\n\nexport interface FlattenWordPressBuildersOptions {\n registry?: BuilderThemeConfig[];\n widgetRegistry?: WordPressWidgetRegistry;\n}\n\nexport interface FlattenWordPressBuildersResult {\n html: string;\n detectedThemes: string[];\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/** Read a quoted shortcode attribute value (supports multiline). */\nexport function extractQuotedParam(params: string, name: string): string | undefined {\n const pattern = new RegExp(`\\\\b${escapeRegExp(name)}\\\\s*=\\\\s*`, \"i\");\n const match = pattern.exec(params);\n if (!match) return undefined;\n\n let index = match.index + match[0].length;\n while (index < params.length && /\\s/.test(params[index]!)) index += 1;\n\n if (params.slice(index, index + 6) === \""\") {\n index += 6;\n let value = \"\";\n while (index < params.length) {\n if (params.slice(index, index + 6) === \""\") break;\n value += params[index]!;\n index += 1;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n }\n\n const quote = params[index];\n if (quote !== '\"' && quote !== \"'\") return undefined;\n index += 1;\n\n let value = \"\";\n while (index < params.length) {\n const char = params[index]!;\n if (char === \"\\\\\" && index + 1 < params.length) {\n value += params[index + 1];\n index += 2;\n continue;\n }\n if (char === quote) break;\n value += char;\n index += 1;\n }\n\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction escapeLayoutAttr(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\");\n}\n\n/** Parse `width=\"1/2\"` / `columns=\"1/3+1/3+1/3\"` style strings → percentage or column count. */\nexport function parseFractionWidth(fraction: string | undefined): string | undefined {\n if (!fraction?.trim()) return undefined;\n const trimmed = fraction.trim();\n const match = trimmed.match(/^(\\d+)\\s*\\/\\s*(\\d+)$/);\n if (!match) return undefined;\n const numerator = Number(match[1]);\n const denominator = Number(match[2]);\n if (!Number.isFinite(numerator) || !Number.isFinite(denominator) || denominator <= 0) {\n return undefined;\n }\n const percent = (numerator / denominator) * 100;\n const rounded = Math.round(percent * 100) / 100;\n return `${rounded % 1 === 0 ? rounded.toFixed(0) : rounded}%`;\n}\n\n/** Parse row `layout=\"1/2+1/2\"` style strings → column count. */\nexport function parseRowLayoutCols(layout: string | undefined): number | undefined {\n if (!layout?.trim()) return undefined;\n const parts = layout.split(\"+\").map((part) => part.trim()).filter(Boolean);\n return parts.length > 1 ? parts.length : undefined;\n}\n\nfunction openSectionDiv(params: string, bgParamName?: string): string {\n const attrs = ['data-layout=\"section\"'];\n const bgImage = extractQuotedParam(params, bgParamName ?? \"bg_image\");\n if (bgImage?.startsWith(\"http\")) {\n attrs.push(`data-bg-image=\"${escapeLayoutAttr(bgImage)}\"`);\n }\n return `<div ${attrs.join(\" \")}>`;\n}\n\nfunction openRowDiv(params: string, colsParamName?: string): string {\n const attrs = ['data-layout=\"row\"'];\n const cols = parseRowLayoutCols(extractQuotedParam(params, colsParamName ?? \"layout\"));\n if (cols) attrs.push(`data-cols=\"${cols}\"`);\n return `<div ${attrs.join(\" \")}>`;\n}\n\nfunction openColumnDiv(params: string, widthParamName?: string): string {\n const attrs = ['data-layout=\"column\"'];\n const width = parseFractionWidth(extractQuotedParam(params, widthParamName ?? \"width\"));\n if (width) attrs.push(`data-col-width=\"${width}\"`);\n return `<div ${attrs.join(\" \")}>`;\n}\n\nfunction applyPrefixedLayoutMap(content: string, map: PrefixedLayoutMap): string {\n let html = content;\n html = html.replace(map.sectionRegex, (_, params: string) => openSectionDiv(params, map.bgParamName));\n html = html.replace(map.sectionCloseRegex, \"</div>\");\n html = html.replace(map.rowRegex, (_, params: string) => openRowDiv(params, map.colsParamName));\n html = html.replace(map.rowCloseRegex, \"</div>\");\n html = html.replace(map.columnRegex, '<div data-layout=\"column\">');\n html = html.replace(map.columnCloseRegex, \"</div>\");\n return html;\n}\n\nfunction applyFractionalLayoutMap(content: string, map: FractionalLayoutMap): string {\n let html = content;\n html = html.replace(map.sectionRegex, (_, params: string) => openSectionDiv(params, map.bgParamName));\n html = html.replace(map.sectionCloseRegex, \"</div>\");\n html = html.replace(map.rowRegex, (_, params: string) => openRowDiv(params));\n html = html.replace(map.rowCloseRegex, \"</div>\");\n\n for (let index = 0; index < map.columnTokens.length; index += 1) {\n const token = map.columnTokens[index]!;\n const width = map.columnWidths[token];\n const openRegex = map.columnOpenRegexes[index]!;\n const closeRegex = map.columnCloseRegexes[index]!;\n html = html.replace(openRegex, () => {\n const attrs = ['data-layout=\"column\"'];\n if (width) attrs.push(`data-col-width=\"${width}\"`);\n return `<div ${attrs.join(\" \")}>`;\n });\n html = html.replace(closeRegex, \"</div>\");\n }\n return html;\n}\n\nfunction applyExtendedPrefixedLayoutMap(content: string, map: ExtendedPrefixedLayoutMap): string {\n let html = content;\n const levels = [...map.levels].sort((left, right) => {\n const leftMax = Math.max(...left.tokens.map((token) => token.length));\n const rightMax = Math.max(...right.tokens.map((token) => token.length));\n return rightMax - leftMax;\n });\n\n for (const level of levels) {\n const tokens = [...level.tokens].sort((left, right) => right.length - left.length);\n for (const token of tokens) {\n const openRegex = new RegExp(`\\\\[${escapeRegExp(token)}\\\\b([^\\\\]]*)\\\\]`, \"gi\");\n const closeRegex = new RegExp(`\\\\[\\\\/${escapeRegExp(token)}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n\n html = html.replace(openRegex, (_, params: string) => {\n switch (level.role) {\n case \"section\":\n return openSectionDiv(params, level.bgParamName);\n case \"row\":\n return openRowDiv(params, level.colsParamName);\n case \"column\":\n return openColumnDiv(params, level.widthParamName);\n }\n });\n html = html.replace(closeRegex, \"</div>\");\n }\n }\n\n return html;\n}\n\n/** Map builder layout shortcodes → editor-neutral `data-layout` HTML. */\nexport function applyStructuralLayoutMap(content: string, map: StructuralLayoutMap): string {\n switch (map.kind) {\n case \"prefixed\":\n return applyPrefixedLayoutMap(content, map);\n case \"fractional\":\n return applyFractionalLayoutMap(content, map);\n case \"extended-prefixed\":\n return applyExtendedPrefixedLayoutMap(content, map);\n }\n}\n\nfunction collectLayoutMaps(theme: BuilderThemeConfig): StructuralLayoutMap[] {\n const maps: StructuralLayoutMap[] = [];\n if (theme.layoutMap) maps.push(theme.layoutMap);\n if (theme.layoutMaps?.length) maps.push(...theme.layoutMaps);\n return maps;\n}\n\nfunction extractShortcodeParam(params: string, names: string[]): string | undefined {\n for (const name of names) {\n const value = extractQuotedParam(params, name);\n if (value) return value;\n }\n return undefined;\n}\n\nfunction escapeHtmlText(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\nfunction textToHtml(text: string, tag: TextHtmlTag): string {\n const paragraphs = text.split(/\\n{2,}/).map((part) => part.trim()).filter(Boolean);\n if (paragraphs.length === 0) return \"\";\n\n return paragraphs\n .map((paragraph) => {\n const inner = escapeHtmlText(paragraph).replace(/\\n/g, \"<br />\");\n return `<${tag}>${inner}</${tag}>`;\n })\n .join(\"\\n\");\n}\n\nfunction emitHtmlTag(tag: BuilderHtmlTag, url: string): string {\n const normalized = normalizeAssetUrl(url) ?? url;\n const escaped = normalized\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\");\n\n switch (tag) {\n case \"img\":\n return `<img src=\"${escaped}\" alt=\"\" />`;\n case \"video\":\n return `<video src=\"${escaped}\" controls></video>`;\n case \"iframe\":\n return `<iframe src=\"${escaped}\" loading=\"lazy\"></iframe>`;\n }\n}\n\nfunction convertUrlRule(content: string, rule: BuilderUrlRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n\n return content.replace(pattern, (block, params: string) => {\n const url = extractShortcodeParam(params, rule.urlParams);\n if (!url) return block;\n return emitHtmlTag(rule.tag, url);\n });\n}\n\nfunction convertTextRule(content: string, rule: BuilderTextRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gis\",\n );\n\n return content.replace(pattern, (block, params: string) => {\n const parts: string[] = [];\n for (const field of rule.fields) {\n const text = extractQuotedParam(params, field.param);\n if (!text) continue;\n const html = textToHtml(text, field.tag);\n if (html) parts.push(html);\n }\n return parts.length > 0 ? parts.join(\"\\n\") : block;\n });\n}\n\nfunction convertWrapperRule(content: string, rule: BuilderWrapperRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n\n return content.replace(pattern, (_, params: string, inner: string) => {\n const parts: string[] = [];\n if (rule.urlParams?.length) {\n const url = extractShortcodeParam(params, rule.urlParams);\n if (url) parts.push(emitHtmlTag(\"img\", url));\n }\n parts.push(inner.trim());\n return parts.filter(Boolean).join(\"\\n\");\n });\n}\n\nfunction isPlaceholderImageUrl(url: string): boolean {\n return /placehold\\.it|placeholder\\.com|via\\.placeholder/i.test(url);\n}\n\nfunction convertIconImageRule(content: string, rule: BuilderIconImageRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n\n return content.replace(pattern, (_, params: string) => {\n const iconImage =\n extractQuotedParam(params, rule.imageParam) ?? extractQuotedParam(params, \"image\");\n if (!iconImage?.startsWith(\"http\") || isPlaceholderImageUrl(iconImage)) {\n return \"\";\n }\n const img = emitHtmlTag(\"img\", iconImage);\n if (rule.hrefParam) {\n const href = extractQuotedParam(params, rule.hrefParam);\n if (href?.startsWith(\"http\")) {\n const escapedHref = href\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\");\n return `<a href=\"${escapedHref}\">${img}</a>`;\n }\n }\n return img;\n });\n}\n\nfunction convertPlaceholderRule(content: string, rule: BuilderPlaceholderRule): string {\n const prefix = escapeRegExp(rule.shortcodePrefix);\n const pattern = new RegExp(\n `\\\\[${prefix}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${prefix}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n return content.replace(pattern, rule.html);\n}\n\nfunction stripScaffoldingPrefix(content: string, prefix: string): string {\n const escaped = escapeRegExp(prefix);\n const opener = new RegExp(`\\\\[${escaped}[a-z0-9_-]*[^\\\\]]*\\\\]`, \"gi\");\n const closer = new RegExp(`\\\\[\\\\/${escaped}[a-z0-9_-]*[^\\\\]]*\\\\]`, \"gi\");\n return content.replace(opener, \"\").replace(closer, \"\");\n}\n\nfunction stripLegacyTokens(content: string, tokens: string[]): string {\n let result = content;\n for (const token of tokens) {\n const escaped = escapeRegExp(token);\n const opener = new RegExp(`\\\\[${escaped}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n const closer = new RegExp(`\\\\[\\\\/${escaped}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n result = result.replace(opener, \"\").replace(closer, \"\");\n }\n return result;\n}\n\nfunction detectThemes(content: string, registry: BuilderThemeConfig[]): BuilderThemeConfig[] {\n return registry.filter((theme) => theme.detect.test(content));\n}\n\nfunction extractBareOrQuotedParam(params: string, name: string): string | undefined {\n const quoted = extractQuotedParam(params, name);\n if (quoted) return quoted;\n const pattern = new RegExp(`\\\\b${escapeRegExp(name)}\\\\s*=\\\\s*([^\\\\s\"'\\\\]]+)`, \"i\");\n const match = pattern.exec(params);\n return match?.[1]?.trim() || undefined;\n}\n\nfunction emitWidgetStub(\n widget: string,\n attrs: Record<string, string | undefined>,\n tag: \"div\" | \"section\" = \"div\",\n): string {\n const parts = [`data-wp-widget=\"${escapeLayoutAttr(widget)}\"`];\n for (const [key, value] of Object.entries(attrs)) {\n if (value) parts.push(`${key}=\"${escapeLayoutAttr(value)}\"`);\n }\n return `<${tag} ${parts.join(\" \")}>${WP_WIDGET_PLACEHOLDER}</${tag}>`;\n}\n\n/** Normalize YouTube/Vimeo share URLs to canonical embed URLs. */\nexport function normalizeVideoEmbedUrl(\n raw: string,\n): { provider: \"youtube\" | \"vimeo\" | \"external\"; embedUrl: string } | undefined {\n const trimmed = raw.trim();\n if (!trimmed || trimmed.startsWith(\"data:\")) return undefined;\n\n try {\n const url = new URL(trimmed.startsWith(\"//\") ? `https:${trimmed}` : trimmed);\n const host = url.hostname.replace(/^www\\./, \"\").replace(/^m\\./, \"\");\n\n if (host === \"youtu.be\") {\n const id = url.pathname.split(\"/\").filter(Boolean)[0];\n if (id) {\n return { provider: \"youtube\", embedUrl: `https://www.youtube-nocookie.com/embed/${id}` };\n }\n }\n\n if (host === \"youtube.com\" || host === \"youtube-nocookie.com\") {\n const embedMatch = url.pathname.match(/\\/embed\\/([^/?#]+)/);\n if (embedMatch?.[1]) {\n const start = url.searchParams.get(\"start\");\n const suffix = start ? `?start=${start}` : \"\";\n return {\n provider: \"youtube\",\n embedUrl: `https://www.youtube-nocookie.com/embed/${embedMatch[1]}${suffix}`,\n };\n }\n const videoId = url.searchParams.get(\"v\");\n if (videoId) {\n const t = url.searchParams.get(\"t\") ?? url.searchParams.get(\"start\");\n const startSeconds = t?.endsWith(\"s\") ? t.slice(0, -1) : t;\n const suffix = startSeconds ? `?start=${startSeconds}` : \"\";\n return {\n provider: \"youtube\",\n embedUrl: `https://www.youtube-nocookie.com/embed/${videoId}${suffix}`,\n };\n }\n }\n\n if (host === \"vimeo.com\") {\n const segments = url.pathname.split(\"/\").filter(Boolean);\n const id = segments[segments.length - 1];\n if (id && /^\\d+$/.test(id)) {\n return { provider: \"vimeo\", embedUrl: `https://player.vimeo.com/video/${id}` };\n }\n }\n\n if (host === \"player.vimeo.com\") {\n const match = url.pathname.match(/\\/video\\/(\\d+)/);\n if (match?.[1]) {\n return { provider: \"vimeo\", embedUrl: `https://player.vimeo.com/video/${match[1]}` };\n }\n }\n } catch {\n return undefined;\n }\n\n return undefined;\n}\n\nfunction emitVideoWidgetFromParams(params: string, inner: string): string {\n const url =\n extractShortcodeParam(params, [\"url\", \"src\", \"video\", \"link\", \"youtube_url\", \"vimeo_url\"]) ??\n inner.trim().match(/^https?:\\/\\/\\S+/)?.[0];\n\n if (!url) {\n return emitWidgetStub(\"video\", { \"data-video-provider\": \"external\" });\n }\n\n const normalized = normalizeVideoEmbedUrl(url);\n if (normalized) {\n return emitWidgetStub(\"video\", {\n \"data-video-provider\": normalized.provider,\n \"data-embed-url\": normalized.embedUrl,\n });\n }\n\n if (/\\.(mp4|webm|ogg)(\\?|#|$)/i.test(url)) {\n return emitHtmlTag(\"video\", url);\n }\n\n return emitWidgetStub(\"video\", {\n \"data-video-provider\": \"external\",\n \"data-embed-url\": url,\n });\n}\n\n/** Build a Google Maps iframe embed URL from map shortcode params. */\nexport function buildGoogleMapsEmbedUrlFromMapParams(params: string): {\n embedUrl?: string;\n lat?: string;\n lng?: string;\n query?: string;\n} {\n const direct = extractShortcodeParam(params, [\n \"embed_url\",\n \"url\",\n \"src\",\n \"map_url\",\n \"iframe_url\",\n \"embed\",\n ]);\n if (direct && /google\\.com\\/maps|maps\\.google\\.com/i.test(direct)) {\n return { embedUrl: direct.trim() };\n }\n\n const lat =\n extractBareOrQuotedParam(params, \"lat\") ??\n extractBareOrQuotedParam(params, \"latitude\") ??\n extractBareOrQuotedParam(params, \"map_lat\");\n const lng =\n extractBareOrQuotedParam(params, \"lng\") ??\n extractBareOrQuotedParam(params, \"longitude\") ??\n extractBareOrQuotedParam(params, \"map_lng\");\n const address =\n extractBareOrQuotedParam(params, \"address\") ??\n extractBareOrQuotedParam(params, \"map_address\") ??\n extractBareOrQuotedParam(params, \"location\") ??\n extractBareOrQuotedParam(params, \"map_location\") ??\n extractBareOrQuotedParam(params, \"q\");\n\n if (lat && lng) {\n const zoom = extractBareOrQuotedParam(params, \"zoom\") ?? \"14\";\n return {\n embedUrl: `https://maps.google.com/maps?q=${encodeURIComponent(`${lat},${lng}`)}&z=${zoom}&output=embed`,\n lat,\n lng,\n };\n }\n\n if (address) {\n return {\n embedUrl: `https://maps.google.com/maps?q=${encodeURIComponent(address)}&output=embed`,\n query: address,\n };\n }\n\n return {};\n}\n\nfunction flattenMapShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n let html = content;\n for (const prefix of widgetRegistry.mapShortcodePrefixes) {\n const pattern = new RegExp(\n `\\\\[${escapeRegExp(prefix)}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${escapeRegExp(prefix)}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n html = html.replace(pattern, (_, params: string) => {\n const resolved = buildGoogleMapsEmbedUrlFromMapParams(params);\n return emitWidgetStub(\"map\", {\n ...(resolved.embedUrl ? { \"data-embed-url\": resolved.embedUrl } : {}),\n ...(resolved.lat ? { \"data-wp-map-lat\": resolved.lat } : {}),\n ...(resolved.lng ? { \"data-wp-map-lng\": resolved.lng } : {}),\n ...(resolved.query ? { \"data-wp-map-query\": resolved.query } : {}),\n });\n });\n }\n return html;\n}\n\nfunction flattenContactFormShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n let html = content;\n for (const rule of widgetRegistry.contactFormRules) {\n const pattern = new RegExp(\n `\\\\[${escapeRegExp(rule.tag)}\\\\b([^\\\\]]*)\\\\]\\\\s*(?:\\\\[\\\\/${escapeRegExp(rule.tag)}\\\\b[^\\\\]]*\\\\])?`,\n \"gi\",\n );\n html = html.replace(pattern, (_, params: string) => {\n const id = extractBareOrQuotedParam(params, rule.idParam);\n return emitWidgetStub(\n \"contact-form\",\n {\n \"data-wp-form-source\": rule.source,\n ...(id ? { \"data-wp-form-id\": id } : {}),\n },\n \"section\",\n );\n });\n }\n return html;\n}\n\nfunction emitInlineGalleryFromIds(idList: string[]): string {\n const images = idList\n .map((id) => `<img data-wp-attachment-id=\"${escapeLayoutAttr(id)}\" alt=\"\" />`)\n .join(\"\");\n return `<figure data-wp-inline-gallery>${images}</figure>`;\n}\n\nfunction parseGalleryAttachmentIds(params: string): string[] | undefined {\n const ids = extractBareOrQuotedParam(params, \"ids\");\n const idList = ids\n ?.split(\",\")\n .map((part) => part.trim())\n .filter((part) => /^\\d+$/.test(part));\n return idList?.length ? idList : undefined;\n}\n\nfunction flattenIdGalleryShortcode(content: string, tag: string): string {\n const escaped = escapeRegExp(tag);\n const pattern = new RegExp(`\\\\[${escaped}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${escaped}\\\\])?`, \"gi\");\n return content.replace(pattern, (fullMatch, params: string) => {\n const idList = parseGalleryAttachmentIds(params);\n if (idList?.length) {\n return emitInlineGalleryFromIds(idList);\n }\n return fullMatch;\n });\n}\n\nfunction flattenGalleryShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n const tag = escapeRegExp(widgetRegistry.galleryShortcode);\n const pattern = new RegExp(`\\\\[${tag}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${tag}\\\\])?`, \"gi\");\n return content.replace(pattern, (_, params: string) => {\n const idList = parseGalleryAttachmentIds(params);\n\n if (idList?.length) {\n return emitInlineGalleryFromIds(idList);\n }\n\n const category = extractBareOrQuotedParam(params, \"category\") ?? extractBareOrQuotedParam(params, \"type\");\n return emitWidgetStub(\"portfolio\", {\n \"data-wp-gallery-dynamic\": \"1\",\n ...(category ? { \"data-wp-portfolio-category\": category } : {}),\n });\n });\n}\n\nfunction flattenIdBasedGalleryShortcodes(\n content: string,\n widgetRegistry: WordPressWidgetRegistry,\n): string {\n let html = content;\n for (const tag of widgetRegistry.idGalleryShortcodes) {\n html = flattenIdGalleryShortcode(html, tag);\n }\n return html;\n}\n\nconst SHORTCODE_WORD_COUNTS: Record<string, string> = {\n one: \"1\",\n two: \"2\",\n three: \"3\",\n four: \"4\",\n five: \"5\",\n six: \"6\",\n seven: \"7\",\n eight: \"8\",\n nine: \"9\",\n ten: \"10\",\n};\n\nfunction normalizeShortcodeCount(raw: string | undefined): string | undefined {\n if (!raw?.trim()) return undefined;\n const trimmed = raw.trim().toLowerCase();\n if (/^\\d+$/.test(trimmed)) return trimmed;\n return SHORTCODE_WORD_COUNTS[trimmed];\n}\n\nfunction inferBlogListingLayout(params: string): string {\n const raw =\n extractBareOrQuotedParam(params, \"builderLayout\") ??\n extractBareOrQuotedParam(params, \"layout\") ??\n extractBareOrQuotedParam(params, \"style\");\n if (!raw) return \"grid\";\n const normalized = raw.trim().toLowerCase();\n if (normalized === \"list\" || normalized === \"grid\" || normalized === \"featured\" || normalized === \"sidebar\") {\n return normalized;\n }\n return \"grid\";\n}\n\nfunction flattenBlogListingShortcodes(\n content: string,\n widgetRegistry: WordPressWidgetRegistry,\n): string {\n let html = content;\n for (const tag of widgetRegistry.blogShortcodeTags) {\n const escaped = escapeRegExp(tag);\n const pattern = new RegExp(`\\\\[${escaped}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${escaped}\\\\])?`, \"gi\");\n html = html.replace(pattern, (_, params: string) => {\n const limit =\n normalizeShortcodeCount(extractBareOrQuotedParam(params, \"number_of_posts\")) ??\n normalizeShortcodeCount(extractBareOrQuotedParam(params, \"count\")) ??\n normalizeShortcodeCount(extractBareOrQuotedParam(params, \"posts_per_page\")) ??\n normalizeShortcodeCount(extractBareOrQuotedParam(params, \"number\"));\n const filterBy = extractBareOrQuotedParam(params, \"filter_by\")?.toLowerCase();\n const categories = extractBareOrQuotedParam(params, \"categories\");\n const tags = extractBareOrQuotedParam(params, \"tags\");\n const col = extractBareOrQuotedParam(params, \"col\");\n\n return emitWidgetStub(\n \"blog-listing\",\n {\n \"data-wp-blog-layout\": inferBlogListingLayout(params),\n ...(limit ? { \"data-wp-blog-limit\": limit } : {}),\n ...(col ? { \"data-wp-blog-columns\": col } : {}),\n ...(filterBy === \"category\" && categories ? { \"data-wp-blog-category\": categories } : {}),\n ...(filterBy === \"tag\" && tags ? { \"data-wp-blog-tags\": tags } : {}),\n },\n \"section\",\n );\n });\n }\n return html;\n}\n\nfunction flattenPortfolioShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n const tag = escapeRegExp(widgetRegistry.portfolioShortcode);\n const pattern = new RegExp(`\\\\[${tag}\\\\b([^\\\\]]*)\\\\](?:\\\\s*\\\\[\\\\/${tag}\\\\])?`, \"gi\");\n return content.replace(pattern, (_, params: string) => {\n const category = extractBareOrQuotedParam(params, \"category\");\n const slug = extractBareOrQuotedParam(params, \"slug\");\n return emitWidgetStub(\"portfolio\", {\n ...(category ? { \"data-wp-portfolio-category\": category } : {}),\n ...(slug ? { \"data-wp-portfolio-slug\": slug } : {}),\n });\n });\n}\n\nfunction flattenVideoShortcodes(content: string, widgetRegistry: WordPressWidgetRegistry): string {\n let html = content;\n for (const prefix of widgetRegistry.videoShortcodePrefixes) {\n const wrapped = new RegExp(\n `\\\\[${escapeRegExp(prefix)}\\\\b([^\\\\]]*)\\\\]([\\\\s\\\\S]*?)\\\\[\\\\/${escapeRegExp(prefix)}\\\\b[^\\\\]]*\\\\]`,\n \"gi\",\n );\n html = html.replace(wrapped, (_, params: string, inner: string) =>\n emitVideoWidgetFromParams(params, inner),\n );\n\n const selfClosing = new RegExp(\n `\\\\[${escapeRegExp(prefix)}\\\\b([^\\\\]]*)\\\\]`,\n \"gi\",\n );\n html = html.replace(selfClosing, (_, params: string) => emitVideoWidgetFromParams(params, \"\"));\n }\n return html;\n}\n\n/** Detect embedded HTML contact forms (e.g. Tatsu `[tatsu_code]` with `<form>`). */\nexport function looksLikeContactFormHtml(formHtml: string): boolean {\n if (!/<form\\b/i.test(formHtml)) return false;\n\n const lower = formHtml.toLowerCase();\n if (/searchform|wp-login-form|loginform|lostpasswordform/i.test(lower)) return false;\n if (/type\\s*=\\s*[\"']search[\"']/i.test(formHtml)) return false;\n if (/newsletter|subscribe/i.test(lower) && !/<textarea\\b/i.test(formHtml)) return false;\n\n const hasEmailField =\n /type\\s*=\\s*[\"']email[\"']/i.test(formHtml) ||\n /name\\s*=\\s*[\"'][^\"']*email/i.test(formHtml) ||\n /class\\s*=\\s*[\"'][^\"']*email/i.test(formHtml);\n const hasMessageField =\n /<textarea\\b/i.test(formHtml) ||\n /name\\s*=\\s*[\"'][^\"']*(message|comment|body|enquiry|inquiry)/i.test(formHtml);\n const hasContactHint =\n /contact|serverless-contact|get-in-touch|request-quote|quote-request/i.test(lower);\n\n if (hasEmailField && hasMessageField) return true;\n if (hasContactHint && hasEmailField) return true;\n if (hasContactHint && hasMessageField) return true;\n\n return false;\n}\n\nfunction stripContactFormHelperScripts(html: string): string {\n return html.replace(\n /<script\\b[^>]*\\bsrc\\s*=\\s*[\"'][^\"']*(?:recaptcha|contact_form|contact-form)[^\"']*[\"'][^>]*>\\s*<\\/script>\\s*/gi,\n \"\",\n );\n}\n\nfunction flattenCustomHtmlContactForms(content: string): string {\n let html = content.replace(/<form\\b[^>]*>[\\s\\S]*?<\\/form>/gi, (formHtml) => {\n if (!looksLikeContactFormHtml(formHtml)) return formHtml;\n\n const formId =\n formHtml.match(/\\bid\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1]?.trim() ||\n formHtml.match(/\\bname\\s*=\\s*[\"']([^\"']+)[\"']/i)?.[1]?.trim();\n\n return emitWidgetStub(\n \"contact-form\",\n {\n \"data-wp-form-source\": \"custom-html\",\n ...(formId ? { \"data-wp-form-id\": formId } : {}),\n },\n \"section\",\n );\n });\n\n html = stripContactFormHelperScripts(html);\n return html;\n}\n\n/** Cross-builder widget + video stubs (before scaffolding strip). */\nfunction flattenWordPressWidgets(\n content: string,\n widgetRegistry: WordPressWidgetRegistry = WORDPRESS_WIDGET_REGISTRY,\n): string {\n let html = content;\n html = flattenGalleryShortcodes(html, widgetRegistry);\n html = flattenIdBasedGalleryShortcodes(html, widgetRegistry);\n html = flattenPortfolioShortcodes(html, widgetRegistry);\n html = flattenBlogListingShortcodes(html, widgetRegistry);\n html = flattenMapShortcodes(html, widgetRegistry);\n html = flattenContactFormShortcodes(html, widgetRegistry);\n html = flattenVideoShortcodes(html, widgetRegistry);\n html = flattenCustomHtmlContactForms(html);\n return html;\n}\n\n/**\n * Pre-DTO WordPress builder flattening — Bucket 1 (asset/text shortcodes → HTML) then\n * Bucket 2 (layout scaffolding stripped). Decoupled from sink-time rewriteInlineImages.\n */\nexport function flattenWordPressBuilders(\n content: string,\n options: FlattenWordPressBuildersOptions = {},\n): FlattenWordPressBuildersResult {\n if (!content.trim()) {\n return { html: content, detectedThemes: [] };\n }\n\n const registry = options.registry ?? WORDPRESS_BUILDER_REGISTRY;\n const themes = detectThemes(content, registry);\n\n const widgetRegistry = options.widgetRegistry ?? WORDPRESS_WIDGET_REGISTRY;\n // Widget stubs before scaffolding strips (e.g. blox_gmap, tatsu_video, portfolio).\n let html = flattenWordPressWidgets(content, widgetRegistry);\n for (const theme of themes) {\n for (const rule of theme.wrapperRules ?? []) {\n html = convertWrapperRule(html, rule);\n }\n for (const rule of theme.textRules ?? []) {\n html = convertTextRule(html, rule);\n }\n for (const rule of theme.urlRules ?? []) {\n html = convertUrlRule(html, rule);\n }\n for (const rule of theme.placeholderRules ?? []) {\n html = convertPlaceholderRule(html, rule);\n }\n for (const rule of theme.iconImageRules ?? []) {\n html = convertIconImageRule(html, rule);\n }\n for (const layoutMap of collectLayoutMaps(theme)) {\n html = applyStructuralLayoutMap(html, layoutMap);\n }\n for (const prefix of theme.scaffoldingPrefixes ?? []) {\n html = stripScaffoldingPrefix(html, prefix);\n }\n if (theme.legacyScaffoldingTokens?.length) {\n html = stripLegacyTokens(html, theme.legacyScaffoldingTokens);\n }\n }\n\n // Catch widget shortcodes revealed after wrapper unwrap (e.g. blox_gmap inside tatsu_text_with_shortcodes).\n html = flattenWordPressWidgets(html, widgetRegistry);\n\n html = html.replace(/\\n{3,}/g, \"\\n\\n\").trim();\n\n return {\n html,\n detectedThemes: themes.map((theme) => theme.id),\n };\n}\n"],"mappings":"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","names":["value","trimmed"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/normalizer/validate.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport type { ValidationIssue, ValidationResult } from \"./types.js\";\n\nconst migrationPlatformSchema = z.enum([\"wordpress\", \"smugmug\", \"squarespace\", \"wix\"]);\nconst publishStatusSchema = z.enum([\"draft\", \"published\", \"archived\"]);\n\nexport const sourceMetadataSchema = z.object({\n platform: migrationPlatformSchema,\n id: z.string().min(1),\n url: z.string().optional(),\n path: z.string().optional(),\n exportedAt: z.string().optional(),\n});\n\nexport const normalizedPostSchema = z.object({\n type: z.literal(\"post\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n title: z.string().min(1),\n slug: z.string().min(1),\n excerpt: z.string().optional(),\n contentHtml: z.string(),\n publishedAt: z.string().optional(),\n status: publishStatusSchema,\n categorySlugs: z.array(z.string().min(1)).optional(),\n tagSlugs: z.array(z.string().min(1)).optional(),\n sourceFeaturedMediaId: z.string().optional(),\n featuredAssetSourceId: z.string().optional(),\n seoTitle: z.string().optional(),\n seoDescription: z.string().optional(),\n});\n\nexport const normalizedPageSchema = z.object({\n type: z.literal(\"page\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n title: z.string().min(1),\n slug: z.string().min(1),\n contentHtml: z.string(),\n contentCss: z.string().optional(),\n isHomePage: z.boolean().optional(),\n isPortfolioPage: z.boolean().optional(),\n status: publishStatusSchema,\n seoTitle: z.string().optional(),\n seoDescription: z.string().optional(),\n});\n\nexport const normalizedAssetExifSchema = z.object({\n iso: z.number().optional(),\n aperture: z.number().optional(),\n shutter: z.string().optional(),\n focalLength: z.number().optional(),\n});\n\nexport const normalizedAssetSchema = z.object({\n type: z.literal(\"asset\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n sourceUrl: z.string().min(1),\n filename: z.string().min(1),\n mimeType: z.string().optional(),\n caption: z.string().optional(),\n altText: z.string().optional(),\n keywords: z.array(z.string()).optional(),\n exif: normalizedAssetExifSchema.optional(),\n portfolioSourceId: z.string().optional(),\n sort: z.number().optional(),\n});\n\nexport const normalizedPortfolioSchema = z.object({\n type: z.literal(\"portfolio\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n title: z.string().min(1),\n slug: z.string().min(1),\n description: z.string().optional(),\n parentSourceId: z.string().optional(),\n});\n\nexport const normalizedCategorySchema = z.object({\n type: z.literal(\"category\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n name: z.string().min(1),\n slug: z.string().min(1),\n});\n\nexport const normalizedTagSchema = z.object({\n type: z.literal(\"tag\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n name: z.string().min(1),\n slug: z.string().min(1),\n});\n\nexport const normalizedEntitySchema = z.discriminatedUnion(\"type\", [\n normalizedPostSchema,\n normalizedPageSchema,\n normalizedAssetSchema,\n normalizedPortfolioSchema,\n normalizedCategorySchema,\n normalizedTagSchema,\n]);\n\nfunction zodIssuesToValidationIssues(issues: z.ZodIssue[]): ValidationIssue[] {\n return issues.map((issue) => ({\n code: issue.code,\n message: issue.message,\n path: issue.path.length > 0 ? issue.path.join(\".\") : undefined,\n }));\n}\n\nfunction parseToValidationResult(schema: z.ZodTypeAny, value: unknown): ValidationResult {\n const result = schema.safeParse(value);\n if (result.success) {\n return { ok: true, issues: [] };\n }\n return { ok: false, issues: zodIssuesToValidationIssues(result.error.issues) };\n}\n\n/** Opt-in structural check for a normalized post DTO (no cross-entity FK validation). */\nexport function validateNormalizedPost(post: unknown): ValidationResult {\n return parseToValidationResult(normalizedPostSchema, post);\n}\n\n/** Opt-in structural check for a normalized page DTO (no cross-entity FK validation). */\nexport function validateNormalizedPage(page: unknown): ValidationResult {\n return parseToValidationResult(normalizedPageSchema, page);\n}\n\n/** Opt-in structural check for a normalized asset DTO. */\nexport function validateNormalizedAsset(asset: unknown): ValidationResult {\n return parseToValidationResult(normalizedAssetSchema, asset);\n}\n\n/** Opt-in structural check for a normalized portfolio DTO. */\nexport function validateNormalizedPortfolio(portfolio: unknown): ValidationResult {\n return parseToValidationResult(normalizedPortfolioSchema, portfolio);\n}\n\n/** Opt-in structural check for a normalized category DTO. */\nexport function validateNormalizedCategory(category: unknown): ValidationResult {\n return parseToValidationResult(normalizedCategorySchema, category);\n}\n\n/** Opt-in structural check for a normalized tag DTO. */\nexport function validateNormalizedTag(tag: unknown): ValidationResult {\n return parseToValidationResult(normalizedTagSchema, tag);\n}\n\n/** Opt-in structural check for any normalized entity discriminated by `type`. */\nexport function validateNormalizedEntity(entity: unknown): ValidationResult {\n return parseToValidationResult(normalizedEntitySchema, entity);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/normalizer/types.ts","../src/normalizer/idempotency.ts","../src/normalizer/bundle.ts","../src/normalizer/portfolio-media.ts"],"sourcesContent":["export type MigrationPlatform = \"wordpress\" | \"smugmug\" | \"squarespace\" | \"wix\";\n\nexport type EntityType = \"post\" | \"page\" | \"asset\" | \"portfolio\" | \"category\" | \"tag\";\n\nexport type PublishStatus = \"draft\" | \"published\" | \"archived\";\n\nexport interface SourceMetadata {\n platform: MigrationPlatform;\n id: string;\n url?: string;\n path?: string;\n exportedAt?: string;\n /** WordPress `post_type` when the DTO shape differs (e.g. portfolio CPT emitted as `page`). */\n postType?: string;\n}\n\n/** Canonical post DTO — raw HTML; sanitize at host sink. */\nexport interface NormalizedPost {\n type: \"post\";\n source: SourceMetadata;\n sourceId: string;\n title: string;\n slug: string;\n excerpt?: string;\n contentHtml: string;\n publishedAt?: string;\n status: PublishStatus;\n categorySlugs?: string[];\n tagSlugs?: string[];\n /** WordPress attachment id before two-pass resolution. */\n sourceFeaturedMediaId?: string;\n featuredAssetSourceId?: string;\n seoTitle?: string;\n seoDescription?: string;\n}\n\n/** Canonical page DTO — raw HTML snapshot. */\nexport interface NormalizedPage {\n type: \"page\";\n source: SourceMetadata;\n sourceId: string;\n title: string;\n slug: string;\n contentHtml: string;\n contentCss?: string;\n isHomePage?: boolean;\n /** Site portfolio listing shell (distinct from portfolio CPT singles). */\n isPortfolioPage?: boolean;\n status: PublishStatus;\n seoTitle?: string;\n seoDescription?: string;\n}\n\n/** EXIF fields preserved from SmugMug / camera metadata when present. */\nexport interface NormalizedAssetExif {\n iso?: number;\n aperture?: number;\n shutter?: string;\n focalLength?: number;\n}\n\n/** Remote asset to stream into the host sink. */\nexport interface NormalizedAsset {\n type: \"asset\";\n source: SourceMetadata;\n sourceId: string;\n sourceUrl: string;\n filename: string;\n mimeType?: string;\n caption?: string;\n altText?: string;\n keywords?: string[];\n exif?: NormalizedAssetExif;\n portfolioSourceId?: string;\n sort?: number;\n}\n\n/** M2M index: portfolio ↔ asset membership and sort order. */\nexport interface PortfolioMediaLink {\n portfolioSourceId: string;\n assetSourceId: string;\n sort: number;\n}\n\nexport interface NormalizedPortfolio {\n type: \"portfolio\";\n source: SourceMetadata;\n sourceId: string;\n title: string;\n slug: string;\n description?: string;\n parentSourceId?: string;\n}\n\nexport interface NormalizedCategory {\n type: \"category\";\n source: SourceMetadata;\n sourceId: string;\n name: string;\n slug: string;\n}\n\nexport interface NormalizedTag {\n type: \"tag\";\n source: SourceMetadata;\n sourceId: string;\n name: string;\n slug: string;\n}\n\nexport type NormalizedEntity =\n | NormalizedPost\n | NormalizedPage\n | NormalizedAsset\n | NormalizedPortfolio\n | NormalizedCategory\n | NormalizedTag;\n\nexport interface ValidationIssue {\n code: string;\n message: string;\n path?: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n issues: ValidationIssue[];\n summary?: {\n posts?: number;\n pages?: number;\n assets?: number;\n portfolios?: number;\n /** WordPress `post_type=portfolio` (and configured CPT slugs) in raw WXR. */\n portfolioCpt?: number;\n categories?: number;\n tags?: number;\n /** WXR rows the parser would emit (OSS-19). */\n importableItemCount?: number;\n unsupportedOnly?: boolean;\n skippedPostTypes?: Record<string, number>;\n };\n}\n\nexport interface WxrImportSummary {\n importableItemCount: number;\n unsupportedOnly: boolean;\n skippedPostTypes: Record<string, number>;\n skippedWooCommerceStubPages?: number;\n}\n\nexport interface AdapterContext {\n input: unknown;\n cursor?: MigrationCursor;\n}\n\nexport interface MigrationAdapter {\n platform: MigrationPlatform;\n validateInput(input: unknown): ValidationResult | Promise<ValidationResult>;\n enumerateEntities(ctx: AdapterContext): AsyncIterable<NormalizedEntity>;\n /** Platform-specific import accounting (e.g. WordPress skipped `post_type`s). */\n getImportSummary?(input: unknown): Promise<WxrImportSummary | undefined>;\n}\n\nexport interface MigrationCursor {\n lastEntityKey?: EntityKey;\n state?: Record<string, unknown>;\n}\n\nexport interface EntityKey {\n platform: MigrationPlatform;\n entityType: EntityType;\n sourceId: string;\n}\n\nexport function entityKey(entity: NormalizedEntity, platform: MigrationPlatform): EntityKey {\n return {\n platform,\n entityType: entity.type,\n sourceId: entity.sourceId,\n };\n}\n","import type { EntityKey, MigrationCursor } from \"./types.js\";\n\n/** Portable entity state for resume / idempotency (not Directus field names). */\nexport type EntityState = \"pending\" | \"done\" | \"failed\" | \"skipped\";\n\nexport interface TrackedEntity extends EntityKey {\n state: EntityState;\n targetId?: string;\n errorMessage?: string;\n}\n\nexport interface MigrationCheckpoint {\n jobId: string;\n cursor: MigrationCursor;\n entities: TrackedEntity[];\n updatedAt: string;\n}\n\nexport function isTerminalState(state: EntityState): boolean {\n return state === \"done\" || state === \"skipped\";\n}\n\nexport function shouldProcessEntity(\n key: EntityKey,\n entities: TrackedEntity[],\n): boolean {\n const existing = entities.find(\n (e) =>\n e.platform === key.platform &&\n e.entityType === key.entityType &&\n e.sourceId === key.sourceId,\n );\n return !existing || !isTerminalState(existing.state);\n}\n","import type {\n NormalizedAsset,\n NormalizedCategory,\n NormalizedEntity,\n NormalizedPage,\n NormalizedPortfolio,\n NormalizedPost,\n NormalizedTag,\n} from \"./types.js\";\n\nexport interface EntityBundle {\n posts: NormalizedPost[];\n pages: NormalizedPage[];\n media: NormalizedAsset[];\n portfolios: NormalizedPortfolio[];\n categories: NormalizedCategory[];\n tags: NormalizedTag[];\n}\n\nexport function emptyBundle(): EntityBundle {\n return {\n posts: [],\n pages: [],\n media: [],\n portfolios: [],\n categories: [],\n tags: [],\n };\n}\n\nexport async function collectEntities(\n entities: AsyncIterable<NormalizedEntity>,\n): Promise<EntityBundle> {\n const bundle = emptyBundle();\n\n for await (const entity of entities) {\n switch (entity.type) {\n case \"post\":\n bundle.posts.push(entity);\n break;\n case \"page\":\n bundle.pages.push(entity);\n break;\n case \"asset\":\n bundle.media.push(entity);\n break;\n case \"portfolio\":\n bundle.portfolios.push(entity);\n break;\n case \"category\":\n bundle.categories.push(entity);\n break;\n case \"tag\":\n bundle.tags.push(entity);\n break;\n default: {\n const _exhaustive: never = entity;\n throw new Error(`Unknown entity type: ${(_exhaustive as NormalizedEntity).type}`);\n }\n }\n }\n\n return bundle;\n}\n\nexport interface BundleCounts {\n posts: number;\n pages: number;\n assets: number;\n portfolios: number;\n categories: number;\n tags: number;\n}\n\nexport function bundleCounts(bundle: EntityBundle): BundleCounts {\n return {\n posts: bundle.posts.length,\n pages: bundle.pages.length,\n assets: bundle.media.length,\n portfolios: bundle.portfolios.length,\n categories: bundle.categories.length,\n tags: bundle.tags.length,\n };\n}\n","import type { EntityBundle } from \"./bundle.js\";\nimport type { PortfolioMediaLink } from \"./types.js\";\n\n/** Derive portfolio↔asset M2M rows from assets carrying `portfolioSourceId`. */\nexport function buildPortfolioMediaLinks(bundle: EntityBundle): PortfolioMediaLink[] {\n const links: PortfolioMediaLink[] = [];\n\n for (const asset of bundle.media) {\n if (!asset.portfolioSourceId) continue;\n links.push({\n portfolioSourceId: asset.portfolioSourceId,\n assetSourceId: asset.sourceId,\n sort: asset.sort ?? 0,\n });\n }\n\n links.sort((a, b) => {\n if (a.portfolioSourceId !== b.portfolioSourceId) {\n return a.portfolioSourceId.localeCompare(b.portfolioSourceId);\n }\n return a.sort - b.sort || a.assetSourceId.localeCompare(b.assetSourceId);\n });\n\n return links;\n}\n"],"mappings":";AA8KO,SAAS,UAAU,QAA0B,UAAwC;AAC1F,SAAO;AAAA,IACL;AAAA,IACA,YAAY,OAAO;AAAA,IACnB,UAAU,OAAO;AAAA,EACnB;AACF;;;AClKO,SAAS,gBAAgB,OAA6B;AAC3D,SAAO,UAAU,UAAU,UAAU;AACvC;AAEO,SAAS,oBACd,KACA,UACS;AACT,QAAM,WAAW,SAAS;AAAA,IACxB,CAAC,MACC,EAAE,aAAa,IAAI,YACnB,EAAE,eAAe,IAAI,cACrB,EAAE,aAAa,IAAI;AAAA,EACvB;AACA,SAAO,CAAC,YAAY,CAAC,gBAAgB,SAAS,KAAK;AACrD;;;ACdO,SAAS,cAA4B;AAC1C,SAAO;AAAA,IACL,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,IACR,YAAY,CAAC;AAAA,IACb,YAAY,CAAC;AAAA,IACb,MAAM,CAAC;AAAA,EACT;AACF;AAEA,eAAsB,gBACpB,UACuB;AACvB,QAAM,SAAS,YAAY;AAE3B,mBAAiB,UAAU,UAAU;AACnC,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,eAAO,MAAM,KAAK,MAAM;AACxB;AAAA,MACF,KAAK;AACH,eAAO,MAAM,KAAK,MAAM;AACxB;AAAA,MACF,KAAK;AACH,eAAO,MAAM,KAAK,MAAM;AACxB;AAAA,MACF,KAAK;AACH,eAAO,WAAW,KAAK,MAAM;AAC7B;AAAA,MACF,KAAK;AACH,eAAO,WAAW,KAAK,MAAM;AAC7B;AAAA,MACF,KAAK;AACH,eAAO,KAAK,KAAK,MAAM;AACvB;AAAA,MACF,SAAS;AACP,cAAM,cAAqB;AAC3B,cAAM,IAAI,MAAM,wBAAyB,YAAiC,IAAI,EAAE;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAWO,SAAS,aAAa,QAAoC;AAC/D,SAAO;AAAA,IACL,OAAO,OAAO,MAAM;AAAA,IACpB,OAAO,OAAO,MAAM;AAAA,IACpB,QAAQ,OAAO,MAAM;AAAA,IACrB,YAAY,OAAO,WAAW;AAAA,IAC9B,YAAY,OAAO,WAAW;AAAA,IAC9B,MAAM,OAAO,KAAK;AAAA,EACpB;AACF;;;AC/EO,SAAS,yBAAyB,QAA4C;AACnF,QAAM,QAA8B,CAAC;AAErC,aAAW,SAAS,OAAO,OAAO;AAChC,QAAI,CAAC,MAAM,kBAAmB;AAC9B,UAAM,KAAK;AAAA,MACT,mBAAmB,MAAM;AAAA,MACzB,eAAe,MAAM;AAAA,MACrB,MAAM,MAAM,QAAQ;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,QAAM,KAAK,CAAC,GAAG,MAAM;AACnB,QAAI,EAAE,sBAAsB,EAAE,mBAAmB;AAC/C,aAAO,EAAE,kBAAkB,cAAc,EAAE,iBAAiB;AAAA,IAC9D;AACA,WAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,cAAc,EAAE,aAAa;AAAA,EACzE,CAAC;AAED,SAAO;AACT;","names":[]}
|