@se-studio/site-check 1.1.3 → 1.3.1

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.
@@ -0,0 +1,16 @@
1
+ import type { PlainClient } from './cma-types.js';
2
+ import type { SiteSeoConfig } from './seo-audit.js';
3
+ export interface FeaturedImageBackfillOptions {
4
+ apply: boolean;
5
+ }
6
+ export interface FeaturedImageBackfillResult {
7
+ scanned: number;
8
+ alreadySet: number;
9
+ updated: number;
10
+ fromHero: number;
11
+ fromLogo: number;
12
+ noSource: number;
13
+ errors: number;
14
+ }
15
+ export declare function runFeaturedImageBackfill(client: PlainClient, config: SiteSeoConfig, options: FeaturedImageBackfillOptions): Promise<FeaturedImageBackfillResult>;
16
+ //# sourceMappingURL=featured-image-backfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featured-image-backfill.d.ts","sourceRoot":"","sources":["../../src/cms-seo/featured-image-backfill.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAoBpD,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAuTD,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,2BAA2B,CAAC,CAkFtC"}
@@ -0,0 +1,357 @@
1
+ const LOCALE = 'en-US';
2
+ const NEWS_IMAGE_LOGO_TAG_NAME = 'news-image-logo';
3
+ const LOGO_TITLE_PREFIX = 'News Image Logo — ';
4
+ const HERO_COMPONENT_TYPES = new Set([
5
+ 'Hero',
6
+ 'Image Hero',
7
+ 'Dynamic hero',
8
+ 'Split Hero',
9
+ 'Scroll Hero',
10
+ 'News Hero',
11
+ 'Publications Hero',
12
+ 'Person Hero',
13
+ 'Lander',
14
+ 'Publications hero carousel',
15
+ 'Publication Poster Image',
16
+ ]);
17
+ function field(entry, key) {
18
+ return entry.fields?.[key]?.[LOCALE];
19
+ }
20
+ function linkIds(entry, fieldName) {
21
+ const value = field(entry, fieldName);
22
+ if (!value)
23
+ return [];
24
+ if (Array.isArray(value)) {
25
+ return value
26
+ .map((item) => {
27
+ if (item && typeof item === 'object' && 'sys' in item) {
28
+ return item.sys?.id ?? '';
29
+ }
30
+ return '';
31
+ })
32
+ .filter(Boolean);
33
+ }
34
+ if (typeof value === 'object' && value !== null && 'sys' in value) {
35
+ const id = value.sys?.id;
36
+ return id ? [id] : [];
37
+ }
38
+ return [];
39
+ }
40
+ function assetLinkId(value) {
41
+ if (!value || typeof value !== 'object')
42
+ return null;
43
+ const sys = value.sys;
44
+ if (!sys?.id)
45
+ return null;
46
+ if (sys.type === 'Asset' || (sys.type === 'Link' && sys.linkType === 'Asset')) {
47
+ return sys.id;
48
+ }
49
+ return null;
50
+ }
51
+ function entryLinkId(value) {
52
+ if (!value || typeof value !== 'object')
53
+ return null;
54
+ const sys = value.sys;
55
+ if (!sys?.id)
56
+ return null;
57
+ if (sys.type === 'Entry' || (sys.type === 'Link' && sys.linkType === 'Entry')) {
58
+ return sys.id;
59
+ }
60
+ return null;
61
+ }
62
+ function hasFeaturedImage(entry) {
63
+ return Boolean(assetLinkId(field(entry, 'featuredImage')));
64
+ }
65
+ async function fetchEntriesByType(client, contentType) {
66
+ const items = [];
67
+ let skip = 0;
68
+ while (true) {
69
+ const page = await client.entry.getMany({
70
+ query: { content_type: contentType, limit: 100, skip },
71
+ });
72
+ items.push(...page.items);
73
+ skip += 100;
74
+ if (skip >= page.total)
75
+ break;
76
+ }
77
+ return items;
78
+ }
79
+ function parseLogoSlugFromAssetTitle(title) {
80
+ if (!title?.startsWith(LOGO_TITLE_PREFIX))
81
+ return null;
82
+ const slug = title.slice(LOGO_TITLE_PREFIX.length).trim().toLowerCase();
83
+ return slug || null;
84
+ }
85
+ async function resolveDefaultLogoAssetId(client, logoSlug, explicitAssetId) {
86
+ if (explicitAssetId) {
87
+ try {
88
+ await client.asset.get({ assetId: explicitAssetId });
89
+ return explicitAssetId;
90
+ }
91
+ catch {
92
+ // fall through to tag lookup
93
+ }
94
+ }
95
+ const tagRes = await client.tag.getMany({ query: { limit: 1000 } });
96
+ const tag = tagRes.items.find((item) => item.name === NEWS_IMAGE_LOGO_TAG_NAME);
97
+ if (!tag)
98
+ return null;
99
+ const tagId = tag.sys.id;
100
+ let skip = 0;
101
+ let total = Number.POSITIVE_INFINITY;
102
+ while (skip < total) {
103
+ const res = await client.asset.getMany({
104
+ query: {
105
+ limit: 100,
106
+ skip,
107
+ 'metadata.tags.sys.id[in]': tagId,
108
+ },
109
+ });
110
+ total = res.total;
111
+ for (const asset of res.items) {
112
+ const title = asset.fields?.title?.[LOCALE];
113
+ if (parseLogoSlugFromAssetTitle(title) === logoSlug) {
114
+ return asset.sys.id;
115
+ }
116
+ }
117
+ skip += 100;
118
+ }
119
+ return null;
120
+ }
121
+ function extractImageFromComponent(entry, graph) {
122
+ const background = assetLinkId(field(entry, 'backgroundVisual'));
123
+ if (background)
124
+ return background;
125
+ const mobileBackground = assetLinkId(field(entry, 'mobileBackgroundVisual'));
126
+ if (mobileBackground)
127
+ return mobileBackground;
128
+ const visualId = entryLinkId(field(entry, 'visual'));
129
+ if (visualId) {
130
+ const media = graph.entryById.get(visualId);
131
+ if (media) {
132
+ const asset = assetLinkId(field(media, 'asset'));
133
+ if (asset)
134
+ return asset;
135
+ }
136
+ }
137
+ const icon = assetLinkId(field(entry, 'icon'));
138
+ if (icon)
139
+ return icon;
140
+ const otherMedia = field(entry, 'otherMedia');
141
+ if (Array.isArray(otherMedia)) {
142
+ for (const item of otherMedia) {
143
+ const asset = assetLinkId(item);
144
+ if (asset)
145
+ return asset;
146
+ }
147
+ }
148
+ return null;
149
+ }
150
+ function findHeroAssetInEntry(entryId, graph) {
151
+ const entry = graph.entryById.get(entryId);
152
+ if (!entry)
153
+ return null;
154
+ const contentTypeId = entry.sys.contentType?.sys?.id;
155
+ if (contentTypeId === 'component') {
156
+ const componentType = field(entry, 'componentType');
157
+ if (componentType && !HERO_COMPONENT_TYPES.has(componentType)) {
158
+ return null;
159
+ }
160
+ return extractImageFromComponent(entry, graph);
161
+ }
162
+ if (contentTypeId === 'media') {
163
+ return assetLinkId(field(entry, 'asset'));
164
+ }
165
+ if (contentTypeId === 'collection') {
166
+ const collectionType = field(entry, 'collectionType') ?? '';
167
+ const background = assetLinkId(field(entry, 'backgroundVisual'));
168
+ if (background)
169
+ return background;
170
+ if (/hero/i.test(collectionType)) {
171
+ for (const childId of linkIds(entry, 'contents')) {
172
+ const asset = findHeroAssetInEntry(childId, graph);
173
+ if (asset)
174
+ return asset;
175
+ }
176
+ }
177
+ }
178
+ return null;
179
+ }
180
+ function findHeroAssetInLinks(linkIdList, graph) {
181
+ for (const id of linkIdList) {
182
+ const asset = findHeroAssetInEntry(id, graph);
183
+ if (asset)
184
+ return asset;
185
+ }
186
+ return null;
187
+ }
188
+ function templatePreContentIds(entry, templateField, graph) {
189
+ const templateId = entryLinkId(field(entry, templateField));
190
+ if (!templateId)
191
+ return [];
192
+ const template = graph.entryById.get(templateId);
193
+ return template ? linkIds(template, 'preContent') : [];
194
+ }
195
+ function resolveHeroForPage(page, graph) {
196
+ const chains = [
197
+ linkIds(page, 'topContent'),
198
+ templatePreContentIds(page, 'template', graph),
199
+ linkIds(page, 'content'),
200
+ ].filter((chain) => chain.length > 0);
201
+ for (const chain of chains) {
202
+ const asset = findHeroAssetInLinks(chain, graph);
203
+ if (asset)
204
+ return asset;
205
+ }
206
+ return null;
207
+ }
208
+ function resolveHeroForArticle(article, graph) {
209
+ const articleTypeId = entryLinkId(field(article, 'articleType'));
210
+ const articleType = articleTypeId ? graph.entryById.get(articleTypeId) : undefined;
211
+ const templateId = entryLinkId(field(article, 'template')) ??
212
+ (articleType ? entryLinkId(field(articleType, 'articleTemplate')) : null);
213
+ const chains = [linkIds(article, 'topContent')];
214
+ if (articleType) {
215
+ chains.push(linkIds(articleType, 'articlePageTopContent'));
216
+ }
217
+ if (templateId) {
218
+ const template = graph.entryById.get(templateId);
219
+ if (template)
220
+ chains.push(linkIds(template, 'preContent'));
221
+ }
222
+ chains.push(linkIds(article, 'content'));
223
+ for (const chain of chains) {
224
+ const asset = findHeroAssetInLinks(chain, graph);
225
+ if (asset)
226
+ return asset;
227
+ }
228
+ return null;
229
+ }
230
+ function resolveHeroForArticleType(articleType, graph) {
231
+ const chains = [
232
+ linkIds(articleType, 'indexPageTopContent'),
233
+ templatePreContentIds(articleType, 'indexPageTemplate', graph),
234
+ ].filter((chain) => chain.length > 0);
235
+ for (const chain of chains) {
236
+ const asset = findHeroAssetInLinks(chain, graph);
237
+ if (asset)
238
+ return asset;
239
+ }
240
+ return null;
241
+ }
242
+ function resolveHeroForCustomType(customType, graph) {
243
+ const chains = [
244
+ linkIds(customType, 'indexPageTopContent'),
245
+ linkIds(customType, 'topContent'),
246
+ templatePreContentIds(customType, 'indexPageTemplate', graph),
247
+ templatePreContentIds(customType, 'template', graph),
248
+ ].filter((chain) => chain.length > 0);
249
+ for (const chain of chains) {
250
+ const asset = findHeroAssetInLinks(chain, graph);
251
+ if (asset)
252
+ return asset;
253
+ }
254
+ return null;
255
+ }
256
+ function resolveHeroForTag(tag, graph) {
257
+ return findHeroAssetInLinks(linkIds(tag, 'topContent'), graph);
258
+ }
259
+ function resolveHeroAsset(entry, contentType, graph) {
260
+ switch (contentType) {
261
+ case 'page':
262
+ case 'pageVariant':
263
+ return resolveHeroForPage(entry, graph);
264
+ case 'article':
265
+ return resolveHeroForArticle(entry, graph);
266
+ case 'articleType':
267
+ return resolveHeroForArticleType(entry, graph);
268
+ case 'customType':
269
+ return resolveHeroForCustomType(entry, graph);
270
+ case 'tag':
271
+ return resolveHeroForTag(entry, graph);
272
+ default:
273
+ return null;
274
+ }
275
+ }
276
+ async function updateFeaturedImage(client, entryId, assetId) {
277
+ const entry = await client.entry.get({ entryId });
278
+ const merged = {
279
+ ...entry.fields,
280
+ featuredImage: {
281
+ [LOCALE]: {
282
+ sys: { type: 'Link', linkType: 'Asset', id: assetId },
283
+ },
284
+ },
285
+ };
286
+ await client.entry.update({ entryId }, { ...entry, fields: merged });
287
+ }
288
+ export async function runFeaturedImageBackfill(client, config, options) {
289
+ const logoSlug = config.defaultLogoSlug ?? config.siteKey;
290
+ const defaultLogoAssetId = await resolveDefaultLogoAssetId(client, logoSlug, config.defaultLogoAssetId);
291
+ if (!defaultLogoAssetId) {
292
+ throw new Error(`Could not find logo asset tagged "${NEWS_IMAGE_LOGO_TAG_NAME}" with slug "${logoSlug}"`);
293
+ }
294
+ const contentTypes = [
295
+ 'page',
296
+ 'pageVariant',
297
+ 'article',
298
+ 'articleType',
299
+ 'customType',
300
+ 'tag',
301
+ ];
302
+ const supportTypes = ['template', 'component', 'media', 'collection'];
303
+ const fetched = await Promise.all([
304
+ ...contentTypes.map((ct) => fetchEntriesByType(client, ct)),
305
+ ...supportTypes.map((ct) => fetchEntriesByType(client, ct)),
306
+ ]);
307
+ const entryById = new Map();
308
+ for (const group of fetched) {
309
+ for (const entry of group) {
310
+ entryById.set(entry.sys.id, entry);
311
+ }
312
+ }
313
+ const graph = { entryById };
314
+ const targets = contentTypes.flatMap((contentType, index) => fetched[index].map((entry) => ({ entry, contentType })));
315
+ const result = {
316
+ scanned: targets.length,
317
+ alreadySet: 0,
318
+ updated: 0,
319
+ fromHero: 0,
320
+ fromLogo: 0,
321
+ noSource: 0,
322
+ errors: 0,
323
+ };
324
+ for (const { entry, contentType } of targets) {
325
+ if (hasFeaturedImage(entry)) {
326
+ result.alreadySet += 1;
327
+ continue;
328
+ }
329
+ const heroAssetId = resolveHeroAsset(entry, contentType, graph);
330
+ const assetId = heroAssetId ?? defaultLogoAssetId;
331
+ const source = heroAssetId ? 'hero' : 'logo';
332
+ if (!assetId) {
333
+ result.noSource += 1;
334
+ continue;
335
+ }
336
+ if (!options.apply) {
337
+ if (source === 'hero')
338
+ result.fromHero += 1;
339
+ else
340
+ result.fromLogo += 1;
341
+ continue;
342
+ }
343
+ try {
344
+ await updateFeaturedImage(client, entry.sys.id, assetId);
345
+ result.updated += 1;
346
+ if (source === 'hero')
347
+ result.fromHero += 1;
348
+ else
349
+ result.fromLogo += 1;
350
+ }
351
+ catch {
352
+ result.errors += 1;
353
+ }
354
+ }
355
+ return result;
356
+ }
357
+ //# sourceMappingURL=featured-image-backfill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featured-image-backfill.js","sourceRoot":"","sources":["../../src/cms-seo/featured-image-backfill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { BULK_PUBLISH_PHASES, type BulkActionPublishOptions, type BulkActionPublishResult, type BulkPublishCounts, type BulkPublishFailure, type BulkPublishPhase, bulkActionPublishAll, formatBulkEntityError, formatBulkErrorDetails, formatCaughtBulkError, needsPublish, parseBulkPublishArgv, printFailureReport, } from './bulk-action-publish.js';
2
+ export { type CreateCmaClientOptions, createCmaClient } from './cma-client.js';
3
+ export type { PlainClient } from './cma-types.js';
4
+ export { type FeaturedImageBackfillOptions, type FeaturedImageBackfillResult, runFeaturedImageBackfill, } from './featured-image-backfill.js';
5
+ export { parseSeoAuditArgv, profilePageMarkup, runSeoAudit, type SeoAuditOptions, type SeoAuditRow, type SiteSeoConfig, } from './seo-audit.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cms-seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,sBAAsB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC/E,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { BULK_PUBLISH_PHASES, bulkActionPublishAll, formatBulkEntityError, formatBulkErrorDetails, formatCaughtBulkError, needsPublish, parseBulkPublishArgv, printFailureReport, } from './bulk-action-publish.js';
2
+ export { createCmaClient } from './cma-client.js';
3
+ export { runFeaturedImageBackfill, } from './featured-image-backfill.js';
4
+ export { parseSeoAuditArgv, profilePageMarkup, runSeoAudit, } from './seo-audit.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cms-seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAMnB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAA+B,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EAGL,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,GAIZ,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,74 @@
1
+ import type { PlainClient } from './cma-types.js';
2
+ export interface SiteSeoConfig {
3
+ /** Site identifier for logging and logo slug fallback. */
4
+ siteKey: string;
5
+ /** When true, WebSite schema includes SearchAction (site has /search). */
6
+ enableSearchAction?: boolean;
7
+ /** Slug for CMS logo asset tagged `news-image-logo` (defaults to siteKey). */
8
+ defaultLogoSlug?: string;
9
+ /** Explicit Contentful asset ID for site logo fallback. */
10
+ defaultLogoAssetId?: string;
11
+ siteName: string;
12
+ orgName: string;
13
+ siteDescription: string;
14
+ linkedInUrl?: string;
15
+ articlesBase: string;
16
+ tagsBase: string;
17
+ peopleBase: string;
18
+ defaultTopic: string;
19
+ enablePrimaryTagPartOfSlug: boolean;
20
+ outputCsvPath: string;
21
+ /** slug → recommended description (150–160 chars) */
22
+ pageDescriptions: Record<string, string>;
23
+ /** slug → target keyword */
24
+ pageKeywords: Record<string, string>;
25
+ /** customType / articleType slug → index description */
26
+ indexDescriptions: Record<string, string>;
27
+ indexKeywords: Record<string, string>;
28
+ /** Existing schema entry IDs to reuse (if present in space) */
29
+ schemaIds?: {
30
+ organization?: string;
31
+ website?: string;
32
+ webPage?: string;
33
+ collectionPage?: string;
34
+ blogPosting?: string;
35
+ scholarlyArticle?: string;
36
+ aboutPage?: string;
37
+ contactPage?: string;
38
+ profilePage?: string;
39
+ };
40
+ }
41
+ export interface SeoAuditRow {
42
+ url: string;
43
+ contentType: string;
44
+ slug: string;
45
+ entryId: string;
46
+ status: 'draft' | 'published';
47
+ currentDescription: string;
48
+ chars: number;
49
+ recommendedDescription: string;
50
+ targetKeyword: string;
51
+ currentSchemaLinks: string;
52
+ recommendedSchemaTypes: string;
53
+ schemaAction: string;
54
+ schemaTemplateNotes: string;
55
+ flags: string;
56
+ reviewStatus: 'Approved' | 'Revise' | 'Skip';
57
+ applied: string;
58
+ }
59
+ export interface SeoAuditOptions {
60
+ apply: boolean;
61
+ /** When true, only hub pages + indexes + sample articles (5 per type). Default false = all entries. */
62
+ sampleArticlesOnly?: boolean;
63
+ /** Backfill featuredImage from hero visuals, then site logo. */
64
+ featuredImages?: boolean;
65
+ /** Skip SEO CSV/apply; run featured-image backfill only. */
66
+ featuredImagesOnly?: boolean;
67
+ }
68
+ export declare function runSeoAudit(client: PlainClient, config: SiteSeoConfig, options: SeoAuditOptions): Promise<{
69
+ rows: SeoAuditRow[];
70
+ csvPath: string;
71
+ }>;
72
+ export declare function profilePageMarkup(config: Pick<SiteSeoConfig, 'orgName'>): string;
73
+ export declare function parseSeoAuditArgv(argv: string[]): SeoAuditOptions;
74
+ //# sourceMappingURL=seo-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-audit.d.ts","sourceRoot":"","sources":["../../src/cms-seo/seo-audit.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,0BAA0B,EAAE,OAAO,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,wDAAwD;IACxD,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,+DAA+D;IAC/D,SAAS,CAAC,EAAE;QACV,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,WAAW,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,uGAAuG;IACvG,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,gEAAgE;IAChE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,4DAA4D;IAC5D,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AA4QD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAiYnD;AA8LD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,MAAM,CA6BhF;AAgND,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAQjE"}