@webx-ui/module-audit 0.2.1 → 0.3.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/api.ts","../src/messages.ts","../src/i18n.ts","../src/AuditHostPlaces.vue","../src/AuditLayout.vue","../src/AuditHostsPage.vue","../src/AuditDetails.vue","../src/AuditFixDialog.vue","../src/AuditHideDialog.vue","../src/AuditIssueList.vue","../src/AuditIssuesPage.vue","../src/AuditOverviewPage.vue","../src/resources.ts","../src/AuditPageCard.vue","../src/fields.ts","../src/AuditPagesPage.vue","../src/AuditCompareIssues.vue","../src/AuditRunsPage.vue","../src/AuditSettingsPage.vue","../src/module.ts"],"sourcesContent":["import type { AdminContext } from '@webx-ui/module-admin'\nimport type {\n AuditCheckRow,\n AuditComparison,\n AuditComparisonKind,\n AuditFixOffer,\n AuditFixResult,\n AuditHosts,\n AuditHostClass,\n AuditIgnoreRule,\n AuditIssue,\n AuditIssueQuery,\n AuditLatest,\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditPageQuery,\n AuditPageRow,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditScope,\n} from './types'\n\nexport interface AuditApi {\n /** The run that is going, the last one that finished, and whether the queue can take one. */\n latest(): Promise<AuditLatest>\n run(id: number): Promise<AuditRun>\n /** Every run, newest first — the history. */\n runs(query?: { page?: number; per_page?: number }): Promise<AuditPage<AuditRun>>\n /**\n * Queues a run; refused with 409 on a `sync` queue or while another one is going. A `urls` run\n * is a recheck of the addresses given.\n */\n start(scope: AuditScope, urls?: string[]): Promise<AuditRun>\n cancel(id: number): Promise<AuditRun>\n /** The checks of a run that found something, worst first. */\n checks(run: number, query?: AuditIssueQuery): Promise<AuditCheckRow[]>\n /** The findings of a run — of one check when `check` is given. */\n issues(run: number, query?: AuditIssueQuery): Promise<AuditPage<AuditIssue>>\n /** The crawled pages of a run under the screen's filters. */\n pages(run: number, query?: AuditPageQuery): Promise<AuditPage<AuditPageRow>>\n /** Where the browser downloads the same list as CSV, under the panel's session. */\n pagesFile(run: number, query: AuditPageQuery, columns: string[]): string\n page(run: number, id: number): Promise<AuditPageCard>\n /** The links of a page: `out` — what it points at, `in` — what points at it. */\n links(\n run: number,\n id: number,\n query?: { direction?: 'in' | 'out'; kind?: string; page?: number; per_page?: number },\n ): Promise<AuditPage<AuditLinkRow>>\n /** What a page loads, a tab of the card at a time. */\n resources(\n run: number,\n id: number,\n query: { tab: AuditResourceTab; page?: number; per_page?: number },\n ): Promise<AuditPage<AuditResourceRow>>\n /** The fixes that can close a finding now, each with what it would change. */\n fixes(run: number, issue: number): Promise<AuditFixOffer[]>\n /** Presses a fix — or, with `dryRun`, only asks again what it would change. */\n fix(run: number, issue: number, fix: string, dryRun?: boolean): Promise<AuditFixResult>\n /** Where the browser downloads one page of a run — its snapshot, findings and links. */\n pageFile(run: number, id: number): string\n /** Two runs by fingerprint; without `from`, `to` against the run it was analysed against. */\n compare(to: number, from?: number | null): Promise<AuditComparison>\n /** The findings of one kind of a comparison, of one check when given. */\n compareIssues(query: {\n to: number\n from?: number | null\n kind: AuditComparisonKind\n check?: string\n page?: number\n per_page?: number\n }): Promise<AuditPage<AuditIssue>>\n /** Every host the site points at, by class — stands first; with `host`, where it stands. */\n hosts(query?: {\n class?: AuditHostClass | null\n search?: string\n host?: string\n }): Promise<AuditHosts>\n /** The hiding rules. */\n ignores(): Promise<AuditIgnoreRule[]>\n /** Hides what a rule matches, with the reason. */\n hide(rule: { check: string; pattern: string; reason: string }): Promise<AuditIgnoreRule>\n /** How many findings of the last run a rule would hide — nothing is hidden. */\n hidePreview(rule: { check: string; pattern: string }): Promise<number>\n /** Removes a rule: its findings count again. */\n unhide(id: number): Promise<void>\n /** The section's settings, keyed as the screen names them. */\n settings(): Promise<Record<string, unknown>>\n saveSettings(values: Record<string, unknown>): Promise<Record<string, unknown>>\n}\n\n/** The query of the pages screen as the API reads it: `f[field]=op:value` for each filter. */\nexport function pageParams(query: AuditPageQuery): Record<string, string | number | undefined> {\n const params: Record<string, string | number | undefined> = {\n search: query.search || undefined,\n status: query.status || undefined,\n indexable:\n query.indexable === null || query.indexable === undefined\n ? undefined\n : query.indexable\n ? 1\n : 0,\n check: query.check || undefined,\n sort: query.sort || undefined,\n page: query.page,\n per_page: query.per_page,\n }\n\n for (const filter of query.filters ?? []) {\n params[`f[${filter.field}]`] =\n filter.value === undefined || filter.value === '' ? filter.op : `${filter.op}:${filter.value}`\n }\n\n return params\n}\n\n/** Everything under `/audit`, below the panel's API path. */\nexport function createAuditApi(admin: AdminContext): AuditApi {\n const base = `${admin.apiPath}/audit`\n const data = <T>(body: { data: T }): T => body.data\n\n /* `undefined` drops a parameter; `null` and `''` would be sent as words. */\n const filters = (query: AuditIssueQuery) => ({\n check: query.check || undefined,\n severity: query.severity || undefined,\n group: query.group || undefined,\n state: query.state || undefined,\n page: query.page,\n per_page: query.per_page,\n })\n\n return {\n latest: () => admin.http.get<{ data: AuditLatest }>(`${base}/runs/latest`).then(data),\n\n run: (id) => admin.http.get<{ data: AuditRun }>(`${base}/runs/${id}`).then(data),\n\n runs: (query = {}) =>\n admin.http\n .get<{\n data: AuditRun[]\n meta: Omit<AuditPage<AuditRun>, 'data'>\n }>(`${base}/runs`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n start: (scope, urls) =>\n admin.http\n .post<{ data: AuditRun }>(`${base}/runs`, scope === 'urls' ? { scope, urls } : { scope })\n .then(data),\n\n cancel: (id) => admin.http.post<{ data: AuditRun }>(`${base}/runs/${id}/cancel`, {}).then(data),\n\n checks: (run, query = {}) =>\n admin.http\n .get<{ data: AuditCheckRow[] }>(`${base}/runs/${run}/checks`, { query: filters(query) })\n .then(data),\n\n issues: (run, query = {}) =>\n admin.http\n .get<{\n data: AuditIssue[]\n meta: Omit<AuditPage<AuditIssue>, 'data'>\n }>(`${base}/runs/${run}/issues`, { query: filters(query) })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n pages: (run, query = {}) =>\n admin.http\n .get<{\n data: AuditPageRow[]\n meta: Omit<AuditPage<AuditPageRow>, 'data'>\n }>(`${base}/runs/${run}/pages`, { query: pageParams(query) })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n pagesFile: (run, query, columns) => {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries({\n ...pageParams(query),\n page: undefined,\n per_page: undefined,\n })) {\n if (value !== undefined) params.set(key, String(value))\n }\n\n params.set('columns', columns.join(','))\n\n return `${base}/runs/${run}/pages/export?${params.toString()}`\n },\n\n page: (run, id) =>\n admin.http.get<{ data: AuditPageCard }>(`${base}/runs/${run}/pages/${id}`).then(data),\n\n links: (run, id, query = {}) =>\n admin.http\n .get<{\n data: AuditLinkRow[]\n meta: Omit<AuditPage<AuditLinkRow>, 'data'>\n }>(`${base}/runs/${run}/pages/${id}/links`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n resources: (run, id, query) =>\n admin.http\n .get<{\n data: AuditResourceRow[]\n meta: Omit<AuditPage<AuditResourceRow>, 'data'>\n }>(`${base}/runs/${run}/pages/${id}/resources`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n fixes: (run, issue) =>\n admin.http\n .get<{ data: AuditFixOffer[] }>(`${base}/runs/${run}/issues/${issue}/fixes`)\n .then(data),\n\n fix: (run, issue, fix, dryRun = false) =>\n admin.http\n .post<{\n data: AuditFixResult\n }>(`${base}/runs/${run}/issues/${issue}/fixes/${encodeURIComponent(fix)}`, {\n dry_run: dryRun,\n })\n .then(data),\n\n pageFile: (run, id) => `${base}/runs/${run}/pages/${id}/export`,\n\n compare: (to, from) =>\n admin.http\n .get<{\n data: AuditComparison\n }>(`${base}/runs/compare`, { query: { to, from: from ?? undefined } })\n .then(data),\n\n compareIssues: (query) =>\n admin.http\n .get<{\n data: AuditIssue[]\n meta: Omit<AuditPage<AuditIssue>, 'data'>\n }>(`${base}/runs/compare/issues`, {\n query: { ...query, from: query.from ?? undefined, check: query.check || undefined },\n })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n hosts: (query = {}) =>\n admin.http\n .get<{ data: AuditHosts }>(`${base}/hosts`, {\n query: {\n class: query.class || undefined,\n search: query.search || undefined,\n host: query.host || undefined,\n },\n })\n .then(data),\n\n ignores: () => admin.http.get<{ data: AuditIgnoreRule[] }>(`${base}/ignores`).then(data),\n\n hide: (rule) => admin.http.post<{ data: AuditIgnoreRule }>(`${base}/ignores`, rule).then(data),\n\n hidePreview: (rule) =>\n admin.http\n .post<{ data: { hidden: number } }>(`${base}/ignores`, { ...rule, dry_run: true })\n .then((body) => body.data.hidden),\n\n unhide: (id) => admin.http.delete(`${base}/ignores/${id}`).then(() => undefined),\n\n settings: () =>\n admin.http\n .get<{ data: { values: Record<string, unknown> } }>(`${base}/settings`)\n .then((body) => body.data.values),\n\n saveSettings: (values) =>\n admin.http\n .put<{ data: { values: Record<string, unknown> } }>(`${base}/settings`, { values })\n .then((body) => body.data.values),\n }\n}\n","import type { Messages } from '@webx-ui/module-admin'\n\n/**\n * What this package says, in English — the same keys `webx-ui/module-audit` ships as\n * `lang/en/*.php`, so a key never reaches the screen while the dictionary is on its way. The\n * server's dictionary wins; the check texts and the details arrive translated from the server and\n * are not repeated here.\n */\nexport const auditMessages: Record<string, Messages> = {\n module: {\n title: 'Audit',\n },\n\n page: {\n overview: 'Overview',\n issues: 'Findings',\n settings: 'Settings',\n run: 'Run the audit',\n scope: 'Scope',\n 'scope-full': 'Full',\n 'scope-full-help': 'Everything the audit can check.',\n 'scope-quick': 'Quick',\n 'scope-quick-help': 'The config, the host and the database — takes seconds.',\n start: 'Start',\n started: 'The audit has started.',\n cancel: 'Cancel the run',\n never: 'No audit has been run yet.',\n 'never-help':\n 'Run the first one to see how the site looks to a visitor and to a search engine.',\n health: 'Health',\n errors: 'Errors',\n warnings: 'Warnings',\n notices: 'Notices',\n new: 'New',\n fixed: 'Fixed',\n 'health-pages': 'Pages without errors: :clean of :pages',\n 'health-site': 'Errors of the whole site: :count',\n 'health-warnings': 'Checks with warnings: :count',\n 'health-help':\n 'The share of pages without errors, minus 10 points for each error of the whole site and 2 for each check with warnings — the warnings take 20 at most.',\n 'last-run': 'Last run',\n 'base-url': 'Address',\n 'status-queued': 'Waiting in the queue',\n 'status-running': 'Running',\n 'status-done': 'Done',\n 'status-failed': 'Failed',\n 'status-cancelled': 'Cancelled',\n 'stage-probes': 'Config and host',\n 'stage-database': 'Database',\n 'stage-crawl': 'Pages',\n 'stage-analyse': 'Analysis',\n 'last-failed': 'The last run did not finish: :error',\n 'by-group': 'By group',\n 'group-config': 'Configuration',\n 'group-host': 'Host and addresses',\n 'group-hosts': 'Outgoing addresses',\n 'group-other': 'Other',\n sources: 'Content searched',\n 'sources-missing': 'Installed, but not searched:',\n 'sources-help':\n 'Besides crawling the site, the audit reads the text modules keep in the database — drafts, hidden records and fields the template never prints — and looks there for absolute addresses, such as links to a development stand. Green: modules that hand their text over. Orange: modules installed here that do not yet. Their published pages are still crawled, but their drafts and hidden fields are not searched, and a fix button cannot reach them.',\n 'sources-help-label': 'What this means',\n 'sync-queue':\n 'The queue runs jobs inside the request (sync), so the panel cannot start a run. Run php artisan webx:audit:run from the terminal or cron.',\n 'already-running': 'An audit is already running.',\n check: 'Check',\n count: 'Found',\n severity: 'Severity',\n 'severity-error': 'Error',\n 'severity-warning': 'Warning',\n 'severity-notice': 'Notice',\n 'any-severity': 'Any severity',\n 'any-group': 'Any group',\n 'any-state': 'New and persisting',\n 'state-new': 'New',\n 'state-persisting': 'Persisting',\n address: 'Address',\n empty: 'Nothing found.',\n clean: 'The last run found nothing.',\n found: 'What was found',\n why: 'Why it matters',\n fix: 'How to fix it',\n explain: 'What this check means',\n 'open-editor': 'Open in the editor',\n 'fix-button': 'Fix',\n 'fix-apply': 'Apply',\n 'fix-applied': 'Done. Run the audit again to see the finding go.',\n 'fix-none': 'Nothing left to change: no fix can close this finding now.',\n 'fix-pressed': 'Fixed — waiting for the next run',\n 'fix-changes': 'Changes',\n 'fix-before': 'Now',\n 'fix-after': 'After',\n yes: 'Yes',\n no: 'No',\n missing: 'Missing',\n pages: 'Pages',\n 'pages-progress': 'Pages crawled: :crawled of at most :limit',\n 'resources-progress':\n 'Pictures, styles, scripts and external links checked: :checked of :total',\n 'pages-none': 'No full run has crawled the site yet. Start a full audit to see every page.',\n 'pages-run': 'Full run of :date',\n 'group-indexing': 'Indexing',\n 'group-redirects': 'Redirects',\n 'group-page': 'Page',\n 'group-content': 'Content and speed',\n 'group-links': 'Links',\n 'group-images': 'Pictures',\n 'group-a11y': 'Accessibility',\n 'group-structure': 'Structure',\n columns: 'Columns',\n export: 'Export CSV',\n 'search-url': 'Search by address',\n 'any-status': 'Any answer',\n 'status-none': 'No answer',\n 'any-indexable': 'Indexable or not',\n 'indexable-yes': 'Indexable',\n 'indexable-no': 'Not indexable',\n 'any-check': 'With any findings or none',\n 'add-filter': 'Add a filter',\n 'remove-filter': 'Remove the filter',\n 'op-contains': 'contains',\n 'op-eq': 'is',\n 'op-empty': 'is empty',\n 'op-filled': 'is not empty',\n 'op-gt': 'more than',\n 'op-lt': 'less than',\n 'op-yes': 'yes',\n 'op-no': 'no',\n value: 'Value',\n 'field-url': 'Address',\n 'field-status': 'Code',\n 'field-final_status': 'Final code',\n 'field-redirect_to': 'Redirects to',\n 'field-source': 'Found through',\n 'field-depth': 'Depth',\n 'field-indexable': 'Indexable',\n 'field-issues': 'Findings',\n 'field-title': 'Title',\n 'field-description': 'Description',\n 'field-h1': 'H1',\n 'field-canonical': 'Canonical',\n 'field-robots_meta': 'Meta robots',\n 'field-x_robots_tag': 'X-Robots-Tag',\n 'field-lang': 'Language',\n 'field-content_type': 'Content type',\n 'field-bytes': 'Size, bytes',\n 'field-ttfb_ms': 'First byte, ms',\n 'field-total_ms': 'Answer, ms',\n 'field-compression': 'Compression',\n 'field-word_count': 'Words',\n 'field-links_in': 'Links in',\n 'field-links_out_internal': 'Internal links out',\n 'field-links_out_external': 'External links out',\n 'field-images': 'Pictures',\n 'field-images_without_alt': 'Pictures without alt',\n 'field-in_sitemap': 'In the sitemap',\n 'field-in_registry': 'In the registry',\n 'field-blocked_by_robots': 'Closed in robots.txt',\n 'source-home': 'Home page',\n 'source-sitemap': 'Sitemap',\n 'source-registry': 'Address registry',\n 'source-link': 'Link',\n 'card-overview': 'Overview',\n 'card-issues': 'Problems',\n 'card-incoming': 'Incoming',\n 'card-outgoing': 'Outgoing',\n 'card-images': 'Pictures',\n 'card-css': 'CSS',\n 'card-js': 'JS',\n 'card-microdata': 'Structured data',\n response: 'Response',\n headers: 'Headers',\n markup: 'Markup',\n 'open-page': 'Open the page',\n 'no-issues': 'No problems on this page.',\n 'no-links': 'No links.',\n kind: 'Kind',\n anchor: 'Anchor',\n host: 'Host',\n size: 'Size',\n cache: 'Cache',\n alt: 'Alt',\n 'not-checked': 'Not checked',\n 'no-resources': 'Nothing of this kind on the page.',\n 'no-json-ld': 'The page has no structured data.',\n 'jsonld-block': 'Block :number',\n 'jsonld-error': 'Does not parse:',\n 'jsonld-required': 'Required fields missing:',\n 'jsonld-recommended': 'Recommended fields missing:',\n 'jsonld-complete': 'Every field search engines ask for is there.',\n 'host-own': 'Own',\n 'host-own_mirror': 'Other mirror',\n 'host-dev': 'Stand',\n 'host-external': 'External',\n error: 'Error',\n 'source-list': 'Recheck list',\n hosts: 'Outgoing',\n runs: 'Runs',\n 'scope-urls': 'Recheck',\n 'urls-foreign': 'None of these addresses is on the audited site.',\n 'state-hidden': 'Hidden',\n hide: 'Hide',\n 'hide-title': 'Hide this finding',\n 'hide-help':\n 'Hidden findings stop counting, in this run and in every later one. Nothing is deleted: the hidden list shows them again.',\n 'hide-pattern': 'Addresses',\n 'hide-pattern-help':\n 'This address, or a mask of them: * is a stretch without a slash, ** one with slashes (/search/**). Empty hides every finding of the check.',\n 'hide-reason': 'Why it is all right',\n 'hide-count': 'Findings of the last run it would hide: :count',\n 'hidden-done': 'Hidden.',\n 'hidden-reason': 'Hidden: :reason',\n 'hidden-by': 'Hidden by :who: :reason',\n unhide: 'Show again',\n unhidden: 'Shown again.',\n recheck: 'Recheck',\n 'recheck-running': 'Rechecking the page…',\n 'recheck-fixed': 'Fixed since the last full run: :count',\n 'recheck-new': 'New since the last full run: :count',\n 'recheck-compare': 'Compare the runs',\n 'export-page': 'Export',\n 'runs-empty': 'No runs yet.',\n 'run-id': 'Run',\n status: 'Status',\n 'started-at': 'Started',\n 'started-by': 'Started by',\n 'by-schedule': 'Schedule',\n 'by-mcp': 'Agent',\n 'by-console': 'Console',\n 'by-person': 'Administrator',\n compare: 'Compare',\n 'compare-help':\n 'Pick two runs: what the later one found that the earlier did not, what both found, and what is gone.',\n 'compare-from': 'Earlier run',\n 'compare-to': 'Later run',\n 'compare-none': 'Both runs found the same.',\n 'compare-scopes':\n 'The runs differ in scope: only the checks the later run ran can count as fixed.',\n 'kind-new': 'New',\n 'kind-persisting': 'Persisting',\n 'kind-fixed': 'Fixed',\n 'hosts-empty': 'No run has seen a link or an address in the database yet.',\n 'search-host': 'Search by host',\n 'any-class': 'Any class',\n links: 'Links',\n fields: 'Fields in the database',\n broken: 'Broken',\n 'first-seen': 'First seen',\n 'host-pages': 'On pages',\n 'host-fields': 'In the database',\n record: 'Record',\n field: 'Field',\n unpublished: 'Not published',\n save: 'Save',\n saved: 'Saved.',\n dismiss: 'Cancel',\n 'view-full': 'View full size',\n },\n}\n","import { useAdmin } from '@webx-ui/module-admin'\nimport { auditMessages } from './messages'\n\nconst seeded = new WeakSet<object>()\n\n/** Puts this package's English under the panel's dictionary, once per panel. */\nexport function useAuditMessages(): void {\n try {\n const { i18n } = useAdmin()\n\n if (!seeded.has(i18n)) {\n i18n.defaults('webx-audit', auditMessages)\n seeded.add(i18n)\n }\n } catch {\n // Outside a panel there is no dictionary to seed, and `useTranslate` falls back on its own.\n }\n}\n","<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxLink, WxSkeleton, WxText } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditHosts } from './types'\n\n/**\n * Where one host stands, under its row on «Outgoing»: the pages that link to it with the anchor\n * and what it answered, and the fields of the database that hold it, with «Open in the editor».\n * Fifty of each, broken links first — enough to see the pattern, and the findings list the rest.\n */\nconst props = defineProps<{ host: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\nconst router = useRouter()\n\nconst places = ref<AuditHosts | null>(null)\nconst failure = ref<string | null>(null)\n\n/** What the row's «Broken» counts: an error, or no answer at all (0). */\nconst broken = (status: number | null | undefined) =>\n status !== null && status !== undefined && (status >= 400 || status === 0)\n\nonMounted(async () => {\n try {\n places.value = await api.hosts({ host: props.host })\n } catch (error) {\n failure.value = message(error)\n }\n})\n</script>\n\n<template>\n <div class=\"wx-audit-places\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!places\" :rows=\"2\" />\n\n <template v-else>\n <section v-if=\"places.pages?.length\" class=\"wx-audit-places__group\">\n <wx-text size=\"sm\" weight=\"semibold\">{{ t('page.host-pages') }}</wx-text>\n <div v-for=\"(place, index) in places.pages\" :key=\"index\" class=\"wx-audit-places__row\">\n <wx-link :href=\"place.page\" target=\"_blank\" class=\"wx-audit-places__url\">{{\n place.page\n }}</wx-link>\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-places__url\"\n >{{ place.kind }} → {{ place.url }}</wx-text\n >\n <wx-text v-if=\"place.anchor\" size=\"sm\">«{{ place.anchor }}»</wx-text>\n <wx-badge v-if=\"broken(place.status)\" type=\"danger\" size=\"sm\">{{\n place.status || t('page.status-none')\n }}</wx-badge>\n </div>\n </section>\n\n <section v-if=\"places.fields?.length\" class=\"wx-audit-places__group\">\n <wx-text size=\"sm\" weight=\"semibold\">{{ t('page.host-fields') }}</wx-text>\n <div v-for=\"(field, index) in places.fields\" :key=\"index\" class=\"wx-audit-places__row\">\n <wx-text size=\"sm\">{{ field.record_label }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\"\n >{{ field.source }} · {{ field.field\n }}{{ field.locale ? ` · ${field.locale}` : '' }}</wx-text\n >\n <wx-badge v-if=\"!field.published\" size=\"sm\">{{ t('page.unpublished') }}</wx-badge>\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-places__url\">{{ field.url }}</wx-text>\n <wx-button\n v-if=\"field.edit_url\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n @click=\"router.push(field.edit_url)\"\n >{{ t('page.open-editor') }}</wx-button\n >\n </div>\n </section>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-places {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-places__group {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-places__row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-4) var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-places__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useAdmin, useTranslate, WxListScreen, type ScreenAction } from '@webx-ui/module-admin'\nimport type { TabItem, TabValue } from '@webx-ui/core'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The head of the section: its name, its views — the overview, the findings, the pages, the\n * hosts the site points at and the runs — and the way to the section's own settings.\n */\n/*\n * `card` has its default here and not as `?? true` below: Vue turns a Boolean prop nobody passed\n * into `false`, so the coalescing never fired and every table stood without its card.\n */\nconst props = withDefaults(\n defineProps<{\n base: string\n current: 'overview' | 'issues' | 'pages' | 'hosts' | 'runs' | 'settings'\n /** A card around the slot — the tables want one, the overview draws its own. */\n card?: boolean\n }>(),\n { card: true },\n)\n\ndefineSlots<{ default?: () => unknown }>()\n\nconst context = useAdmin()\nconst router = useRouter()\nconst route = useRoute()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst title = computed(\n () =>\n context.state.manifest?.modules.find((module) => module.id === 'audit')?.title ??\n t('module.title'),\n)\n\nconst views = computed<TabItem[]>(() => [\n { value: 'overview', label: t('page.overview') },\n { value: 'issues', label: t('page.issues') },\n { value: 'pages', label: t('page.pages') },\n { value: 'hosts', label: t('page.hosts') },\n { value: 'runs', label: t('page.runs') },\n])\n\n/* The settings are a view of their own, out of the tabs: opened now and then, not every day. */\nconst actions = computed<ScreenAction[]>(() =>\n props.current === 'settings'\n ? []\n : [\n {\n key: 'settings',\n label: t('page.settings'),\n icon: 'settings',\n run: () => void router.push(`${props.base}/settings`),\n },\n ],\n)\n\nconst where = computed<TabValue>({\n /* The settings belong to no tab; the overview's stays lit as the way back. */\n get: () => (props.current === 'settings' ? 'overview' : props.current),\n set: (next) => {\n const path = next === 'overview' ? props.base : `${props.base}/${String(next)}`\n\n if (path !== route.path) void router.push(path)\n },\n})\n</script>\n\n<template>\n <wx-list-screen\n v-model:view=\"where\"\n :title=\"title\"\n :views=\"views\"\n :actions=\"actions\"\n :card=\"props.card\"\n >\n <slot />\n </wx-list-screen>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type RowKey,\n type SelectValue,\n type TableColumn,\n} from '@webx-ui/core'\nimport AuditHostPlaces from './AuditHostPlaces.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditHostClass, AuditHostRow, AuditHosts } from './types'\n\n/**\n * «Outgoing» (§8): every host the site points at — in the pages of the last full run and in the\n * fields of the database — by class, development stands on top and in red. A row opens into\n * where the host stands: the pages with their anchors, the records with the field and the way to\n * the editor.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst answer = ref<AuditHosts | null>(null)\nconst loading = ref(false)\nconst search = ref('')\nconst hostClass = ref<AuditHostClass | null>(null)\nconst expanded = ref<RowKey[]>([])\n\nconst classes: Record<AuditHostClass, BadgeType> = {\n dev: 'danger',\n own_mirror: 'warning',\n external: 'info',\n own: 'success',\n}\n\nconst columns = computed<TableColumn<AuditHostRow>[]>(() => [\n { key: 'host', label: t('page.host'), minWidth: 220 },\n { key: 'links', label: t('page.links'), width: 90, align: 'right' },\n { key: 'pages', label: t('page.pages'), width: 90, align: 'right', hideBelow: 560 },\n { key: 'broken', label: t('page.broken'), width: 100, align: 'right', hideBelow: 640 },\n { key: 'fields', label: t('page.fields'), width: 120, align: 'right' },\n { key: 'first_seen', label: t('page.first-seen'), minWidth: 140, hideBelow: 760 },\n])\n\nconst classOptions = computed(() =>\n (Object.keys(classes) as AuditHostClass[]).map((value) => ({\n value,\n label: `${t(`page.host-${value}`)}${answer.value?.classes[value] ? ` · ${answer.value.classes[value]}` : ''}`,\n })),\n)\n\nfunction pick(value: SelectValue | SelectValue[] | null | undefined): AuditHostClass | null {\n return typeof value === 'string' && value in classes ? (value as AuditHostClass) : null\n}\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n answer.value = await api.hosts({ class: hostClass.value, search: search.value })\n expanded.value = []\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nwatch([hostClass, search], () => void load())\n\nonMounted(load)\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"hosts\">\n <wx-table\n v-model:expanded=\"expanded\"\n v-model:search=\"search\"\n :data=\"answer?.hosts ?? []\"\n :columns=\"columns\"\n row-key=\"host\"\n expandable\n flush\n searchable\n :search-placeholder=\"t('page.search-host')\"\n :loading=\"loading\"\n :filters-count=\"hostClass ? 1 : 0\"\n :filters-label=\"panel('filters.title')\"\n :row-class=\"(row: AuditHostRow) => (row.class === 'dev' ? 'is-stand' : undefined)\"\n :empty-text=\"t('page.hosts-empty')\"\n >\n <template #filters>\n <wx-select\n :model-value=\"hostClass\"\n :options=\"classOptions\"\n :placeholder=\"t('page.any-class')\"\n clearable\n @update:model-value=\"hostClass = pick($event)\"\n />\n </template>\n\n <template #cell-host=\"{ row }\">\n <span class=\"wx-audit-hosts__host\">\n <wx-badge :type=\"classes[row.class]\" size=\"sm\">{{\n t(`page.host-${row.class}`)\n }}</wx-badge>\n <wx-text size=\"sm\" :tone=\"row.class === 'dev' ? 'danger' : undefined\" weight=\"medium\">{{\n row.host\n }}</wx-text>\n </span>\n </template>\n <template #cell-broken=\"{ row }\">\n <wx-text size=\"sm\" :tone=\"row.broken ? 'danger' : 'muted'\">{{ row.broken }}</wx-text>\n </template>\n <template #cell-fields=\"{ row }\">\n <wx-text size=\"sm\" :tone=\"row.fields && row.class === 'dev' ? 'danger' : undefined\">{{\n row.fields\n }}</wx-text>\n </template>\n <template #cell-first_seen=\"{ row }\">\n <wx-date v-if=\"row.first_seen\" :value=\"row.first_seen\" />\n </template>\n\n <template #expanded=\"{ row }\">\n <audit-host-places :host=\"row.host\" />\n </template>\n </wx-table>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-hosts__host {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n/* A stand is the one class that is always a mistake: a red edge, like an error in a list. */\n:deep(.is-stand > td:first-child) {\n box-shadow: inset 3px 0 0 var(--wx-color-danger);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useRouter } from 'vue-router'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxLink, WxText, type BadgeType } from '@webx-ui/core'\nimport { useAuditMessages } from './i18n'\nimport type { AuditDetails, AuditDetailsColumn } from './types'\n\n/**\n * The expansion of a finding, for every check alike (§4 of the spec): a summary line and, when\n * the check gave one, a table whose cells are drawn by their type — an address opens, a code is\n * coloured, a missing value is said in red, an editor link goes to the record in the panel, and\n * markup quoted from the page is shown as code.\n */\nconst props = defineProps<{ details: AuditDetails }>()\n\nconst router = useRouter()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nfunction statusType(value: unknown): BadgeType {\n const code = Number(value)\n\n if (code >= 500 || code === 0) return 'danger'\n if (code >= 400) return 'warning'\n if (code >= 300) return 'info'\n\n return 'success'\n}\n\nfunction cell(row: Record<string, unknown>, column: AuditDetailsColumn): unknown {\n return row[column.key]\n}\n\n/** Yes, no — or nothing, when the check could not tell (the other page was not crawled). */\nfunction yesNo(value: unknown): string {\n if (value === null || value === undefined) return ''\n\n return value ? t('page.yes') : t('page.no')\n}\n\nfunction text(value: unknown): string {\n return value === null || value === undefined ? '' : String(value)\n}\n</script>\n\n<template>\n <div class=\"wx-audit-details\">\n <wx-text v-if=\"props.details.summary\" size=\"sm\">{{ props.details.summary }}</wx-text>\n\n <div\n v-if=\"props.details.table && props.details.table.rows.length\"\n class=\"wx-audit-details__scroll\"\n >\n <table class=\"wx-audit-details__table\">\n <thead>\n <tr>\n <th v-for=\"column in props.details.table.columns\" :key=\"column.key\">\n {{ column.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, index) in props.details.table.rows\" :key=\"index\">\n <td v-for=\"column in props.details.table.columns\" :key=\"column.key\">\n <template v-if=\"column.type === 'url' && text(cell(row, column))\">\n <wx-link\n :href=\"text(cell(row, column))\"\n target=\"_blank\"\n class=\"wx-audit-details__url\"\n >{{ text(cell(row, column)) }}</wx-link\n >\n </template>\n <wx-badge\n v-else-if=\"column.type === 'status' && cell(row, column) !== null\"\n :type=\"statusType(cell(row, column))\"\n size=\"sm\"\n >{{ text(cell(row, column)) }}</wx-badge\n >\n <template v-else-if=\"column.type === 'bool'\">\n {{ yesNo(cell(row, column)) }}\n </template>\n <wx-text\n v-else-if=\"column.type === 'missing' && !text(cell(row, column))\"\n size=\"sm\"\n tone=\"danger\"\n >{{ t('page.missing') }}</wx-text\n >\n <wx-button\n v-else-if=\"column.type === 'edit' && text(cell(row, column))\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n @click=\"router.push(text(cell(row, column)))\"\n >{{ t('page.open-editor') }}</wx-button\n >\n <code v-else-if=\"column.type === 'code'\" class=\"wx-audit-details__code\">{{\n text(cell(row, column))\n }}</code>\n <template v-else>{{ text(cell(row, column)) }}</template>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-details {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n/* A wide table scrolls inside itself rather than pushing the panel sideways on a phone. */\n.wx-audit-details__scroll {\n overflow-x: auto;\n}\n\n.wx-audit-details__table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-details__table th {\n color: var(--wx-text-muted);\n font-weight: normal;\n text-align: left;\n white-space: nowrap;\n}\n\n.wx-audit-details__table th,\n.wx-audit-details__table td {\n padding: var(--wx-space-4) var(--wx-space-8);\n border-bottom: 1px solid var(--wx-border-muted);\n vertical-align: top;\n}\n\n/* Quoted markup is one long line more often than not; it wraps anywhere rather than scrolling. */\n.wx-audit-details__code {\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n\n.wx-audit-details__url {\n overflow-wrap: anywhere;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxDialog, WxSkeleton, WxText, toast } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditFixOffer, AuditIssue } from './types'\n\n/**\n * The fix button's dialog (§8, decision 4): the fixes that can close one finding, each with what\n * it would change — the records and fields with their counts, or a setting before and after —\n * and \"Apply\" under each. Nothing changes until it is pressed; the finding then waits for the\n * next run, which is the only thing that says it is gone.\n */\nconst props = defineProps<{ run: number; issue: AuditIssue }>()\nconst emit = defineEmits<{ fixed: [fix: string] }>()\nconst open = defineModel<boolean>('open', { default: false })\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\nconst router = useRouter()\n\nconst offers = ref<AuditFixOffer[] | null>(null)\nconst failure = ref<string | null>(null)\nconst applying = ref<string | null>(null)\n\nasync function load(): Promise<void> {\n offers.value = null\n failure.value = null\n\n try {\n offers.value = await api.fixes(props.run, props.issue.id)\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nasync function apply(offer: AuditFixOffer): Promise<void> {\n applying.value = offer.id\n\n try {\n await api.fix(props.run, props.issue.id, offer.id)\n toast.success(t('page.fix-applied'))\n emit('fixed', offer.id)\n open.value = false\n } catch (error) {\n toast.danger(message(error))\n } finally {\n applying.value = null\n }\n}\n\nfunction edit(url: string): void {\n open.value = false\n void router.push(url)\n}\n\n// Immediate: the list mounts the dialog already open, the first time a button is pressed.\nwatch(\n [open, () => props.issue.id],\n ([now]) => {\n if (now) void load()\n },\n { immediate: true },\n)\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('page.fix-button')\" :width=\"640\">\n <div class=\"wx-audit-fix\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!offers\" :rows=\"3\" />\n <wx-text v-else-if=\"offers.length === 0\" size=\"sm\" tone=\"muted\">{{\n t('page.fix-none')\n }}</wx-text>\n\n <section v-for=\"offer in offers ?? []\" :key=\"offer.id\" class=\"wx-audit-fix__offer\">\n <wx-text weight=\"semibold\">{{ offer.title }}</wx-text>\n <wx-text v-if=\"offer.description\" size=\"sm\" tone=\"muted\">{{ offer.description }}</wx-text>\n\n <table class=\"wx-audit-fix__changes\">\n <thead>\n <tr>\n <th>{{ t('page.fix-changes') }}</th>\n <th>{{ t('page.fix-before') }}</th>\n <th>{{ t('page.fix-after') }}</th>\n <th />\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(change, index) in offer.changes\" :key=\"index\">\n <td>\n <div>{{ change.label }}</div>\n <div v-if=\"change.field\" class=\"wx-audit-fix__field\">{{ change.field }}</div>\n </td>\n <td class=\"wx-audit-fix__value\">\n {{ change.before ?? '' }}\n <span v-if=\"change.count\" class=\"wx-audit-fix__count\">× {{ change.count }}</span>\n </td>\n <td class=\"wx-audit-fix__value\">{{ change.after ?? '' }}</td>\n <td>\n <wx-button\n v-if=\"change.edit_url\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n :aria-label=\"t('page.open-editor')\"\n @click=\"edit(change.edit_url)\"\n />\n </td>\n </tr>\n </tbody>\n </table>\n\n <wx-text v-if=\"offer.note\" size=\"sm\" tone=\"muted\">{{ offer.note }}</wx-text>\n\n <div class=\"wx-audit-fix__actions\">\n <wx-button\n type=\"primary\"\n size=\"sm\"\n :loading=\"applying === offer.id\"\n :disabled=\"applying !== null\"\n @click=\"apply(offer)\"\n >{{ t('page.fix-apply') }}</wx-button\n >\n </div>\n </section>\n </div>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-audit-fix {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-fix__offer {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-fix__changes {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-fix__changes th {\n padding: var(--wx-space-4) var(--wx-space-8);\n color: var(--wx-text-muted);\n font-weight: var(--wx-font-weight-medium);\n text-align: start;\n border-bottom: 1px solid var(--wx-border-default);\n}\n\n.wx-audit-fix__changes td {\n padding: var(--wx-space-6) var(--wx-space-8);\n vertical-align: top;\n border-bottom: 1px solid var(--wx-border-default);\n overflow-wrap: anywhere;\n}\n\n.wx-audit-fix__field,\n.wx-audit-fix__count {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-fix__value {\n white-space: pre-line;\n}\n\n.wx-audit-fix__actions {\n display: flex;\n justify-content: flex-end;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxDialog, WxFormItem, WxInput, WxText, WxTextarea, toast } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIgnoreRule, AuditIssue } from './types'\n\n/**\n * «Hide» on a finding (decision 9): which addresses — this one, a mask of them, or the whole\n * check — and why. While the mask is typed the dialog says how many findings of the last run it\n * would hide; nothing is hidden until the button is pressed, and nothing is ever deleted.\n */\nconst props = defineProps<{ issue: AuditIssue; title: string }>()\nconst emit = defineEmits<{ hidden: [rule: AuditIgnoreRule] }>()\nconst open = defineModel<boolean>('open', { default: false })\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst pattern = ref('')\nconst reason = ref('')\nconst count = ref<number | null>(null)\nconst saving = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\n/* The path, not the whole address: a mask of the path hides it on every mirror a run opened. */\nfunction pathOf(url: string | null): string {\n if (!url) return ''\n\n try {\n const parsed = new URL(url)\n\n return parsed.pathname + parsed.search\n } catch {\n return url\n }\n}\n\nconst ready = computed(() => reason.value.trim() !== '')\n\nfunction preview(): void {\n clearTimeout(timer)\n timer = setTimeout(async () => {\n try {\n count.value = await api.hidePreview({ check: props.issue.check, pattern: pattern.value })\n } catch {\n count.value = null\n }\n }, 300)\n}\n\nasync function hide(): Promise<void> {\n saving.value = true\n\n try {\n const rule = await api.hide({\n check: props.issue.check,\n pattern: pattern.value,\n reason: reason.value,\n })\n\n toast.success(t('page.hidden-done'))\n emit('hidden', rule)\n open.value = false\n } catch (error) {\n toast.danger(message(error))\n } finally {\n saving.value = false\n }\n}\n\nwatch(\n [open, () => props.issue.id],\n ([now]) => {\n if (!now) return\n\n pattern.value = pathOf(props.issue.url)\n reason.value = ''\n count.value = null\n preview()\n },\n { immediate: true },\n)\n\nwatch(pattern, () => {\n if (open.value) preview()\n})\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('page.hide-title')\" :width=\"560\">\n <div class=\"wx-audit-hide\">\n <wx-text weight=\"semibold\">{{ props.title }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\">{{ t('page.hide-help') }}</wx-text>\n\n <wx-form-item :label=\"t('page.hide-pattern')\" :help=\"t('page.hide-pattern-help')\">\n <wx-input v-model=\"pattern\" placeholder=\"/search/**\" />\n </wx-form-item>\n\n <wx-form-item :label=\"t('page.hide-reason')\" required>\n <wx-textarea v-model=\"reason\" :rows=\"3\" />\n </wx-form-item>\n\n <wx-text v-if=\"count !== null\" size=\"sm\" tone=\"muted\">{{\n t('page.hide-count', { count })\n }}</wx-text>\n </div>\n\n <template #footer>\n <wx-button @click=\"open = false\">{{ t('page.dismiss') }}</wx-button>\n <wx-button type=\"primary\" :loading=\"saving\" :disabled=\"!ready\" @click=\"hide\">{{\n t('page.hide')\n }}</wx-button>\n </template>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-audit-hide {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { toast, WxBadge, WxButton, WxLink, WxSkeleton, WxText } from '@webx-ui/core'\nimport AuditDetails from './AuditDetails.vue'\nimport AuditFixDialog from './AuditFixDialog.vue'\nimport AuditHideDialog from './AuditHideDialog.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIgnoreRule, AuditIssue, AuditIssueQuery } from './types'\n\n/**\n * The addresses of one check, under its row in the findings table: loaded when the row opens,\n * fifty at a time. A check that has fixes gets a button on each address; the dialog shows what\n * it would change before anything does. «Hide» asks for the reason; on the list of hidden ones\n * each says why, and «Show again» removes the rule.\n */\nconst props = defineProps<{\n run: number\n query: AuditIssueQuery\n fixable?: boolean\n /** The check's title, for the hiding dialog. */\n title?: string\n}>()\n\nconst emit = defineEmits<{ changed: [] }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\n// A boolean, not a computed: the permissions do not change while the screen is open.\nconst can = context.can('audit.manage')\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst issues = ref<AuditIssue[] | null>(null)\nconst more = ref(false)\nconst page = ref(1)\nconst failure = ref<string | null>(null)\nconst fixing = ref<AuditIssue | null>(null)\nconst dialog = ref(false)\nconst hiding = ref<AuditIssue | null>(null)\nconst hideDialog = ref(false)\n\nfunction hide(issue: AuditIssue): void {\n hiding.value = issue\n hideDialog.value = true\n}\n\n/* What the rule hid leaves this list at once; the table above counts again. */\nfunction hidden(rule: AuditIgnoreRule): void {\n if (issues.value && !rule.pattern) issues.value = []\n else if (issues.value && hiding.value)\n issues.value = issues.value.filter((one) => one.id !== hiding.value?.id)\n\n emit('changed')\n}\n\nasync function unhide(issue: AuditIssue): Promise<void> {\n if (!issue.ignore) return\n\n try {\n await api.unhide(issue.ignore.id)\n toast.success(t('page.unhidden'))\n emit('changed')\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction why(issue: AuditIssue): string {\n const rule = issue.ignore\n\n if (!rule) return ''\n\n return rule.created_by\n ? t('page.hidden-by', { who: rule.created_by, reason: rule.reason })\n : t('page.hidden-reason', { reason: rule.reason })\n}\n\nfunction fix(issue: AuditIssue): void {\n fixing.value = issue\n dialog.value = true\n}\n\nfunction fixed(id: string): void {\n if (fixing.value) fixing.value.fixed_with = id\n}\n\nasync function load(next = 1): Promise<void> {\n try {\n const answer = await api.issues(props.run, { ...props.query, page: next, per_page: 50 })\n\n issues.value = next === 1 ? answer.data : [...(issues.value ?? []), ...answer.data]\n page.value = answer.current_page\n more.value = answer.current_page < answer.last_page\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nonMounted(() => load())\n</script>\n\n<template>\n <div class=\"wx-audit-issues\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!issues\" :rows=\"2\" />\n\n <template v-else>\n <div v-for=\"issue in issues\" :key=\"issue.id\" class=\"wx-audit-issues__item\">\n <div class=\"wx-audit-issues__head\">\n <wx-link\n v-if=\"issue.url\"\n :href=\"issue.url\"\n target=\"_blank\"\n class=\"wx-audit-issues__url\"\n >{{ issue.url }}</wx-link\n >\n <wx-badge v-if=\"issue.state === 'new'\" type=\"primary\" size=\"sm\">{{\n t('page.state-new')\n }}</wx-badge>\n <wx-badge v-if=\"issue.fixed_with\" type=\"success\" size=\"sm\">{{\n t('page.fix-pressed')\n }}</wx-badge>\n <wx-button\n v-else-if=\"fixable && can && !issue.ignored\"\n size=\"sm\"\n variant=\"outline\"\n icon=\"check\"\n class=\"wx-audit-issues__fix\"\n @click=\"fix(issue)\"\n >{{ t('page.fix-button') }}</wx-button\n >\n <wx-button\n v-if=\"can && issue.ignored && issue.ignore\"\n size=\"sm\"\n variant=\"text\"\n icon=\"eye\"\n class=\"wx-audit-issues__end\"\n @click=\"unhide(issue)\"\n >{{ t('page.unhide') }}</wx-button\n >\n <wx-button\n v-else-if=\"can && !issue.ignored\"\n size=\"sm\"\n variant=\"text\"\n icon=\"eye-off\"\n :class=\"{ 'wx-audit-issues__end': !fixable || issue.fixed_with }\"\n @click=\"hide(issue)\"\n >{{ t('page.hide') }}</wx-button\n >\n </div>\n <wx-text v-if=\"issue.ignore\" size=\"sm\" tone=\"muted\">{{ why(issue) }}</wx-text>\n <audit-details :details=\"issue.details\" />\n </div>\n\n <wx-button v-if=\"more\" size=\"sm\" variant=\"text\" @click=\"load(page + 1)\">…</wx-button>\n </template>\n\n <audit-fix-dialog\n v-if=\"fixing\"\n v-model:open=\"dialog\"\n :run=\"run\"\n :issue=\"fixing\"\n @fixed=\"fixed\"\n />\n\n <audit-hide-dialog\n v-if=\"hiding\"\n v-model:open=\"hideDialog\"\n :issue=\"hiding\"\n :title=\"props.title ?? hiding.check\"\n @hidden=\"hidden\"\n />\n </div>\n</template>\n\n<style scoped>\n.wx-audit-issues {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-issues__item {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n.wx-audit-issues__head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-issues__fix,\n.wx-audit-issues__end {\n margin-inline-start: auto;\n}\n\n.wx-audit-issues__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxButton,\n WxPopover,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type SelectValue,\n type TableColumn,\n} from '@webx-ui/core'\nimport AuditIssueList from './AuditIssueList.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditCheckRow, AuditSeverity } from './types'\n\n/**\n * The findings of the last finished run (§8): one row per check, worst first; a row opens into\n * its addresses. «Hidden» in the state filter lists what the rules hide, each with its reason. The «?» beside a check says what was found, why it matters and how to fix it —\n * the three texts every check carries.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst run = ref<number | null>(null)\nconst checks = ref<AuditCheckRow[] | null>(null)\nconst loading = ref(false)\nconst expanded = ref<(string | number)[]>([])\n\nconst severity = ref<AuditSeverity | null>(null)\nconst group = ref<string | null>(null)\ntype State = 'new' | 'persisting' | 'hidden'\n\nconst state = ref<State | null>(null)\n\nconst query = computed(() => ({ severity: severity.value, group: group.value, state: state.value }))\nconst filtersCount = computed(\n () => [severity.value, group.value, state.value].filter(Boolean).length,\n)\n\nconst types: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst columns = computed<TableColumn<AuditCheckRow>[]>(() => [\n { key: 'severity', label: t('page.severity'), width: 130 },\n { key: 'title', label: t('page.check') },\n { key: 'count', label: t('page.count'), width: 110, align: 'right' },\n])\n\nconst severityOptions = computed(() =>\n (['error', 'warning', 'notice'] as const).map((value) => ({\n value,\n label: t(`page.severity-${value}`),\n })),\n)\n\nconst groupOptions = computed(() =>\n [\n 'config',\n 'host',\n 'hosts',\n 'indexing',\n 'page',\n 'content',\n 'links',\n 'images',\n 'a11y',\n 'structure',\n ].map((value) => ({ value, label: t(`page.group-${value}`) })),\n)\n\nconst stateOptions = computed(() =>\n (['new', 'persisting', 'hidden'] as const).map((value) => ({\n value,\n label: t(`page.state-${value}`),\n })),\n)\n\n/* The selects hand back `string | number`; the filters only ever hold the values offered. */\nfunction pick<T extends string>(value: SelectValue | SelectValue[] | null | undefined): T | null {\n return typeof value === 'string' && value !== '' ? (value as T) : null\n}\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n if (run.value === null) {\n run.value = (await api.latest()).done?.id ?? null\n }\n\n checks.value = run.value === null ? [] : await api.checks(run.value, query.value)\n expanded.value = []\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nwatch(query, () => void load())\n\nonMounted(load)\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"issues\">\n <wx-table\n v-model:expanded=\"expanded\"\n :data=\"checks ?? []\"\n :columns=\"columns\"\n row-key=\"id\"\n expandable\n flush\n :loading=\"loading\"\n :filters-count=\"filtersCount\"\n :filters-label=\"panel('filters.title')\"\n :empty-text=\"run === null ? t('page.never') : t('page.empty')\"\n >\n <template #filters>\n <div class=\"wx-audit-findings__filters\">\n <wx-select\n :model-value=\"severity\"\n :options=\"severityOptions\"\n :placeholder=\"t('page.any-severity')\"\n clearable\n @update:model-value=\"severity = pick<AuditSeverity>($event)\"\n />\n <wx-select\n :model-value=\"group\"\n :options=\"groupOptions\"\n :placeholder=\"t('page.any-group')\"\n clearable\n @update:model-value=\"group = pick($event)\"\n />\n <wx-select\n :model-value=\"state\"\n :options=\"stateOptions\"\n :placeholder=\"t('page.any-state')\"\n clearable\n @update:model-value=\"state = pick<State>($event)\"\n />\n </div>\n </template>\n\n <template #cell-severity=\"{ row }\">\n <wx-badge :type=\"types[row.severity]\" dot>{{\n t(`page.severity-${row.severity}`)\n }}</wx-badge>\n </template>\n\n <template #cell-title=\"{ row }\">\n <span class=\"wx-audit-findings__title\">\n <wx-text size=\"sm\">{{ row.title }}</wx-text>\n <wx-badge v-if=\"row.new > 0\" type=\"primary\" size=\"sm\">{{ t('page.state-new') }}</wx-badge>\n <wx-popover :title=\"row.title\" width=\"360\">\n <template #trigger>\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"question\"\n :aria-label=\"t('page.explain')\"\n @click.stop\n />\n </template>\n <dl class=\"wx-audit-findings__texts\">\n <dt>{{ t('page.found') }}</dt>\n <dd>{{ row.found }}</dd>\n <dt>{{ t('page.why') }}</dt>\n <dd>{{ row.why }}</dd>\n <dt>{{ t('page.fix') }}</dt>\n <dd>{{ row.fix }}</dd>\n </dl>\n </wx-popover>\n </span>\n </template>\n\n <template #expanded=\"{ row }\">\n <audit-issue-list\n v-if=\"run !== null\"\n :run=\"run\"\n :query=\"{ ...query, check: row.id }\"\n :fixable=\"(row.fixes ?? []).length > 0\"\n :title=\"row.title\"\n @changed=\"load\"\n />\n </template>\n </wx-table>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-findings__filters {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-findings__title {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-findings__texts {\n display: grid;\n gap: var(--wx-space-4);\n margin: 0;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-findings__texts dt {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-findings__texts dd {\n margin: 0 0 var(--wx-space-8);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxButton,\n WxCard,\n WxEmpty,\n WxPopover,\n WxProgress,\n WxSegmented,\n WxSkeleton,\n WxStatistic,\n WxText,\n type ProgressStatus,\n} from '@webx-ui/core'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditLatest, AuditRun, AuditScope, AuditSeverity } from './types'\n\n/**\n * The last run at a glance (§8): health and what it is made of, the counts by severity and by\n * group, what is new and what got fixed since the run before, and the button that starts the next one. While a run is\n * going the page asks for it every couple of seconds and shows the stage it is in.\n */\nconst props = defineProps<{ base: string }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst POLL_MS = 2000\n\nconst latest = ref<AuditLatest | null>(null)\nconst scope = ref<AuditScope>('quick')\nconst starting = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nconst canRun = context.can('audit.run') || context.can('audit.manage')\n\nconst active = computed(() => latest.value?.active ?? null)\nconst done = computed(() => latest.value?.done ?? null)\nconst counts = computed(() => done.value?.counts ?? null)\n\nconst scopes = computed(() => [\n { value: 'quick', label: t('page.scope-quick') },\n { value: 'full', label: t('page.scope-full') },\n])\n\nconst severities: { key: AuditSeverity; label: string; tone: 'danger' | 'warning' | 'info' }[] = [\n { key: 'error', label: 'page.errors', tone: 'danger' },\n { key: 'warning', label: 'page.warnings', tone: 'warning' },\n { key: 'notice', label: 'page.notices', tone: 'info' },\n]\n\nconst parts = computed(() => counts.value?.health_parts ?? null)\n\nconst healthStatus = computed<ProgressStatus>(() => {\n const health = counts.value?.health ?? 0\n\n if (health >= 90) return 'success'\n if (health >= 60) return 'warning'\n\n return 'danger'\n})\n\n/* The groups this package has words for; a module's own group reads as «Other». */\nconst GROUPS = [\n 'config',\n 'host',\n 'hosts',\n 'indexing',\n 'page',\n 'content',\n 'links',\n 'images',\n 'a11y',\n 'structure',\n]\n\nconst groups = computed(() =>\n Object.entries(counts.value?.groups ?? {}).map(([id, bySeverity]) => ({\n id,\n label: t(`page.group-${GROUPS.includes(id) ? id : 'other'}`),\n bySeverity,\n })),\n)\n\nfunction stageLabel(run: AuditRun): string {\n if (run.status === 'queued') return t('page.status-queued')\n\n return run.progress.stage ? t(`page.stage-${run.progress.stage}`) : t('page.status-running')\n}\n\nasync function load(): Promise<void> {\n try {\n latest.value = await api.latest()\n } catch (error) {\n toast.danger(message(error))\n }\n\n clearTimeout(timer)\n\n if (latest.value?.active) {\n timer = setTimeout(() => void load(), POLL_MS)\n }\n}\n\nasync function start(): Promise<void> {\n starting.value = true\n\n try {\n await api.start(scope.value)\n toast.success(t('page.started'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n } finally {\n starting.value = false\n }\n}\n\nasync function cancel(run: AuditRun): Promise<void> {\n try {\n await api.cancel(run.id)\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nonMounted(load)\nonBeforeUnmount(() => clearTimeout(timer))\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"overview\" :card=\"false\">\n <div class=\"wx-audit-overview\">\n <wx-card v-if=\"!latest\"><wx-skeleton :rows=\"4\" /></wx-card>\n\n <template v-else>\n <wx-alert v-if=\"latest.queue.sync\" type=\"warning\" :description=\"t('page.sync-queue')\" />\n\n <wx-alert\n v-if=\"latest.last && latest.last.status === 'failed'\"\n type=\"danger\"\n :description=\"t('page.last-failed', { error: latest.last.error ?? '' })\"\n />\n\n <wx-card v-if=\"active\" class=\"wx-audit-overview__active\">\n <div class=\"wx-audit-overview__row\">\n <wx-text weight=\"semibold\">{{ stageLabel(active) }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-overview__url\">{{\n active.base_url\n }}</wx-text>\n <wx-button\n v-if=\"canRun\"\n size=\"sm\"\n class=\"wx-audit-overview__end\"\n @click=\"cancel(active)\"\n >{{ t('page.cancel') }}</wx-button\n >\n </div>\n <wx-progress indeterminate :aria-label=\"stageLabel(active)\" />\n <wx-text v-if=\"active.progress.resources\" size=\"sm\" tone=\"muted\">{{\n t('page.resources-progress', {\n checked: active.progress.resources.checked,\n total: active.progress.resources.total,\n })\n }}</wx-text>\n <wx-text v-else-if=\"active.progress.stage === 'crawl'\" size=\"sm\" tone=\"muted\">{{\n t('page.pages-progress', {\n crawled: active.progress.pages.crawled,\n limit: active.progress.pages.limit,\n })\n }}</wx-text>\n </wx-card>\n\n <wx-card v-else-if=\"canRun && !latest.queue.sync\">\n <div class=\"wx-audit-overview__row\">\n <wx-segmented v-model=\"scope\" :options=\"scopes\" :aria-label=\"t('page.scope')\" />\n <wx-text size=\"sm\" tone=\"muted\">{{\n scope === 'full' ? t('page.scope-full-help') : t('page.scope-quick-help')\n }}</wx-text>\n <wx-button\n type=\"primary\"\n icon=\"refresh\"\n :loading=\"starting\"\n class=\"wx-audit-overview__end\"\n @click=\"start\"\n >{{ t('page.run') }}</wx-button\n >\n </div>\n </wx-card>\n\n <wx-card v-if=\"!done && !active\">\n <wx-empty\n icon=\"check-circle\"\n :title=\"t('page.never')\"\n :description=\"t('page.never-help')\"\n />\n </wx-card>\n\n <template v-if=\"done && counts\">\n <wx-card>\n <div class=\"wx-audit-overview__summary\">\n <div class=\"wx-audit-overview__health\">\n <wx-progress\n type=\"circle\"\n :value=\"counts.health\"\n :status=\"healthStatus\"\n show-value\n :formatter=\"(value: number) => `${value}%`\"\n :aria-label=\"t('page.health')\"\n />\n <div v-if=\"parts\" class=\"wx-audit-overview__parts\">\n <wx-text v-if=\"parts.pages > 0\" size=\"sm\">{{\n t('page.health-pages', { clean: parts.clean, pages: parts.pages })\n }}</wx-text>\n <wx-text v-if=\"parts.site_errors > 0\" size=\"sm\" tone=\"danger\">{{\n t('page.health-site', { count: parts.site_errors })\n }}</wx-text>\n <wx-text v-if=\"parts.warnings > 0\" size=\"sm\" tone=\"warning\">{{\n t('page.health-warnings', { count: parts.warnings })\n }}</wx-text>\n <wx-text size=\"xs\" tone=\"muted\">{{ t('page.health-help') }}</wx-text>\n </div>\n </div>\n <div class=\"wx-audit-overview__stats\">\n <wx-statistic\n v-for=\"severity in severities\"\n :key=\"severity.key\"\n :title=\"t(severity.label)\"\n :value=\"counts.severity[severity.key] ?? 0\"\n :tone=\"(counts.severity[severity.key] ?? 0) > 0 ? severity.tone : 'muted'\"\n />\n <wx-statistic :title=\"t('page.new')\" :value=\"counts.new\" />\n <wx-statistic :title=\"t('page.fixed')\" :value=\"counts.fixed\" tone=\"success\" />\n </div>\n </div>\n <div class=\"wx-audit-overview__meta\">\n <wx-text size=\"sm\" tone=\"muted\">\n {{ t('page.last-run') }} <wx-date :value=\"done.finished_at\" /> ·\n {{ t(`page.scope-${done.scope}`) }} ·\n </wx-text>\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-overview__url\">{{\n done.base_url\n }}</wx-text>\n </div>\n </wx-card>\n\n <wx-card v-if=\"groups.length\" :title=\"t('page.by-group')\">\n <ul class=\"wx-audit-overview__groups\">\n <li v-for=\"group in groups\" :key=\"group.id\">\n <wx-text size=\"sm\">{{ group.label }}</wx-text>\n <span class=\"wx-audit-overview__badges\">\n <template v-for=\"severity in severities\" :key=\"severity.key\">\n <wx-badge\n v-if=\"(group.bySeverity[severity.key] ?? 0) > 0\"\n :type=\"severity.tone\"\n size=\"sm\"\n >{{ t(severity.label) }} · {{ group.bySeverity[severity.key] }}</wx-badge\n >\n </template>\n </span>\n </li>\n </ul>\n </wx-card>\n\n <wx-card v-else>\n <wx-empty icon=\"check-circle\" :title=\"t('page.clean')\" size=\"sm\" />\n </wx-card>\n\n <wx-card>\n <template #header>\n <span class=\"wx-audit-overview__title\">\n {{ t('page.sources') }}\n <wx-popover :title=\"t('page.sources')\" :width=\"360\" teleport>\n <template #trigger>\n <wx-button\n variant=\"text\"\n size=\"sm\"\n icon=\"question\"\n :aria-label=\"t('page.sources-help-label')\"\n />\n </template>\n <wx-text size=\"sm\">{{ t('page.sources-help') }}</wx-text>\n </wx-popover>\n </span>\n </template>\n <div class=\"wx-audit-overview__badges\">\n <wx-badge v-for=\"source in counts.sources.searched\" :key=\"source\" type=\"success\">{{\n source\n }}</wx-badge>\n </div>\n <div v-if=\"counts.sources.missing.length\" class=\"wx-audit-overview__missing\">\n <wx-text size=\"sm\" tone=\"warning\">{{ t('page.sources-missing') }}</wx-text>\n <wx-badge v-for=\"source in counts.sources.missing\" :key=\"source\" type=\"warning\">{{\n source\n }}</wx-badge>\n </div>\n </wx-card>\n </template>\n </template>\n </div>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-overview {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n container-type: inline-size;\n}\n\n.wx-audit-overview__row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8) var(--wx-space-12);\n margin-bottom: var(--wx-space-8);\n}\n\n.wx-audit-overview__end {\n margin-left: auto;\n}\n\n.wx-audit-overview__summary {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-24);\n}\n\n.wx-audit-overview__health {\n display: flex;\n flex: 1 1 20rem;\n align-items: center;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n/* The help is a sentence; it wraps beside the circle rather than stretching the card. */\n.wx-audit-overview__parts {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n max-width: 36ch;\n min-width: 0;\n}\n\n.wx-audit-overview__stats {\n display: flex;\n flex: 1 1 auto;\n flex-wrap: wrap;\n gap: var(--wx-space-16) var(--wx-space-32);\n}\n\n.wx-audit-overview__meta {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n margin-top: var(--wx-space-16);\n}\n\n/* A long domain breaks rather than pushing the card sideways on a phone. */\n.wx-audit-overview__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-overview__groups {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.wx-audit-overview__groups li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-overview__badges,\n.wx-audit-overview__missing {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-overview__missing {\n margin-top: var(--wx-space-12);\n}\n\n.wx-audit-overview__title {\n display: inline-flex;\n align-items: center;\n gap: var(--wx-space-4);\n}\n</style>\n","import type { AuditResourceRow } from './types'\n\n/**\n * Whether the browser is worth asking for a picture of the page: the run reached it and it\n * answered. One past the run's limit or on the stand was never asked, and one that failed for the\n * run would fail here too — the card keeps the placeholder for those, with nothing to open.\n */\nexport function viewable(row: AuditResourceRow): boolean {\n return row.checked && row.status !== null && row.status < 400 && row.error === null\n}\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxButton,\n WxDrawer,\n WxIcon,\n WxImage,\n WxLink,\n WxSkeleton,\n WxTable,\n WxTabs,\n WxText,\n type BadgeType,\n type TabItem,\n type TabValue,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditDetails from './AuditDetails.vue'\nimport { createAuditApi } from './api'\nimport { viewable } from './resources'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditSeverity,\n} from './types'\n\n/**\n * One page of the snapshot, sliding in from the right (§8): what it answered and what its head\n * says, its findings, the links that lead in and out of it — with the answer of each own page\n * and the class of each host — what it loads (pictures, CSS, JS) with what each answered, and\n * its structured data with what the types lack.\n *\n * «Recheck» asks this one address again (a run of the `urls` scope) and says what of its findings\n * in the last full run are fixed; «Export» downloads the page — snapshot, findings and links.\n */\nconst props = defineProps<{\n run: number\n /** Where the section lives — the recheck's comparison opens on its runs. */\n base?: string\n /** The page to show; null keeps the card closed. */\n pageId: number | null\n /** Check ids and their titles in the reader's language, for the findings tab. */\n titles: Record<string, string>\n}>()\n\nconst emit = defineEmits<{ close: [] }>()\n\n/*\n * The card is wide: a page has long addresses, headers and hreflang lists. Its width is kept under\n * a key of its own, so one remembered from the narrow card of before does not keep it narrow.\n */\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nconst router = useRouter()\nuseAuditMessages()\n\nconst canRun = context.can('audit.run') || context.can('audit.manage')\nconst recheck = ref<AuditRun | null>(null)\nconst rechecking = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nconst POLL_MS = 2000\n\n/* The page in its own words: the run it was crawled in, then one more, of just this address. */\nasync function startRecheck(): Promise<void> {\n if (!card.value) return\n\n rechecking.value = true\n recheck.value = null\n\n try {\n follow(await api.start('urls', [card.value.page.url]))\n } catch (error) {\n rechecking.value = false\n toast.danger(message(error))\n }\n}\n\nfunction follow(run: AuditRun): void {\n clearTimeout(timer)\n\n if (run.status === 'queued' || run.status === 'running') {\n timer = setTimeout(async () => {\n try {\n follow(await api.run(run.id))\n } catch (error) {\n rechecking.value = false\n toast.danger(message(error))\n }\n }, POLL_MS)\n\n return\n }\n\n rechecking.value = false\n recheck.value = run\n}\n\nfunction compareRecheck(): void {\n if (recheck.value && props.base) {\n void router.push({ path: `${props.base}/runs`, query: { to: String(recheck.value.id) } })\n }\n}\n\nonBeforeUnmount(() => clearTimeout(timer))\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst card = ref<AuditPageCard | null>(null)\nconst failure = ref<string | null>(null)\nconst tab = ref<TabValue>('overview')\nconst links = ref<AuditPage<AuditLinkRow> | null>(null)\nconst linksLoading = ref(false)\nconst resources = ref<AuditPage<AuditResourceRow> | null>(null)\nconst resourcesLoading = ref(false)\n\nconst resourceTabs: AuditResourceTab[] = ['images', 'css', 'js']\n\nconst open = computed({\n get: () => props.pageId !== null,\n set: (value) => {\n if (!value) emit('close')\n },\n})\n\nconst tabs = computed<TabItem[]>(() => [\n { value: 'overview', label: t('page.card-overview') },\n { value: 'issues', label: t('page.card-issues'), badge: card.value?.counts.issues || undefined },\n { value: 'in', label: t('page.card-incoming'), badge: card.value?.counts.incoming || undefined },\n { value: 'out', label: t('page.card-outgoing'), badge: card.value?.counts.outgoing || undefined },\n { value: 'images', label: t('page.card-images'), badge: card.value?.counts.images || undefined },\n { value: 'css', label: t('page.card-css'), badge: card.value?.counts.css || undefined },\n { value: 'js', label: t('page.card-js'), badge: card.value?.counts.js || undefined },\n {\n value: 'microdata',\n label: t('page.card-microdata'),\n badge: card.value?.counts.microdata || undefined,\n },\n])\n\nconst resourceTab = computed<AuditResourceTab | null>(() =>\n resourceTabs.includes(tab.value as AuditResourceTab) ? (tab.value as AuditResourceTab) : null,\n)\n\nconst severities: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst hostTypes: Record<string, BadgeType> = {\n own: 'success',\n own_mirror: 'warning',\n dev: 'danger',\n external: 'info',\n}\n\nconst linkColumns = computed<TableColumn<AuditLinkRow>[]>(() => [\n { key: 'url', label: t('page.address'), minWidth: 220 },\n { key: 'status', label: t('page.field-status'), width: 80 },\n { key: 'kind', label: t('page.kind'), width: 90 },\n { key: 'anchor', label: t('page.anchor'), minWidth: 140 },\n { key: 'host_class', label: t('page.host'), width: 120 },\n])\n\n/** Pictures show their alt; stylesheets and scripts how they are cached and compressed. */\nconst resourceColumns = computed<TableColumn<AuditResourceRow>[]>(() => [\n { key: 'url', label: t('page.address'), minWidth: 220 },\n { key: 'status', label: t('page.field-status'), width: 80 },\n { key: 'bytes', label: t('page.size'), width: 110 },\n ...(resourceTab.value === 'images'\n ? [{ key: 'alt', label: t('page.alt'), minWidth: 120 }]\n : [\n { key: 'cache_control', label: t('page.cache'), minWidth: 120 },\n { key: 'compression', label: t('page.field-compression'), width: 100 },\n ]),\n])\n\n/*\n * The block indented, the way a person reads JSON. One the server cut at its length limit does not\n * parse, and is shown as the page printed it rather than not at all.\n */\nfunction pretty(source: string): string {\n try {\n return JSON.stringify(JSON.parse(source), null, 2)\n } catch {\n return source\n }\n}\n\nfunction size(row: AuditResourceRow): string {\n if (row.bytes === null) return ''\n\n const kb = row.bytes / 1024\n const text = kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${Math.round(kb)} KB`\n\n return row.width && row.height ? `${text} · ${row.width}×${row.height}` : text\n}\n\n/** The answer, the markup and where the page came from — label and value, in reading order. */\n/*\n * A fact is a line, or a list: hreflang and Open Graph are key and value per row, the key set apart\n * as a tag so the eye does not run it into the address after it; JSON-LD is the types as tags.\n */\ntype Fact = string | { pairs: [string, string][] } | { tags: string[]; error?: string | null }\n\nconst facts = computed<[string, Fact][]>(() => {\n const page = card.value?.page\n\n if (!page) return []\n\n const rows: [string, unknown][] = [\n [t('page.field-status'), page.status ?? t('page.status-none')],\n [t('page.field-final_status'), page.redirect_to ? page.final_status : null],\n [t('page.field-redirect_to'), page.redirect_to],\n [t('page.error'), page.error],\n [t('page.field-content_type'), page.content_type],\n [t('page.field-bytes'), page.bytes],\n [t('page.field-ttfb_ms'), page.ttfb_ms],\n [t('page.field-total_ms'), page.total_ms],\n [t('page.field-compression'), page.compression],\n [t('page.field-source'), t(`page.source-${page.source}`)],\n [t('page.field-depth'), page.depth],\n [t('page.field-indexable'), page.indexable ? t('page.yes') : t('page.no')],\n [t('page.field-blocked_by_robots'), page.blocked_by_robots ? t('page.yes') : null],\n [t('page.field-title'), page.title],\n [t('page.field-description'), page.description],\n [t('page.field-h1'), page.h1.join(' · ') || null],\n [t('page.field-canonical'), page.canonical],\n [t('page.field-robots_meta'), page.robots_meta],\n [t('page.field-x_robots_tag'), page.x_robots_tag],\n [t('page.field-lang'), page.lang],\n [\n 'hreflang',\n page.hreflang.length\n ? { pairs: page.hreflang.map((alternate) => [alternate.lang, alternate.url]) }\n : null,\n ],\n [\n 'Open Graph',\n Object.keys(page.og).length\n ? { pairs: Object.entries(page.og).map(([key, value]) => [`og:${key}`, String(value)]) }\n : null,\n ],\n [\n 'Twitter',\n Object.keys(page.twitter).length\n ? {\n pairs: Object.entries(page.twitter).map(([key, value]) => [\n `twitter:${key}`,\n String(value),\n ]),\n }\n : null,\n ],\n [\n 'JSON-LD',\n page.json_ld.length\n ? {\n tags: page.json_ld.flatMap((block) => block.types),\n error: page.json_ld.find((block) => block.error)?.error ?? null,\n }\n : null,\n ],\n [t('page.field-word_count'), page.word_count],\n [t('page.field-links_in'), page.links_in],\n [t('page.field-links_out_internal'), page.links_out_internal],\n [t('page.field-links_out_external'), page.links_out_external],\n [t('page.field-images'), page.images],\n [t('page.field-images_without_alt'), page.images_without_alt || null],\n ]\n\n return rows\n .filter(([, value]) => value !== null && value !== undefined && value !== '')\n .map(([label, value]) => [label, typeof value === 'object' ? (value as Fact) : String(value)])\n})\n\nfunction statusType(value: number | null): BadgeType {\n if (value === null) return 'danger'\n if (value >= 500) return 'danger'\n if (value >= 400) return 'warning'\n if (value >= 300) return 'info'\n\n return 'success'\n}\n\nasync function load(id: number): Promise<void> {\n clearTimeout(timer)\n rechecking.value = false\n recheck.value = null\n card.value = null\n failure.value = null\n links.value = null\n resources.value = null\n tab.value = 'overview'\n\n try {\n card.value = await api.page(props.run, id)\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nasync function loadLinks(state: TableState): Promise<void> {\n if (props.pageId === null || (tab.value !== 'in' && tab.value !== 'out')) return\n\n linksLoading.value = true\n\n try {\n links.value = await api.links(props.run, props.pageId, {\n direction: tab.value,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n failure.value = message(error)\n } finally {\n linksLoading.value = false\n }\n}\n\nasync function loadResources(state: TableState): Promise<void> {\n const current = resourceTab.value\n\n if (props.pageId === null || current === null) return\n\n resourcesLoading.value = true\n\n try {\n resources.value = await api.resources(props.run, props.pageId, {\n tab: current,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n failure.value = message(error)\n } finally {\n resourcesLoading.value = false\n }\n}\n\nwatch(\n () => props.pageId,\n (id) => {\n if (id !== null) void load(id)\n },\n { immediate: true },\n)\n\nwatch(tab, () => {\n links.value = null\n resources.value = null\n})\n</script>\n\n<template>\n <wx-drawer\n v-model:open=\"open\"\n size=\"min(1100px, 75vw)\"\n :min-size=\"480\"\n resizable\n persist=\"webx-audit.page-card-wide\"\n >\n <template #title>\n <span class=\"wx-audit-card__title\">\n <wx-badge v-if=\"card\" :type=\"statusType(card.page.status)\" size=\"sm\">{{\n card.page.status ?? '—'\n }}</wx-badge>\n <span class=\"wx-audit-card__url\">{{ card?.page.url ?? '' }}</span>\n </span>\n </template>\n\n <template #extra>\n <span v-if=\"card\" class=\"wx-audit-card__extra\">\n <wx-button\n v-if=\"canRun\"\n size=\"sm\"\n icon=\"refresh\"\n :loading=\"rechecking\"\n @click=\"startRecheck\"\n >{{ t('page.recheck') }}</wx-button\n >\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"download\"\n :href=\"api.pageFile(props.run, card.page.id)\"\n >{{ t('page.export-page') }}</wx-button\n >\n <wx-link :href=\"card.page.url\" target=\"_blank\">{{ t('page.open-page') }}</wx-link>\n </span>\n </template>\n\n <wx-text v-if=\"failure\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!card\" :rows=\"6\" />\n\n <div v-else class=\"wx-audit-card\">\n <wx-alert v-if=\"rechecking\" type=\"info\" :description=\"t('page.recheck-running')\" />\n <wx-alert\n v-else-if=\"recheck && recheck.status === 'done' && recheck.counts\"\n :type=\"recheck.counts.new > 0 ? 'warning' : 'success'\"\n >\n <div class=\"wx-audit-card__recheck\">\n <span>{{ t('page.recheck-fixed', { count: recheck.counts.fixed }) }}</span>\n <span>{{ t('page.recheck-new', { count: recheck.counts.new }) }}</span>\n <wx-button v-if=\"props.base\" size=\"sm\" variant=\"text\" @click=\"compareRecheck\">{{\n t('page.recheck-compare')\n }}</wx-button>\n </div>\n </wx-alert>\n <wx-alert\n v-else-if=\"recheck\"\n type=\"danger\"\n :description=\"recheck.error ?? t(`page.status-${recheck.status}`)\"\n />\n <wx-text v-if=\"card.page.title\" weight=\"semibold\">{{ card.page.title }}</wx-text>\n\n <wx-tabs v-model=\"tab\" :items=\"tabs\">\n <dl v-if=\"tab === 'overview'\" class=\"wx-audit-card__facts\">\n <template v-for=\"[label, value] in facts\" :key=\"label\">\n <dt>{{ label }}</dt>\n <dd v-if=\"typeof value === 'string'\">{{ value }}</dd>\n <dd v-else-if=\"'pairs' in value\" class=\"wx-audit-card__pairs\">\n <template v-for=\"([key, text], index) in value.pairs\" :key=\"index\">\n <wx-badge size=\"sm\" class=\"wx-audit-card__key\">{{ key }}</wx-badge>\n <span>{{ text }}</span>\n </template>\n </dd>\n <dd v-else class=\"wx-audit-card__tags\">\n <wx-badge v-for=\"(tag, index) in value.tags\" :key=\"index\" type=\"info\" size=\"sm\">{{\n tag\n }}</wx-badge>\n <wx-text v-if=\"value.error\" size=\"sm\" tone=\"danger\">{{ value.error }}</wx-text>\n </dd>\n </template>\n <template v-if=\"Object.keys(card.page.headers).length\">\n <dt class=\"wx-audit-card__section\">{{ t('page.headers') }}</dt>\n <dd />\n <template v-for=\"(value, name) in card.page.headers\" :key=\"name\">\n <dt class=\"wx-audit-card__code\">{{ name }}</dt>\n <dd class=\"wx-audit-card__code\">{{ value }}</dd>\n </template>\n </template>\n </dl>\n\n <div v-else-if=\"tab === 'issues'\" class=\"wx-audit-card__issues\">\n <wx-text v-if=\"!card.issues.length\" tone=\"muted\">{{ t('page.no-issues') }}</wx-text>\n <div v-for=\"issue in card.issues\" :key=\"issue.id\" class=\"wx-audit-card__issue\">\n <div class=\"wx-audit-card__issue-head\">\n <wx-badge :type=\"severities[issue.severity]\" dot>{{\n t(`page.severity-${issue.severity}`)\n }}</wx-badge>\n <wx-text size=\"sm\" weight=\"semibold\">{{\n props.titles[issue.check] ?? issue.check\n }}</wx-text>\n <wx-badge v-if=\"issue.state === 'new'\" type=\"primary\" size=\"sm\">{{\n t('page.state-new')\n }}</wx-badge>\n </div>\n <audit-details :details=\"issue.details\" />\n </div>\n </div>\n\n <wx-table\n v-else-if=\"resourceTab\"\n :key=\"`resources-${String(tab)}`\"\n :data=\"resources\"\n :columns=\"resourceColumns\"\n row-key=\"id\"\n flush\n :loading=\"resourcesLoading\"\n :per-page-options=\"[]\"\n :empty-text=\"t('page.no-resources')\"\n @state-change=\"loadResources\"\n >\n <template #cell-url=\"{ row }\">\n <span v-if=\"resourceTab === 'images'\" class=\"wx-audit-card__picture\">\n <!-- Only a picture that answered is fetched: the stand's and a broken one keep the\n placeholder rather than a request the browser is sure to lose. -->\n <wx-image\n :src=\"viewable(row) ? row.url : undefined\"\n :alt=\"row.alt ?? ''\"\n :width=\"48\"\n :height=\"48\"\n fit=\"cover\"\n radius=\"var(--wx-radius-sm)\"\n preview\n :preview-label=\"t('page.view-full')\"\n class=\"wx-audit-card__thumb\"\n :class=\"{ 'is-unviewable': !viewable(row) }\"\n >\n <template v-if=\"!viewable(row)\" #placeholder>\n <wx-icon name=\"image\" />\n </template>\n </wx-image>\n <span class=\"wx-audit-card__url\">{{ row.url }}</span>\n </span>\n <span v-else class=\"wx-audit-card__url\">{{ row.url }}</span>\n <wx-text v-if=\"row.location\" size=\"sm\" tone=\"muted\" class=\"wx-audit-card__url\">\n → {{ row.location }}</wx-text\n >\n <wx-text v-if=\"row.error\" size=\"sm\" tone=\"danger\">{{ row.error }}</wx-text>\n </template>\n <template #cell-status=\"{ row }\">\n <wx-badge v-if=\"row.status !== null\" :type=\"statusType(row.status)\" size=\"sm\">{{\n row.status\n }}</wx-badge>\n <wx-badge v-else-if=\"row.checked\" type=\"danger\" size=\"sm\">—</wx-badge>\n <wx-text v-else size=\"sm\" tone=\"muted\">{{ t('page.not-checked') }}</wx-text>\n </template>\n <template #cell-bytes=\"{ row }\">{{ size(row) }}</template>\n <template #cell-alt=\"{ row }\">\n <wx-text v-if=\"row.alt === null && row.kind === 'img'\" size=\"sm\" tone=\"danger\">{{\n t('page.missing')\n }}</wx-text>\n <template v-else>{{ row.alt ?? '' }}</template>\n </template>\n </wx-table>\n\n <div v-else-if=\"tab === 'microdata'\" class=\"wx-audit-card__issues\">\n <wx-text v-if=\"!card.page.json_ld.length\" tone=\"muted\">{{\n t('page.no-json-ld')\n }}</wx-text>\n <div\n v-for=\"(block, index) in card.page.json_ld\"\n :key=\"index\"\n class=\"wx-audit-card__issue\"\n >\n <div class=\"wx-audit-card__issue-head\">\n <wx-text size=\"sm\" weight=\"semibold\">{{\n t('page.jsonld-block', { number: index + 1 })\n }}</wx-text>\n <wx-badge v-for=\"type in block.types\" :key=\"type\" size=\"sm\">{{ type }}</wx-badge>\n </div>\n <wx-text v-if=\"block.error\" size=\"sm\" tone=\"danger\"\n >{{ t('page.jsonld-error') }} {{ block.error }}</wx-text\n >\n <template v-for=\"(item, position) in block.items ?? []\" :key=\"position\">\n <wx-text v-if=\"item.missing.length\" size=\"sm\" tone=\"danger\"\n >{{ item.type }} — {{ t('page.jsonld-required') }}\n {{ item.missing.join(', ') }}</wx-text\n >\n <wx-text v-if=\"item.recommended.length\" size=\"sm\" tone=\"muted\"\n >{{ item.type }} — {{ t('page.jsonld-recommended') }}\n {{ item.recommended.join(', ') }}</wx-text\n >\n <wx-text\n v-if=\"!item.missing.length && !item.recommended.length\"\n size=\"sm\"\n tone=\"success\"\n >{{ item.type }} — {{ t('page.jsonld-complete') }}</wx-text\n >\n </template>\n <pre v-if=\"block.source\" class=\"wx-audit-card__source\">{{ pretty(block.source) }}</pre>\n </div>\n </div>\n\n <wx-table\n v-else\n :key=\"String(tab)\"\n :data=\"links\"\n :columns=\"linkColumns\"\n row-key=\"id\"\n flush\n :loading=\"linksLoading\"\n :per-page-options=\"[]\"\n :empty-text=\"t('page.no-links')\"\n @state-change=\"loadLinks\"\n >\n <template #cell-url=\"{ row }\">\n <span class=\"wx-audit-card__url\">{{ row.url ?? '—' }}</span>\n </template>\n <template #cell-status=\"{ row }\">\n <wx-badge v-if=\"row.status !== null\" :type=\"statusType(row.status)\" size=\"sm\">{{\n row.status\n }}</wx-badge>\n </template>\n <template #cell-host_class=\"{ row }\">\n <wx-badge v-if=\"row.host_class\" :type=\"hostTypes[row.host_class] ?? 'info'\" size=\"sm\">{{\n t(`page.host-${row.host_class}`)\n }}</wx-badge>\n </template>\n </wx-table>\n </wx-tabs>\n </div>\n </wx-drawer>\n</template>\n\n<style scoped>\n.wx-audit-card {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-card__title {\n display: inline-flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-card__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-card__facts {\n display: grid;\n grid-template-columns: minmax(120px, max-content) minmax(0, 1fr);\n gap: var(--wx-space-6) var(--wx-space-16);\n margin: var(--wx-space-12) 0 0;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-card__facts dt {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-card__facts dd {\n margin: 0;\n overflow-wrap: anywhere;\n white-space: pre-line;\n}\n\n/* Key and value in two columns of their own, the key against its value, a row apart from the next pair. */\n.wx-audit-card__pairs {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n gap: var(--wx-space-6) var(--wx-space-8);\n align-items: baseline;\n}\n\n.wx-audit-card__key {\n justify-self: end;\n font-family: var(--wx-font-family-mono);\n}\n\n.wx-audit-card__tags {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-card__section {\n margin-top: var(--wx-space-12);\n font-weight: var(--wx-font-weight-semibold);\n}\n\n.wx-audit-card__code {\n font-family: var(--wx-font-family-mono);\n}\n\n.wx-audit-card__issues {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n margin-top: var(--wx-space-12);\n}\n\n.wx-audit-card__issue {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n/* A picture is recognised by sight faster than by its hashed file name. */\n.wx-audit-card__picture {\n display: flex;\n align-items: center;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-card__thumb {\n flex: none;\n}\n\n/* The same box as a picture that would not load, with the same mark — nothing here to open. */\n.wx-audit-card__thumb.is-unviewable :deep(.wx-image__placeholder .wx-icon) {\n width: 32px;\n height: 32px;\n}\n\n.wx-audit-card__source {\n max-height: 480px;\n margin: 0;\n padding: var(--wx-space-8);\n overflow: auto;\n border-radius: var(--wx-radius-sm);\n background: var(--wx-bg-muted);\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-card__issue-head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-card__extra {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-card__recheck {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-4) var(--wx-space-12);\n}\n</style>\n","import type { AuditFieldType, AuditFilterOp, AuditPageField } from './types'\n\n/**\n * The fields of the snapshot, as `PageColumns` lists them on the server: what the pages screen\n * can show, filter on, sort by and export. Kept in the same order, so the column picker reads\n * like the page's card — address and answer first, markup, then speed and links.\n */\nexport const PAGE_FIELDS: Record<AuditPageField, AuditFieldType> = {\n url: 'url',\n status: 'status',\n final_status: 'status',\n redirect_to: 'url',\n source: 'source',\n depth: 'number',\n indexable: 'bool',\n issues: 'number',\n title: 'text',\n description: 'text',\n h1: 'text',\n canonical: 'url',\n robots_meta: 'text',\n x_robots_tag: 'text',\n lang: 'text',\n content_type: 'text',\n bytes: 'number',\n ttfb_ms: 'number',\n total_ms: 'number',\n compression: 'text',\n word_count: 'number',\n links_in: 'number',\n links_out_internal: 'number',\n links_out_external: 'number',\n images: 'number',\n images_without_alt: 'number',\n in_sitemap: 'bool',\n in_registry: 'bool',\n blocked_by_robots: 'bool',\n}\n\nexport const DEFAULT_COLUMNS: AuditPageField[] = [\n 'url',\n 'status',\n 'indexable',\n 'title',\n 'word_count',\n 'links_in',\n 'issues',\n]\n\n/** `h1` is read out of a JSON list: shown and exported, not filtered or sorted on. */\nexport const COMPUTED_FIELDS: AuditPageField[] = ['h1']\n\n/** What can be asked of a field of each type. */\nexport const OPERATIONS: Record<AuditFieldType, AuditFilterOp[]> = {\n url: ['contains', 'eq', 'empty', 'filled'],\n text: ['contains', 'eq', 'empty', 'filled'],\n number: ['gt', 'lt', 'eq', 'empty'],\n status: ['eq', 'gt', 'lt', 'empty'],\n bool: ['yes', 'no'],\n source: ['eq'],\n}\n\n/** The operations that need a value typed beside them. */\nexport const WITH_VALUE: AuditFilterOp[] = ['contains', 'eq', 'gt', 'lt']\n\nexport const SOURCES = ['home', 'sitemap', 'registry', 'link'] as const\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useDates, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxButton,\n WxCheckboxGroup,\n WxInput,\n WxPopover,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type SelectValue,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditLayout from './AuditLayout.vue'\nimport AuditPageCard from './AuditPageCard.vue'\nimport { createAuditApi } from './api'\nimport {\n COMPUTED_FIELDS,\n DEFAULT_COLUMNS,\n OPERATIONS,\n PAGE_FIELDS,\n SOURCES,\n WITH_VALUE,\n} from './fields'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditFieldFilter,\n AuditFilterOp,\n AuditPage,\n AuditPageField,\n AuditPageQuery,\n AuditPageRow,\n AuditRun,\n} from './types'\n\n/**\n * Every address the last full run crawled (§8, «Pages»): any field of the snapshot as a column,\n * a filter on any of them, the list as CSV, and a row that opens the page's card.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\nconst dates = useDates()\n\nconst STORAGE = 'webx-audit.pages.columns'\n\nconst run = ref<AuditRun | null>(null)\nconst ready = ref(false)\nconst page = ref<AuditPage<AuditPageRow> | null>(null)\nconst loading = ref(false)\nconst opened = ref<number | null>(null)\nconst titles = ref<Record<string, string>>({})\n\nconst status = ref<string | null>(null)\nconst indexable = ref<string | null>(null)\nconst check = ref<string | null>(null)\nconst filters = ref<AuditFieldFilter[]>([])\nlet last: TableState = { page: 1, perPage: 50, sort: null, search: '' }\n\nconst visible = ref<AuditPageField[]>(restore())\n\nfunction restore(): AuditPageField[] {\n try {\n const saved: unknown = JSON.parse(window.localStorage.getItem(STORAGE) ?? 'null')\n\n if (Array.isArray(saved)) {\n const known = saved.filter((key): key is AuditPageField => key in PAGE_FIELDS)\n\n if (known.length) return known\n }\n } catch {\n // A private window or a broken value: the default columns, as for anyone else.\n }\n\n return [...DEFAULT_COLUMNS]\n}\n\nwatch(visible, (keys) => {\n try {\n window.localStorage.setItem(STORAGE, JSON.stringify(keys))\n } catch {\n // Not remembered — still shown.\n }\n})\n\nconst fields = Object.keys(PAGE_FIELDS) as AuditPageField[]\n\nconst columnOptions = computed(() =>\n fields.map((key) => ({ value: key, label: t(`page.field-${key}`) })),\n)\n\nconst filterFields = computed(() =>\n fields\n .filter((key) => !COMPUTED_FIELDS.includes(key))\n .map((key) => ({ value: key, label: t(`page.field-${key}`) })),\n)\n\nconst columns = computed<TableColumn<AuditPageRow>[]>(() =>\n /* The picker keeps the order things were ticked in; the table keeps the card's order. */\n fields\n .filter((key) => visible.value.includes(key))\n .map((key) => ({\n key,\n label: t(`page.field-${key}`),\n sortable: !COMPUTED_FIELDS.includes(key),\n minWidth: PAGE_FIELDS[key] === 'url' || PAGE_FIELDS[key] === 'text' ? 220 : undefined,\n align: PAGE_FIELDS[key] === 'number' ? 'right' : undefined,\n })),\n)\n\nconst statusOptions = computed(() => [\n ...['2xx', '3xx', '4xx', '5xx'].map((value) => ({ value, label: value })),\n { value: 'none', label: t('page.status-none') },\n])\n\nconst indexableOptions = computed(() => [\n { value: '1', label: t('page.indexable-yes') },\n { value: '0', label: t('page.indexable-no') },\n])\n\nconst checkOptions = computed(() =>\n Object.entries(titles.value).map(([value, label]) => ({ value, label })),\n)\n\nconst filtersCount = computed(\n () =>\n [status.value, indexable.value, check.value].filter(Boolean).length +\n filters.value.filter(complete).length,\n)\n\nconst query = computed<AuditPageQuery>(() => ({\n status: status.value,\n indexable: indexable.value === null ? null : indexable.value === '1',\n check: check.value,\n filters: filters.value.filter(complete),\n}))\n\nfunction complete(filter: AuditFieldFilter): boolean {\n return !WITH_VALUE.includes(filter.op) || (filter.value ?? '').trim() !== ''\n}\n\nfunction pick(value: SelectValue | SelectValue[] | null | undefined): string | null {\n return typeof value === 'string' && value !== '' ? value : null\n}\n\nfunction operations(field: AuditPageField) {\n return OPERATIONS[PAGE_FIELDS[field]].map((op) => ({ value: op, label: t(`page.op-${op}`) }))\n}\n\nfunction addFilter(): void {\n filters.value = [...filters.value, { field: 'title', op: 'empty' }]\n}\n\nfunction setField(index: number, value: SelectValue | SelectValue[] | null | undefined): void {\n const field = pick(value) as AuditPageField | null\n\n if (!field) return\n\n filters.value = filters.value.map((filter, at) =>\n at === index ? { field, op: OPERATIONS[PAGE_FIELDS[field]][0]!, value: '' } : filter,\n )\n}\n\nfunction setOp(index: number, value: SelectValue | SelectValue[] | null | undefined): void {\n const op = pick(value) as AuditFilterOp | null\n\n if (op)\n filters.value = filters.value.map((filter, at) => (at === index ? { ...filter, op } : filter))\n}\n\nfunction setValue(index: number, value: string): void {\n filters.value = filters.value.map((filter, at) => (at === index ? { ...filter, value } : filter))\n}\n\nfunction removeFilter(index: number): void {\n filters.value = filters.value.filter((_, at) => at !== index)\n}\n\nfunction setColumns(keys: unknown[]): void {\n const next = keys.filter((key): key is AuditPageField => String(key) in PAGE_FIELDS)\n\n /* A table without columns is a blank card; the address stays at least. */\n visible.value = next.length ? next : ['url']\n}\n\nconst types: Record<string, BadgeType> = {\n '2': 'success',\n '3': 'info',\n '4': 'warning',\n '5': 'danger',\n}\n\nfunction statusType(value: unknown): BadgeType {\n return types[String(value ?? '').charAt(0)] ?? 'danger'\n}\n\nfunction text(value: unknown): string {\n return value === null || value === undefined || value === '' ? '—' : String(value)\n}\n\nasync function load(state: TableState = last): Promise<void> {\n last = state\n\n if (run.value === null) return\n\n loading.value = true\n\n try {\n page.value = await api.pages(run.value.id, {\n ...query.value,\n search: state.search,\n sort: state.sort ? `${state.sort.order === 'desc' ? '-' : ''}${state.sort.key}` : null,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nfunction download(): void {\n if (run.value === null) return\n\n window.location.assign(\n api.pagesFile(\n run.value.id,\n { ...query.value, search: last.search },\n columns.value.map((column) => column.key),\n ),\n )\n}\n\nwatch(query, () => void load({ ...last, page: 1 }), { deep: true })\n\nonMounted(async () => {\n try {\n run.value = (await api.latest()).crawled\n\n if (run.value !== null) {\n const checks = await api.checks(run.value.id)\n titles.value = Object.fromEntries(checks.map((row) => [row.id, row.title]))\n }\n } catch (error) {\n toast.danger(message(error))\n } finally {\n ready.value = true\n }\n\n void load()\n})\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"pages\">\n <wx-text v-if=\"ready && run === null\" tone=\"muted\" class=\"wx-audit-pages__none\">{{\n t('page.pages-none')\n }}</wx-text>\n\n <wx-table\n v-else\n :data=\"page\"\n :columns=\"columns\"\n row-key=\"id\"\n searchable\n clickable\n hover\n flush\n :loading=\"loading || !ready\"\n :per-page-options=\"[50, 100, 200]\"\n :search-placeholder=\"t('page.search-url')\"\n :filters-count=\"filtersCount\"\n :filters-label=\"panel('filters.title')\"\n :filters-width=\"420\"\n :empty-text=\"t('page.empty')\"\n @state-change=\"load\"\n @row-click=\"(row) => (opened = row.id)\"\n >\n <template #title>\n <wx-text v-if=\"run\" size=\"sm\" tone=\"muted\">{{\n t('page.pages-run', { date: dates.short(run.finished_at) })\n }}</wx-text>\n </template>\n\n <template #actions>\n <wx-popover :title=\"t('page.columns')\" width=\"300\">\n <template #trigger>\n <wx-button size=\"sm\" variant=\"text\" icon=\"sliders\">{{ t('page.columns') }}</wx-button>\n </template>\n <wx-checkbox-group\n :model-value=\"visible\"\n :options=\"columnOptions\"\n size=\"sm\"\n class=\"wx-audit-pages__picker\"\n @update:model-value=\"setColumns\"\n />\n </wx-popover>\n <wx-button size=\"sm\" variant=\"text\" icon=\"download\" :disabled=\"!run\" @click=\"download\">{{\n t('page.export')\n }}</wx-button>\n </template>\n\n <template #filters>\n <div class=\"wx-audit-pages__filters\">\n <wx-select\n :model-value=\"status\"\n :options=\"statusOptions\"\n :placeholder=\"t('page.any-status')\"\n clearable\n @update:model-value=\"status = pick($event)\"\n />\n <wx-select\n :model-value=\"indexable\"\n :options=\"indexableOptions\"\n :placeholder=\"t('page.any-indexable')\"\n clearable\n @update:model-value=\"indexable = pick($event)\"\n />\n <wx-select\n :model-value=\"check\"\n :options=\"checkOptions\"\n :placeholder=\"t('page.any-check')\"\n clearable\n filterable\n @update:model-value=\"check = pick($event)\"\n />\n\n <div v-for=\"(filter, index) in filters\" :key=\"index\" class=\"wx-audit-pages__filter\">\n <wx-select\n :model-value=\"filter.field\"\n :options=\"filterFields\"\n filterable\n size=\"sm\"\n @update:model-value=\"setField(index, $event)\"\n />\n <wx-select\n :model-value=\"filter.op\"\n :options=\"operations(filter.field)\"\n size=\"sm\"\n @update:model-value=\"setOp(index, $event)\"\n />\n <wx-select\n v-if=\"WITH_VALUE.includes(filter.op) && PAGE_FIELDS[filter.field] === 'source'\"\n :model-value=\"filter.value ?? null\"\n :options=\"SOURCES.map((value) => ({ value, label: t(`page.source-${value}`) }))\"\n size=\"sm\"\n @update:model-value=\"setValue(index, pick($event) ?? '')\"\n />\n <wx-input\n v-else-if=\"WITH_VALUE.includes(filter.op)\"\n :model-value=\"filter.value ?? ''\"\n :placeholder=\"t('page.value')\"\n size=\"sm\"\n @update:model-value=\"setValue(index, String($event ?? ''))\"\n />\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"close\"\n :aria-label=\"t('page.remove-filter')\"\n @click=\"removeFilter(index)\"\n />\n </div>\n\n <wx-button size=\"sm\" variant=\"text\" icon=\"plus\" @click=\"addFilter\">{{\n t('page.add-filter')\n }}</wx-button>\n </div>\n </template>\n\n <template v-for=\"key in visible\" :key=\"key\" #[`cell-${key}`]=\"{ row }\">\n <wx-badge\n v-if=\"PAGE_FIELDS[key] === 'status' && row[key] !== null\"\n :type=\"statusType(row[key])\"\n size=\"sm\"\n >{{ row[key] }}</wx-badge\n >\n <wx-text v-else-if=\"PAGE_FIELDS[key] === 'status'\" size=\"sm\" tone=\"danger\">{{\n t('page.status-none')\n }}</wx-text>\n <template v-else-if=\"PAGE_FIELDS[key] === 'bool'\">{{\n row[key] ? t('page.yes') : t('page.no')\n }}</template>\n <template v-else-if=\"PAGE_FIELDS[key] === 'source'\">{{\n t(`page.source-${row[key]}`)\n }}</template>\n <wx-badge v-else-if=\"key === 'issues' && row.issues > 0\" type=\"warning\" size=\"sm\">{{\n row.issues\n }}</wx-badge>\n <span v-else :class=\"{ 'wx-audit-pages__long': PAGE_FIELDS[key] === 'url' }\">{{\n text(row[key])\n }}</span>\n </template>\n </wx-table>\n\n <audit-page-card\n v-if=\"run\"\n :run=\"run.id\"\n :base=\"props.base\"\n :page-id=\"opened\"\n :titles=\"titles\"\n @close=\"opened = null\"\n />\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-pages__none {\n display: block;\n padding: var(--wx-space-24);\n}\n\n.wx-audit-pages__filters {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-pages__filter {\n display: grid;\n grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr) auto;\n gap: var(--wx-space-4);\n align-items: center;\n}\n\n.wx-audit-pages__picker {\n max-height: 360px;\n overflow-y: auto;\n}\n\n.wx-audit-pages__long {\n overflow-wrap: anywhere;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxLink, WxSegmented, WxSkeleton, WxText } from '@webx-ui/core'\nimport AuditDetails from './AuditDetails.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditComparisonKind, AuditComparisonRow, AuditIssue } from './types'\n\n/**\n * One check of a comparison opened: its new, fixed or persisting findings, fifty at a time —\n * fixed ones as the earlier run stored them, the others from the later run.\n */\nconst props = defineProps<{ from: number; to: number; row: AuditComparisonRow }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst KINDS: AuditComparisonKind[] = ['new', 'fixed', 'persisting']\n\n/* Open on what changed: new first, then fixed — persisting only when nothing else is there. */\nconst kind = ref<AuditComparisonKind>(KINDS.find((one) => props.row[one] > 0) ?? 'new')\nconst issues = ref<AuditIssue[] | null>(null)\nconst page = ref(1)\nconst more = ref(false)\nconst failure = ref<string | null>(null)\n\nconst options = computed(() =>\n KINDS.map((value) => ({\n value,\n label: `${t(`page.kind-${value}`)} · ${props.row[value]}`,\n disabled: props.row[value] === 0,\n })),\n)\n\nasync function load(next = 1): Promise<void> {\n failure.value = null\n\n try {\n const answer = await api.compareIssues({\n from: props.from,\n to: props.to,\n kind: kind.value,\n check: props.row.check,\n page: next,\n per_page: 50,\n })\n\n issues.value = next === 1 ? answer.data : [...(issues.value ?? []), ...answer.data]\n page.value = answer.current_page\n more.value = answer.current_page < answer.last_page\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nwatch(\n kind,\n () => {\n issues.value = null\n void load()\n },\n { immediate: true },\n)\n</script>\n\n<template>\n <div class=\"wx-audit-compare\">\n <wx-segmented v-model=\"kind\" :options=\"options\" size=\"sm\" :aria-label=\"t('page.compare')\" />\n\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!issues\" :rows=\"2\" />\n\n <template v-else>\n <div v-for=\"issue in issues\" :key=\"issue.id\" class=\"wx-audit-compare__item\">\n <wx-link v-if=\"issue.url\" :href=\"issue.url\" target=\"_blank\" class=\"wx-audit-compare__url\">{{\n issue.url\n }}</wx-link>\n <audit-details :details=\"issue.details\" />\n </div>\n\n <wx-button v-if=\"more\" size=\"sm\" variant=\"text\" @click=\"load(page + 1)\">…</wx-button>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-compare {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-compare__item {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n.wx-audit-compare__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useRoute } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxCard,\n WxTable,\n WxText,\n type BadgeType,\n type RowKey,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditCompareIssues from './AuditCompareIssues.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditComparison,\n AuditComparisonRow,\n AuditPage,\n AuditRun,\n AuditRunStatus,\n AuditSeverity,\n} from './types'\n\n/**\n * The history (§8 «Runs»): every run kept, newest first, with its health and counts. Ticking a\n * run compares it with the one it was analysed against; ticking two compares those two — by\n * fingerprint (decision 8): what is new in the later one, what both have, what is gone. `?to=`\n * opens on one run already ticked — the way the page card's recheck leads here.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nconst route = useRoute()\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst runs = ref<AuditPage<AuditRun> | null>(null)\nconst loading = ref(false)\nconst selected = ref<RowKey[]>([])\nconst comparison = ref<AuditComparison | null>(null)\nconst comparing = ref(false)\nconst expanded = ref<RowKey[]>([])\n\nconst statuses: Record<AuditRunStatus, BadgeType> = {\n queued: 'info',\n running: 'primary',\n done: 'success',\n failed: 'danger',\n cancelled: 'warning',\n}\n\nconst severities: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst columns = computed<TableColumn<AuditRun>[]>(() => [\n { key: 'id', label: t('page.run-id'), width: 90 },\n { key: 'created_at', label: t('page.started-at'), minWidth: 160 },\n { key: 'scope', label: t('page.scope'), width: 120 },\n { key: 'status', label: t('page.status'), width: 130 },\n { key: 'health', label: t('page.health'), width: 100, align: 'right' },\n { key: 'severity', label: t('page.severity'), minWidth: 170, hideBelow: 640 },\n { key: 'started_by', label: t('page.started-by'), minWidth: 130, hideBelow: 760 },\n])\n\nconst compareColumns = computed<TableColumn<AuditComparisonRow>[]>(() => [\n { key: 'severity', label: t('page.severity'), width: 130 },\n { key: 'title', label: t('page.check') },\n { key: 'new', label: t('page.kind-new'), width: 90, align: 'right' },\n { key: 'fixed', label: t('page.kind-fixed'), width: 100, align: 'right' },\n { key: 'persisting', label: t('page.kind-persisting'), width: 120, align: 'right' },\n])\n\n/* What the selection means: one run against its own previous, or two against each other. */\nconst pair = computed<{ to: number; from: number | null } | null>(() => {\n const ids = selected.value.map(Number).sort((a, b) => a - b)\n\n if (ids.length === 0) return null\n\n return ids.length === 1\n ? { to: ids[0]!, from: null }\n : { to: ids[ids.length - 1]!, from: ids[0]! }\n})\n\nconst scopesDiffer = computed(\n () => comparison.value !== null && comparison.value.from.scope !== comparison.value.to.scope,\n)\n\nfunction who(run: AuditRun): string {\n if (run.started_by === 'schedule') return t('page.by-schedule')\n if (run.started_by === 'mcp') return t('page.by-mcp')\n if (run.started_by === 'console') return t('page.by-console')\n\n return run.started_by ? t('page.by-person') : ''\n}\n\nasync function load(state?: TableState): Promise<void> {\n loading.value = true\n\n try {\n runs.value = await api.runs({ page: state?.page ?? 1, per_page: state?.perPage ?? 20 })\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nasync function compare(): Promise<void> {\n const current = pair.value\n\n comparison.value = null\n expanded.value = []\n\n if (!current) return\n\n comparing.value = true\n\n try {\n comparison.value = await api.compare(current.to, current.from)\n } catch (error) {\n toast.danger(message(error))\n } finally {\n comparing.value = false\n }\n}\n\nonMounted(() => {\n const to = Number(route.query.to)\n\n if (Number.isInteger(to) && to > 0) selected.value = [to]\n})\n\nwatch(selected, (keys) => {\n /* Two at most: a third tick replaces the oldest one. */\n if (keys.length > 2) selected.value = keys.slice(-2)\n else void compare()\n})\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"runs\" :card=\"false\">\n <div class=\"wx-audit-runs\">\n <wx-card>\n <wx-table\n v-model:selected=\"selected\"\n :data=\"runs\"\n :columns=\"columns\"\n row-key=\"id\"\n selectable\n :selectable-if=\"(row: AuditRun) => row.status === 'done'\"\n flush\n :loading=\"loading\"\n :empty-text=\"t('page.runs-empty')\"\n @state-change=\"load\"\n >\n <template #cell-created_at=\"{ row }\"><wx-date :value=\"row.created_at\" /></template>\n <template #cell-scope=\"{ row }\">{{ t(`page.scope-${row.scope}`) }}</template>\n <template #cell-status=\"{ row }\">\n <wx-badge :type=\"statuses[row.status]\" dot>{{\n t(`page.status-${row.status}`)\n }}</wx-badge>\n </template>\n <template #cell-health=\"{ row }\">{{\n row.counts ? `${row.counts.health}%` : ''\n }}</template>\n <template #cell-severity=\"{ row }\">\n <span v-if=\"row.counts\" class=\"wx-audit-runs__counts\">\n <template v-for=\"(type, key) in severities\" :key=\"key\">\n <wx-badge v-if=\"row.counts.severity[key]\" :type=\"type\" size=\"sm\">{{\n row.counts.severity[key]\n }}</wx-badge>\n </template>\n </span>\n </template>\n <template #cell-started_by=\"{ row }\">{{ who(row) }}</template>\n </wx-table>\n </wx-card>\n\n <wx-text v-if=\"!pair\" size=\"sm\" tone=\"muted\">{{ t('page.compare-help') }}</wx-text>\n\n <wx-card v-else :title=\"t('page.compare')\">\n <wx-text v-if=\"comparison\" size=\"sm\" tone=\"muted\" class=\"wx-audit-runs__pair\">\n {{ t('page.compare-from') }} #{{ comparison.from.id }} ·\n <wx-date :value=\"comparison.from.created_at\" /> → {{ t('page.compare-to') }} #{{\n comparison.to.id\n }}\n · <wx-date :value=\"comparison.to.created_at\" />\n </wx-text>\n\n <wx-alert\n v-if=\"scopesDiffer\"\n type=\"info\"\n :description=\"t('page.compare-scopes')\"\n class=\"wx-audit-runs__note\"\n />\n\n <wx-table\n v-model:expanded=\"expanded\"\n :data=\"comparison?.checks ?? []\"\n :columns=\"compareColumns\"\n row-key=\"check\"\n expandable\n flush\n :pagination=\"false\"\n :loading=\"comparing\"\n :empty-text=\"t('page.compare-none')\"\n >\n <template #cell-severity=\"{ row }\">\n <wx-badge :type=\"severities[row.severity]\" dot>{{\n t(`page.severity-${row.severity}`)\n }}</wx-badge>\n </template>\n <template #cell-new=\"{ row }\">\n <wx-text :tone=\"row.new ? 'danger' : 'muted'\" size=\"sm\">{{ row.new }}</wx-text>\n </template>\n <template #cell-fixed=\"{ row }\">\n <wx-text :tone=\"row.fixed ? 'success' : 'muted'\" size=\"sm\">{{ row.fixed }}</wx-text>\n </template>\n <template #expanded=\"{ row }\">\n <audit-compare-issues\n v-if=\"comparison\"\n :from=\"comparison.from.id\"\n :to=\"comparison.to.id\"\n :row=\"row\"\n />\n </template>\n </wx-table>\n </wx-card>\n </div>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-runs {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-runs__counts {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n}\n\n.wx-audit-runs__pair {\n display: block;\n margin-bottom: var(--wx-space-12);\n}\n\n.wx-audit-runs__note {\n margin-bottom: var(--wx-space-12);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue'\nimport { useAdmin, useErrorText, useTranslate, WxScreen } from '@webx-ui/module-admin'\nimport { toast, WxActionBar, WxButton, WxSkeleton } from '@webx-ui/core'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The section's settings (§8): where the site is and which hosts are its stands, the limits of\n * the crawl and the paths it leaves out, the thresholds, the nightly run and how much history\n * to keep. The form is the screen the server describes (`audit.settings`), so a project patches\n * a field in the way it does everywhere else; saving is this page's own.\n */\nconst props = defineProps<{ base: string }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst values = ref<ScreenModel>({})\nconst errors = ref<Record<string, string[]>>({})\nconst loading = ref(true)\nconst saving = ref(false)\n\n// A boolean, not a computed: the permissions do not change while the screen is open.\nconst canManage = context.can('audit.manage')\n\nonMounted(async () => {\n try {\n values.value = (await api.settings()) as ScreenModel\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n})\n\nasync function save(): Promise<void> {\n saving.value = true\n errors.value = {}\n\n try {\n values.value = (await api.saveSettings(values.value)) as ScreenModel\n toast.success(t('page.saved'))\n } catch (error) {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n if (body?.errors) errors.value = body.errors\n\n toast.danger(message(error))\n } finally {\n saving.value = false\n }\n}\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"settings\" :card=\"false\">\n <div class=\"wx-audit-settings\">\n <wx-skeleton v-if=\"loading\" :rows=\"6\" />\n <wx-screen\n v-else\n v-model=\"values\"\n name=\"audit.settings\"\n :errors=\"errors\"\n :disabled=\"!canManage\"\n />\n\n <wx-action-bar v-if=\"canManage && !loading\">\n <wx-button type=\"primary\" :loading=\"saving\" @click=\"save\">{{ t('page.save') }}</wx-button>\n </wx-action-bar>\n </div>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-settings {\n display: flex;\n flex-direction: column;\n gap: var(--wx-gap, var(--wx-space-16));\n}\n</style>\n","import type { AdminModule } from '@webx-ui/module-admin'\nimport AuditHostsPage from './AuditHostsPage.vue'\nimport AuditIssuesPage from './AuditIssuesPage.vue'\nimport AuditOverviewPage from './AuditOverviewPage.vue'\nimport AuditPagesPage from './AuditPagesPage.vue'\nimport AuditRunsPage from './AuditRunsPage.vue'\nimport AuditSettingsPage from './AuditSettingsPage.vue'\n\nexport interface AuditOptions {\n /** Where the section lives inside the panel. */\n path?: string\n /**\n * @deprecated The audit's settings are a view of the section itself (`<path>/settings`); the\n * option is read by nothing and stays only so that a panel which passed it still compiles.\n */\n settingsPath?: string\n}\n\n/**\n * «System → Audit» as a section of the panel: the overview of the last run, its findings, the\n * pages the last full run crawled, the hosts the site points at, the history of runs with two of\n * them compared, and the section's settings.\n *\n * The id matches the module the server reports, which is what makes the entry appear in the\n * navigation: the section shows up when both halves are installed.\n */\nexport function audit(options: AuditOptions = {}): AdminModule {\n const path = options.path ?? '/audit'\n const props = { base: path }\n\n return {\n id: 'audit',\n path,\n routes: [\n { path, name: 'webx.audit', component: AuditOverviewPage, props },\n { path: `${path}/issues`, name: 'webx.audit.issues', component: AuditIssuesPage, props },\n { path: `${path}/pages`, name: 'webx.audit.pages', component: AuditPagesPage, props },\n { path: `${path}/hosts`, name: 'webx.audit.hosts', component: AuditHostsPage, props },\n { path: `${path}/runs`, name: 'webx.audit.runs', component: AuditRunsPage, props },\n {\n path: `${path}/settings`,\n name: 'webx.audit.settings',\n component: AuditSettingsPage,\n props,\n },\n ],\n }\n}\n"],"names":["pageParams","query","params","filter","createAuditApi","admin","base","data","body","filters","id","scope","urls","run","columns","key","value","issue","fix","dryRun","to","from","rule","values","auditMessages","seeded","useAuditMessages","i18n","useAdmin","props","__props","api","t","useTranslate","message","useErrorText","router","useRouter","places","ref","failure","broken","status","onMounted","error","_openBlock","_createElementBlock","_hoisted_1","_createBlock","_unref","WxText","_Fragment","_hoisted_2","_createVNode","place","index","WxLink","_createTextVNode","_toDisplayString","WxBadge","_hoisted_3","field","WxButton","WxSkeleton","context","route","useRoute","title","computed","module","views","actions","where","next","path","WxListScreen","$event","_renderSlot","_ctx","panel","answer","loading","search","hostClass","expanded","classes","classOptions","pick","load","toast","watch","AuditLayout","WxTable","row","WxSelect","_cache","_withCtx","_createElementVNode","WxDate","AuditHostPlaces","statusType","code","cell","column","yesNo","text","_renderList","_hoisted_4","emit","__emit","open","_useModel","offers","applying","apply","offer","edit","url","now","WxDialog","change","_hoisted_5","_hoisted_6","_hoisted_7","pattern","reason","count","saving","timer","pathOf","parsed","ready","preview","hide","WxFormItem","WxInput","WxTextarea","can","issues","more","page","fixing","dialog","hiding","hideDialog","hidden","one","unhide","why","fixed","_normalizeClass","AuditDetails","AuditFixDialog","AuditHideDialog","checks","severity","group","state","filtersCount","types","severityOptions","groupOptions","stateOptions","WxPopover","AuditIssueList","POLL_MS","latest","starting","canRun","active","done","counts","scopes","severities","parts","healthStatus","health","GROUPS","groups","bySeverity","stageLabel","start","cancel","onBeforeUnmount","WxAlert","WxCard","WxProgress","WxSegmented","WxEmpty","WxStatistic","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","source","_hoisted_13","viewable","recheck","rechecking","startRecheck","card","follow","compareRecheck","tab","links","linksLoading","resources","resourcesLoading","resourceTabs","tabs","resourceTab","hostTypes","linkColumns","resourceColumns","pretty","size","kb","facts","alternate","block","label","loadLinks","loadResources","current","WxDrawer","WxTabs","tag","name","_hoisted_14","_hoisted_15","WxImage","WxIcon","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","type","item","position","_hoisted_20","_hoisted_21","PAGE_FIELDS","DEFAULT_COLUMNS","COMPUTED_FIELDS","OPERATIONS","WITH_VALUE","SOURCES","STORAGE","dates","useDates","opened","titles","indexable","check","last","visible","restore","saved","known","keys","fields","columnOptions","filterFields","statusOptions","indexableOptions","checkOptions","complete","operations","op","addFilter","setField","at","setOp","setValue","removeFilter","_","setColumns","download","WxCheckboxGroup","AuditPageCard","KINDS","kind","options","runs","selected","comparison","comparing","statuses","compareColumns","pair","ids","a","b","scopesDiffer","who","compare","AuditCompareIssues","errors","canManage","save","WxScreen","WxActionBar","audit","AuditOverviewPage","AuditIssuesPage","AuditPagesPage","AuditHostsPage","AuditRunsPage","AuditSettingsPage"],"mappings":";;;;AA8FO,SAASA,GAAWC,GAAoE;AAC7F,QAAMC,IAAsD;AAAA,IAC1D,QAAQD,EAAM,UAAU;AAAA,IACxB,QAAQA,EAAM,UAAU;AAAA,IACxB,WACEA,EAAM,cAAc,QAAQA,EAAM,cAAc,SAC5C,SACAA,EAAM,YACJ,IACA;AAAA,IACR,OAAOA,EAAM,SAAS;AAAA,IACtB,MAAMA,EAAM,QAAQ;AAAA,IACpB,MAAMA,EAAM;AAAA,IACZ,UAAUA,EAAM;AAAA,EAAA;AAGlB,aAAWE,KAAUF,EAAM,WAAW,CAAA;AACpC,IAAAC,EAAO,KAAKC,EAAO,KAAK,GAAG,IACzBA,EAAO,UAAU,UAAaA,EAAO,UAAU,KAAKA,EAAO,KAAK,GAAGA,EAAO,EAAE,IAAIA,EAAO,KAAK;AAGhG,SAAOD;AACT;AAGO,SAASE,GAAeC,GAA+B;AAC5D,QAAMC,IAAO,GAAGD,EAAM,OAAO,UACvBE,IAAO,CAAIC,MAAyBA,EAAK,MAGzCC,IAAU,CAACR,OAA4B;AAAA,IAC3C,OAAOA,EAAM,SAAS;AAAA,IACtB,UAAUA,EAAM,YAAY;AAAA,IAC5B,OAAOA,EAAM,SAAS;AAAA,IACtB,OAAOA,EAAM,SAAS;AAAA,IACtB,MAAMA,EAAM;AAAA,IACZ,UAAUA,EAAM;AAAA,EAAA;AAGlB,SAAO;AAAA,IACL,QAAQ,MAAMI,EAAM,KAAK,IAA2B,GAAGC,CAAI,cAAc,EAAE,KAAKC,CAAI;AAAA,IAEpF,KAAK,CAACG,MAAOL,EAAM,KAAK,IAAwB,GAAGC,CAAI,SAASI,CAAE,EAAE,EAAE,KAAKH,CAAI;AAAA,IAE/E,MAAM,CAACN,IAAQ,CAAA,MACbI,EAAM,KACH,IAGE,GAAGC,CAAI,SAAS,EAAE,OAAAL,GAAO,EAC3B,KAAK,CAACO,OAAU,EAAE,GAAGA,EAAK,MAAM,MAAMA,EAAK,KAAA,EAAO;AAAA,IAEvD,OAAO,CAACG,GAAOC,MACbP,EAAM,KACH,KAAyB,GAAGC,CAAI,SAASK,MAAU,SAAS,EAAE,OAAAA,GAAO,MAAAC,EAAA,IAAS,EAAE,OAAAD,EAAA,CAAO,EACvF,KAAKJ,CAAI;AAAA,IAEd,QAAQ,CAACG,MAAOL,EAAM,KAAK,KAAyB,GAAGC,CAAI,SAASI,CAAE,WAAW,CAAA,CAAE,EAAE,KAAKH,CAAI;AAAA,IAE9F,QAAQ,CAACM,GAAKZ,IAAQ,CAAA,MACpBI,EAAM,KACH,IAA+B,GAAGC,CAAI,SAASO,CAAG,WAAW,EAAE,OAAOJ,EAAQR,CAAK,EAAA,CAAG,EACtF,KAAKM,CAAI;AAAA,IAEd,QAAQ,CAACM,GAAKZ,IAAQ,CAAA,MACpBI,EAAM,KACH,IAGE,GAAGC,CAAI,SAASO,CAAG,WAAW,EAAE,OAAOJ,EAAQR,CAAK,EAAA,CAAG,EACzD,KAAK,CAACO,OAAU,EAAE,GAAGA,EAAK,MAAM,MAAMA,EAAK,OAAO;AAAA,IAEvD,OAAO,CAACK,GAAKZ,IAAQ,CAAA,MACnBI,EAAM,KACH,IAGE,GAAGC,CAAI,SAASO,CAAG,UAAU,EAAE,OAAOb,GAAWC,CAAK,EAAA,CAAG,EAC3D,KAAK,CAACO,OAAU,EAAE,GAAGA,EAAK,MAAM,MAAMA,EAAK,OAAO;AAAA,IAEvD,WAAW,CAACK,GAAKZ,GAAOa,MAAY;AAClC,YAAMZ,IAAS,IAAI,gBAAA;AAEnB,iBAAW,CAACa,GAAKC,CAAK,KAAK,OAAO,QAAQ;AAAA,QACxC,GAAGhB,GAAWC,CAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,MAAA,CACX;AACC,QAAIe,MAAU,UAAWd,EAAO,IAAIa,GAAK,OAAOC,CAAK,CAAC;AAGxD,aAAAd,EAAO,IAAI,WAAWY,EAAQ,KAAK,GAAG,CAAC,GAEhC,GAAGR,CAAI,SAASO,CAAG,iBAAiBX,EAAO,UAAU;AAAA,IAC9D;AAAA,IAEA,MAAM,CAACW,GAAKH,MACVL,EAAM,KAAK,IAA6B,GAAGC,CAAI,SAASO,CAAG,UAAUH,CAAE,EAAE,EAAE,KAAKH,CAAI;AAAA,IAEtF,OAAO,CAACM,GAAKH,GAAIT,IAAQ,CAAA,MACvBI,EAAM,KACH,IAGE,GAAGC,CAAI,SAASO,CAAG,UAAUH,CAAE,UAAU,EAAE,OAAAT,EAAA,CAAO,EACpD,KAAK,CAACO,OAAU,EAAE,GAAGA,EAAK,MAAM,MAAMA,EAAK,OAAO;AAAA,IAEvD,WAAW,CAACK,GAAKH,GAAIT,MACnBI,EAAM,KACH,IAGE,GAAGC,CAAI,SAASO,CAAG,UAAUH,CAAE,cAAc,EAAE,OAAAT,EAAA,CAAO,EACxD,KAAK,CAACO,OAAU,EAAE,GAAGA,EAAK,MAAM,MAAMA,EAAK,OAAO;AAAA,IAEvD,OAAO,CAACK,GAAKI,MACXZ,EAAM,KACH,IAA+B,GAAGC,CAAI,SAASO,CAAG,WAAWI,CAAK,QAAQ,EAC1E,KAAKV,CAAI;AAAA,IAEd,KAAK,CAACM,GAAKI,GAAOC,GAAKC,IAAS,OAC9Bd,EAAM,KACH,KAEE,GAAGC,CAAI,SAASO,CAAG,WAAWI,CAAK,UAAU,mBAAmBC,CAAG,CAAC,IAAI;AAAA,MACzE,SAASC;AAAA,IAAA,CACV,EACA,KAAKZ,CAAI;AAAA,IAEd,UAAU,CAACM,GAAKH,MAAO,GAAGJ,CAAI,SAASO,CAAG,UAAUH,CAAE;AAAA,IAEtD,SAAS,CAACU,GAAIC,MACZhB,EAAM,KACH,IAEE,GAAGC,CAAI,iBAAiB,EAAE,OAAO,EAAE,IAAAc,GAAI,MAAMC,KAAQ,SAAU,CAAG,EACpE,KAAKd,CAAI;AAAA,IAEd,eAAe,CAACN,MACdI,EAAM,KACH,IAGE,GAAGC,CAAI,wBAAwB;AAAA,MAChC,OAAO,EAAE,GAAGL,GAAO,MAAMA,EAAM,QAAQ,QAAW,OAAOA,EAAM,SAAS,OAAA;AAAA,IAAU,CACnF,EACA,KAAK,CAACO,OAAU,EAAE,GAAGA,EAAK,MAAM,MAAMA,EAAK,KAAA,EAAO;AAAA,IAEvD,OAAO,CAACP,IAAQ,CAAA,MACdI,EAAM,KACH,IAA0B,GAAGC,CAAI,UAAU;AAAA,MAC1C,OAAO;AAAA,QACL,OAAOL,EAAM,SAAS;AAAA,QACtB,QAAQA,EAAM,UAAU;AAAA,QACxB,MAAMA,EAAM,QAAQ;AAAA,MAAA;AAAA,IACtB,CACD,EACA,KAAKM,CAAI;AAAA,IAEd,SAAS,MAAMF,EAAM,KAAK,IAAiC,GAAGC,CAAI,UAAU,EAAE,KAAKC,CAAI;AAAA,IAEvF,MAAM,CAACe,MAASjB,EAAM,KAAK,KAAgC,GAAGC,CAAI,YAAYgB,CAAI,EAAE,KAAKf,CAAI;AAAA,IAE7F,aAAa,CAACe,MACZjB,EAAM,KACH,KAAmC,GAAGC,CAAI,YAAY,EAAE,GAAGgB,GAAM,SAAS,IAAM,EAChF,KAAK,CAACd,MAASA,EAAK,KAAK,MAAM;AAAA,IAEpC,QAAQ,CAACE,MAAOL,EAAM,KAAK,OAAO,GAAGC,CAAI,YAAYI,CAAE,EAAE,EAAE,KAAK,MAAA;AAAA,KAAe;AAAA,IAE/E,UAAU,MACRL,EAAM,KACH,IAAmD,GAAGC,CAAI,WAAW,EACrE,KAAK,CAACE,MAASA,EAAK,KAAK,MAAM;AAAA,IAEpC,cAAc,CAACe,MACblB,EAAM,KACH,IAAmD,GAAGC,CAAI,aAAa,EAAE,QAAAiB,EAAA,CAAQ,EACjF,KAAK,CAACf,MAASA,EAAK,KAAK,MAAM;AAAA,EAAA;AAExC;AC1QO,MAAMgB,KAA0C;AAAA,EACrD,QAAQ;AAAA,IACN,OAAO;AAAA,EAAA;AAAA,EAGT,MAAM;AAAA,IACJ,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,KAAK;AAAA,IACL,OAAO;AAAA,IACP,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,cACE;AAAA,IACF,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,SAAS;AAAA,IACT,KAAK;AAAA,IACL,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,eACE;AAAA,IACF,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,eAAe;AAAA,IACf,eAAe;AAAA,IACf,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,gBACE;AAAA,IACF,sBAAsB;AAAA,IACtB,cACE;AAAA,IACF,mBAAmB;AAAA,IACnB,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,IACb,oBAAoB;AAAA,IACpB,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,eAAe;AAAA,IACf,cAAc;AAAA,IACd,aAAa;AAAA,IACb,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,eAAe;AAAA,IACf,cAAc;AAAA,IACd,aAAa;AAAA,IACb,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBACE;AAAA,IACF,cAAc;AAAA,IACd,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,cAAc;AAAA,IACd,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,IACtB,qBAAqB;AAAA,IACrB,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,qBAAqB;AAAA,IACrB,YAAY;AAAA,IACZ,mBAAmB;AAAA,IACnB,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,IACtB,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,IACrB,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,4BAA4B;AAAA,IAC5B,4BAA4B;AAAA,IAC5B,gBAAgB;AAAA,IAChB,4BAA4B;AAAA,IAC5B,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,2BAA2B;AAAA,IAC3B,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,UAAU;AAAA,IACV,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,mBAAmB;AAAA,IACnB,YAAY;AAAA,IACZ,mBAAmB;AAAA,IACnB,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,eAAe;AAAA,IACf,OAAO;AAAA,IACP,MAAM;AAAA,IACN,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,cAAc;AAAA,IACd,aACE;AAAA,IACF,gBAAgB;AAAA,IAChB,qBACE;AAAA,IACF,eAAe;AAAA,IACf,cAAc;AAAA,IACd,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,cAAc;AAAA,IACd,eAAe;AAAA,IACf,UAAU;AAAA,IACV,cAAc;AAAA,IACd,aAAa;AAAA,IACb,SAAS;AAAA,IACT,gBACE;AAAA,IACF,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,kBACE;AAAA,IACF,YAAY;AAAA,IACZ,mBAAmB;AAAA,IACnB,cAAc;AAAA,IACd,eAAe;AAAA,IACf,eAAe;AAAA,IACf,aAAa;AAAA,IACb,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,cAAc;AAAA,IACd,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,EAAA;AAEjB,GC/PMC,yBAAa,QAAA;AAGZ,SAASC,KAAyB;AACvC,MAAI;AACF,UAAM,EAAE,MAAAC,EAAA,IAASC,GAAA;AAEjB,IAAKH,GAAO,IAAIE,CAAI,MAClBA,EAAK,SAAS,cAAcH,EAAa,GACzCC,GAAO,IAAIE,CAAI;AAAA,EAEnB,QAAQ;AAAA,EAER;AACF;;;;;;;;;;;;;ACHA,UAAME,IAAQC,GAERC,IAAM3B,GAAewB,IAAU;AACrC,IAAAF,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GACVC,IAASC,GAAA,GAETC,IAASC,EAAuB,IAAI,GACpCC,IAAUD,EAAmB,IAAI,GAGjCE,IAAS,CAACC,MACdA,KAAW,SAAiCA,KAAU,OAAOA,MAAW;AAE1E,WAAAC,GAAU,YAAY;AACpB,UAAI;AACF,QAAAL,EAAO,QAAQ,MAAMP,EAAI,MAAM,EAAE,MAAMF,EAAM,MAAM;AAAA,MACrD,SAASe,GAAO;AACd,QAAAJ,EAAQ,QAAQN,EAAQU,CAAK;AAAA,MAC/B;AAAA,IACF,CAAC,cAICC,EAAA,GAAAC,EA0CM,OA1CNC,IA0CM;AAAA,MAzCWP,EAAA,cAAfQ,EAAuEC,EAAAC,CAAA,GAAA;AAAA;QAA/C,MAAK;AAAA,QAAK,MAAK;AAAA,MAAA;mBAAS,MAAa;AAAA,cAAVV,EAAA,KAAO,GAAA,CAAA;AAAA,QAAA;;YACjCF,EAAA,cAEzBQ,EAqCWK,GAAA,EAAA,KAAA,KAAA;AAAA,QApCMb,EAAA,MAAO,OAAO,UAA7BO,KAAAC,EAcU,WAdVM,IAcU;AAAA,UAbRC,EAAyEJ,EAAAC,CAAA,GAAA;AAAA,YAAhE,MAAK;AAAA,YAAK,QAAO;AAAA,UAAA;uBAAW,MAA0B;AAAA,kBAAvBD,EAAAjB,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;WACzCa,EAAA,EAAA,GAAAC,EAWMK,WAXwBb,EAAA,MAAO,OAAK,CAA7BgB,GAAOC,YAApBT,EAWM,OAAA;AAAA,YAXuC,KAAKS;AAAA,YAAO,OAAM;AAAA,UAAA;YAC7DF,EAEYJ,EAAAO,EAAA,GAAA;AAAA,cAFF,MAAMF,EAAM;AAAA,cAAM,QAAO;AAAA,cAAS,OAAM;AAAA,YAAA;yBAAuB,MAEvE;AAAA,gBADAG,EAAAC,EAAAJ,EAAM,IAAI,GAAA,CAAA;AAAA,cAAA;;;YAEZD,EAECJ,EAAAC,CAAA,GAAA;AAAA,cAFQ,MAAK;AAAA,cAAK,MAAK;AAAA,cAAQ,OAAM;AAAA,YAAA;yBACnC,MAAgB;AAAA,gBAAbO,EAAAC,EAAAJ,EAAM,IAAI,IAAG,QAAGI,EAAGJ,EAAM,GAAG,GAAA,CAAA;AAAA,cAAA;;;YAEnBA,EAAM,eAArBN,EAAqEC,EAAAC,CAAA,GAAA;AAAA;cAAxC,MAAK;AAAA,YAAA;yBAAK,MAAC;AAAA,gBAADO,EAAA,MAACC,EAAGJ,EAAM,MAAM,IAAG,KAAC,CAAA;AAAA,cAAA;;;YAC3Cb,EAAOa,EAAM,MAAM,UAAnCN,EAEaC,EAAAU,CAAA,GAAA;AAAA;cAFyB,MAAK;AAAA,cAAS,MAAK;AAAA,YAAA;yBAAK,MAE5D;AAAA,oBADAL,EAAM,UAAUL,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;;QAKRM,EAAA,MAAO,QAAQ,UAA9BO,KAAAC,EAmBU,WAnBVc,IAmBU;AAAA,UAlBRP,EAA0EJ,EAAAC,CAAA,GAAA;AAAA,YAAjE,MAAK;AAAA,YAAK,QAAO;AAAA,UAAA;uBAAW,MAA2B;AAAA,kBAAxBD,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;WACzCa,EAAA,EAAA,GAAAC,EAgBMK,WAhBwBb,EAAA,MAAO,QAAM,CAA9BuB,GAAON,YAApBT,EAgBM,OAAA;AAAA,YAhBwC,KAAKS;AAAA,YAAO,OAAM;AAAA,UAAA;YAC9DF,EAAqDJ,EAAAC,CAAA,GAAA,EAA5C,MAAK,QAAI;AAAA,yBAAC,MAAwB;AAAA,gBAArBO,EAAAC,EAAAG,EAAM,YAAY,GAAA,CAAA;AAAA,cAAA;;;YACxCR,EAGCJ,EAAAC,CAAA,GAAA;AAAA,cAHQ,MAAK;AAAA,cAAK,MAAK;AAAA,YAAA;yBACrB,MAAkB;AAAA,gBAAfO,EAAAC,EAAAG,EAAM,MAAM,IAAG,UAAMA,EAAM,KAAK,IAAAH,EAC/BG,EAAM,SAAM,MAASA,EAAM,MAAM,KAAA,EAAA,GAAA,CAAA;AAAA,cAAA;;;YAEvBA,EAAM,8BAAvBb,EAAkFC,EAAAU,CAAA,GAAA;AAAA;cAAhD,MAAK;AAAA,YAAA;yBAAK,MAA2B;AAAA,oBAAxBV,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAChDqB,EAAsFJ,EAAAC,CAAA,GAAA;AAAA,cAA7E,MAAK;AAAA,cAAK,MAAK;AAAA,cAAQ,OAAM;AAAA,YAAA;yBAAuB,MAAe;AAAA,gBAAZO,EAAAC,EAAAG,EAAM,GAAG,GAAA,CAAA;AAAA,cAAA;;;YAEjEA,EAAM,iBADdb,EAOCC,EAAAa,CAAA,GAAA;AAAA;cALC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACJ,gBAAOb,EAAAb,CAAA,EAAO,KAAKyB,EAAM,QAAQ;AAAA,YAAA;yBACjC,MAA2B;AAAA,oBAAxBZ,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;;sBAnCbgB,EAA6CC,EAAAc,EAAA,GAAA;AAAA;QAAX,MAAM;AAAA,MAAA;;;;;;;;;;;;;;;;AC3B5C,UAAMlC,IAAQC,GAYRkC,IAAUpC,GAAA,GACVQ,IAASC,GAAA,GACT4B,IAAQC,GAAA;AAEd,IAAAxC,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAE7BkC,IAAQC;AAAA,MACZ,MACEJ,EAAQ,MAAM,UAAU,QAAQ,KAAK,CAACK,MAAWA,EAAO,OAAO,OAAO,GAAG,SACzErC,EAAE,cAAc;AAAA,IAAA,GAGdsC,IAAQF,EAAoB,MAAM;AAAA,MACtC,EAAE,OAAO,YAAY,OAAOpC,EAAE,eAAe,EAAA;AAAA,MAC7C,EAAE,OAAO,UAAU,OAAOA,EAAE,aAAa,EAAA;AAAA,MACzC,EAAE,OAAO,SAAS,OAAOA,EAAE,YAAY,EAAA;AAAA,MACvC,EAAE,OAAO,SAAS,OAAOA,EAAE,YAAY,EAAA;AAAA,MACvC,EAAE,OAAO,QAAQ,OAAOA,EAAE,WAAW,EAAA;AAAA,IAAE,CACxC,GAGKuC,IAAUH;AAAA,MAAyB,MACvCvC,EAAM,YAAY,aACd,KACA;AAAA,QACE;AAAA,UACE,KAAK;AAAA,UACL,OAAOG,EAAE,eAAe;AAAA,UACxB,MAAM;AAAA,UACN,KAAK,MAAA;AAAM,YAAKI,EAAO,KAAK,GAAGP,EAAM,IAAI,WAAW;AAAA;AAAA,QAAA;AAAA,MACtD;AAAA,IACF,GAGA2C,IAAQJ,EAAmB;AAAA;AAAA,MAE/B,KAAK,MAAOvC,EAAM,YAAY,aAAa,aAAaA,EAAM;AAAA,MAC9D,KAAK,CAAC4C,MAAS;AACb,cAAMC,IAAOD,MAAS,aAAa5C,EAAM,OAAO,GAAGA,EAAM,IAAI,IAAI,OAAO4C,CAAI,CAAC;AAE7E,QAAIC,MAAST,EAAM,QAAW7B,EAAO,KAAKsC,CAAI;AAAA,MAChD;AAAA,IAAA,CACD;2BAIC1B,EAQiBC,EAAA0B,EAAA,GAAA;AAAA,MAPP,MAAMH,EAAA;AAAA,8CAAAA,EAAK,QAAAI;AAAA,MAClB,OAAOT,EAAA;AAAA,MACP,OAAOG,EAAA;AAAA,MACP,SAASC,EAAA;AAAA,MACT,MAAM1C,EAAM;AAAA,IAAA;iBAEb,MAAQ;AAAA,QAARgD,GAAQC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;;;;;;ACxDZ,UAAMjD,IAAQC,GAERC,IAAM3B,GAAewB,IAAU;AACrC,IAAAF,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7B8C,IAAQ9C,GAAa,YAAY,GACjCC,IAAUC,GAAA,GAEV6C,IAASzC,EAAuB,IAAI,GACpC0C,IAAU1C,EAAI,EAAK,GACnB2C,IAAS3C,EAAI,EAAE,GACf4C,IAAY5C,EAA2B,IAAI,GAC3C6C,IAAW7C,EAAc,EAAE,GAE3B8C,IAA6C;AAAA,MACjD,KAAK;AAAA,MACL,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,KAAK;AAAA,IAAA,GAGDvE,IAAUsD,EAAsC,MAAM;AAAA,MAC1D,EAAE,KAAK,QAAQ,OAAOpC,EAAE,WAAW,GAAG,UAAU,IAAA;AAAA,MAChD,EAAE,KAAK,SAAS,OAAOA,EAAE,YAAY,GAAG,OAAO,IAAI,OAAO,QAAA;AAAA,MAC1D,EAAE,KAAK,SAAS,OAAOA,EAAE,YAAY,GAAG,OAAO,IAAI,OAAO,SAAS,WAAW,IAAA;AAAA,MAC9E,EAAE,KAAK,UAAU,OAAOA,EAAE,aAAa,GAAG,OAAO,KAAK,OAAO,SAAS,WAAW,IAAA;AAAA,MACjF,EAAE,KAAK,UAAU,OAAOA,EAAE,aAAa,GAAG,OAAO,KAAK,OAAO,QAAA;AAAA,MAC7D,EAAE,KAAK,cAAc,OAAOA,EAAE,iBAAiB,GAAG,UAAU,KAAK,WAAW,IAAA;AAAA,IAAI,CACjF,GAEKsD,IAAelB;AAAA,MAAS,MAC3B,OAAO,KAAKiB,CAAO,EAAuB,IAAI,CAACrE,OAAW;AAAA,QACzD,OAAAA;AAAA,QACA,OAAO,GAAGgB,EAAE,aAAahB,CAAK,EAAE,CAAC,GAAGgE,EAAO,OAAO,QAAQhE,CAAK,IAAI,MAAMgE,EAAO,MAAM,QAAQhE,CAAK,CAAC,KAAK,EAAE;AAAA,MAAA,EAC3G;AAAA,IAAA;AAGJ,aAASuE,EAAKvE,GAA8E;AAC1F,aAAO,OAAOA,KAAU,YAAYA,KAASqE,IAAWrE,IAA2B;AAAA,IACrF;AAEA,mBAAewE,IAAsB;AACnC,MAAAP,EAAQ,QAAQ;AAEhB,UAAI;AACF,QAAAD,EAAO,QAAQ,MAAMjD,EAAI,MAAM,EAAE,OAAOoD,EAAU,OAAO,QAAQD,EAAO,MAAA,CAAO,GAC/EE,EAAS,QAAQ,CAAA;AAAA,MACnB,SAASxC,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAqC,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAEA,WAAAS,GAAM,CAACP,GAAWD,CAAM,GAAG,MAAA;AAAM,MAAKM;KAAM,GAE5C7C,GAAU6C,CAAI,mBAIZxC,EAqDe2C,IAAA;AAAA,MArDA,MAAM9D,EAAM;AAAA,MAAM,SAAQ;AAAA,IAAA;iBACvC,MAmDW;AAAA,QAnDXwB,EAmDWJ,EAAA2C,EAAA,GAAA;AAAA,UAlDD,UAAUR,EAAA;AAAA,sDAAAA,EAAQ,QAAAR;AAAA,UAClB,QAAQM,EAAA;AAAA,oDAAAA,EAAM,QAAAN;AAAA,UACrB,MAAMI,EAAA,OAAQ,SAAK,CAAA;AAAA,UACnB,SAASlE,EAAA;AAAA,UACV,WAAQ;AAAA,UACR,YAAA;AAAA,UACA,OAAA;AAAA,UACA,YAAA;AAAA,UACC,sBAAoBmC,EAAAjB,CAAA,EAAC,kBAAA;AAAA,UACrB,SAASiD,EAAA;AAAA,UACT,iBAAeE,EAAA,QAAS,IAAA;AAAA,UACxB,iBAAelC,EAAA8B,CAAA,EAAK,eAAA;AAAA,UACpB,cAAYc,MAAuBA,EAAI,+BAA+B;AAAA,UACtE,cAAY5C,EAAAjB,CAAA,EAAC,kBAAA;AAAA,QAAA;UAEH,WACT,MAME;AAAA,YANFqB,EAMEJ,EAAA6C,EAAA,GAAA;AAAA,cALC,eAAaX,EAAA;AAAA,cACb,SAASG,EAAA;AAAA,cACT,aAAarC,EAAAjB,CAAA,EAAC,gBAAA;AAAA,cACf,WAAA;AAAA,cACC,uBAAkB+D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAEO,EAAA,QAAYI,EAAKX,CAAM;AAAA,YAAA;;UAIrC,aAASoB,EAClB,CAOO,EARe,KAAAH,QAAG;AAAA,YACzBI,EAOO,QAPPlD,IAOO;AAAA,cANLM,EAEaJ,EAAAU,CAAA,GAAA;AAAA,gBAFF,MAAM0B,EAAQQ,EAAI,KAAK;AAAA,gBAAG,MAAK;AAAA,cAAA;2BAAK,MAE7C;AAAA,sBADA5C,EAAAjB,CAAA,EAAC,aAAc6D,EAAI,KAAK,EAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;cAE1BxC,EAEYJ,EAAAC,CAAA,GAAA;AAAA,gBAFH,MAAK;AAAA,gBAAM,MAAM2C,EAAI,6BAA6B;AAAA,gBAAW,QAAO;AAAA,cAAA;2BAAS,MAEpF;AAAA,kBADApC,EAAAC,EAAAmC,EAAI,IAAI,GAAA,CAAA;AAAA,gBAAA;;;;;UAIH,eAAWG,EACpB,CAAqF,EAD7D,KAAAH,QAAG;AAAA,YAC3BxC,EAAqFJ,EAAAC,CAAA,GAAA;AAAA,cAA5E,MAAK;AAAA,cAAM,MAAM2C,EAAI,SAAM,WAAA;AAAA,YAAA;yBAAuB,MAAgB;AAAA,gBAAbpC,EAAAC,EAAAmC,EAAI,MAAM,GAAA,CAAA;AAAA,cAAA;;;;UAE/D,eAAWG,EACpB,CAEY,EAHY,KAAAH,QAAG;AAAA,YAC3BxC,EAEYJ,EAAAC,CAAA,GAAA;AAAA,cAFH,MAAK;AAAA,cAAM,MAAM2C,EAAI,UAAUA,EAAI,UAAK,QAAA,WAAwB;AAAA,YAAA;yBAAW,MAElF;AAAA,gBADApC,EAAAC,EAAAmC,EAAI,MAAM,GAAA,CAAA;AAAA,cAAA;;;;UAGH,mBAAeG,EACxB,CAAyD,EAD7B,KAAAH,QAAG;AAAA,YAChBA,EAAI,mBAAnB7C,EAAyDC,EAAAiD,EAAA,GAAA;AAAA;cAAzB,OAAOL,EAAI;AAAA,YAAA;;UAGlC,UAAQG,EACjB,CAAsC,EADjB,KAAAH,QAAG;AAAA,YACxBxC,EAAsC8C,IAAA;AAAA,cAAlB,MAAMN,EAAI;AAAA,YAAA;;;;;;;;;;;;;;;;;;;;AC5HtC,UAAMhE,IAAQC,GAERM,IAASC,GAAA;AAEf,IAAAX,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY;AAEnC,aAASmE,EAAWpF,GAA2B;AAC7C,YAAMqF,IAAO,OAAOrF,CAAK;AAEzB,aAAIqF,KAAQ,OAAOA,MAAS,IAAU,WAClCA,KAAQ,MAAY,YACpBA,KAAQ,MAAY,SAEjB;AAAA,IACT;AAEA,aAASC,EAAKT,GAA8BU,GAAqC;AAC/E,aAAOV,EAAIU,EAAO,GAAG;AAAA,IACvB;AAGA,aAASC,EAAMxF,GAAwB;AACrC,aAAIA,KAAU,OAAoC,KAEnCgB,EAARhB,IAAU,aAAgB,SAAN;AAAA,IAC7B;AAEA,aAASyF,EAAKzF,GAAwB;AACpC,aAAOA,KAAU,OAA8B,KAAK,OAAOA,CAAK;AAAA,IAClE;sBAIE6B,EAAA,GAAAC,EA0DM,OA1DNC,IA0DM;AAAA,MAzDWlB,EAAM,QAAQ,gBAA7BmB,EAAqFC,EAAAC,CAAA,GAAA;AAAA;QAA/C,MAAK;AAAA,MAAA;mBAAK,MAA2B;AAAA,cAAxBrB,EAAM,QAAQ,OAAO,GAAA,CAAA;AAAA,QAAA;;;MAGhEA,EAAM,QAAQ,SAASA,EAAM,QAAQ,MAAM,KAAK,UADxDgB,EAAA,GAAAC,EAsDM,OAtDNM,IAsDM;AAAA,QAlDJ6C,EAiDQ,SAjDRrC,IAiDQ;AAAA,UAhDNqC,EAMQ,SAAA,MAAA;AAAA,YALNA,EAIK,MAAA,MAAA;AAAA,sBAHHnD,EAEKK,GAAA,MAAAuD,EAFgB7E,EAAM,QAAQ,MAAM,SAAO,CAArC0E,YAAXzD,EAEK,MAAA;AAAA,gBAF8C,KAAKyD,EAAO;AAAA,cAAA,GAC1D7C,EAAA6C,EAAO,KAAK,GAAA,CAAA;;;UAIrBN,EAwCQ,SAAA,MAAA;AAAA,oBAvCNnD,EAsCKK,GAAA,MAAAuD,EAtCsB7E,EAAM,QAAQ,MAAM,MAAI,CAAvCgE,GAAKtC,YAAjBT,EAsCK,MAAA,EAtCiD,KAAKS,KAAK;AAAA,sBAC9DT,EAoCKK,GAAA,MAAAuD,EApCgB7E,EAAM,QAAQ,MAAM,SAAO,CAArC0E,YAAXzD,EAoCK,MAAA;AAAA,gBApC8C,KAAKyD,EAAO;AAAA,cAAA;gBAC7CA,EAAO,SAAI,SAAcE,EAAKH,EAAKT,GAAKU,CAAM,CAAA,UAC5DvD,EAKCC,EAAAO,EAAA,GAAA;AAAA;kBAJE,MAAMiD,EAAKH,EAAKT,GAAKU,CAAM,CAAA;AAAA,kBAC5B,QAAO;AAAA,kBACP,OAAM;AAAA,gBAAA;6BACL,MAA6B;AAAA,oBAA1B9C,EAAAC,EAAA+C,EAAKH,EAAKT,GAAKU,CAAM,CAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;sCAIhBA,EAAO,SAAI,YAAiBD,EAAKT,GAAKU,CAAM,MAAA,aADzDvD,EAKCC,EAAAU,CAAA,GAAA;AAAA;kBAHE,MAAMyC,EAAWE,EAAKT,GAAKU,CAAM,CAAA;AAAA,kBAClC,MAAK;AAAA,gBAAA;6BACJ,MAA6B;AAAA,oBAA1B9C,EAAAC,EAAA+C,EAAKH,EAAKT,GAAKU,CAAM,CAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;sCAENA,EAAO,SAAI,eAAhCzD,EAEWK,GAAA,EAAA,KAAA,KAAA;AAAA,kBADNM,EAAAC,EAAA8C,EAAMF,EAAKT,GAAKU,CAAM,CAAA,CAAA,GAAA,CAAA;AAAA,gBAAA,UAGdA,EAAO,SAAI,aAAA,CAAmBE,EAAKH,EAAKT,GAAKU,CAAM,CAAA,UADhEvD,EAKCC,EAAAC,CAAA,GAAA;AAAA;kBAHC,MAAK;AAAA,kBACL,MAAK;AAAA,gBAAA;6BACJ,MAAuB;AAAA,wBAApBD,EAAAjB,CAAA,EAAC,cAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;sBAGMuE,EAAO,SAAI,UAAeE,EAAKH,EAAKT,GAAKU,CAAM,CAAA,UAD5DvD,EAOCC,EAAAa,CAAA,GAAA;AAAA;kBALC,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACJ,SAAK,CAAAc,MAAE3B,EAAAb,CAAA,EAAO,KAAKqE,EAAKH,EAAKT,GAAKU,CAAM,CAAA,CAAA;AAAA,gBAAA;6BACxC,MAA2B;AAAA,wBAAxBtD,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;sCAEUuE,EAAO,SAAI,eAA5BzD,EAES,QAFT6D,IAESjD,EADP+C,EAAKH,EAAKT,GAAKU,CAAM,CAAA,CAAA,GAAA,CAAA,WAEvBzD,EAAyDK,GAAA,EAAA,KAAA,KAAA;AAAA,kBAArCM,EAAAC,EAAA+C,EAAKH,EAAKT,GAAKU,CAAM,CAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;;;;;;;;;;;;;;;;;;;;;;ACrFvD,UAAM1E,IAAQC,GACR8E,IAAOC,GACPC,IAAOC,GAAoBjF,GAAC,MAA0B,GAEtDC,IAAM3B,GAAewB,IAAU;AACrC,IAAAF,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GACVC,IAASC,GAAA,GAET2E,IAASzE,EAA4B,IAAI,GACzCC,IAAUD,EAAmB,IAAI,GACjC0E,IAAW1E,EAAmB,IAAI;AAExC,mBAAeiD,IAAsB;AACnC,MAAAwB,EAAO,QAAQ,MACfxE,EAAQ,QAAQ;AAEhB,UAAI;AACF,QAAAwE,EAAO,QAAQ,MAAMjF,EAAI,MAAMF,EAAM,KAAKA,EAAM,MAAM,EAAE;AAAA,MAC1D,SAASe,GAAO;AACd,QAAAJ,EAAQ,QAAQN,EAAQU,CAAK;AAAA,MAC/B;AAAA,IACF;AAEA,mBAAesE,EAAMC,GAAqC;AACxD,MAAAF,EAAS,QAAQE,EAAM;AAEvB,UAAI;AACF,cAAMpF,EAAI,IAAIF,EAAM,KAAKA,EAAM,MAAM,IAAIsF,EAAM,EAAE,GACjD1B,EAAM,QAAQzD,EAAE,kBAAkB,CAAC,GACnC4E,EAAK,SAASO,EAAM,EAAE,GACtBL,EAAK,QAAQ;AAAA,MACf,SAASlE,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAqE,EAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,aAASG,EAAKC,GAAmB;AAC/B,MAAAP,EAAK,QAAQ,IACR1E,EAAO,KAAKiF,CAAG;AAAA,IACtB;AAGA,WAAA3B;AAAA,MACE,CAACoB,GAAM,MAAMjF,EAAM,MAAM,EAAE;AAAA,MAC3B,CAAC,CAACyF,CAAG,MAAM;AACT,QAAIA,KAAU9B,EAAA;AAAA,MAChB;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK,mBAKlBxC,EA4DYC,EAAAsE,EAAA,GAAA;AAAA,MA5DO,MAAMT,EAAA;AAAA,8CAAAA,EAAI,QAAAlC;AAAA,MAAG,OAAO3B,EAAAjB,CAAA,EAAC,iBAAA;AAAA,MAAsB,OAAO;AAAA,IAAA;iBACnE,MA0DM;AAAA,QA1DNiE,EA0DM,OA1DNlD,IA0DM;AAAA,UAzDWP,EAAA,cAAfQ,EAAuEC,EAAAC,CAAA,GAAA;AAAA;YAA/C,MAAK;AAAA,YAAK,MAAK;AAAA,UAAA;uBAAS,MAAa;AAAA,kBAAVV,EAAA,KAAO,GAAA,CAAA;AAAA,YAAA;;gBACjCwE,EAAA,QACLA,EAAA,MAAO,WAAM,UAAjChE,EAEYC,EAAAC,CAAA,GAAA;AAAA;YAF6B,MAAK;AAAA,YAAK,MAAK;AAAA,UAAA;uBAAQ,MAE9D;AAAA,kBADAD,EAAAjB,CAAA,EAAC,eAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;kCAFHgB,EAA6CC,EAAAc,EAAA,GAAA;AAAA;YAAX,MAAM;AAAA,UAAA;kBAKxCjB,EAkDUK,GAAA,MAAAuD,EAlDeM,EAAA,SAAM,CAAA,GAAA,CAAfG,YAAhBrE,EAkDU,WAAA;AAAA,YAlD8B,KAAKqE,EAAM;AAAA,YAAI,OAAM;AAAA,UAAA;YAC3D9D,EAAsDJ,EAAAC,CAAA,GAAA,EAA7C,QAAO,cAAU;AAAA,yBAAC,MAAiB;AAAA,gBAAdO,EAAAC,EAAAyD,EAAM,KAAK,GAAA,CAAA;AAAA,cAAA;;;YAC1BA,EAAM,oBAArBnE,EAA0FC,EAAAC,CAAA,GAAA;AAAA;cAAxD,MAAK;AAAA,cAAK,MAAK;AAAA,YAAA;yBAAQ,MAAuB;AAAA,gBAApBO,EAAAC,EAAAyD,EAAM,WAAW,GAAA,CAAA;AAAA,cAAA;;;YAE7ElB,EAgCQ,SAhCR7C,IAgCQ;AAAA,cA/BN6C,EAOQ,SAAA,MAAA;AAAA,gBANNA,EAKK,MAAA,MAAA;AAAA,kBAJHA,EAAoC,cAA7BhD,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,kBACRiE,EAAmC,cAA5BhD,EAAAjB,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,kBACRiE,EAAkC,cAA3BhD,EAAAjB,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,kCACRiE,EAAM,MAAA,MAAA,MAAA,EAAA;AAAA,gBAAA;;cAGVA,EAsBQ,SAAA,MAAA;AAAA,iBArBNpD,EAAA,EAAA,GAAAC,EAoBKK,WApByBgE,EAAM,SAAO,CAA/BK,GAAQjE,YAApBT,EAoBK,MAAA,EApByC,KAAKS,KAAK;AAAA,kBACtD0C,EAGK,MAAA,MAAA;AAAA,oBAFHA,EAA6B,OAAA,MAAAvC,EAArB8D,EAAO,KAAK,GAAA,CAAA;AAAA,oBACTA,EAAO,SAAlB3E,EAAA,GAAAC,EAA6E,OAA7Ec,IAA6EF,EAArB8D,EAAO,KAAK,GAAA,CAAA;;kBAEtEvB,EAGK,MAHLU,IAGK;AAAA,wBAFAa,EAAO,UAAM,EAAA,IAAS,KACzB,CAAA;AAAA,oBAAYA,EAAO,SAAnB3E,EAAA,GAAAC,EAAiF,QAAjF2E,IAAsD,OAAE/D,EAAG8D,EAAO,KAAK,GAAA,CAAA;;kBAEzEvB,EAA6D,MAA7DyB,IAA6DhE,EAA1B8D,EAAO,SAAK,EAAA,GAAA,CAAA;AAAA,kBAC/CvB,EASK,MAAA,MAAA;AAAA,oBAPKuB,EAAO,iBADfxE,EAOEC,EAAAa,CAAA,GAAA;AAAA;sBALA,MAAK;AAAA,sBACL,SAAQ;AAAA,sBACR,MAAK;AAAA,sBACJ,cAAYb,EAAAjB,CAAA,EAAC,kBAAA;AAAA,sBACb,SAAK,CAAA4C,MAAEwC,EAAKI,EAAO,QAAQ;AAAA,oBAAA;;;;;YAOvBL,EAAM,aAArBnE,EAA4EC,EAAAC,CAAA,GAAA;AAAA;cAAjD,MAAK;AAAA,cAAK,MAAK;AAAA,YAAA;yBAAQ,MAAgB;AAAA,gBAAbO,EAAAC,EAAAyD,EAAM,IAAI,GAAA,CAAA;AAAA,cAAA;;;YAE/DlB,EASM,OATN0B,IASM;AAAA,cARJtE,EAOCJ,EAAAa,CAAA,GAAA;AAAA,gBANC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACJ,SAASmD,EAAA,UAAaE,EAAM;AAAA,gBAC5B,UAAUF,EAAA,UAAQ;AAAA,gBAClB,SAAK,CAAArC,MAAEsC,EAAMC,CAAK;AAAA,cAAA;2BAClB,MAAyB;AAAA,sBAAtBlE,EAAAjB,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;;;;;;;;;;;;;;;;;;AClHjB,UAAMH,IAAQC,GACR8E,IAAOC,GACPC,IAAOC,GAAoBjF,GAAC,MAA0B,GAEtDC,IAAM3B,GAAewB,IAAU;AACrC,IAAAF,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GAEVyF,IAAUrF,EAAI,EAAE,GAChBsF,IAAStF,EAAI,EAAE,GACfuF,IAAQvF,EAAmB,IAAI,GAC/BwF,IAASxF,EAAI,EAAK;AACxB,QAAIyF;AAGJ,aAASC,EAAOZ,GAA4B;AAC1C,UAAI,CAACA,EAAK,QAAO;AAEjB,UAAI;AACF,cAAMa,IAAS,IAAI,IAAIb,CAAG;AAE1B,eAAOa,EAAO,WAAWA,EAAO;AAAA,MAClC,QAAQ;AACN,eAAOb;AAAA,MACT;AAAA,IACF;AAEA,UAAMc,IAAQ/D,EAAS,MAAMyD,EAAO,MAAM,KAAA,MAAW,EAAE;AAEvD,aAASO,IAAgB;AACvB,mBAAaJ,CAAK,GAClBA,IAAQ,WAAW,YAAY;AAC7B,YAAI;AACF,UAAAF,EAAM,QAAQ,MAAM/F,EAAI,YAAY,EAAE,OAAOF,EAAM,MAAM,OAAO,SAAS+F,EAAQ,MAAA,CAAO;AAAA,QAC1F,QAAQ;AACN,UAAAE,EAAM,QAAQ;AAAA,QAChB;AAAA,MACF,GAAG,GAAG;AAAA,IACR;AAEA,mBAAeO,IAAsB;AACnC,MAAAN,EAAO,QAAQ;AAEf,UAAI;AACF,cAAMzG,IAAO,MAAMS,EAAI,KAAK;AAAA,UAC1B,OAAOF,EAAM,MAAM;AAAA,UACnB,SAAS+F,EAAQ;AAAA,UACjB,QAAQC,EAAO;AAAA,QAAA,CAChB;AAED,QAAApC,EAAM,QAAQzD,EAAE,kBAAkB,CAAC,GACnC4E,EAAK,UAAUtF,CAAI,GACnBwF,EAAK,QAAQ;AAAA,MACf,SAASlE,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAmF,EAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AAEA,WAAArC;AAAA,MACE,CAACoB,GAAM,MAAMjF,EAAM,MAAM,EAAE;AAAA,MAC3B,CAAC,CAACyF,CAAG,MAAM;AACT,QAAKA,MAELM,EAAQ,QAAQK,EAAOpG,EAAM,MAAM,GAAG,GACtCgG,EAAO,QAAQ,IACfC,EAAM,QAAQ,MACdM,EAAA;AAAA,MACF;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK,GAGpB1C,GAAMkC,GAAS,MAAM;AACnB,MAAId,EAAK,SAAOsB,EAAA;AAAA,IAClB,CAAC,mBAICpF,EAwBYC,EAAAsE,EAAA,GAAA;AAAA,MAxBO,MAAMT,EAAA;AAAA,8CAAAA,EAAI,QAAAlC;AAAA,MAAG,OAAO3B,EAAAjB,CAAA,EAAC,iBAAA;AAAA,MAAsB,OAAO;AAAA,IAAA;MAkBxD,UACT,MAAoE;AAAA,QAApEqB,EAAoEJ,EAAAa,CAAA,GAAA;AAAA,UAAxD,gCAAOgD,EAAA,QAAI;AAAA,QAAA;qBAAU,MAAuB;AAAA,gBAApB7D,EAAAjB,CAAA,EAAC,cAAA,CAAA,GAAA,CAAA;AAAA,UAAA;;;QACrCqB,EAEcJ,EAAAa,CAAA,GAAA;AAAA,UAFH,MAAK;AAAA,UAAW,SAASiE,EAAA;AAAA,UAAS,WAAWI,EAAA;AAAA,UAAQ,SAAOE;AAAA,QAAA;qBAAM,MAE3E;AAAA,gBADApF,EAAAjB,CAAA,EAAC,WAAA,CAAA,GAAA,CAAA;AAAA,UAAA;;;;iBApBL,MAeM;AAAA,QAfNiE,EAeM,OAfNlD,IAeM;AAAA,UAdJM,EAAsDJ,EAAAC,CAAA,GAAA,EAA7C,QAAO,cAAU;AAAA,uBAAC,MAAiB;AAAA,cAAdO,EAAAC,EAAA7B,EAAM,KAAK,GAAA,CAAA;AAAA,YAAA;;;UACzCwB,EAAmEJ,EAAAC,CAAA,GAAA;AAAA,YAA1D,MAAK;AAAA,YAAK,MAAK;AAAA,UAAA;uBAAQ,MAAyB;AAAA,kBAAtBD,EAAAjB,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAEpCqB,EAEeJ,EAAAqF,EAAA,GAAA;AAAA,YAFA,OAAOrF,EAAAjB,CAAA,EAAC,mBAAA;AAAA,YAAwB,MAAMiB,EAAAjB,CAAA,EAAC,wBAAA;AAAA,UAAA;uBACpD,MAAuD;AAAA,cAAvDqB,EAAuDJ,EAAAsF,EAAA,GAAA;AAAA,4BAApCX,EAAA;AAAA,8DAAAA,EAAO,QAAAhD;AAAA,gBAAE,aAAY;AAAA,cAAA;;;;UAG1CvB,EAEeJ,EAAAqF,EAAA,GAAA;AAAA,YAFA,OAAOrF,EAAAjB,CAAA,EAAC,kBAAA;AAAA,YAAsB,UAAA;AAAA,UAAA;uBAC3C,MAA0C;AAAA,cAA1CqB,EAA0CJ,EAAAuF,EAAA,GAAA;AAAA,4BAApBX,EAAA;AAAA,8DAAAA,EAAM,QAAAjD;AAAA,gBAAG,MAAM;AAAA,cAAA;;;;UAGxBkD,EAAA,UAAK,aAApB9E,EAEYC,EAAAC,CAAA,GAAA;AAAA;YAFmB,MAAK;AAAA,YAAK,MAAK;AAAA,UAAA;uBAAQ,MAEpD;AAAA,cADAO,EAAAC,EAAAT,EAAAjB,CAAA,8BAAuB8F,EAAA,MAAA,CAAK,CAAA,GAAA,CAAA;AAAA,YAAA;;;;;;;;;;;;;;;;;;AC3FpC,UAAMjG,IAAQC,GAQR8E,IAAOC,GAEP7C,IAAUpC,GAAA,GACVG,IAAM3B,GAAe4D,CAAO,GAE5ByE,IAAMzE,EAAQ,IAAI,cAAc;AACtC,IAAAtC,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GAEVuG,IAASnG,EAAyB,IAAI,GACtCoG,IAAOpG,EAAI,EAAK,GAChBqG,IAAOrG,EAAI,CAAC,GACZC,IAAUD,EAAmB,IAAI,GACjCsG,IAAStG,EAAuB,IAAI,GACpCuG,IAASvG,EAAI,EAAK,GAClBwG,IAASxG,EAAuB,IAAI,GACpCyG,IAAazG,EAAI,EAAK;AAE5B,aAAS8F,EAAKpH,GAAyB;AACrC,MAAA8H,EAAO,QAAQ9H,GACf+H,EAAW,QAAQ;AAAA,IACrB;AAGA,aAASC,EAAO3H,GAA6B;AAC3C,MAAIoH,EAAO,SAAS,CAACpH,EAAK,UAASoH,EAAO,QAAQ,CAAA,IACzCA,EAAO,SAASK,EAAO,UAC9BL,EAAO,QAAQA,EAAO,MAAM,OAAO,CAACQ,MAAQA,EAAI,OAAOH,EAAO,OAAO,EAAE,IAEzEnC,EAAK,SAAS;AAAA,IAChB;AAEA,mBAAeuC,EAAOlI,GAAkC;AACtD,UAAKA,EAAM;AAEX,YAAI;AACF,gBAAMc,EAAI,OAAOd,EAAM,OAAO,EAAE,GAChCwE,EAAM,QAAQzD,EAAE,eAAe,CAAC,GAChC4E,EAAK,SAAS;AAAA,QAChB,SAAShE,GAAO;AACd,UAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,QAC7B;AAAA,IACF;AAEA,aAASwG,EAAInI,GAA2B;AACtC,YAAMK,IAAOL,EAAM;AAEnB,aAAKK,IAEEA,EAAK,aACRU,EAAE,kBAAkB,EAAE,KAAKV,EAAK,YAAY,QAAQA,EAAK,OAAA,CAAQ,IACjEU,EAAE,sBAAsB,EAAE,QAAQV,EAAK,QAAQ,IAJjC;AAAA,IAKpB;AAEA,aAASJ,EAAID,GAAyB;AACpC,MAAA4H,EAAO,QAAQ5H,GACf6H,EAAO,QAAQ;AAAA,IACjB;AAEA,aAASO,EAAM3I,GAAkB;AAC/B,MAAImI,EAAO,UAAOA,EAAO,MAAM,aAAanI;AAAA,IAC9C;AAEA,mBAAe8E,EAAKf,IAAO,GAAkB;AAC3C,UAAI;AACF,cAAMO,IAAS,MAAMjD,EAAI,OAAOF,EAAM,KAAK,EAAE,GAAGA,EAAM,OAAO,MAAM4C,GAAM,UAAU,IAAI;AAEvF,QAAAiE,EAAO,QAAQjE,MAAS,IAAIO,EAAO,OAAO,CAAC,GAAI0D,EAAO,SAAS,CAAA,GAAK,GAAG1D,EAAO,IAAI,GAClF4D,EAAK,QAAQ5D,EAAO,cACpB2D,EAAK,QAAQ3D,EAAO,eAAeA,EAAO;AAAA,MAC5C,SAASpC,GAAO;AACd,QAAAJ,EAAQ,QAAQN,EAAQU,CAAK;AAAA,MAC/B;AAAA,IACF;AAEA,WAAAD,GAAU,MAAM6C,GAAM,cAIpB3C,EAAA,GAAAC,EAsEM,OAtENC,IAsEM;AAAA,MArEWP,EAAA,cAAfQ,EAAuEC,EAAAC,CAAA,GAAA;AAAA;QAA/C,MAAK;AAAA,QAAK,MAAK;AAAA,MAAA;mBAAS,MAAa;AAAA,cAAVV,EAAA,KAAO,GAAA,CAAA;AAAA,QAAA;;YACjCkG,EAAA,cAEzB5F,EAiDWK,GAAA,EAAA,KAAA,KAAA;AAAA,gBAhDTL,EA6CMK,GAAA,MAAAuD,EA7CegC,EAAA,OAAM,CAAfzH,YAAZ6B,EA6CM,OAAA;AAAA,UA7CwB,KAAK7B,EAAM;AAAA,UAAI,OAAM;AAAA,QAAA;UACjDgF,EAyCM,OAzCN7C,IAyCM;AAAA,YAvCInC,EAAM,YADd+B,EAMCC,EAAAO,EAAA,GAAA;AAAA;cAJE,MAAMvC,EAAM;AAAA,cACb,QAAO;AAAA,cACP,OAAM;AAAA,YAAA;yBACL,MAAe;AAAA,gBAAZwC,EAAAC,EAAAzC,EAAM,GAAG,GAAA,CAAA;AAAA,cAAA;;;YAECA,EAAM,UAAK,cAA3B+B,EAEaC,EAAAU,CAAA,GAAA;AAAA;cAF0B,MAAK;AAAA,cAAU,MAAK;AAAA,YAAA;yBAAK,MAE9D;AAAA,oBADAV,EAAAjB,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAEaf,EAAM,mBAAtB+B,EAEaC,EAAAU,CAAA,GAAA;AAAA;cAFqB,MAAK;AAAA,cAAU,MAAK;AAAA,YAAA;yBAAK,MAEzD;AAAA,oBADAV,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;kBAGUF,EAAA,WAAWmB,EAAAwF,CAAA,KAAG,CAAKxH,EAAM,gBADtC+B,EAQCC,EAAAa,CAAA,GAAA;AAAA;cANC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,OAAM;AAAA,cACL,SAAK,CAAAc,OAAE1D,EAAID,CAAK;AAAA,YAAA;yBAChB,MAA0B;AAAA,oBAAvBgC,EAAAjB,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAGCiB,EAAAwF,CAAA,KAAOxH,EAAM,WAAWA,EAAM,eADtC+B,EAQCC,EAAAa,CAAA,GAAA;AAAA;cANC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,OAAM;AAAA,cACL,SAAK,CAAAc,OAAEuE,EAAOlI,CAAK;AAAA,YAAA;yBACnB,MAAsB;AAAA,oBAAnBgC,EAAAjB,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;kCAGMiB,EAAAwF,CAAA,KAAG,CAAKxH,EAAM,gBAD3B+B,EAQCC,EAAAa,CAAA,GAAA;AAAA;cANC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACJ,OAAKwF,GAAA,EAAA,wBAAA,CAA6BxH,EAAA,WAAWb,EAAM,YAAU;AAAA,cAC7D,SAAK,CAAA2D,OAAEyD,EAAKpH,CAAK;AAAA,YAAA;yBACjB,MAAoB;AAAA,oBAAjBgC,EAAAjB,CAAA,EAAC,WAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;UAGMf,EAAM,eAArB+B,EAA8EC,EAAAC,CAAA,GAAA;AAAA;YAAjD,MAAK;AAAA,YAAK,MAAK;AAAA,UAAA;uBAAQ,MAAgB;AAAA,cAAbO,EAAAC,EAAA0F,EAAInI,CAAK,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAChEoC,EAA0CkG,IAAA;AAAA,YAA1B,SAAStI,EAAM;AAAA,UAAA;;QAGhB0H,EAAA,cAAjB3F,EAAqFC,EAAAa,CAAA,GAAA;AAAA;UAA9D,MAAK;AAAA,UAAK,SAAQ;AAAA,UAAQ,SAAKiC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAEY,EAAKoD,EAAA,QAAI,CAAA;AAAA,QAAA;qBAAO,MAAC,CAAA,GAAA7C,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA;AAAA,cAAD,KAAC,EAAA;AAAA,UAAA;;;sBAlD3E/C,EAA6CC,EAAAc,EAAA,GAAA;AAAA;QAAX,MAAM;AAAA,MAAA;MAsDhC8E,EAAA,cADR7F,EAMEwG,IAAA;AAAA;QAJQ,MAAMV,EAAA;AAAA,gDAAAA,EAAM,QAAAlE;AAAA,QACnB,KAAK9C,EAAA;AAAA,QACL,OAAO+G,EAAA;AAAA,QACP,SAAOQ;AAAA,MAAA;MAIFN,EAAA,cADR/F,EAMEyG,IAAA;AAAA;QAJQ,MAAMT,EAAA;AAAA,gDAAAA,EAAU,QAAApE;AAAA,QACvB,OAAOmE,EAAA;AAAA,QACP,OAAOlH,EAAM,SAASkH,EAAA,MAAO;AAAA,QAC7B,UAAQE;AAAA,MAAA;;;;;;;;;ACpJf,UAAMpH,IAAQC,GAERC,IAAM3B,GAAewB,IAAU;AACrC,IAAAF,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7B8C,IAAQ9C,GAAa,YAAY,GACjCC,IAAUC,GAAA,GAEVtB,IAAM0B,EAAmB,IAAI,GAC7BmH,IAASnH,EAA4B,IAAI,GACzC0C,IAAU1C,EAAI,EAAK,GACnB6C,IAAW7C,EAAyB,EAAE,GAEtCoH,IAAWpH,EAA0B,IAAI,GACzCqH,IAAQrH,EAAmB,IAAI,GAG/BsH,IAAQtH,EAAkB,IAAI,GAE9BtC,IAAQmE,EAAS,OAAO,EAAE,UAAUuF,EAAS,OAAO,OAAOC,EAAM,OAAO,OAAOC,EAAM,QAAQ,GAC7FC,IAAe1F;AAAA,MACnB,MAAM,CAACuF,EAAS,OAAOC,EAAM,OAAOC,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE;AAAA,IAAA,GAG7DE,IAA0C;AAAA,MAC9C,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,IAAA,GAGJjJ,IAAUsD,EAAuC,MAAM;AAAA,MAC3D,EAAE,KAAK,YAAY,OAAOpC,EAAE,eAAe,GAAG,OAAO,IAAA;AAAA,MACrD,EAAE,KAAK,SAAS,OAAOA,EAAE,YAAY,EAAA;AAAA,MACrC,EAAE,KAAK,SAAS,OAAOA,EAAE,YAAY,GAAG,OAAO,KAAK,OAAO,QAAA;AAAA,IAAQ,CACpE,GAEKgI,IAAkB5F;AAAA,MAAS,MAC9B,CAAC,SAAS,WAAW,QAAQ,EAAY,IAAI,CAACpD,OAAW;AAAA,QACxD,OAAAA;AAAA,QACA,OAAOgB,EAAE,iBAAiBhB,CAAK,EAAE;AAAA,MAAA,EACjC;AAAA,IAAA,GAGEiJ,IAAe7F;AAAA,MAAS,MAC5B;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,EACA,IAAI,CAACpD,OAAW,EAAE,OAAAA,GAAO,OAAOgB,EAAE,cAAchB,CAAK,EAAE,EAAA,EAAI;AAAA,IAAA,GAGzDkJ,IAAe9F;AAAA,MAAS,MAC3B,CAAC,OAAO,cAAc,QAAQ,EAAY,IAAI,CAACpD,OAAW;AAAA,QACzD,OAAAA;AAAA,QACA,OAAOgB,EAAE,cAAchB,CAAK,EAAE;AAAA,MAAA,EAC9B;AAAA,IAAA;AAIJ,aAASuE,EAAuBvE,GAAiE;AAC/F,aAAO,OAAOA,KAAU,YAAYA,MAAU,KAAMA,IAAc;AAAA,IACpE;AAEA,mBAAewE,IAAsB;AACnC,MAAAP,EAAQ,QAAQ;AAEhB,UAAI;AACF,QAAIpE,EAAI,UAAU,SAChBA,EAAI,SAAS,MAAMkB,EAAI,UAAU,MAAM,MAAM,OAG/C2H,EAAO,QAAQ7I,EAAI,UAAU,OAAO,CAAA,IAAK,MAAMkB,EAAI,OAAOlB,EAAI,OAAOZ,EAAM,KAAK,GAChFmF,EAAS,QAAQ,CAAA;AAAA,MACnB,SAASxC,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAqC,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAEA,WAAAS,GAAMzF,GAAO;AAAM,MAAKuF;KAAM,GAE9B7C,GAAU6C,CAAI,mBAIZxC,EAkFe2C,IAAA;AAAA,MAlFA,MAAM9D,EAAM;AAAA,MAAM,SAAQ;AAAA,IAAA;iBACvC,MAgFW;AAAA,QAhFXwB,EAgFWJ,EAAA2C,EAAA,GAAA;AAAA,UA/ED,UAAUR,EAAA;AAAA,sDAAAA,EAAQ,QAAAR;AAAA,UACzB,MAAM8E,EAAA,SAAM,CAAA;AAAA,UACZ,SAAS5I,EAAA;AAAA,UACV,WAAQ;AAAA,UACR,YAAA;AAAA,UACA,OAAA;AAAA,UACC,SAASmE,EAAA;AAAA,UACT,iBAAe6E,EAAA;AAAA,UACf,iBAAe7G,EAAA8B,CAAA,EAAK,eAAA;AAAA,UACpB,cAAYlE,EAAA,UAAG,OAAYoC,EAAAjB,CAAA,kBAAkBiB,EAAAjB,CAAA,EAAC,YAAA;AAAA,QAAA;UAEpC,WACT,MAsBM;AAAA,YAtBNiE,EAsBM,OAtBNlD,IAsBM;AAAA,cArBJM,EAMEJ,EAAA6C,EAAA,GAAA;AAAA,gBALC,eAAa6D,EAAA;AAAA,gBACb,SAASK,EAAA;AAAA,gBACT,aAAa/G,EAAAjB,CAAA,EAAC,mBAAA;AAAA,gBACf,WAAA;AAAA,gBACC,uBAAkB+D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAE+E,EAAA,QAAWpE,EAAoBX,CAAM;AAAA,cAAA;cAE5DvB,EAMEJ,EAAA6C,EAAA,GAAA;AAAA,gBALC,eAAa8D,EAAA;AAAA,gBACb,SAASK,EAAA;AAAA,gBACT,aAAahH,EAAAjB,CAAA,EAAC,gBAAA;AAAA,gBACf,WAAA;AAAA,gBACC,uBAAkB+D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAEgF,EAAA,QAAQrE,EAAKX,CAAM;AAAA,cAAA;cAE1CvB,EAMEJ,EAAA6C,EAAA,GAAA;AAAA,gBALC,eAAa+D,EAAA;AAAA,gBACb,SAASK,EAAA;AAAA,gBACT,aAAajH,EAAAjB,CAAA,EAAC,gBAAA;AAAA,gBACf,WAAA;AAAA,gBACC,uBAAkB+D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAEiF,EAAA,QAAQtE,EAAYX,CAAM;AAAA,cAAA;;;UAK1C,iBAAaoB,EACtB,CAEa,EAHa,KAAAH,QAAG;AAAA,YAC7BxC,EAEaJ,EAAAU,CAAA,GAAA;AAAA,cAFF,MAAMoG,EAAMlE,EAAI,QAAQ;AAAA,cAAG,KAAA;AAAA,YAAA;yBAAI,MAExC;AAAA,oBADA5C,EAAAjB,CAAA,EAAC,iBAAkB6D,EAAI,QAAQ,EAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;UAIxB,cAAUG,EACnB,CAsBO,EAvBgB,KAAAH,QAAG;AAAA,YAC1BI,EAsBO,QAtBP7C,IAsBO;AAAA,cArBLC,EAA4CJ,EAAAC,CAAA,GAAA,EAAnC,MAAK,QAAI;AAAA,2BAAC,MAAe;AAAA,kBAAZO,EAAAC,EAAAmC,EAAI,KAAK,GAAA,CAAA;AAAA,gBAAA;;;cACfA,EAAI,MAAG,UAAvB7C,EAA0FC,EAAAU,CAAA,GAAA;AAAA;gBAA7D,MAAK;AAAA,gBAAU,MAAK;AAAA,cAAA;2BAAK,MAAyB;AAAA,sBAAtBV,EAAAjB,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;cAC1DqB,EAkBaJ,EAAAkH,EAAA,GAAA;AAAA,gBAlBA,OAAOtE,EAAI;AAAA,gBAAO,OAAM;AAAA,cAAA;gBACxB,WACT,MAME;AAAA,kBANFxC,EAMEJ,EAAAa,CAAA,GAAA;AAAA,oBALA,MAAK;AAAA,oBACL,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACJ,cAAYb,EAAAjB,CAAA,EAAC,cAAA;AAAA,oBACb,4BAAD,MAAA;AAAA,oBAAA,GAAW,CAAA,MAAA,CAAA;AAAA,kBAAA;;2BAGf,MAOK;AAAA,kBAPLiE,EAOK,MAPLrC,IAOK;AAAA,oBANHqC,EAA8B,cAAvBhD,EAAAjB,CAAA,EAAC,YAAA,CAAA,GAAA,CAAA;AAAA,oBACRiE,EAAwB,MAAA,MAAAvC,EAAjBmC,EAAI,KAAK,GAAA,CAAA;AAAA,oBAChBI,EAA4B,cAArBhD,EAAAjB,CAAA,EAAC,UAAA,CAAA,GAAA,CAAA;AAAA,oBACRiE,EAAsB,MAAA,MAAAvC,EAAfmC,EAAI,GAAG,GAAA,CAAA;AAAA,oBACdI,EAA4B,cAArBhD,EAAAjB,CAAA,EAAC,UAAA,CAAA,GAAA,CAAA;AAAA,oBACRiE,EAAsB,MAAA,MAAAvC,EAAfmC,EAAI,GAAG,GAAA,CAAA;AAAA,kBAAA;;;;;;UAMX,UAAQG,EACjB,CAOE,EARmB,KAAAH,QAAG;AAAA,YAEhBhF,EAAA,UAAG,aADXmC,EAOEoH,IAAA;AAAA;cALC,KAAKvJ,EAAA;AAAA,cACL,OAAK,EAAA,GAAOZ,EAAA,OAAK,OAAS4F,EAAI,GAAA;AAAA,cAC9B,UAAUA,EAAI,aAAa,SAAM;AAAA,cACjC,OAAOA,EAAI;AAAA,cACX,WAASL;AAAA,YAAA;;;;;;;;;;;;;;GCjKd6E,KAAU;;;;;;AAThB,UAAMxI,IAAQC,GAERkC,IAAUpC,GAAA,GACVG,IAAM3B,GAAe4D,CAAO;AAClC,IAAAtC,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GAIVmI,IAAS/H,EAAwB,IAAI,GACrC5B,IAAQ4B,EAAgB,OAAO,GAC/BgI,IAAWhI,EAAI,EAAK;AAC1B,QAAIyF;AAEJ,UAAMwC,IAASxG,EAAQ,IAAI,WAAW,KAAKA,EAAQ,IAAI,cAAc,GAE/DyG,IAASrG,EAAS,MAAMkG,EAAO,OAAO,UAAU,IAAI,GACpDI,IAAOtG,EAAS,MAAMkG,EAAO,OAAO,QAAQ,IAAI,GAChDK,IAASvG,EAAS,MAAMsG,EAAK,OAAO,UAAU,IAAI,GAElDE,IAASxG,EAAS,MAAM;AAAA,MAC5B,EAAE,OAAO,SAAS,OAAOpC,EAAE,kBAAkB,EAAA;AAAA,MAC7C,EAAE,OAAO,QAAQ,OAAOA,EAAE,iBAAiB,EAAA;AAAA,IAAE,CAC9C,GAEK6I,IAA2F;AAAA,MAC/F,EAAE,KAAK,SAAS,OAAO,eAAe,MAAM,SAAA;AAAA,MAC5C,EAAE,KAAK,WAAW,OAAO,iBAAiB,MAAM,UAAA;AAAA,MAChD,EAAE,KAAK,UAAU,OAAO,gBAAgB,MAAM,OAAA;AAAA,IAAO,GAGjDC,IAAQ1G,EAAS,MAAMuG,EAAO,OAAO,gBAAgB,IAAI,GAEzDI,IAAe3G,EAAyB,MAAM;AAClD,YAAM4G,IAASL,EAAO,OAAO,UAAU;AAEvC,aAAIK,KAAU,KAAW,YACrBA,KAAU,KAAW,YAElB;AAAA,IACT,CAAC,GAGKC,IAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,GAGIC,IAAS9G;AAAA,MAAS,MACtB,OAAO,QAAQuG,EAAO,OAAO,UAAU,EAAE,EAAE,IAAI,CAAC,CAACjK,GAAIyK,CAAU,OAAO;AAAA,QACpE,IAAAzK;AAAA,QACA,OAAOsB,EAAE,cAAciJ,EAAO,SAASvK,CAAE,IAAIA,IAAK,OAAO,EAAE;AAAA,QAC3D,YAAAyK;AAAA,MAAA,EACA;AAAA,IAAA;AAGJ,aAASC,EAAWvK,GAAuB;AACzC,aAAIA,EAAI,WAAW,WAAiBmB,EAAE,oBAAoB,IAEnDnB,EAAI,SAAS,QAAQmB,EAAE,cAAcnB,EAAI,SAAS,KAAK,EAAE,IAAImB,EAAE,qBAAqB;AAAA,IAC7F;AAEA,mBAAewD,IAAsB;AACnC,UAAI;AACF,QAAA8E,EAAO,QAAQ,MAAMvI,EAAI,OAAA;AAAA,MAC3B,SAASa,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B;AAEA,mBAAaoF,CAAK,GAEdsC,EAAO,OAAO,WAChBtC,IAAQ,WAAW,MAAA;AAAM,QAAKxC,EAAA;AAAA,SAAQ6E,EAAO;AAAA,IAEjD;AAEA,mBAAegB,IAAuB;AACpC,MAAAd,EAAS,QAAQ;AAEjB,UAAI;AACF,cAAMxI,EAAI,MAAMpB,EAAM,KAAK,GAC3B8E,EAAM,QAAQzD,EAAE,cAAc,CAAC,GAC/B,MAAMwD,EAAA;AAAA,MACR,SAAS5C,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAA2H,EAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,mBAAee,EAAOzK,GAA8B;AAClD,UAAI;AACF,cAAMkB,EAAI,OAAOlB,EAAI,EAAE,GACvB,MAAM2E,EAAA;AAAA,MACR,SAAS5C,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B;AAAA,IACF;AAEA,WAAAD,GAAU6C,CAAI,GACd+F,GAAgB,MAAM,aAAavD,CAAK,CAAC,mBAIvChF,EAyKe2C,IAAA;AAAA,MAzKA,MAAM9D,EAAM;AAAA,MAAM,SAAQ;AAAA,MAAY,MAAM;AAAA,IAAA;iBACzD,MAuKM;AAAA,QAvKNoE,EAuKM,OAvKNlD,IAuKM;AAAA,UAtKYuH,EAAA,cAEhBxH,EAmKWK,GAAA,EAAA,KAAA,KAAA;AAAA,YAlKOmH,EAAA,MAAO,MAAM,aAA7BtH,EAAwFC,EAAAuI,EAAA,GAAA;AAAA;cAArD,MAAK;AAAA,cAAW,aAAavI,EAAAjB,CAAA,EAAC,iBAAA;AAAA,YAAA;YAGzDsI,EAAA,MAAO,QAAQA,QAAO,KAAK,WAAM,iBADzCtH,EAIEC,EAAAuI,EAAA,GAAA;AAAA;cAFA,MAAK;AAAA,cACJ,aAAavI,EAAAjB,CAAA,EAAC,oBAAA,EAAA,OAA8BsI,QAAO,KAAK,SAAK,GAAA,CAAA;AAAA,YAAA;YAGjDG,EAAA,cAAfzH,EA2BUC,EAAAwI,EAAA,GAAA;AAAA;cA3Ba,OAAM;AAAA,YAAA;yBAC3B,MAYM;AAAA,gBAZNxF,EAYM,OAZN7C,IAYM;AAAA,kBAXJC,EAA6DJ,EAAAC,CAAA,GAAA,EAApD,QAAO,cAAU;AAAA,+BAAC,MAAwB;AAAA,sBAArBO,EAAAC,EAAA0H,EAAWX,EAAA,KAAM,CAAA,GAAA,CAAA;AAAA,oBAAA;;;kBAC/CpH,EAEYJ,EAAAC,CAAA,GAAA;AAAA,oBAFH,MAAK;AAAA,oBAAK,MAAK;AAAA,oBAAQ,OAAM;AAAA,kBAAA;+BAAyB,MAE7D;AAAA,sBADAO,EAAAC,EAAA+G,EAAA,MAAO,QAAQ,GAAA,CAAA;AAAA,oBAAA;;;kBAGTxH,EAAAuH,CAAA,UADRxH,EAMCC,EAAAa,CAAA,GAAA;AAAA;oBAJC,MAAK;AAAA,oBACL,OAAM;AAAA,oBACL,SAAKiC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAE0G,EAAOb,EAAA,KAAM;AAAA,kBAAA;+BACpB,MAAsB;AAAA,0BAAnBxH,EAAAjB,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;gBAGTqB,EAA8DJ,EAAAyI,EAAA,GAAA;AAAA,kBAAjD,eAAA;AAAA,kBAAe,cAAYN,EAAWX,EAAA,KAAM;AAAA,gBAAA;gBAC1CA,EAAA,MAAO,SAAS,kBAA/BzH,EAKYC,EAAAC,CAAA,GAAA;AAAA;kBAL8B,MAAK;AAAA,kBAAK,MAAK;AAAA,gBAAA;6BAAQ,MAK/D;AAAA,wBAJAD,EAAAjB,CAAA,EAAC,2BAAA;AAAA,sBAAqD,SAAAyI,EAAA,MAAO,SAAS,UAAU;AAAA,sBAA8B,OAAAA,EAAA,MAAO,SAAS,UAAU;AAAA,oBAAA;;;sBAKtHA,EAAA,MAAO,SAAS,UAAK,gBAAzCzH,EAKYC,EAAAC,CAAA,GAAA;AAAA;kBAL2C,MAAK;AAAA,kBAAK,MAAK;AAAA,gBAAA;6BAAQ,MAK5E;AAAA,wBAJAD,EAAAjB,CAAA,EAAC,uBAAA;AAAA,sBAAiD,SAAAyI,EAAA,MAAO,SAAS,MAAM;AAAA,sBAA8B,OAAAA,EAAA,MAAO,SAAS,MAAM;AAAA,oBAAA;;;;;;kBAO5GxH,EAAAuH,CAAA,KAAM,CAAKF,EAAA,MAAO,MAAM,aAA5CtH,EAeUC,EAAAwI,EAAA,GAAA,EAAA,KAAA,KAAA;AAAA,yBAdR,MAaM;AAAA,gBAbNxF,EAaM,OAbNrC,IAaM;AAAA,kBAZJP,EAAgFJ,EAAA0I,EAAA,GAAA;AAAA,gCAAzDhL,EAAA;AAAA,kEAAAA,EAAK,QAAAiE;AAAA,oBAAG,SAASgG,EAAA;AAAA,oBAAS,cAAY3H,EAAAjB,CAAA,EAAC,YAAA;AAAA,kBAAA;kBAC9DqB,EAEYJ,EAAAC,CAAA,GAAA;AAAA,oBAFH,MAAK;AAAA,oBAAK,MAAK;AAAA,kBAAA;+BAAQ,MAE9B;AAAA,0BADAvC,EAAA,UAAK,SAAcsC,EAAAjB,CAAA,EAAC,sBAAA,IAA2BiB,EAAAjB,CAAA,EAAC,uBAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;kBAElDqB,EAOCJ,EAAAa,CAAA,GAAA;AAAA,oBANC,MAAK;AAAA,oBACL,MAAK;AAAA,oBACJ,SAASyG,EAAA;AAAA,oBACV,OAAM;AAAA,oBACL,SAAOc;AAAA,kBAAA;+BACP,MAAmB;AAAA,0BAAhBpI,EAAAjB,CAAA,EAAC,UAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;;;;YAKK,CAAA0I,EAAA,UAASD,EAAA,cAAzBzH,EAMUC,EAAAwI,EAAA,GAAA,EAAA,KAAA,KAAA;AAAA,yBALR,MAIE;AAAA,gBAJFpI,EAIEJ,EAAA2I,EAAA,GAAA;AAAA,kBAHA,MAAK;AAAA,kBACJ,OAAO3I,EAAAjB,CAAA,EAAC,YAAA;AAAA,kBACR,aAAaiB,EAAAjB,CAAA,EAAC,iBAAA;AAAA,gBAAA;;;;YAIH0I,EAAA,SAAQC,EAAA,cAAxB7H,EAmGWK,GAAA,EAAA,KAAA,KAAA;AAAA,cAlGTE,EA6CUJ,EAAAwI,EAAA,GAAA,MAAA;AAAA,2BA5CR,MAkCM;AAAA,kBAlCNxF,EAkCM,OAlCNU,IAkCM;AAAA,oBAjCJV,EAqBM,OArBNwB,IAqBM;AAAA,sBApBJpE,EAOEJ,EAAAyI,EAAA,GAAA;AAAA,wBANA,MAAK;AAAA,wBACJ,OAAOf,EAAA,MAAO;AAAA,wBACd,QAAQI,EAAA;AAAA,wBACT,cAAA;AAAA,wBACC,WAAS,CAAG/J,MAAa,GAAQA,CAAK;AAAA,wBACtC,cAAYiC,EAAAjB,CAAA,EAAC,aAAA;AAAA,sBAAA;sBAEL8I,EAAA,SAAXjI,EAAA,GAAAC,EAWM,OAXN4E,IAWM;AAAA,wBAVWoD,EAAA,MAAM,QAAK,UAA1B9H,EAEYC,EAAAC,CAAA,GAAA;AAAA;0BAFoB,MAAK;AAAA,wBAAA;qCAAK,MAExC;AAAA,4BADAO,EAAAC,EAAAT,EAAAjB,CAAA,gCAAgC8I,EAAA,MAAM,OAAK,OAASA,EAAA,MAAM,OAAK,CAAA,GAAA,CAAA;AAAA,0BAAA;;;wBAElDA,EAAA,MAAM,cAAW,UAAhC9H,EAEYC,EAAAC,CAAA,GAAA;AAAA;0BAF0B,MAAK;AAAA,0BAAK,MAAK;AAAA,wBAAA;qCAAS,MAE5D;AAAA,gCADAD,EAAAjB,CAAA,EAAC,oBAAA,EAAA,OAA8B8I,EAAA,MAAM,YAAA,CAAW,CAAA,GAAA,CAAA;AAAA,0BAAA;;;wBAEnCA,EAAA,MAAM,WAAQ,UAA7B9H,EAEYC,EAAAC,CAAA,GAAA;AAAA;0BAFuB,MAAK;AAAA,0BAAK,MAAK;AAAA,wBAAA;qCAAU,MAE1D;AAAA,gCADAD,EAAAjB,CAAA,EAAC,wBAAA,EAAA,OAAkC8I,EAAA,MAAM,SAAA,CAAQ,CAAA,GAAA,CAAA;AAAA,0BAAA;;;wBAEnDzH,EAAqEJ,EAAAC,CAAA,GAAA;AAAA,0BAA5D,MAAK;AAAA,0BAAK,MAAK;AAAA,wBAAA;qCAAQ,MAA2B;AAAA,gCAAxBD,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,0BAAA;;;;;oBAGxCiE,EAUM,OAVN0B,IAUM;AAAA,4BATJ7E,EAMEK,GAAA,MAAAuD,EALmBmE,GAAU,CAAtBlB,MADTtG,EAMEJ,EAAA4I,EAAA,GAAA;AAAA,wBAJC,KAAKlC,EAAS;AAAA,wBACd,OAAO1G,EAAAjB,CAAA,EAAE2H,EAAS,KAAK;AAAA,wBACvB,OAAOgB,EAAA,MAAO,SAAShB,EAAS,GAAG,KAAA;AAAA,wBACnC,OAAOgB,EAAA,MAAO,SAAShB,EAAS,GAAG,KAAA,KAAA,IAAcA,EAAS,OAAI;AAAA,sBAAA;sBAEjEtG,EAA2DJ,EAAA4I,EAAA,GAAA;AAAA,wBAA5C,OAAO5I,EAAAjB,CAAA,EAAC,UAAA;AAAA,wBAAe,OAAO2I,EAAA,MAAO;AAAA,sBAAA;sBACpDtH,EAA8EJ,EAAA4I,EAAA,GAAA;AAAA,wBAA/D,OAAO5I,EAAAjB,CAAA,EAAC,YAAA;AAAA,wBAAiB,OAAO2I,EAAA,MAAO;AAAA,wBAAO,MAAK;AAAA,sBAAA;;;kBAGtE1E,EAQM,OARN6F,IAQM;AAAA,oBAPJzI,EAGUJ,EAAAC,CAAA,GAAA;AAAA,sBAHD,MAAK;AAAA,sBAAK,MAAK;AAAA,oBAAA;iCACtB,MAAwB;AAAA,wBAArBO,EAAAC,EAAAT,EAAAjB,CAAA,sBAAqB,KAAC,CAAA;AAAA,wBAAAqB,EAAqCJ,EAAAiD,EAAA,GAAA;AAAA,0BAA3B,OAAOwE,EAAA,MAAK;AAAA,wBAAA;wBAAejH,EAAA,UAC3DR,EAAAjB,CAAA,EAAC,cAAe0I,QAAK,KAAK,OAAM,OACrC,CAAA;AAAA,sBAAA;;;oBACArH,EAEYJ,EAAAC,CAAA,GAAA;AAAA,sBAFH,MAAK;AAAA,sBAAK,MAAK;AAAA,sBAAQ,OAAM;AAAA,oBAAA;iCAAyB,MAE7D;AAAA,wBADAO,EAAAC,EAAAgH,EAAA,MAAK,QAAQ,GAAA,CAAA;AAAA,sBAAA;;;;;;;cAKJQ,EAAA,MAAO,eAAtBlI,EAgBUC,EAAAwI,EAAA,GAAA;AAAA;gBAhBqB,OAAOxI,EAAAjB,CAAA,EAAC,eAAA;AAAA,cAAA;2BACrC,MAcK;AAAA,kBAdLiE,EAcK,MAdL8F,IAcK;AAAA,4BAbHjJ,EAYKK,GAAA,MAAAuD,EAZewE,EAAA,OAAM,CAAftB,YAAX9G,EAYK,MAAA;AAAA,sBAZwB,KAAK8G,EAAM;AAAA,oBAAA;sBACtCvG,EAA8CJ,EAAAC,CAAA,GAAA,EAArC,MAAK,QAAI;AAAA,mCAAC,MAAiB;AAAA,0BAAdO,EAAAC,EAAAkG,EAAM,KAAK,GAAA,CAAA;AAAA,wBAAA;;;sBACjC3D,EASO,QATP+F,IASO;AAAA,8BARLlJ,EAOWK,GAAA,MAAAuD,EAPkBmE,GAAU,CAAtBlB;0BAA8B,KAAAA,GAAS;AAAA,wBAAA;2BAE7CC,EAAM,WAAWD,GAAS,GAAG,KAAA,KAAA,UADtC3G,EAKCC,EAAAU,CAAA,GAAA;AAAA;4BAHE,MAAMgG,GAAS;AAAA,4BAChB,MAAK;AAAA,0BAAA;uCACJ,MAAuB;AAAA,8BAApBlG,EAAAC,EAAAT,EAAAjB,CAAA,EAAE2H,GAAS,KAAK,CAAA,IAAI,QAAGjG,EAAGkG,EAAM,WAAWD,GAAS,GAAG,CAAA,GAAA,CAAA;AAAA,4BAAA;;;;;;;;;wCAQvE3G,EAEUC,EAAAwI,EAAA,GAAA,EAAA,KAAA,KAAA;AAAA,2BADR,MAAmE;AAAA,kBAAnEpI,EAAmEJ,EAAA2I,EAAA,GAAA;AAAA,oBAAzD,MAAK;AAAA,oBAAgB,OAAO3I,EAAAjB,CAAA,EAAC,YAAA;AAAA,oBAAgB,MAAK;AAAA,kBAAA;;;;cAG9DqB,EA4BUJ,EAAAwI,EAAA,GAAA,MAAA;AAAA,gBA3BG,UACT,MAaO;AAAA,kBAbPxF,EAaO,QAbPgG,IAaO;AAAA,oBAZFxI,EAAAC,EAAAT,EAAAjB,CAAA,qBAAoB,KACvB,CAAA;AAAA,oBAAAqB,EAUaJ,EAAAkH,EAAA,GAAA;AAAA,sBAVA,OAAOlH,EAAAjB,CAAA,EAAC,cAAA;AAAA,sBAAmB,OAAO;AAAA,sBAAK,UAAA;AAAA,oBAAA;sBACvC,WACT,MAKE;AAAA,wBALFqB,EAKEJ,EAAAa,CAAA,GAAA;AAAA,0BAJA,SAAQ;AAAA,0BACR,MAAK;AAAA,0BACL,MAAK;AAAA,0BACJ,cAAYb,EAAAjB,CAAA,EAAC,yBAAA;AAAA,wBAAA;;iCAGlB,MAAyD;AAAA,wBAAzDqB,EAAyDJ,EAAAC,CAAA,GAAA,EAAhD,MAAK,QAAI;AAAA,qCAAC,MAA4B;AAAA,gCAAzBD,EAAAjB,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,0BAAA;;;;;;;;2BAI7B,MAIM;AAAA,kBAJNiE,EAIM,OAJNiG,IAIM;AAAA,qBAHJrJ,EAAA,EAAA,GAAAC,EAEaK,WAFcwH,EAAA,MAAO,QAAQ,WAAzBwB,YAAjBnJ,EAEaC,EAAAU,CAAA,GAAA;AAAA,sBAFwC,KAAKwI;AAAA,sBAAQ,MAAK;AAAA,oBAAA;iCAAU,MAE/E;AAAA,4BADAA,CAAM,GAAA,CAAA;AAAA,sBAAA;;;;kBAGCxB,EAAA,MAAO,QAAQ,QAAQ,UAAlC9H,KAAAC,EAKM,OALNsJ,IAKM;AAAA,oBAJJ/I,EAA2EJ,EAAAC,CAAA,GAAA;AAAA,sBAAlE,MAAK;AAAA,sBAAK,MAAK;AAAA,oBAAA;iCAAU,MAA+B;AAAA,4BAA5BD,EAAAjB,CAAA,EAAC,sBAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;qBACtCa,EAAA,EAAA,GAAAC,EAEaK,WAFcwH,EAAA,MAAO,QAAQ,UAAzBwB,YAAjBnJ,EAEaC,EAAAU,CAAA,GAAA;AAAA,sBAFuC,KAAKwI;AAAA,sBAAQ,MAAK;AAAA,oBAAA;iCAAU,MAE9E;AAAA,4BADAA,CAAM,GAAA,CAAA;AAAA,sBAAA;;;;;;;;0BAhKhBnJ,EAA2DC,EAAAwI,EAAA,GAAA,EAAA,KAAA,KAAA;AAAA,uBAAnC,MAAyB;AAAA,cAAzBpI,EAAyBJ,EAAAc,EAAA,GAAA,EAAX,MAAM,GAAC;AAAA,YAAA;;;;;;;;;ACzI5C,SAASsI,GAASxG,GAAgC;AACvD,SAAOA,EAAI,WAAWA,EAAI,WAAW,QAAQA,EAAI,SAAS,OAAOA,EAAI,UAAU;AACjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCCgEMwE,KAAU;;;;;;;;;;AA3BhB,UAAMxI,IAAQC,GAUR8E,IAAOC,GAOP7C,IAAUpC,GAAA,GACVG,IAAM3B,GAAe4D,CAAO,GAC5B5B,IAASC,GAAA;AACf,IAAAX,GAAA;AAEA,UAAM8I,IAASxG,EAAQ,IAAI,WAAW,KAAKA,EAAQ,IAAI,cAAc,GAC/DsI,IAAU/J,EAAqB,IAAI,GACnCgK,IAAahK,EAAI,EAAK;AAC5B,QAAIyF;AAKJ,mBAAewE,IAA8B;AAC3C,UAAKC,EAAK,OAEV;AAAA,QAAAF,EAAW,QAAQ,IACnBD,EAAQ,QAAQ;AAEhB,YAAI;AACF,UAAAI,EAAO,MAAM3K,EAAI,MAAM,QAAQ,CAAC0K,EAAK,MAAM,KAAK,GAAG,CAAC,CAAC;AAAA,QACvD,SAAS7J,GAAO;AACd,UAAA2J,EAAW,QAAQ,IACnB9G,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,QAC7B;AAAA;AAAA,IACF;AAEA,aAAS8J,EAAO7L,GAAqB;AAGnC,UAFA,aAAamH,CAAK,GAEdnH,EAAI,WAAW,YAAYA,EAAI,WAAW,WAAW;AACvD,QAAAmH,IAAQ,WAAW,YAAY;AAC7B,cAAI;AACF,YAAA0E,EAAO,MAAM3K,EAAI,IAAIlB,EAAI,EAAE,CAAC;AAAA,UAC9B,SAAS+B,GAAO;AACd,YAAA2J,EAAW,QAAQ,IACnB9G,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,UAC7B;AAAA,QACF,GAAGyH,EAAO;AAEV;AAAA,MACF;AAEA,MAAAkC,EAAW,QAAQ,IACnBD,EAAQ,QAAQzL;AAAA,IAClB;AAEA,aAAS8L,IAAuB;AAC9B,MAAIL,EAAQ,SAASzK,EAAM,QACpBO,EAAO,KAAK,EAAE,MAAM,GAAGP,EAAM,IAAI,SAAS,OAAO,EAAE,IAAI,OAAOyK,EAAQ,MAAM,EAAE,EAAA,GAAK;AAAA,IAE5F;AAEA,IAAAf,GAAgB,MAAM,aAAavD,CAAK,CAAC;AAEzC,UAAMhG,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GAEVsK,IAAOlK,EAA0B,IAAI,GACrCC,IAAUD,EAAmB,IAAI,GACjCqK,IAAMrK,EAAc,UAAU,GAC9BsK,IAAQtK,EAAoC,IAAI,GAChDuK,IAAevK,EAAI,EAAK,GACxBwK,IAAYxK,EAAwC,IAAI,GACxDyK,IAAmBzK,EAAI,EAAK,GAE5B0K,IAAmC,CAAC,UAAU,OAAO,IAAI,GAEzDnG,IAAO1C,EAAS;AAAA,MACpB,KAAK,MAAMvC,EAAM,WAAW;AAAA,MAC5B,KAAK,CAACb,MAAU;AACd,QAAKA,KAAO4F,EAAK,OAAO;AAAA,MAC1B;AAAA,IAAA,CACD,GAEKsG,IAAO9I,EAAoB,MAAM;AAAA,MACrC,EAAE,OAAO,YAAY,OAAOpC,EAAE,oBAAoB,EAAA;AAAA,MAClD,EAAE,OAAO,UAAU,OAAOA,EAAE,kBAAkB,GAAG,OAAOyK,EAAK,OAAO,OAAO,UAAU,OAAA;AAAA,MACrF,EAAE,OAAO,MAAM,OAAOzK,EAAE,oBAAoB,GAAG,OAAOyK,EAAK,OAAO,OAAO,YAAY,OAAA;AAAA,MACrF,EAAE,OAAO,OAAO,OAAOzK,EAAE,oBAAoB,GAAG,OAAOyK,EAAK,OAAO,OAAO,YAAY,OAAA;AAAA,MACtF,EAAE,OAAO,UAAU,OAAOzK,EAAE,kBAAkB,GAAG,OAAOyK,EAAK,OAAO,OAAO,UAAU,OAAA;AAAA,MACrF,EAAE,OAAO,OAAO,OAAOzK,EAAE,eAAe,GAAG,OAAOyK,EAAK,OAAO,OAAO,OAAO,OAAA;AAAA,MAC5E,EAAE,OAAO,MAAM,OAAOzK,EAAE,cAAc,GAAG,OAAOyK,EAAK,OAAO,OAAO,MAAM,OAAA;AAAA,MACzE;AAAA,QACE,OAAO;AAAA,QACP,OAAOzK,EAAE,qBAAqB;AAAA,QAC9B,OAAOyK,EAAK,OAAO,OAAO,aAAa;AAAA,MAAA;AAAA,IACzC,CACD,GAEKU,IAAc/I;AAAA,MAAkC,MACpD6I,EAAa,SAASL,EAAI,KAAyB,IAAKA,EAAI,QAA6B;AAAA,IAAA,GAGrF/B,KAA+C;AAAA,MACnD,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,IAAA,GAGJuC,KAAuC;AAAA,MAC3C,KAAK;AAAA,MACL,YAAY;AAAA,MACZ,KAAK;AAAA,MACL,UAAU;AAAA,IAAA,GAGNC,KAAcjJ,EAAsC,MAAM;AAAA,MAC9D,EAAE,KAAK,OAAO,OAAOpC,EAAE,cAAc,GAAG,UAAU,IAAA;AAAA,MAClD,EAAE,KAAK,UAAU,OAAOA,EAAE,mBAAmB,GAAG,OAAO,GAAA;AAAA,MACvD,EAAE,KAAK,QAAQ,OAAOA,EAAE,WAAW,GAAG,OAAO,GAAA;AAAA,MAC7C,EAAE,KAAK,UAAU,OAAOA,EAAE,aAAa,GAAG,UAAU,IAAA;AAAA,MACpD,EAAE,KAAK,cAAc,OAAOA,EAAE,WAAW,GAAG,OAAO,IAAA;AAAA,IAAI,CACxD,GAGKsL,KAAkBlJ,EAA0C,MAAM;AAAA,MACtE,EAAE,KAAK,OAAO,OAAOpC,EAAE,cAAc,GAAG,UAAU,IAAA;AAAA,MAClD,EAAE,KAAK,UAAU,OAAOA,EAAE,mBAAmB,GAAG,OAAO,GAAA;AAAA,MACvD,EAAE,KAAK,SAAS,OAAOA,EAAE,WAAW,GAAG,OAAO,IAAA;AAAA,MAC9C,GAAImL,EAAY,UAAU,WACtB,CAAC,EAAE,KAAK,OAAO,OAAOnL,EAAE,UAAU,GAAG,UAAU,IAAA,CAAK,IACpD;AAAA,QACE,EAAE,KAAK,iBAAiB,OAAOA,EAAE,YAAY,GAAG,UAAU,IAAA;AAAA,QAC1D,EAAE,KAAK,eAAe,OAAOA,EAAE,wBAAwB,GAAG,OAAO,IAAA;AAAA,MAAI;AAAA,IACvE,CACL;AAMD,aAASuL,GAAOpB,GAAwB;AACtC,UAAI;AACF,eAAO,KAAK,UAAU,KAAK,MAAMA,CAAM,GAAG,MAAM,CAAC;AAAA,MACnD,QAAQ;AACN,eAAOA;AAAA,MACT;AAAA,IACF;AAEA,aAASqB,GAAK3H,GAA+B;AAC3C,UAAIA,EAAI,UAAU,KAAM,QAAO;AAE/B,YAAM4H,IAAK5H,EAAI,QAAQ,MACjBY,IAAOgH,KAAM,OAAO,IAAIA,IAAK,MAAM,QAAQ,CAAC,CAAC,QAAQ,GAAG,KAAK,MAAMA,CAAE,CAAC;AAE5E,aAAO5H,EAAI,SAASA,EAAI,SAAS,GAAGY,CAAI,MAAMZ,EAAI,KAAK,IAAIA,EAAI,MAAM,KAAKY;AAAA,IAC5E;AASA,UAAMiH,KAAQtJ,EAA2B,MAAM;AAC7C,YAAMwE,IAAO6D,EAAK,OAAO;AAEzB,aAAK7D,IAE6B;AAAA,QAChC,CAAC5G,EAAE,mBAAmB,GAAG4G,EAAK,UAAU5G,EAAE,kBAAkB,CAAC;AAAA,QAC7D,CAACA,EAAE,yBAAyB,GAAG4G,EAAK,cAAcA,EAAK,eAAe,IAAI;AAAA,QAC1E,CAAC5G,EAAE,wBAAwB,GAAG4G,EAAK,WAAW;AAAA,QAC9C,CAAC5G,EAAE,YAAY,GAAG4G,EAAK,KAAK;AAAA,QAC5B,CAAC5G,EAAE,yBAAyB,GAAG4G,EAAK,YAAY;AAAA,QAChD,CAAC5G,EAAE,kBAAkB,GAAG4G,EAAK,KAAK;AAAA,QAClC,CAAC5G,EAAE,oBAAoB,GAAG4G,EAAK,OAAO;AAAA,QACtC,CAAC5G,EAAE,qBAAqB,GAAG4G,EAAK,QAAQ;AAAA,QACxC,CAAC5G,EAAE,wBAAwB,GAAG4G,EAAK,WAAW;AAAA,QAC9C,CAAC5G,EAAE,mBAAmB,GAAGA,EAAE,eAAe4G,EAAK,MAAM,EAAE,CAAC;AAAA,QACxD,CAAC5G,EAAE,kBAAkB,GAAG4G,EAAK,KAAK;AAAA,QAClC,CAAC5G,EAAE,sBAAsB,GAAG4G,EAAK,YAAY5G,EAAE,UAAU,IAAIA,EAAE,SAAS,CAAC;AAAA,QACzE,CAACA,EAAE,8BAA8B,GAAG4G,EAAK,oBAAoB5G,EAAE,UAAU,IAAI,IAAI;AAAA,QACjF,CAACA,EAAE,kBAAkB,GAAG4G,EAAK,KAAK;AAAA,QAClC,CAAC5G,EAAE,wBAAwB,GAAG4G,EAAK,WAAW;AAAA,QAC9C,CAAC5G,EAAE,eAAe,GAAG4G,EAAK,GAAG,KAAK,KAAK,KAAK,IAAI;AAAA,QAChD,CAAC5G,EAAE,sBAAsB,GAAG4G,EAAK,SAAS;AAAA,QAC1C,CAAC5G,EAAE,wBAAwB,GAAG4G,EAAK,WAAW;AAAA,QAC9C,CAAC5G,EAAE,yBAAyB,GAAG4G,EAAK,YAAY;AAAA,QAChD,CAAC5G,EAAE,iBAAiB,GAAG4G,EAAK,IAAI;AAAA,QAChC;AAAA,UACE;AAAA,UACAA,EAAK,SAAS,SACV,EAAE,OAAOA,EAAK,SAAS,IAAI,CAAC+E,MAAc,CAACA,EAAU,MAAMA,EAAU,GAAG,CAAC,MACzE;AAAA,QAAA;AAAA,QAEN;AAAA,UACE;AAAA,UACA,OAAO,KAAK/E,EAAK,EAAE,EAAE,SACjB,EAAE,OAAO,OAAO,QAAQA,EAAK,EAAE,EAAE,IAAI,CAAC,CAAC7H,GAAKC,CAAK,MAAM,CAAC,MAAMD,CAAG,IAAI,OAAOC,CAAK,CAAC,CAAC,EAAA,IACnF;AAAA,QAAA;AAAA,QAEN;AAAA,UACE;AAAA,UACA,OAAO,KAAK4H,EAAK,OAAO,EAAE,SACtB;AAAA,YACE,OAAO,OAAO,QAAQA,EAAK,OAAO,EAAE,IAAI,CAAC,CAAC7H,GAAKC,CAAK,MAAM;AAAA,cACxD,WAAWD,CAAG;AAAA,cACd,OAAOC,CAAK;AAAA,YAAA,CACb;AAAA,UAAA,IAEH;AAAA,QAAA;AAAA,QAEN;AAAA,UACE;AAAA,UACA4H,EAAK,QAAQ,SACT;AAAA,YACE,MAAMA,EAAK,QAAQ,QAAQ,CAACgF,MAAUA,EAAM,KAAK;AAAA,YACjD,OAAOhF,EAAK,QAAQ,KAAK,CAACgF,MAAUA,EAAM,KAAK,GAAG,SAAS;AAAA,UAAA,IAE7D;AAAA,QAAA;AAAA,QAEN,CAAC5L,EAAE,uBAAuB,GAAG4G,EAAK,UAAU;AAAA,QAC5C,CAAC5G,EAAE,qBAAqB,GAAG4G,EAAK,QAAQ;AAAA,QACxC,CAAC5G,EAAE,+BAA+B,GAAG4G,EAAK,kBAAkB;AAAA,QAC5D,CAAC5G,EAAE,+BAA+B,GAAG4G,EAAK,kBAAkB;AAAA,QAC5D,CAAC5G,EAAE,mBAAmB,GAAG4G,EAAK,MAAM;AAAA,QACpC,CAAC5G,EAAE,+BAA+B,GAAG4G,EAAK,sBAAsB,IAAI;AAAA,MAAA,EAInE,OAAO,CAAC,CAAA,EAAG5H,CAAK,MAAMA,KAAU,QAA+BA,MAAU,EAAE,EAC3E,IAAI,CAAC,CAAC6M,GAAO7M,CAAK,MAAM,CAAC6M,GAAO,OAAO7M,KAAU,WAAYA,IAAiB,OAAOA,CAAK,CAAC,CAAC,IAjE7E,CAAA;AAAA,IAkEpB,CAAC;AAED,aAASoF,GAAWpF,GAAiC;AAEnD,aADIA,MAAU,QACVA,KAAS,MAAY,WACrBA,KAAS,MAAY,YACrBA,KAAS,MAAY,SAElB;AAAA,IACT;AAEA,mBAAewE,GAAK9E,GAA2B;AAC7C,mBAAasH,CAAK,GAClBuE,EAAW,QAAQ,IACnBD,EAAQ,QAAQ,MAChBG,EAAK,QAAQ,MACbjK,EAAQ,QAAQ,MAChBqK,EAAM,QAAQ,MACdE,EAAU,QAAQ,MAClBH,EAAI,QAAQ;AAEZ,UAAI;AACF,QAAAH,EAAK,QAAQ,MAAM1K,EAAI,KAAKF,EAAM,KAAKnB,CAAE;AAAA,MAC3C,SAASkC,GAAO;AACd,QAAAJ,EAAQ,QAAQN,EAAQU,CAAK;AAAA,MAC/B;AAAA,IACF;AAEA,mBAAekL,GAAUjE,GAAkC;AACzD,UAAI,EAAAhI,EAAM,WAAW,QAAS+K,EAAI,UAAU,QAAQA,EAAI,UAAU,QAElE;AAAA,QAAAE,EAAa,QAAQ;AAErB,YAAI;AACF,UAAAD,EAAM,QAAQ,MAAM9K,EAAI,MAAMF,EAAM,KAAKA,EAAM,QAAQ;AAAA,YACrD,WAAW+K,EAAI;AAAA,YACf,MAAM/C,EAAM;AAAA,YACZ,UAAUA,EAAM;AAAA,UAAA,CACjB;AAAA,QACH,SAASjH,GAAO;AACd,UAAAJ,EAAQ,QAAQN,EAAQU,CAAK;AAAA,QAC/B,UAAA;AACE,UAAAkK,EAAa,QAAQ;AAAA,QACvB;AAAA;AAAA,IACF;AAEA,mBAAeiB,GAAclE,GAAkC;AAC7D,YAAMmE,IAAUb,EAAY;AAE5B,UAAI,EAAAtL,EAAM,WAAW,QAAQmM,MAAY,OAEzC;AAAA,QAAAhB,EAAiB,QAAQ;AAEzB,YAAI;AACF,UAAAD,EAAU,QAAQ,MAAMhL,EAAI,UAAUF,EAAM,KAAKA,EAAM,QAAQ;AAAA,YAC7D,KAAKmM;AAAA,YACL,MAAMnE,EAAM;AAAA,YACZ,UAAUA,EAAM;AAAA,UAAA,CACjB;AAAA,QACH,SAASjH,GAAO;AACd,UAAAJ,EAAQ,QAAQN,EAAQU,CAAK;AAAA,QAC/B,UAAA;AACE,UAAAoK,EAAiB,QAAQ;AAAA,QAC3B;AAAA;AAAA,IACF;AAEA,WAAAtH;AAAA,MACE,MAAM7D,EAAM;AAAA,MACZ,CAACnB,MAAO;AACN,QAAIA,MAAO,QAAW8E,GAAK9E,CAAE;AAAA,MAC/B;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK,GAGpBgF,GAAMkH,GAAK,MAAM;AACf,MAAAC,EAAM,QAAQ,MACdE,EAAU,QAAQ;AAAA,IACpB,CAAC,mBAIC/J,EAqOYC,EAAAgL,EAAA,GAAA;AAAA,MApOF,MAAMnH,EAAA;AAAA,8CAAAA,EAAI,QAAAlC;AAAA,MAClB,MAAK;AAAA,MACJ,YAAU;AAAA,MACX,WAAA;AAAA,MACA,SAAQ;AAAA,IAAA;MAEG,SACT,MAKO;AAAA,QALPqB,EAKO,QALPlD,IAKO;AAAA,UAJW0J,EAAA,cAAhBzJ,EAEaC,EAAAU,CAAA,GAAA;AAAA;YAFU,MAAMyC,GAAWqG,QAAK,KAAK,MAAM;AAAA,YAAG,MAAK;AAAA,UAAA;uBAAK,MAEnE;AAAA,kBADAA,EAAA,MAAK,KAAK,UAAM,GAAA,GAAA,CAAA;AAAA,YAAA;;;UAElBxG,EAAkE,QAAlE7C,IAAkEM,EAA9B+I,SAAM,KAAK,OAAG,EAAA,GAAA,CAAA;AAAA,QAAA;;MAI3C,SACT,MAiBO;AAAA,QAjBKA,EAAA,SAAZ5J,EAAA,GAAAC,EAiBO,QAjBPc,IAiBO;AAAA,UAfGX,EAAAuH,CAAA,UADRxH,EAOCC,EAAAa,CAAA,GAAA;AAAA;YALC,MAAK;AAAA,YACL,MAAK;AAAA,YACJ,SAASyI,EAAA;AAAA,YACT,SAAOC;AAAA,UAAA;uBACP,MAAuB;AAAA,kBAApBvJ,EAAAjB,CAAA,EAAC,cAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAEPqB,EAMCJ,EAAAa,CAAA,GAAA;AAAA,YALC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACJ,MAAMb,EAAAlB,CAAA,EAAI,SAASF,EAAM,KAAK4K,EAAA,MAAK,KAAK,EAAE;AAAA,UAAA;uBAC1C,MAA2B;AAAA,kBAAxBxJ,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAEPqB,EAAkFJ,EAAAO,EAAA,GAAA;AAAA,YAAxE,MAAMiJ,EAAA,MAAK,KAAK;AAAA,YAAK,QAAO;AAAA,UAAA;uBAAS,MAAyB;AAAA,kBAAtBxJ,EAAAjB,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;;;iBAIvD,MAA6D;AAAA,QAA9CQ,EAAA,cAAfQ,EAA6DC,EAAAC,CAAA,GAAA;AAAA;UAArC,MAAK;AAAA,QAAA;qBAAS,MAAa;AAAA,gBAAVV,EAAA,KAAO,GAAA,CAAA;AAAA,UAAA;;cACvBiK,EAAA,SAEzB5J,EAAA,GAAAC,EA4LM,OA5LN6D,IA4LM;AAAA,UA3LY4F,EAAA,cAAhBvJ,EAAmFC,EAAAuI,EAAA,GAAA;AAAA;YAAvD,MAAK;AAAA,YAAQ,aAAavI,EAAAjB,CAAA,EAAC,sBAAA;AAAA,UAAA,gCAE1CsK,EAAA,SAAWA,EAAA,MAAQ,WAAM,UAAeA,EAAA,MAAQ,eAD7DtJ,EAWWC,EAAAuI,EAAA,GAAA;AAAA;YATR,MAAMc,EAAA,MAAQ,OAAO,MAAG,IAAA,YAAA;AAAA,UAAA;uBAEzB,MAMM;AAAA,cANNrG,EAMM,OANNwB,IAMM;AAAA,gBALJxB,EAA2E,gBAAlEhD,EAAAjB,CAAA,EAAC,sBAAA,EAAA,OAAgCsK,QAAQ,OAAO,OAAK,CAAA,GAAA,CAAA;AAAA,gBAC9DrG,EAAuE,gBAA9DhD,EAAAjB,CAAA,EAAC,oBAAA,EAAA,OAA8BsK,QAAQ,OAAO,KAAG,CAAA,GAAA,CAAA;AAAA,gBACzCzK,EAAM,aAAvBmB,EAEcC,EAAAa,CAAA,GAAA;AAAA;kBAFe,MAAK;AAAA,kBAAK,SAAQ;AAAA,kBAAQ,SAAO6I;AAAA,gBAAA;6BAAgB,MAE5E;AAAA,wBADA1J,EAAAjB,CAAA,EAAC,sBAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;;;;6BAKMsK,EAAA,cADbtJ,EAIEC,EAAAuI,EAAA,GAAA;AAAA;YAFA,MAAK;AAAA,YACJ,aAAac,QAAQ,SAASrJ,EAAAjB,CAAA,EAAC,eAAgBsK,EAAA,MAAQ,MAAM,EAAA;AAAA,UAAA;UAEjDG,EAAA,MAAK,KAAK,cAAzBzJ,EAAiFC,EAAAC,CAAA,GAAA;AAAA;YAAjD,QAAO;AAAA,UAAA;uBAAW,MAAqB;AAAA,kBAAlBuJ,EAAA,MAAK,KAAK,KAAK,GAAA,CAAA;AAAA,YAAA;;;UAEpEpJ,EAsKUJ,EAAAiL,EAAA,GAAA;AAAA,wBAtKQtB,EAAA;AAAA,0DAAAA,EAAG,QAAAhI;AAAA,YAAG,OAAOsI,EAAA;AAAA,UAAA;uBAC7B,MAyBK;AAAA,cAzBKN,EAAA,UAAG,cAAb/J,KAAAC,EAyBK,MAzBL4E,IAyBK;AAAA,iBAxBH7E,EAAA,EAAA,GAAAC,EAeWK,GAAA,MAAAuD,EAfwBgH,GAAA,OAAK,CAAA,CAAtBG,GAAO7M,CAAK,wBAAkB6M,KAAK;AAAA,kBACnD5H,EAAoB,cAAb4H,CAAK,GAAA,CAAA;AAAA,yBACK7M,KAAK,YAAtB6B,KAAAC,EAAqD,YAAb9B,CAAK,GAAA,CAAA,gBACnBA,KAA1B6B,KAAAC,EAKK,MALLgJ,IAKK;AAAA,4BAJHhJ,EAGWK,GAAA,MAAAuD,EAH8B1F,EAAM,SAA5BD,GAAK0F,CAAI,GAAGlD,wBAA6BA,KAAK;AAAA,sBAC/DF,EAAmEJ,EAAAU,CAAA,GAAA;AAAA,wBAAzD,MAAK;AAAA,wBAAK,OAAM;AAAA,sBAAA;mCAAqB,MAAS;AAAA,8BAAN5C,CAAG,GAAA,CAAA;AAAA,wBAAA;;;sBACrDkF,EAAuB,gBAAdQ,CAAI,GAAA,CAAA;AAAA,oBAAA;yBAGjB5D,EAAA,GAAAC,EAKK,MALLiJ,IAKK;AAAA,qBAJHlJ,EAAA,EAAA,GAAAC,EAEaK,WAFoBnC,EAAM,MAAI,CAAzBmN,GAAK5K,YAAvBP,EAEaC,EAAAU,CAAA,GAAA;AAAA,sBAFiC,KAAKJ;AAAA,sBAAO,MAAK;AAAA,sBAAO,MAAK;AAAA,oBAAA;iCAAK,MAE9E;AAAA,4BADA4K,CAAG,GAAA,CAAA;AAAA,sBAAA;;;oBAEUnN,EAAM,cAArBgC,EAA+EC,EAAAC,CAAA,GAAA;AAAA;sBAAnD,MAAK;AAAA,sBAAK,MAAK;AAAA,oBAAA;iCAAS,MAAiB;AAAA,wBAAdO,EAAAC,EAAA1C,EAAM,KAAK,GAAA,CAAA;AAAA,sBAAA;;;;;gBAGtD,OAAO,KAAKyL,EAAA,MAAK,KAAK,OAAO,EAAE,eAA/C3J,EAOWK,GAAA,EAAA,KAAA,KAAA;AAAA,kBANT8C,EAA+D,MAA/D+F,IAA+DtI,EAAzBT,EAAAjB,CAAA,EAAC,cAAA,CAAA,GAAA,CAAA;AAAA,kCACvCiE,EAAM,MAAA,MAAA,MAAA,EAAA;AAAA,0BACNnD,EAGWK,GAAA,MAAAuD,EAHuB+F,QAAK,KAAK,SAAO,CAAjCzL,GAAOoN,wBAAkCA,KAAI;AAAA,oBAC7DnI,EAA+C,MAA/CgG,IAA+CvI,EAAZ0K,CAAI,GAAA,CAAA;AAAA,oBACvCnI,EAAgD,MAAhDiG,IAAgDxI,EAAb1C,CAAK,GAAA,CAAA;AAAA,kBAAA;;oBAK9B4L,EAAA,UAAG,YAAnB/J,EAAA,GAAAC,EAgBM,OAhBNsJ,IAgBM;AAAA,gBAfYK,EAAA,MAAK,OAAO,2BAA5BzJ,EAAoFC,EAAAC,CAAA,GAAA;AAAA;kBAAhD,MAAK;AAAA,gBAAA;6BAAQ,MAAyB;AAAA,wBAAtBD,EAAAjB,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;iBACrDa,EAAA,EAAA,GAAAC,EAaMK,GAAA,MAAAuD,EAbe+F,EAAA,MAAK,SAAdxL,YAAZ6B,EAaM,OAAA;AAAA,kBAb6B,KAAK7B,EAAM;AAAA,kBAAI,OAAM;AAAA,gBAAA;kBACtDgF,EAUM,OAVNoI,IAUM;AAAA,oBATJhL,EAEaJ,EAAAU,CAAA,GAAA;AAAA,sBAFF,MAAMkH,GAAW5J,EAAM,QAAQ;AAAA,sBAAG,KAAA;AAAA,oBAAA;iCAAI,MAE/C;AAAA,4BADAgC,EAAAjB,CAAA,EAAC,iBAAkBf,EAAM,QAAQ,EAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;oBAEnCoC,EAEYJ,EAAAC,CAAA,GAAA;AAAA,sBAFH,MAAK;AAAA,sBAAK,QAAO;AAAA,oBAAA;iCAAW,MAEnC;AAAA,4BADArB,EAAM,OAAOZ,EAAM,KAAK,KAAKA,EAAM,KAAK,GAAA,CAAA;AAAA,sBAAA;;;oBAE1BA,EAAM,UAAK,cAA3B+B,EAEaC,EAAAU,CAAA,GAAA;AAAA;sBAF0B,MAAK;AAAA,sBAAU,MAAK;AAAA,oBAAA;iCAAK,MAE9D;AAAA,4BADAV,EAAAjB,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;;kBAGLqB,EAA0CkG,IAAA;AAAA,oBAA1B,SAAStI,EAAM;AAAA,kBAAA;;oBAKtBkM,EAAA,cADbnK,EAsDWC,EAAA2C,EAAA,GAAA;AAAA,gBApDR,KAAG,aAAe,OAAOgH,EAAA,KAAG,CAAA;AAAA,gBAC5B,MAAMG,EAAA;AAAA,gBACN,SAASO,GAAA;AAAA,gBACV,WAAQ;AAAA,gBACR,OAAA;AAAA,gBACC,SAASN,EAAA;AAAA,gBACT,oBAAkB,CAAA;AAAA,gBAClB,cAAY/J,EAAAjB,CAAA,EAAC,mBAAA;AAAA,gBACb,eAAc+L;AAAA,cAAA;gBAEJ,YAAQ/H,EACjB,CAoBO,EArBc,KAAAH,QAAG;AAAA,kBACZsH,EAAA,UAAW,YAAvBtK,KAAAC,EAoBO,QApBPwL,IAoBO;AAAA,oBAjBLjL,EAeWJ,EAAAsL,EAAA,GAAA;AAAA,sBAdR,KAAKtL,MAAS4C,CAAG,IAAIA,EAAI,MAAM;AAAA,sBAC/B,KAAKA,EAAI,OAAG;AAAA,sBACZ,OAAO;AAAA,sBACP,QAAQ;AAAA,sBACT,KAAI;AAAA,sBACJ,QAAO;AAAA,sBACP,SAAA;AAAA,sBACC,iBAAe5C,EAAAjB,CAAA,EAAC,gBAAA;AAAA,sBACjB,OAAKsH,GAAA,CAAC,wBAAsB,EAAA,iBAAA,CACArG,EAAAoJ,EAAA,EAASxG,CAAG,GAAA,CAAA;AAAA,oBAAA;sBAEvB5C,EAAAoJ,EAAA,EAASxG,CAAG;8BAAI;AAAA,8BAC/B,MAAwB;AAAA,0BAAxBxC,EAAwBJ,EAAAuL,EAAA,GAAA,EAAf,MAAK,SAAO;AAAA,wBAAA;;;;oBAGzBvI,EAAqD,QAArDwI,IAAqD/K,EAAjBmC,EAAI,GAAG,GAAA,CAAA;AAAA,kBAAA,OAE7ChD,EAAA,GAAAC,EAA4D,QAA5D4L,IAA4DhL,EAAjBmC,EAAI,GAAG,GAAA,CAAA;AAAA,kBACnCA,EAAI,iBAAnB7C,EAECC,EAAAC,CAAA,GAAA;AAAA;oBAF4B,MAAK;AAAA,oBAAK,MAAK;AAAA,oBAAQ,OAAM;AAAA,kBAAA;+BAAqB,MAC3E;AAAA,wBAD2E,QAC3EQ,EAAGmC,EAAI,QAAQ,GAAA,CAAA;AAAA,oBAAA;;;kBAEJA,EAAI,cAAnB7C,EAA2EC,EAAAC,CAAA,GAAA;AAAA;oBAAjD,MAAK;AAAA,oBAAK,MAAK;AAAA,kBAAA;+BAAS,MAAe;AAAA,sBAAZO,EAAAC,EAAAmC,EAAI,KAAK,GAAA,CAAA;AAAA,oBAAA;;;;gBAErD,eAAWG,EACpB,CAEa,EAHW,KAAAH,QAAG;AAAA,kBACXA,EAAI,WAAM,aAA1B7C,EAEaC,EAAAU,CAAA,GAAA;AAAA;oBAFyB,MAAMyC,GAAWP,EAAI,MAAM;AAAA,oBAAG,MAAK;AAAA,kBAAA;+BAAK,MAE5E;AAAA,sBADApC,EAAAC,EAAAmC,EAAI,MAAM,GAAA,CAAA;AAAA,oBAAA;;wCAESA,EAAI,gBAAzB7C,EAAsEC,EAAAU,CAAA,GAAA;AAAA;oBAApC,MAAK;AAAA,oBAAS,MAAK;AAAA,kBAAA;+BAAK,MAAC,CAAA,GAAAoC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA;AAAA,wBAAD,KAAC,EAAA;AAAA,oBAAA;;8BAC3D/C,EAA4EC,EAAAC,CAAA,GAAA;AAAA;oBAA5D,MAAK;AAAA,oBAAK,MAAK;AAAA,kBAAA;+BAAQ,MAA2B;AAAA,0BAAxBD,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;gBAElC,cAAUgE,EAAW,CAAe,EAAtB,KAAAH,QAAG;AAAA,kBAAOpC,EAAAC,EAAA8J,GAAK3H,CAAG,CAAA,GAAA,CAAA;AAAA,gBAAA;gBAChC,YAAQG,EACjB,CAEY,EAHS,KAAAH,QAAG;AAAA,kBACTA,EAAI,QAAG,QAAaA,EAAI,SAAI,cAA3C7C,EAEYC,EAAAC,CAAA,GAAA;AAAA;oBAF2C,MAAK;AAAA,oBAAK,MAAK;AAAA,kBAAA;+BAAS,MAE7E;AAAA,0BADAD,EAAAjB,CAAA,EAAC,cAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;8BAEHc,EAA+CK,GAAA,EAAA,KAAA,KAAA;AAAA,oBAA3BM,EAAAC,EAAAmC,EAAI,OAAG,EAAA,GAAA,CAAA;AAAA,kBAAA;;;qEAIf+G,EAAA,UAAG,eAAnB/J,EAAA,GAAAC,EAoCM,OApCN6L,IAoCM;AAAA,gBAnCYlC,EAAA,MAAK,KAAK,QAAQ,2BAAlCzJ,EAEYC,EAAAC,CAAA,GAAA;AAAA;kBAF8B,MAAK;AAAA,gBAAA;6BAAQ,MAErD;AAAA,wBADAD,EAAAjB,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;wBAEHc,EA+BMK,GAAA,MAAAuD,EA9BqB+F,QAAK,KAAK,SAAO,CAAlCmB,GAAOrK,YADjBT,EA+BM,OAAA;AAAA,kBA7BH,KAAKS;AAAA,kBACN,OAAM;AAAA,gBAAA;kBAEN0C,EAKM,OALN2I,IAKM;AAAA,oBAJJvL,EAEYJ,EAAAC,CAAA,GAAA;AAAA,sBAFH,MAAK;AAAA,sBAAK,QAAO;AAAA,oBAAA;iCAAW,MAEnC;AAAA,wBADAO,EAAAC,EAAAT,EAAAjB,CAAA,iCAAiCuB,IAAK,EAAA,CAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;qBAExCV,EAAA,EAAA,GAAAC,EAAiFK,GAAA,MAAAuD,EAAxDkH,EAAM,QAAdiB,YAAjB7L,EAAiFC,EAAAU,CAAA,GAAA;AAAA,sBAA1C,KAAKkL;AAAA,sBAAM,MAAK;AAAA,oBAAA;iCAAK,MAAU;AAAA,4BAAPA,CAAI,GAAA,CAAA;AAAA,sBAAA;;;;kBAEtDjB,EAAM,cAArB5K,EAECC,EAAAC,CAAA,GAAA;AAAA;oBAF2B,MAAK;AAAA,oBAAK,MAAK;AAAA,kBAAA;+BACxC,MAA4B;AAAA,sBAAzBO,EAAAC,EAAAT,EAAAjB,CAAA,EAAC,mBAAA,CAAA,IAAwB,MAAC0B,EAAGkK,EAAM,KAAK,GAAA,CAAA;AAAA,oBAAA;;;mBAE9C/K,EAAA,EAAA,GAAAC,EAeWK,WAf0ByK,EAAM,SAAK,CAAA,GAAA,CAA9BkB,GAAMC,wBAAsCA,KAAQ;AAAA,oBACrDD,EAAK,QAAQ,eAA5B9L,EAGCC,EAAAC,CAAA,GAAA;AAAA;sBAHmC,MAAK;AAAA,sBAAK,MAAK;AAAA,oBAAA;iCAChD,MAAe;AAAA,wBAAZO,EAAAC,EAAAoL,EAAK,IAAI,IAAG,QAAGpL,EAAGT,EAAAjB,CAAA,EAAC,sBAAA,CAAA,IAA2B,MAClD0B,EAAGoL,EAAK,QAAQ,KAAI,IAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;oBAEPA,EAAK,YAAY,eAAhC9L,EAGCC,EAAAC,CAAA,GAAA;AAAA;sBAHuC,MAAK;AAAA,sBAAK,MAAK;AAAA,oBAAA;iCACpD,MAAe;AAAA,wBAAZO,EAAAC,EAAAoL,EAAK,IAAI,IAAG,QAAGpL,EAAGT,EAAAjB,CAAA,EAAC,yBAAA,CAAA,IAA8B,MACrD0B,EAAGoL,EAAK,YAAY,KAAI,IAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;qBAGjBA,EAAK,QAAQ,WAAWA,EAAK,YAAY,eADlD9L,EAKCC,EAAAC,CAAA,GAAA;AAAA;sBAHC,MAAK;AAAA,sBACL,MAAK;AAAA,oBAAA;iCACJ,MAAe;AAAA,wBAAZO,EAAAC,EAAAoL,EAAK,IAAI,IAAG,UAAM7L,EAAAjB,CAAA,EAAC,sBAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;;kBAGhB4L,EAAM,UAAjB/K,EAAA,GAAAC,EAAuF,OAAvFkM,IAAuFtL,EAA7B6J,GAAOK,EAAM,MAAM,CAAA,GAAA,CAAA;;0BAIjF5K,EAyBWC,EAAA2C,EAAA,GAAA;AAAA,gBAvBR,KAAK,OAAOgH,EAAA,KAAG;AAAA,gBACf,MAAMC,EAAA;AAAA,gBACN,SAASQ,GAAA;AAAA,gBACV,WAAQ;AAAA,gBACR,OAAA;AAAA,gBACC,SAASP,EAAA;AAAA,gBACT,oBAAkB,CAAA;AAAA,gBAClB,cAAY7J,EAAAjB,CAAA,EAAC,eAAA;AAAA,gBACb,eAAc8L;AAAA,cAAA;gBAEJ,YAAQ9H,EACjB,CAA4D,EADvC,KAAAH,QAAG;AAAA,kBACxBI,EAA4D,QAA5DgJ,IAA4DvL,EAAxBmC,EAAI,OAAG,GAAA,GAAA,CAAA;AAAA,gBAAA;gBAElC,eAAWG,EACpB,CAEa,EAHW,KAAAH,QAAG;AAAA,kBACXA,EAAI,WAAM,aAA1B7C,EAEaC,EAAAU,CAAA,GAAA;AAAA;oBAFyB,MAAMyC,GAAWP,EAAI,MAAM;AAAA,oBAAG,MAAK;AAAA,kBAAA;+BAAK,MAE5E;AAAA,sBADApC,EAAAC,EAAAmC,EAAI,MAAM,GAAA,CAAA;AAAA,oBAAA;;;;gBAGH,mBAAeG,EACxB,CAEa,EAHe,KAAAH,QAAG;AAAA,kBACfA,EAAI,mBAApB7C,EAEaC,EAAAU,CAAA,GAAA;AAAA;oBAFoB,MAAMyJ,GAAUvH,EAAI,UAAU,KAAA;AAAA,oBAAa,MAAK;AAAA,kBAAA;+BAAK,MAEpF;AAAA,0BADA5C,EAAAjB,CAAA,EAAC,aAAc6D,EAAI,UAAU,EAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;;;;;;oBAzLvC7C,EAA2CC,EAAAc,EAAA,GAAA;AAAA;UAAX,MAAM;AAAA,QAAA;;;;;qEChZ7BmL,KAAsD;AAAA,EACjE,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb,IAAI;AAAA,EACJ,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,MAAM;AAAA,EACN,cAAc;AAAA,EACd,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU;AAAA,EACV,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,QAAQ;AAAA,EACR,oBAAoB;AAAA,EACpB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,mBAAmB;AACrB,GAEaC,KAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAGaC,KAAoC,CAAC,IAAI,GAGzCC,KAAsD;AAAA,EACjE,KAAK,CAAC,YAAY,MAAM,SAAS,QAAQ;AAAA,EACzC,MAAM,CAAC,YAAY,MAAM,SAAS,QAAQ;AAAA,EAC1C,QAAQ,CAAC,MAAM,MAAM,MAAM,OAAO;AAAA,EAClC,QAAQ,CAAC,MAAM,MAAM,MAAM,OAAO;AAAA,EAClC,MAAM,CAAC,OAAO,IAAI;AAAA,EAClB,QAAQ,CAAC,IAAI;AACf,GAGaC,KAA8B,CAAC,YAAY,MAAM,MAAM,IAAI,GAE3DC,KAAU,CAAC,QAAQ,WAAW,YAAY,MAAM,8CCXvDC,KAAU;;;;;;AAVhB,UAAM3N,IAAQC,GAERC,IAAM3B,GAAewB,IAAU;AACrC,IAAAF,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7B8C,IAAQ9C,GAAa,YAAY,GACjCC,IAAUC,GAAA,GACVsN,IAAQC,GAAA,GAIR7O,IAAM0B,EAAqB,IAAI,GAC/B4F,IAAQ5F,EAAI,EAAK,GACjBqG,IAAOrG,EAAoC,IAAI,GAC/C0C,IAAU1C,EAAI,EAAK,GACnBoN,IAASpN,EAAmB,IAAI,GAChCqN,IAASrN,EAA4B,EAAE,GAEvCG,IAASH,EAAmB,IAAI,GAChCsN,IAAYtN,EAAmB,IAAI,GACnCuN,IAAQvN,EAAmB,IAAI,GAC/B9B,IAAU8B,EAAwB,EAAE;AAC1C,QAAIwN,IAAmB,EAAE,MAAM,GAAG,SAAS,IAAI,MAAM,MAAM,QAAQ,GAAA;AAEnE,UAAMC,IAAUzN,EAAsB0N,GAAS;AAE/C,aAASA,IAA4B;AACnC,UAAI;AACF,cAAMC,IAAiB,KAAK,MAAM,OAAO,aAAa,QAAQV,EAAO,KAAK,MAAM;AAEhF,YAAI,MAAM,QAAQU,CAAK,GAAG;AACxB,gBAAMC,IAAQD,EAAM,OAAO,CAACnP,MAA+BA,KAAOmO,EAAW;AAE7E,cAAIiB,EAAM,OAAQ,QAAOA;AAAA,QAC3B;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,aAAO,CAAC,GAAGhB,EAAe;AAAA,IAC5B;AAEA,IAAAzJ,GAAMsK,GAAS,CAACI,MAAS;AACvB,UAAI;AACF,eAAO,aAAa,QAAQZ,IAAS,KAAK,UAAUY,CAAI,CAAC;AAAA,MAC3D,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAED,UAAMC,IAAS,OAAO,KAAKnB,EAAW,GAEhCoB,IAAgBlM;AAAA,MAAS,MAC7BiM,EAAO,IAAI,CAACtP,OAAS,EAAE,OAAOA,GAAK,OAAOiB,EAAE,cAAcjB,CAAG,EAAE,IAAI;AAAA,IAAA,GAG/DwP,IAAenM;AAAA,MAAS,MAC5BiM,EACG,OAAO,CAACtP,MAAQ,CAACqO,GAAgB,SAASrO,CAAG,CAAC,EAC9C,IAAI,CAACA,OAAS,EAAE,OAAOA,GAAK,OAAOiB,EAAE,cAAcjB,CAAG,EAAE,IAAI;AAAA,IAAA,GAG3DD,IAAUsD;AAAA,MAAsC;AAAA;AAAA,QAEpDiM,EACG,OAAO,CAACtP,MAAQiP,EAAQ,MAAM,SAASjP,CAAG,CAAC,EAC3C,IAAI,CAACA,OAAS;AAAA,UACb,KAAAA;AAAA,UACA,OAAOiB,EAAE,cAAcjB,CAAG,EAAE;AAAA,UAC5B,UAAU,CAACqO,GAAgB,SAASrO,CAAG;AAAA,UACvC,UAAUmO,GAAYnO,CAAG,MAAM,SAASmO,GAAYnO,CAAG,MAAM,SAAS,MAAM;AAAA,UAC5E,OAAOmO,GAAYnO,CAAG,MAAM,WAAW,UAAU;AAAA,QAAA,EACjD;AAAA;AAAA,IAAA,GAGAyP,IAAgBpM,EAAS,MAAM;AAAA,MACnC,GAAG,CAAC,OAAO,OAAO,OAAO,KAAK,EAAE,IAAI,CAACpD,OAAW,EAAE,OAAAA,GAAO,OAAOA,IAAQ;AAAA,MACxE,EAAE,OAAO,QAAQ,OAAOgB,EAAE,kBAAkB,EAAA;AAAA,IAAE,CAC/C,GAEKyO,IAAmBrM,EAAS,MAAM;AAAA,MACtC,EAAE,OAAO,KAAK,OAAOpC,EAAE,oBAAoB,EAAA;AAAA,MAC3C,EAAE,OAAO,KAAK,OAAOA,EAAE,mBAAmB,EAAA;AAAA,IAAE,CAC7C,GAEK0O,IAAetM;AAAA,MAAS,MAC5B,OAAO,QAAQwL,EAAO,KAAK,EAAE,IAAI,CAAC,CAAC5O,GAAO6M,CAAK,OAAO,EAAE,OAAA7M,GAAO,OAAA6M,IAAQ;AAAA,IAAA,GAGnE/D,KAAe1F;AAAA,MACnB,MACE,CAAC1B,EAAO,OAAOmN,EAAU,OAAOC,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,SAC7DrP,EAAQ,MAAM,OAAOkQ,EAAQ,EAAE;AAAA,IAAA,GAG7B1Q,KAAQmE,EAAyB,OAAO;AAAA,MAC5C,QAAQ1B,EAAO;AAAA,MACf,WAAWmN,EAAU,UAAU,OAAO,OAAOA,EAAU,UAAU;AAAA,MACjE,OAAOC,EAAM;AAAA,MACb,SAASrP,EAAQ,MAAM,OAAOkQ,EAAQ;AAAA,IAAA,EACtC;AAEF,aAASA,GAASxQ,GAAmC;AACnD,aAAO,CAACmP,GAAW,SAASnP,EAAO,EAAE,MAAMA,EAAO,SAAS,IAAI,KAAA,MAAW;AAAA,IAC5E;AAEA,aAASoF,GAAKvE,GAAsE;AAClF,aAAO,OAAOA,KAAU,YAAYA,MAAU,KAAKA,IAAQ;AAAA,IAC7D;AAEA,aAAS4P,GAAW/M,GAAuB;AACzC,aAAOwL,GAAWH,GAAYrL,CAAK,CAAC,EAAE,IAAI,CAACgN,OAAQ,EAAE,OAAOA,GAAI,OAAO7O,EAAE,WAAW6O,CAAE,EAAE,IAAI;AAAA,IAC9F;AAEA,aAASC,KAAkB;AACzB,MAAArQ,EAAQ,QAAQ,CAAC,GAAGA,EAAQ,OAAO,EAAE,OAAO,SAAS,IAAI,SAAS;AAAA,IACpE;AAEA,aAASsQ,GAASxN,GAAevC,GAA6D;AAC5F,YAAM6C,IAAQ0B,GAAKvE,CAAK;AAExB,MAAK6C,MAELpD,EAAQ,QAAQA,EAAQ,MAAM;AAAA,QAAI,CAACN,GAAQ6Q,OACzCA,OAAOzN,IAAQ,EAAE,OAAAM,GAAO,IAAIwL,GAAWH,GAAYrL,CAAK,CAAC,EAAE,CAAC,GAAI,OAAO,OAAO1D;AAAA,MAAA;AAAA,IAElF;AAEA,aAAS8Q,GAAM1N,GAAevC,GAA6D;AACzF,YAAM6P,IAAKtL,GAAKvE,CAAK;AAErB,MAAI6P,MACFpQ,EAAQ,QAAQA,EAAQ,MAAM,IAAI,CAACN,GAAQ6Q,OAAQA,OAAOzN,IAAQ,EAAE,GAAGpD,GAAQ,IAAA0Q,EAAA,IAAO1Q,CAAO;AAAA,IACjG;AAEA,aAAS+Q,GAAS3N,GAAevC,GAAqB;AACpD,MAAAP,EAAQ,QAAQA,EAAQ,MAAM,IAAI,CAACN,GAAQ6Q,MAAQA,MAAOzN,IAAQ,EAAE,GAAGpD,GAAQ,OAAAa,EAAA,IAAUb,CAAO;AAAA,IAClG;AAEA,aAASgR,GAAa5N,GAAqB;AACzC,MAAA9C,EAAQ,QAAQA,EAAQ,MAAM,OAAO,CAAC2Q,GAAGJ,MAAOA,MAAOzN,CAAK;AAAA,IAC9D;AAEA,aAAS8N,GAAWjB,GAAuB;AACzC,YAAM3L,IAAO2L,EAAK,OAAO,CAACrP,MAA+B,OAAOA,CAAG,KAAKmO,EAAW;AAGnF,MAAAc,EAAQ,QAAQvL,EAAK,SAASA,IAAO,CAAC,KAAK;AAAA,IAC7C;AAEA,UAAMsF,IAAmC;AAAA,MACvC,GAAK;AAAA,MACL,GAAK;AAAA,MACL,GAAK;AAAA,MACL,GAAK;AAAA,IAAA;AAGP,aAAS3D,EAAWpF,GAA2B;AAC7C,aAAO+I,EAAM,OAAO/I,KAAS,EAAE,EAAE,OAAO,CAAC,CAAC,KAAK;AAAA,IACjD;AAEA,aAASyF,EAAKzF,GAAwB;AACpC,aAAOA,KAAU,QAA+BA,MAAU,KAAK,MAAM,OAAOA,CAAK;AAAA,IACnF;AAEA,mBAAewE,EAAKqE,IAAoBkG,GAAqB;AAG3D,UAFAA,IAAOlG,GAEHhJ,EAAI,UAAU,MAElB;AAAA,QAAAoE,EAAQ,QAAQ;AAEhB,YAAI;AACF,UAAA2D,EAAK,QAAQ,MAAM7G,EAAI,MAAMlB,EAAI,MAAM,IAAI;AAAA,YACzC,GAAGZ,GAAM;AAAA,YACT,QAAQ4J,EAAM;AAAA,YACd,MAAMA,EAAM,OAAO,GAAGA,EAAM,KAAK,UAAU,SAAS,MAAM,EAAE,GAAGA,EAAM,KAAK,GAAG,KAAK;AAAA,YAClF,MAAMA,EAAM;AAAA,YACZ,UAAUA,EAAM;AAAA,UAAA,CACjB;AAAA,QACH,SAASjH,GAAO;AACd,UAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,QAC7B,UAAA;AACE,UAAAqC,EAAQ,QAAQ;AAAA,QAClB;AAAA;AAAA,IACF;AAEA,aAASqM,IAAiB;AACxB,MAAIzQ,EAAI,UAAU,QAElB,OAAO,SAAS;AAAA,QACdkB,EAAI;AAAA,UACFlB,EAAI,MAAM;AAAA,UACV,EAAE,GAAGZ,GAAM,OAAO,QAAQ8P,EAAK,OAAA;AAAA,UAC/BjP,EAAQ,MAAM,IAAI,CAACyF,MAAWA,EAAO,GAAG;AAAA,QAAA;AAAA,MAC1C;AAAA,IAEJ;AAEA,WAAAb,GAAMzF,IAAO;AAAM,MAAKuF,EAAK,EAAE,GAAGuK,GAAM,MAAM,EAAA,CAAG;AAAA,OAAG,EAAE,MAAM,IAAM,GAElEpN,GAAU,YAAY;AACpB,UAAI;AAGF,YAFA9B,EAAI,SAAS,MAAMkB,EAAI,OAAA,GAAU,SAE7BlB,EAAI,UAAU,MAAM;AACtB,gBAAM6I,IAAS,MAAM3H,EAAI,OAAOlB,EAAI,MAAM,EAAE;AAC5C,UAAA+O,EAAO,QAAQ,OAAO,YAAYlG,EAAO,IAAI,CAAC7D,MAAQ,CAACA,EAAI,IAAIA,EAAI,KAAK,CAAC,CAAC;AAAA,QAC5E;AAAA,MACF,SAASjD,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAuF,EAAM,QAAQ;AAAA,MAChB;AAEA,MAAK3C,EAAA;AAAA,IACP,CAAC,mBAICxC,EAqJe2C,IAAA;AAAA,MArJA,MAAM9D,EAAM;AAAA,MAAM,SAAQ;AAAA,IAAA;iBACvC,MAEY;AAAA,QAFGsG,EAAA,SAAStH,EAAA,UAAG,aAA3BmC,EAEYC,EAAAC,CAAA,GAAA;AAAA;UAF0B,MAAK;AAAA,UAAQ,OAAM;AAAA,QAAA;qBAAuB,MAE9E;AAAA,gBADAD,EAAAjB,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,UAAA;;oBAGHgB,EAsIWC,EAAA2C,EAAA,GAAA;AAAA;UApIR,MAAMgD,EAAA;AAAA,UACN,SAAS9H,EAAA;AAAA,UACV,WAAQ;AAAA,UACR,YAAA;AAAA,UACA,WAAA;AAAA,UACA,OAAA;AAAA,UACA,OAAA;AAAA,UACC,SAASmE,EAAA,SAAO,CAAKkD,EAAA;AAAA,UACrB,oBAAkB,CAAA,IAAA,KAAA,GAAA;AAAA,UAClB,sBAAoBlF,EAAAjB,CAAA,EAAC,iBAAA;AAAA,UACrB,iBAAe8H,GAAA;AAAA,UACf,iBAAe7G,EAAA8B,CAAA,EAAK,eAAA;AAAA,UACpB,iBAAe;AAAA,UACf,cAAY9B,EAAAjB,CAAA,EAAC,YAAA;AAAA,UACb,eAAcwD;AAAA,UACd,6BAAYK,MAAS8J,UAAS9J,EAAI;AAAA,QAAA;UAExB,SACT,MAEY;AAAA,YAFGhF,EAAA,cAAfmC,EAEYC,EAAAC,CAAA,GAAA;AAAA;cAFQ,MAAK;AAAA,cAAK,MAAK;AAAA,YAAA;yBAAQ,MAEzC;AAAA,gBADAO,EAAAC,EAAAT,EAAAjB,CAAA,4BAA4BiB,EAAAwM,CAAA,EAAM,MAAM5O,EAAA,MAAI,WAAW,GAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;UAIhD,WACT,MAWa;AAAA,YAXbwC,EAWaJ,EAAAkH,EAAA,GAAA;AAAA,cAXA,OAAOlH,EAAAjB,CAAA,EAAC,cAAA;AAAA,cAAkB,OAAM;AAAA,YAAA;cAChC,WACT,MAAsF;AAAA,gBAAtFqB,EAAsFJ,EAAAa,CAAA,GAAA;AAAA,kBAA3E,MAAK;AAAA,kBAAK,SAAQ;AAAA,kBAAO,MAAK;AAAA,gBAAA;6BAAU,MAAuB;AAAA,wBAApBb,EAAAjB,CAAA,EAAC,cAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;;yBAEzD,MAME;AAAA,gBANFqB,EAMEJ,EAAAsO,EAAA,GAAA;AAAA,kBALC,eAAavB,EAAA;AAAA,kBACb,SAASM,EAAA;AAAA,kBACV,MAAK;AAAA,kBACL,OAAM;AAAA,kBACL,uBAAoBe;AAAA,gBAAA;;;;YAGzBhO,EAEcJ,EAAAa,CAAA,GAAA;AAAA,cAFH,MAAK;AAAA,cAAK,SAAQ;AAAA,cAAO,MAAK;AAAA,cAAY,WAAWjD,EAAA;AAAA,cAAM,SAAOyQ;AAAA,YAAA;yBAAU,MAErF;AAAA,oBADArO,EAAAjB,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;UAIM,WACT,MAgEM;AAAA,YAhENiE,EAgEM,OAhENlD,IAgEM;AAAA,cA/DJM,EAMEJ,EAAA6C,EAAA,GAAA;AAAA,gBALC,eAAapD,EAAA;AAAA,gBACb,SAAS8N,EAAA;AAAA,gBACT,aAAavN,EAAAjB,CAAA,EAAC,iBAAA;AAAA,gBACf,WAAA;AAAA,gBACC,uBAAkB+D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAElC,EAAA,QAAS6C,GAAKX,CAAM;AAAA,cAAA;cAE3CvB,EAMEJ,EAAA6C,EAAA,GAAA;AAAA,gBALC,eAAa+J,EAAA;AAAA,gBACb,SAASY,EAAA;AAAA,gBACT,aAAaxN,EAAAjB,CAAA,EAAC,oBAAA;AAAA,gBACf,WAAA;AAAA,gBACC,uBAAkB+D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAEiL,EAAA,QAAYtK,GAAKX,CAAM;AAAA,cAAA;cAE9CvB,EAOEJ,EAAA6C,EAAA,GAAA;AAAA,gBANC,eAAagK,EAAA;AAAA,gBACb,SAASY,EAAA;AAAA,gBACT,aAAazN,EAAAjB,CAAA,EAAC,gBAAA;AAAA,gBACf,WAAA;AAAA,gBACA,YAAA;AAAA,gBACC,uBAAkB+D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAEkL,EAAA,QAAQvK,GAAKX,CAAM;AAAA,cAAA;eAG1C/B,EAAA,EAAA,GAAAC,EAmCMK,GAAA,MAAAuD,EAnCyBjG,EAAA,OAAO,CAAzBN,GAAQoD,YAArBT,EAmCM,OAAA;AAAA,gBAnCmC,KAAKS;AAAA,gBAAO,OAAM;AAAA,cAAA;gBACzDF,EAMEJ,EAAA6C,EAAA,GAAA;AAAA,kBALC,eAAa3F,EAAO;AAAA,kBACpB,SAASoQ,EAAA;AAAA,kBACV,YAAA;AAAA,kBACA,MAAK;AAAA,kBACJ,uBAAkB,CAAA3L,OAAEmM,GAASxN,GAAOqB,EAAM;AAAA,gBAAA;gBAE7CvB,EAKEJ,EAAA6C,EAAA,GAAA;AAAA,kBAJC,eAAa3F,EAAO;AAAA,kBACpB,SAASyQ,GAAWzQ,EAAO,KAAK;AAAA,kBACjC,MAAK;AAAA,kBACJ,uBAAkB,CAAAyE,OAAEqM,GAAM1N,GAAOqB,EAAM;AAAA,gBAAA;gBAGlC3B,EAAAqM,EAAA,EAAW,SAASnP,EAAO,EAAE,KAAK8C,EAAAiM,EAAA,EAAY/O,EAAO,KAAK,MAAA,iBADlE6C,EAMEC,EAAA6C,EAAA,GAAA;AAAA;kBAJC,eAAa3F,EAAO,SAAK;AAAA,kBACzB,SAAS8C,EAAAsM,EAAA,EAAQ,IAAG,CAAEvO,QAAK,EAAQ,OAAAA,IAAK,OAASiC,EAAAjB,CAAA,EAAC,eAAgBhB,EAAK,EAAA,IAAA;AAAA,kBACxE,MAAK;AAAA,kBACJ,+BAAoBkQ,GAAS3N,GAAOgC,GAAKX,EAAM,KAAA,EAAA;AAAA,gBAAA,kEAGrC3B,EAAAqM,EAAA,EAAW,SAASnP,EAAO,EAAE,UAD1C6C,EAMEC,EAAAsF,EAAA,GAAA;AAAA;kBAJC,eAAapI,EAAO,SAAK;AAAA,kBACzB,aAAa8C,EAAAjB,CAAA,EAAC,YAAA;AAAA,kBACf,MAAK;AAAA,kBACJ,+BAAoBkP,GAAS3N,GAAO,OAAOqB,MAAM,EAAA,CAAA;AAAA,gBAAA;gBAEpDvB,EAMEJ,EAAAa,CAAA,GAAA;AAAA,kBALA,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACJ,cAAYb,EAAAjB,CAAA,EAAC,oBAAA;AAAA,kBACb,SAAK,CAAA4C,OAAEuM,GAAa5N,CAAK;AAAA,gBAAA;;cAI9BF,EAEcJ,EAAAa,CAAA,GAAA;AAAA,gBAFH,MAAK;AAAA,gBAAK,SAAQ;AAAA,gBAAO,MAAK;AAAA,gBAAQ,SAAOgN;AAAA,cAAA;2BAAW,MAEjE;AAAA,sBADA7N,EAAAjB,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;;;;UAKiB0E,EAAAsJ,EAAA,QAAPjP;0BAAoCA,CAAG;AAAA,YACtD,IAAAiF,EAAA,CAKC,EAN6D,KAAAH,QAAG;AAAA,cAEzD5C,EAAAiM,EAAA,EAAYnO,CAAG,MAAA,YAAkB8E,EAAI9E,CAAG,MAAA,aADhDiC,EAKCC,EAAAU,CAAA,GAAA;AAAA;gBAHE,MAAMyC,EAAWP,EAAI9E,CAAG,CAAA;AAAA,gBACzB,MAAK;AAAA,cAAA;2BACJ,MAAc;AAAA,kBAAX0C,EAAAC,EAAAmC,EAAI9E,CAAG,CAAA,GAAA,CAAA;AAAA,gBAAA;;oCAEOkC,EAAAiM,EAAA,EAAYnO,CAAG,MAAA,iBAAnCiC,EAEYC,EAAAC,CAAA,GAAA;AAAA;gBAFuC,MAAK;AAAA,gBAAK,MAAK;AAAA,cAAA;2BAAS,MAEzE;AAAA,sBADAD,EAAAjB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;oBAEkBiB,EAAAiM,EAAA,EAAYnO,CAAG,MAAA,eAApC+B,EAEaK,GAAA,EAAA,KAAA,KAAA;AAAA,gBADXM,EAAAC,EAAAmC,EAAI9E,CAAG,IAAIkC,EAAAjB,CAAA,gBAAgBiB,EAAAjB,CAAA,EAAC,SAAA,CAAA,GAAA,CAAA;AAAA,cAAA,UAETiB,EAAAiM,EAAA,EAAYnO,CAAG,MAAA,iBAApC+B,EAEaK,GAAA,EAAA,KAAA,KAAA;AAAA,oBADXF,EAAAjB,CAAA,EAAC,eAAgB6D,EAAI9E,CAAG,CAAA,EAAA,CAAA,GAAA,CAAA;AAAA,cAAA,UAELA,MAAG,YAAiB8E,EAAI,SAAM,UAAnD7C,EAEaC,EAAAU,CAAA,GAAA;AAAA;gBAF4C,MAAK;AAAA,gBAAU,MAAK;AAAA,cAAA;2BAAK,MAEhF;AAAA,kBADAF,EAAAC,EAAAmC,EAAI,MAAM,GAAA,CAAA;AAAA,gBAAA;;gCAEZ/C,EAES,QAAA;AAAA;gBAFK,OAAKwG,GAAA,EAAA,wBAA4BrG,EAAAiM,EAAA,EAAYnO,CAAG,MAAA,MAAA,CAAA;AAAA,cAAA,KAC5D0F,EAAKZ,EAAI9E,CAAG,CAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;QAMVF,EAAA,cADRmC,EAOEwO,IAAA;AAAA;UALC,KAAK3Q,EAAA,MAAI;AAAA,UACT,MAAMgB,EAAM;AAAA,UACZ,WAAS8N,EAAA;AAAA,UACT,QAAQC,EAAA;AAAA,UACR,gCAAOD,EAAA,QAAM;AAAA,QAAA;;;;;;;;;;;;;AC/YpB,UAAM9N,IAAQC,GAERC,IAAM3B,GAAewB,IAAU;AACrC,IAAAF,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GAEVsP,IAA+B,CAAC,OAAO,SAAS,YAAY,GAG5DC,IAAOnP,EAAyBkP,EAAM,KAAK,CAACvI,MAAQrH,EAAM,IAAIqH,CAAG,IAAI,CAAC,KAAK,KAAK,GAChFR,IAASnG,EAAyB,IAAI,GACtCqG,IAAOrG,EAAI,CAAC,GACZoG,IAAOpG,EAAI,EAAK,GAChBC,IAAUD,EAAmB,IAAI,GAEjCoP,IAAUvN;AAAA,MAAS,MACvBqN,EAAM,IAAI,CAACzQ,OAAW;AAAA,QACpB,OAAAA;AAAA,QACA,OAAO,GAAGgB,EAAE,aAAahB,CAAK,EAAE,CAAC,MAAMa,EAAM,IAAIb,CAAK,CAAC;AAAA,QACvD,UAAUa,EAAM,IAAIb,CAAK,MAAM;AAAA,MAAA,EAC/B;AAAA,IAAA;AAGJ,mBAAewE,EAAKf,IAAO,GAAkB;AAC3C,MAAAjC,EAAQ,QAAQ;AAEhB,UAAI;AACF,cAAMwC,IAAS,MAAMjD,EAAI,cAAc;AAAA,UACrC,MAAMF,EAAM;AAAA,UACZ,IAAIA,EAAM;AAAA,UACV,MAAM6P,EAAK;AAAA,UACX,OAAO7P,EAAM,IAAI;AAAA,UACjB,MAAM4C;AAAA,UACN,UAAU;AAAA,QAAA,CACX;AAED,QAAAiE,EAAO,QAAQjE,MAAS,IAAIO,EAAO,OAAO,CAAC,GAAI0D,EAAO,SAAS,CAAA,GAAK,GAAG1D,EAAO,IAAI,GAClF4D,EAAK,QAAQ5D,EAAO,cACpB2D,EAAK,QAAQ3D,EAAO,eAAeA,EAAO;AAAA,MAC5C,SAASpC,GAAO;AACd,QAAAJ,EAAQ,QAAQN,EAAQU,CAAK;AAAA,MAC/B;AAAA,IACF;AAEA,WAAA8C;AAAA,MACEgM;AAAA,MACA,MAAM;AACJ,QAAAhJ,EAAO,QAAQ,MACVlD,EAAA;AAAA,MACP;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK,cAKlB3C,EAAA,GAAAC,EAgBM,OAhBNC,IAgBM;AAAA,MAfJM,EAA4FJ,EAAA0I,EAAA,GAAA;AAAA,oBAArE+F,EAAA;AAAA,sDAAAA,EAAI,QAAA9M;AAAA,QAAG,SAAS+M,EAAA;AAAA,QAAS,MAAK;AAAA,QAAM,cAAY1O,EAAAjB,CAAA,EAAC,cAAA;AAAA,MAAA;MAEzDQ,EAAA,cAAfQ,EAAuEC,EAAAC,CAAA,GAAA;AAAA;QAA/C,MAAK;AAAA,QAAK,MAAK;AAAA,MAAA;mBAAS,MAAa;AAAA,cAAVV,EAAA,KAAO,GAAA,CAAA;AAAA,QAAA;;YACjCkG,EAAA,cAEzB5F,EASWK,GAAA,EAAA,KAAA,KAAA;AAAA,gBARTL,EAKMK,GAAA,MAAAuD,EALegC,EAAA,OAAM,CAAfzH,YAAZ6B,EAKM,OAAA;AAAA,UALwB,KAAK7B,EAAM;AAAA,UAAI,OAAM;AAAA,QAAA;UAClCA,EAAM,YAArB+B,EAEYC,EAAAO,EAAA,GAAA;AAAA;YAFe,MAAMvC,EAAM;AAAA,YAAK,QAAO;AAAA,YAAS,OAAM;AAAA,UAAA;uBAAwB,MAExF;AAAA,cADAwC,EAAAC,EAAAzC,EAAM,GAAG,GAAA,CAAA;AAAA,YAAA;;;UAEXoC,EAA0CkG,IAAA;AAAA,YAA1B,SAAStI,EAAM;AAAA,UAAA;;QAGhB0H,EAAA,cAAjB3F,EAAqFC,EAAAa,CAAA,GAAA;AAAA;UAA9D,MAAK;AAAA,UAAK,SAAQ;AAAA,UAAQ,SAAKiC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAnB,MAAEY,EAAKoD,EAAA,QAAI,CAAA;AAAA,QAAA;qBAAO,MAAC,CAAA,GAAA7C,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA;AAAA,cAAD,KAAC,EAAA;AAAA,UAAA;;;sBAV3E/C,EAA6CC,EAAAc,EAAA,GAAA;AAAA;QAAX,MAAM;AAAA,MAAA;;;;;;;;;;;;ACvC5C,UAAMlC,IAAQC,GAERC,IAAM3B,GAAewB,IAAU,GAC/BqC,IAAQC,GAAA;AACd,IAAAxC,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GAEVyP,IAAOrP,EAAgC,IAAI,GAC3C0C,IAAU1C,EAAI,EAAK,GACnBsP,IAAWtP,EAAc,EAAE,GAC3BuP,IAAavP,EAA4B,IAAI,GAC7CwP,IAAYxP,EAAI,EAAK,GACrB6C,IAAW7C,EAAc,EAAE,GAE3ByP,IAA8C;AAAA,MAClD,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW;AAAA,IAAA,GAGPnH,IAA+C;AAAA,MACnD,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,IAAA,GAGJ/J,IAAUsD,EAAkC,MAAM;AAAA,MACtD,EAAE,KAAK,MAAM,OAAOpC,EAAE,aAAa,GAAG,OAAO,GAAA;AAAA,MAC7C,EAAE,KAAK,cAAc,OAAOA,EAAE,iBAAiB,GAAG,UAAU,IAAA;AAAA,MAC5D,EAAE,KAAK,SAAS,OAAOA,EAAE,YAAY,GAAG,OAAO,IAAA;AAAA,MAC/C,EAAE,KAAK,UAAU,OAAOA,EAAE,aAAa,GAAG,OAAO,IAAA;AAAA,MACjD,EAAE,KAAK,UAAU,OAAOA,EAAE,aAAa,GAAG,OAAO,KAAK,OAAO,QAAA;AAAA,MAC7D,EAAE,KAAK,YAAY,OAAOA,EAAE,eAAe,GAAG,UAAU,KAAK,WAAW,IAAA;AAAA,MACxE,EAAE,KAAK,cAAc,OAAOA,EAAE,iBAAiB,GAAG,UAAU,KAAK,WAAW,IAAA;AAAA,IAAI,CACjF,GAEKiQ,IAAiB7N,EAA4C,MAAM;AAAA,MACvE,EAAE,KAAK,YAAY,OAAOpC,EAAE,eAAe,GAAG,OAAO,IAAA;AAAA,MACrD,EAAE,KAAK,SAAS,OAAOA,EAAE,YAAY,EAAA;AAAA,MACrC,EAAE,KAAK,OAAO,OAAOA,EAAE,eAAe,GAAG,OAAO,IAAI,OAAO,QAAA;AAAA,MAC3D,EAAE,KAAK,SAAS,OAAOA,EAAE,iBAAiB,GAAG,OAAO,KAAK,OAAO,QAAA;AAAA,MAChE,EAAE,KAAK,cAAc,OAAOA,EAAE,sBAAsB,GAAG,OAAO,KAAK,OAAO,QAAA;AAAA,IAAQ,CACnF,GAGKkQ,IAAO9N,EAAqD,MAAM;AACtE,YAAM+N,IAAMN,EAAS,MAAM,IAAI,MAAM,EAAE,KAAK,CAACO,GAAGC,MAAMD,IAAIC,CAAC;AAE3D,aAAIF,EAAI,WAAW,IAAU,OAEtBA,EAAI,WAAW,IAClB,EAAE,IAAIA,EAAI,CAAC,GAAI,MAAM,KAAA,IACrB,EAAE,IAAIA,EAAIA,EAAI,SAAS,CAAC,GAAI,MAAMA,EAAI,CAAC,EAAA;AAAA,IAC7C,CAAC,GAEKG,IAAelO;AAAA,MACnB,MAAM0N,EAAW,UAAU,QAAQA,EAAW,MAAM,KAAK,UAAUA,EAAW,MAAM,GAAG;AAAA,IAAA;AAGzF,aAASS,EAAI1R,GAAuB;AAClC,aAAIA,EAAI,eAAe,aAAmBmB,EAAE,kBAAkB,IAC1DnB,EAAI,eAAe,QAAcmB,EAAE,aAAa,IAChDnB,EAAI,eAAe,YAAkBmB,EAAE,iBAAiB,IAErDnB,EAAI,aAAamB,EAAE,gBAAgB,IAAI;AAAA,IAChD;AAEA,mBAAewD,EAAKqE,GAAmC;AACrD,MAAA5E,EAAQ,QAAQ;AAEhB,UAAI;AACF,QAAA2M,EAAK,QAAQ,MAAM7P,EAAI,KAAK,EAAE,MAAM8H,GAAO,QAAQ,GAAG,UAAUA,GAAO,WAAW,IAAI;AAAA,MACxF,SAASjH,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAqC,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAEA,mBAAeuN,IAAyB;AACtC,YAAMxE,IAAUkE,EAAK;AAKrB,UAHAJ,EAAW,QAAQ,MACnB1M,EAAS,QAAQ,CAAA,GAEb,EAAC4I,GAEL;AAAA,QAAA+D,EAAU,QAAQ;AAElB,YAAI;AACF,UAAAD,EAAW,QAAQ,MAAM/P,EAAI,QAAQiM,EAAQ,IAAIA,EAAQ,IAAI;AAAA,QAC/D,SAASpL,GAAO;AACd,UAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,QAC7B,UAAA;AACE,UAAAmP,EAAU,QAAQ;AAAA,QACpB;AAAA;AAAA,IACF;AAEA,WAAApP,GAAU,MAAM;AACd,YAAMvB,IAAK,OAAO6C,EAAM,MAAM,EAAE;AAEhC,MAAI,OAAO,UAAU7C,CAAE,KAAKA,IAAK,MAAGyQ,EAAS,QAAQ,CAACzQ,CAAE;AAAA,IAC1D,CAAC,GAEDsE,GAAMmM,GAAU,CAACzB,MAAS;AAExB,MAAIA,EAAK,SAAS,MAAY,QAAQA,EAAK,MAAM,EAAE,IACzCoC,EAAA;AAAA,IACZ,CAAC,mBAICxP,EAyFe2C,IAAA;AAAA,MAzFA,MAAM9D,EAAM;AAAA,MAAM,SAAQ;AAAA,MAAQ,MAAM;AAAA,IAAA;iBACrD,MAuFM;AAAA,QAvFNoE,EAuFM,OAvFNlD,IAuFM;AAAA,UAtFJM,EAkCUJ,EAAAwI,EAAA,GAAA,MAAA;AAAA,uBAjCR,MAgCW;AAAA,cAhCXpI,EAgCWJ,EAAA2C,EAAA,GAAA;AAAA,gBA/BD,UAAUiM,EAAA;AAAA,4DAAAA,EAAQ,QAAAjN;AAAA,gBACzB,MAAMgN,EAAA;AAAA,gBACN,SAAS9Q,EAAA;AAAA,gBACV,WAAQ;AAAA,gBACR,YAAA;AAAA,gBACC,iBAAa,CAAG+E,MAAkBA,EAAI,WAAM;AAAA,gBAC7C,OAAA;AAAA,gBACC,SAASZ,EAAA;AAAA,gBACT,cAAYhC,EAAAjB,CAAA,EAAC,iBAAA;AAAA,gBACb,eAAcwD;AAAA,cAAA;gBAEJ,mBAAeQ,EAAW,CAAmC,EAA1C,KAAAH,QAAG;AAAA,kBAAIxC,EAAmCJ,EAAAiD,EAAA,GAAA;AAAA,oBAAzB,OAAOL,EAAI;AAAA,kBAAA;;gBAC/C,cAAUG,EAAW,CAAkC,EAAzC,KAAAH,QAAG;AAAA,sBAAO5C,EAAAjB,CAAA,EAAC,cAAe6D,EAAI,KAAK,EAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;gBACjD,eAAWG,EACpB,CAEa,EAHW,KAAAH,QAAG;AAAA,kBAC3BxC,EAEaJ,EAAAU,CAAA,GAAA;AAAA,oBAFF,MAAMqO,EAASnM,EAAI,MAAM;AAAA,oBAAG,KAAA;AAAA,kBAAA;+BAAI,MAEzC;AAAA,0BADA5C,EAAAjB,CAAA,EAAC,eAAgB6D,EAAI,MAAM,EAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;gBAGpB,eAAWG,EAAW,CAE/B,EAFwB,KAAAH,QAAG;AAAA,kBAC3BpC,EAAAC,EAAAmC,EAAI,SAAM,GAAMA,EAAI,OAAO,MAAM,MAAA,EAAA,GAAA,CAAA;AAAA,gBAAA;gBAExB,iBAAaG,EACtB,CAMO,EAPmB,KAAAH,QAAG;AAAA,kBACjBA,EAAI,UAAhBhD,EAAA,GAAAC,EAMO,QANPM,IAMO;AAAA,qBALLP,EAAA,GAAAC,EAIWK,GAAA,MAAAuD,EAJqBmE,GAAU,CAAxBgE,GAAM9N,6BAA6B;AAAA,sBACnC8E,EAAI,OAAO,SAAS9E,CAAG,UAAvCiC,EAEaC,EAAAU,CAAA,GAAA;AAAA;wBAF8B,MAAAkL;AAAA,wBAAY,MAAK;AAAA,sBAAA;mCAAK,MAE/D;AAAA,0BADApL,EAAAC,EAAAmC,EAAI,OAAO,SAAS9E,CAAG,CAAA,GAAA,CAAA;AAAA,wBAAA;;;;;;gBAKpB,mBAAeiF,EAAW,CAAc,EAArB,KAAAH,QAAG;AAAA,kBAAOpC,EAAAC,EAAA6O,EAAI1M,CAAG,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;;;UAInCqM,EAAA,cAEhBlP,EA+CUC,EAAAwI,EAAA,GAAA;AAAA;YA/CO,OAAOxI,EAAAjB,CAAA,EAAC,cAAA;AAAA,UAAA;uBACvB,MAMU;AAAA,cANK8P,EAAA,cAAf9O,EAMUC,EAAAC,CAAA,GAAA;AAAA;gBANiB,MAAK;AAAA,gBAAK,MAAK;AAAA,gBAAQ,OAAM;AAAA,cAAA;2BACtD,MAA4B;AAAA,sBAAzBD,EAAAjB,CAAA,EAAC,mBAAA,CAAA,IAAwB,OAAE0B,EAAGoO,EAAA,MAAW,KAAK,EAAE,IAAG,OACtD,CAAA;AAAA,kBAAAzO,EAA+CJ,EAAAiD,EAAA,GAAA;AAAA,oBAArC,OAAO4L,EAAA,MAAW,KAAK;AAAA,kBAAA;oBAAc,QAAGpO,EAAGT,EAAAjB,CAAA,EAAC,iBAAA,CAAA,IAAsB,OAAE0B,EAC5EoO,EAAA,MAAW,GAAG,EAAE,IAChB,OACA,CAAA;AAAA,kBAAAzO,EAA6CJ,EAAAiD,EAAA,GAAA;AAAA,oBAAnC,OAAO4L,EAAA,MAAW,GAAG;AAAA,kBAAA;;;;cAI3BQ,EAAA,cADRtP,EAKEC,EAAAuI,EAAA,GAAA;AAAA;gBAHA,MAAK;AAAA,gBACJ,aAAavI,EAAAjB,CAAA,EAAC,qBAAA;AAAA,gBACf,OAAM;AAAA,cAAA;cAGRqB,EA8BWJ,EAAA2C,EAAA,GAAA;AAAA,gBA7BD,UAAUR,EAAA;AAAA,4DAAAA,EAAQ,QAAAR;AAAA,gBACzB,MAAMkN,EAAA,OAAY,UAAM,CAAA;AAAA,gBACxB,SAASG,EAAA;AAAA,gBACV,WAAQ;AAAA,gBACR,YAAA;AAAA,gBACA,OAAA;AAAA,gBACC,YAAY;AAAA,gBACZ,SAASF,EAAA;AAAA,gBACT,cAAY9O,EAAAjB,CAAA,EAAC,mBAAA;AAAA,cAAA;gBAEH,iBAAagE,EACtB,CAEa,EAHa,KAAAH,QAAG;AAAA,kBAC7BxC,EAEaJ,EAAAU,CAAA,GAAA;AAAA,oBAFF,MAAMkH,EAAWhF,EAAI,QAAQ;AAAA,oBAAG,KAAA;AAAA,kBAAA;+BAAI,MAE7C;AAAA,0BADA5C,EAAAjB,CAAA,EAAC,iBAAkB6D,EAAI,QAAQ,EAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;gBAGxB,YAAQG,EACjB,CAA+E,EAD1D,KAAAH,QAAG;AAAA,kBACxBxC,EAA+EJ,EAAAC,CAAA,GAAA;AAAA,oBAArE,MAAM2C,EAAI,MAAG,WAAA;AAAA,oBAAuB,MAAK;AAAA,kBAAA;+BAAK,MAAa;AAAA,sBAAVpC,EAAAC,EAAAmC,EAAI,GAAG,GAAA,CAAA;AAAA,oBAAA;;;;gBAEzD,cAAUG,EACnB,CAAoF,EAD7D,KAAAH,QAAG;AAAA,kBAC1BxC,EAAoFJ,EAAAC,CAAA,GAAA;AAAA,oBAA1E,MAAM2C,EAAI,QAAK,YAAA;AAAA,oBAAwB,MAAK;AAAA,kBAAA;+BAAK,MAAe;AAAA,sBAAZpC,EAAAC,EAAAmC,EAAI,KAAK,GAAA,CAAA;AAAA,oBAAA;;;;gBAE9D,UAAQG,EACjB,CAKE,EANmB,KAAAH,QAAG;AAAA,kBAEhBiM,EAAA,cADR9O,EAKEyP,IAAA;AAAA;oBAHC,MAAMX,EAAA,MAAW,KAAK;AAAA,oBACtB,IAAIA,EAAA,MAAW,GAAG;AAAA,oBAClB,KAAAjM;AAAA,kBAAA;;;;;;oCA7CT7C,EAAmFC,EAAAC,CAAA,GAAA;AAAA;YAA7D,MAAK;AAAA,YAAK,MAAK;AAAA,UAAA;uBAAQ,MAA4B;AAAA,kBAAzBD,EAAAjB,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;;;;;;;;;;;;AC9KvD,UAAMH,IAAQC,GAERkC,IAAUpC,GAAA,GACVG,IAAM3B,GAAe4D,CAAO;AAClC,IAAAtC,GAAA;AAEA,UAAMM,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GAEVZ,IAASgB,EAAiB,EAAE,GAC5BmQ,IAASnQ,EAA8B,EAAE,GACzC0C,IAAU1C,EAAI,EAAI,GAClBwF,IAASxF,EAAI,EAAK,GAGlBoQ,IAAY3O,EAAQ,IAAI,cAAc;AAE5C,IAAArB,GAAU,YAAY;AACpB,UAAI;AACF,QAAApB,EAAO,QAAS,MAAMQ,EAAI,SAAA;AAAA,MAC5B,SAASa,GAAO;AACd,QAAA6C,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAqC,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF,CAAC;AAED,mBAAe2N,IAAsB;AACnC,MAAA7K,EAAO,QAAQ,IACf2K,EAAO,QAAQ,CAAA;AAEf,UAAI;AACF,QAAAnR,EAAO,QAAS,MAAMQ,EAAI,aAAaR,EAAO,KAAK,GACnDkE,EAAM,QAAQzD,EAAE,YAAY,CAAC;AAAA,MAC/B,SAASY,GAAO;AACd,cAAMpC,IAAQoC,EAA2D;AAEzE,QAAIpC,GAAM,WAAQkS,EAAO,QAAQlS,EAAK,SAEtCiF,EAAM,OAAOvD,EAAQU,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAmF,EAAO,QAAQ;AAAA,MACjB;AAAA,IACF;2BAIE/E,EAee2C,IAAA;AAAA,MAfA,MAAM9D,EAAM;AAAA,MAAM,SAAQ;AAAA,MAAY,MAAM;AAAA,IAAA;iBACzD,MAaM;AAAA,QAbNoE,EAaM,OAbNlD,IAaM;AAAA,UAZekC,EAAA,cAAnBjC,EAAwCC,EAAAc,EAAA,GAAA;AAAA;YAAX,MAAM;AAAA,UAAA,YACnCf,EAMEC,EAAA4P,EAAA,GAAA;AAAA;wBAJStR,EAAA;AAAA,0DAAAA,EAAM,QAAAqD;AAAA,YACf,MAAK;AAAA,YACJ,QAAQ8N,EAAA;AAAA,YACR,WAAWzP,EAAA0P,CAAA;AAAA,UAAA;UAGO1P,EAAA0P,CAAA,MAAc1N,EAAA,cAAnCjC,EAEgBC,EAAA6P,EAAA,GAAA,EAAA,KAAA,KAAA;AAAA,uBADd,MAA0F;AAAA,cAA1FzP,EAA0FJ,EAAAa,CAAA,GAAA;AAAA,gBAA/E,MAAK;AAAA,gBAAW,SAASiE,EAAA;AAAA,gBAAS,SAAO6K;AAAA,cAAA;2BAAM,MAAoB;AAAA,sBAAjB3P,EAAAjB,CAAA,EAAC,WAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;;;;;;;;;AChD/D,SAAS+Q,GAAMpB,IAAwB,IAAiB;AAC7D,QAAMjN,IAAOiN,EAAQ,QAAQ,UACvB9P,IAAQ,EAAE,MAAM6C,EAAA;AAEtB,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAAA;AAAA,IACA,QAAQ;AAAA,MACN,EAAE,MAAAA,GAAM,MAAM,cAAc,WAAWsO,IAAmB,OAAAnR,EAAA;AAAA,MAC1D,EAAE,MAAM,GAAG6C,CAAI,WAAW,MAAM,qBAAqB,WAAWuO,IAAiB,OAAApR,EAAA;AAAA,MACjF,EAAE,MAAM,GAAG6C,CAAI,UAAU,MAAM,oBAAoB,WAAWwO,IAAgB,OAAArR,EAAA;AAAA,MAC9E,EAAE,MAAM,GAAG6C,CAAI,UAAU,MAAM,oBAAoB,WAAWyO,IAAgB,OAAAtR,EAAA;AAAA,MAC9E,EAAE,MAAM,GAAG6C,CAAI,SAAS,MAAM,mBAAmB,WAAW0O,IAAe,OAAAvR,EAAA;AAAA,MAC3E;AAAA,QACE,MAAM,GAAG6C,CAAI;AAAA,QACb,MAAM;AAAA,QACN,WAAW2O;AAAA,QACX,OAAAxR;AAAA,MAAA;AAAA,IACF;AAAA,EACF;AAEJ;"}
1
+ {"version":3,"file":"index.js","sources":["../src/addresses.ts","../src/AuditAddress.vue","../src/messages.ts","../src/i18n.ts","../src/AuditLinkAttrs.vue","../src/api.ts","../src/AuditStatus.vue","../src/AuditHostPlaces.vue","../src/AuditLayout.vue","../src/AuditHostsPage.vue","../src/AuditDetails.vue","../src/AuditFixDialog.vue","../src/AuditHideDialog.vue","../src/AuditLinkGroups.vue","../src/AuditIssueList.vue","../src/AuditIssuesPage.vue","../src/AuditOverviewPage.vue","../src/headings.ts","../src/AuditHeadings.vue","../src/resources.ts","../src/AuditPageCard.vue","../src/fields.ts","../src/AuditPagesPage.vue","../src/AuditCompareIssues.vue","../src/AuditRunsPage.vue","../src/AuditSettingsPage.vue","../src/module.ts"],"sourcesContent":["import type { BadgeType } from '@webx-ui/core'\n\n/** What tells a redirect's target from its source when the rest of the address is the same. */\nexport type AddressDifference = 'slash' | 'www' | 'https'\n\n/**\n * The small differences between where a link points and where it lands: a trailing slash, `www.`,\n * `http` → `https`. Empty when the addresses differ in anything else (the page really moved) or\n * either is not an address — then there is nothing small to name.\n */\nexport function differences(from: string, to: string): AddressDifference[] {\n let source: URL\n let target: URL\n\n try {\n source = new URL(from)\n target = new URL(to, from)\n } catch {\n return []\n }\n\n const found: AddressDifference[] = []\n\n if (source.protocol === 'http:' && target.protocol === 'https:') found.push('https')\n else if (source.protocol !== target.protocol) return []\n\n const bare = (host: string) => host.replace(/^www\\./, '')\n\n if (source.host !== target.host) {\n if (bare(source.host) !== bare(target.host)) return []\n found.push('www')\n }\n\n const trimmed = (path: string) => path.replace(/\\/+$/, '')\n\n if (source.pathname !== target.pathname) {\n if (trimmed(source.pathname) !== trimmed(target.pathname)) return []\n found.push('slash')\n }\n\n if (source.search !== target.search || source.hash !== target.hash) return []\n\n return found\n}\n\n/** How many characters stay at the end of a shortened address: where a slug or a slash differs. */\nconst TAIL = 14\n\n/**\n * An address cut in two for an ellipsis in the middle: the head gives way, the tail stays —\n * the end of an address is what tells two of them apart.\n */\nexport function splitMiddle(text: string): [string, string] {\n if (text.length <= TAIL * 2) return [text, '']\n\n return [text.slice(0, -TAIL), text.slice(-TAIL)]\n}\n\n/** The colour of an answer's code. */\nexport function statusType(value: unknown): BadgeType {\n const code = Number(value)\n\n if (code >= 500 || code === 0) return 'danger'\n if (code >= 400) return 'warning'\n // A permanent redirect only asks for the link to be updated; a temporary one may move again.\n if (code === 301 || code === 308) return 'info'\n if (code >= 300) return 'warning'\n\n return 'success'\n}\n\n/** The codes with a line of their own in the dictionary; the rest are explained by their class. */\nconst EXPLAINED = [\n 200, 201, 204, 206, 301, 302, 303, 304, 307, 308, 400, 401, 403, 404, 405, 406, 408, 410, 415,\n 429, 451, 500, 502, 503, 504,\n]\n\n/** The dictionary key of what an answer means: `code-404`, `code-5xx`, or `code-none`. */\nexport function statusKey(code: number | null | undefined): string {\n if (!code) return 'code-none'\n if (EXPLAINED.includes(code)) return `code-${code}`\n if (code >= 100 && code < 600) return `code-${Math.floor(code / 100)}xx`\n\n return 'code-none'\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { WxLink, WxTooltip, type LinkType } from '@webx-ui/core'\nimport { splitMiddle } from './addresses'\n\n/**\n * An address on one line, opened in a new tab: a long one loses its middle rather than wrapping,\n * since the start names the site and the end tells two addresses apart. The whole of it is in the\n * panel's tooltip.\n */\nconst props = defineProps<{ href: string; type?: LinkType; strong?: boolean }>()\n\nconst parts = computed(() => splitMiddle(props.href))\n</script>\n\n<template>\n <wx-tooltip :max-width=\"560\">\n <wx-link\n :href=\"props.href\"\n target=\"_blank\"\n :type=\"props.type\"\n :weight=\"props.strong ? 'medium' : undefined\"\n class=\"wx-audit-address\"\n ><span class=\"wx-audit-address__head\">{{ parts[0] }}</span\n ><span v-if=\"parts[1]\" class=\"wx-audit-address__tail\">{{ parts[1] }}</span></wx-link\n >\n <template #content>\n <span class=\"wx-audit-address__full\">{{ props.href }}</span>\n </template>\n </wx-tooltip>\n</template>\n\n<style scoped>\n.wx-audit-address {\n display: flex;\n gap: 0;\n min-width: 0;\n max-width: 100%;\n white-space: nowrap;\n}\n\n.wx-audit-address__head {\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n\n.wx-audit-address__tail {\n flex-shrink: 0;\n}\n\n/* The tip is teleported out of this component, and an address has no spaces to wrap at. */\n:global(.wx-audit-address__full) {\n overflow-wrap: anywhere;\n}\n</style>\n","import type { Messages } from '@webx-ui/module-admin'\n\n/**\n * What this package says, in English — the same keys `webx-ui/module-audit` ships as\n * `lang/en/*.php`, so a key never reaches the screen while the dictionary is on its way. The\n * server's dictionary wins; the check texts and the details arrive translated from the server and\n * are not repeated here.\n */\nexport const auditMessages: Record<string, Messages> = {\n module: {\n title: 'Audit',\n },\n\n page: {\n overview: 'Overview',\n issues: 'Findings',\n settings: 'Settings',\n run: 'Run the audit',\n scope: 'Scope',\n 'scope-full': 'Full',\n 'scope-full-help': 'Everything the audit can check.',\n 'scope-quick': 'Quick',\n 'scope-quick-help': 'The config, the host and the database — takes seconds.',\n start: 'Start',\n started: 'The audit has started.',\n cancel: 'Cancel the run',\n never: 'No audit has been run yet.',\n 'never-help':\n 'Run the first one to see how the site looks to a visitor and to a search engine.',\n health: 'Health',\n errors: 'Errors',\n warnings: 'Warnings',\n notices: 'Notices',\n new: 'New',\n fixed: 'Fixed',\n 'health-pages': 'Pages without errors: :clean of :pages',\n 'health-site': 'Errors of the whole site: :count',\n 'health-warnings': 'Checks with warnings: :count',\n 'health-help':\n 'The share of pages without errors, minus 10 points for each error of the whole site and 2 for each check with warnings — the warnings take 20 at most.',\n 'last-run': 'Last run',\n 'base-url': 'Address',\n 'status-queued': 'Waiting in the queue',\n 'status-running': 'Running',\n 'status-done': 'Done',\n 'status-failed': 'Failed',\n 'status-cancelled': 'Cancelled',\n 'stage-probes': 'Config and host',\n 'stage-database': 'Database',\n 'stage-crawl': 'Pages',\n 'stage-analyse': 'Analysis',\n 'last-failed': 'The last run did not finish: :error',\n 'by-group': 'By group',\n 'group-config': 'Configuration',\n 'group-host': 'Host and addresses',\n 'group-hosts': 'Outgoing addresses',\n 'group-other': 'Other',\n sources: 'Content searched',\n 'sources-missing': 'Installed, but not searched:',\n 'sources-help':\n 'Besides crawling the site, the audit reads the text modules keep in the database — drafts, hidden records and fields the template never prints — and looks there for absolute addresses, such as links to a development stand. Green: modules that hand their text over. Orange: modules installed here that do not yet. Their published pages are still crawled, but their drafts and hidden fields are not searched, and a fix button cannot reach them.',\n 'sources-help-label': 'What this means',\n 'sync-queue':\n 'The queue runs jobs inside the request (sync), so the panel cannot start a run. Run php artisan webx:audit:run from the terminal or cron.',\n 'already-running': 'An audit is already running.',\n check: 'Check',\n count: 'Found',\n severity: 'Severity',\n 'severity-error': 'Error',\n 'severity-warning': 'Warning',\n 'severity-notice': 'Notice',\n 'any-severity': 'Any severity',\n 'any-group': 'Any group',\n 'any-state': 'New and persisting',\n 'state-new': 'New',\n 'state-persisting': 'Persisting',\n address: 'Address',\n empty: 'Nothing found.',\n clean: 'The last run found nothing.',\n found: 'What was found',\n why: 'Why it matters',\n fix: 'How to fix it',\n explain: 'What this check means',\n 'open-editor': 'Open in the editor',\n 'fix-button': 'Fix',\n 'fix-apply': 'Apply',\n 'fix-applied': 'Done. Run the audit again to see the finding go.',\n 'fix-none': 'Nothing left to change: no fix can close this finding now.',\n 'fix-pressed': 'Fixed — waiting for the next run',\n 'fix-changes': 'Changes',\n 'fix-before': 'Now',\n 'fix-after': 'After',\n yes: 'Yes',\n no: 'No',\n missing: 'Missing',\n pages: 'Pages',\n 'pages-progress': 'Pages crawled: :crawled of at most :limit',\n 'resources-progress':\n 'Pictures, styles, scripts and external links checked: :checked of :total',\n 'pages-none': 'No full run has crawled the site yet. Start a full audit to see every page.',\n 'pages-run': 'Full run of :date',\n 'group-indexing': 'Indexing',\n 'group-redirects': 'Redirects',\n 'group-page': 'Page',\n 'group-content': 'Content and speed',\n 'group-links': 'Links',\n 'group-images': 'Pictures',\n 'group-a11y': 'Accessibility',\n 'group-structure': 'Structure',\n columns: 'Columns',\n export: 'Export CSV',\n 'search-url': 'Search by address',\n 'any-status': 'Any answer',\n 'status-none': 'No answer',\n 'any-indexable': 'Indexable or not',\n 'indexable-yes': 'Indexable',\n 'indexable-no': 'Not indexable',\n 'any-check': 'With any findings or none',\n 'add-filter': 'Add a filter',\n 'remove-filter': 'Remove the filter',\n 'op-contains': 'contains',\n 'op-eq': 'is',\n 'op-empty': 'is empty',\n 'op-filled': 'is not empty',\n 'op-gt': 'more than',\n 'op-lt': 'less than',\n 'op-yes': 'yes',\n 'op-no': 'no',\n value: 'Value',\n 'field-url': 'Address',\n 'field-status': 'Code',\n 'field-final_status': 'Final code',\n 'field-redirect_to': 'Redirects to',\n 'field-source': 'Found through',\n 'field-depth': 'Depth',\n 'field-indexable': 'Indexable',\n 'field-issues': 'Findings',\n 'field-title': 'Title',\n 'field-description': 'Description',\n 'field-h1': 'H1',\n 'field-canonical': 'Canonical',\n 'field-robots_meta': 'Meta robots',\n 'field-x_robots_tag': 'X-Robots-Tag',\n 'field-lang': 'Language',\n 'field-content_type': 'Content type',\n 'field-bytes': 'Size, bytes',\n 'field-ttfb_ms': 'First byte, ms',\n 'field-total_ms': 'Answer, ms',\n 'field-compression': 'Compression',\n 'field-word_count': 'Words',\n 'field-links_in': 'Links in',\n 'field-links_out_internal': 'Internal links out',\n 'field-links_out_external': 'External links out',\n 'field-images': 'Pictures',\n 'field-images_without_alt': 'Pictures without alt',\n 'field-in_sitemap': 'In the sitemap',\n 'field-in_registry': 'In the registry',\n 'field-blocked_by_robots': 'Closed in robots.txt',\n 'source-home': 'Home page',\n 'source-sitemap': 'Sitemap',\n 'source-registry': 'Address registry',\n 'source-link': 'Link',\n 'card-overview': 'Overview',\n 'card-issues': 'Problems',\n 'card-incoming': 'Incoming',\n 'card-outgoing': 'Outgoing',\n 'card-images': 'Pictures',\n 'card-css': 'CSS',\n 'card-js': 'JS',\n 'card-microdata': 'Structured data',\n 'card-headings': 'Headings',\n 'no-headings': 'The page has no headings.',\n 'headings-recheck': 'The list of headings appears once the page is checked again.',\n 'heading-empty': 'Empty heading',\n 'headings-hints': 'Not the usual order',\n 'headings-fine':\n 'The headings go in the usual order: one H1 first, each level one step below the one above.',\n 'headings-no-h1':\n 'There is no H1. A page needs one main heading — search engines and screen readers start from it.',\n 'headings-many-h1': 'More than one H1 — keep one, make the rest H2. H1 headings: :count',\n 'headings-h1-not-first':\n 'The page starts with :level, not H1: the main heading should come before the rest.',\n 'headings-skipped':\n 'Levels are skipped — go down one step at a time: after H2 comes H3, not H4. Places: :count',\n 'headings-empty':\n 'Headings with no text — fill them in or make them ordinary text. Empty: :count',\n 'heading-missing': ':level is missing after :after',\n 'headings-summary-ok': 'In order, headings: :count',\n 'headings-summary-bad': 'Out of order, headings: :count',\n 'headings-open': 'Open the map',\n response: 'Response',\n headers: 'Headers',\n markup: 'Markup',\n 'open-page': 'Open the page',\n 'no-issues': 'No problems on this page.',\n 'no-links': 'No links.',\n kind: 'Kind',\n anchor: 'Anchor',\n host: 'Host',\n size: 'Size',\n cache: 'Cache',\n alt: 'Alt',\n 'not-checked': 'Not checked',\n 'no-resources': 'Nothing of this kind on the page.',\n 'no-json-ld': 'The page has no structured data.',\n 'jsonld-block': 'Block :number',\n 'jsonld-error': 'Does not parse:',\n 'jsonld-required': 'Required fields missing:',\n 'jsonld-recommended': 'Recommended fields missing:',\n 'jsonld-complete': 'Every field search engines ask for is there.',\n 'host-own': 'Own',\n 'host-own_mirror': 'Other mirror',\n 'host-dev': 'Stand',\n 'host-external': 'External',\n error: 'Error',\n 'source-list': 'Recheck list',\n hosts: 'Outgoing',\n runs: 'Runs',\n 'scope-urls': 'Recheck',\n 'urls-foreign': 'None of these addresses is on the audited site.',\n 'state-hidden': 'Hidden',\n hide: 'Hide',\n 'hide-title': 'Hide this finding',\n 'hide-help':\n 'Hidden findings stop counting, in this run and in every later one. Nothing is deleted: the hidden list shows them again.',\n 'hide-pattern': 'Addresses',\n 'hide-pattern-help':\n 'This address, or a mask of them: * is a stretch without a slash, ** one with slashes (/search/**). Empty hides every finding of the check.',\n 'hide-reason': 'Why it is all right',\n 'hide-count': 'Findings of the last run it would hide: :count',\n 'hidden-done': 'Hidden.',\n 'hidden-reason': 'Hidden: :reason',\n 'hidden-by': 'Hidden by :who: :reason',\n unhide: 'Show again',\n unhidden: 'Shown again.',\n recheck: 'Recheck',\n 'recheck-running': 'Rechecking the page…',\n 'recheck-fixed': 'Fixed since the last full run: :count',\n 'recheck-new': 'New since the last full run: :count',\n 'recheck-compare': 'Compare the runs',\n 'export-page': 'Export',\n 'runs-empty': 'No runs yet.',\n 'run-id': 'Run',\n status: 'Status',\n 'started-at': 'Started',\n 'started-by': 'Started by',\n 'by-schedule': 'Schedule',\n 'by-mcp': 'Agent',\n 'by-console': 'Console',\n 'by-person': 'Administrator',\n compare: 'Compare',\n 'compare-help':\n 'Pick two runs: what the later one found that the earlier did not, what both found, and what is gone.',\n 'compare-from': 'Earlier run',\n 'compare-to': 'Later run',\n 'compare-none': 'Both runs found the same.',\n 'compare-scopes':\n 'The runs differ in scope: only the checks the later run ran can count as fixed.',\n 'kind-new': 'New',\n 'kind-persisting': 'Persisting',\n 'kind-fixed': 'Fixed',\n 'hosts-empty': 'No run has seen a link or an address in the database yet.',\n 'search-host': 'Search by host',\n 'any-class': 'Any class',\n links: 'Links',\n fields: 'Fields in the database',\n broken: 'Broken',\n 'first-seen': 'First seen',\n 'host-pages': 'On pages',\n 'host-fields': 'In the database',\n record: 'Record',\n field: 'Field',\n unpublished: 'Not published',\n save: 'Save',\n saved: 'Saved.',\n dismiss: 'Cancel',\n 'view-full': 'View full size',\n 'view-pages': 'By page',\n 'view-links': 'By link',\n 'leads-to': 'Leads to',\n 'change-slash': 'Slash only',\n 'change-www': 'www',\n 'change-https': 'http → https',\n 'link-pages': 'Pages: :count',\n 'link-show-all': 'Show all',\n 'link-collapse': 'Collapse',\n 'attrs-opener':\n 'Opens in a new tab without noopener. Current browsers add it themselves; older ones let the opened page control this one.',\n 'section-answer': 'Server answer',\n 'section-crawl': 'Crawl',\n 'section-head': 'Markup',\n 'section-sharing': 'Preview and structured data',\n 'code-none':\n 'No answer — the server did not respond in time or the connection failed (DNS, certificate, refused). Open the address in a browser.',\n 'code-200': '200 OK — the page opens normally.',\n 'code-201': '201 Created — the server created something; a link should not lead here.',\n 'code-204': '204 No Content — answered, but with an empty page.',\n 'code-206': '206 Partial Content — a part of the file was sent, as video and downloads do.',\n 'code-301':\n '301 Moved Permanently — the address has moved for good. Update the link to where it leads.',\n 'code-302':\n '302 Found — a temporary redirect. The target may change again; search engines keep the old address.',\n 'code-303':\n '303 See Other — sent elsewhere after a form or an action; a link should point at the result.',\n 'code-304': \"304 Not Modified — the browser's copy is still current.\",\n 'code-307': '307 Temporary Redirect — like 302: temporary, the old address stays the main one.',\n 'code-308': '308 Permanent Redirect — like 301: moved for good. Update the link.',\n 'code-400':\n '400 Bad Request — the server did not understand the request; often a broken address.',\n 'code-401': '401 Unauthorized — sign-in needed. Visitors without an account cannot open it.',\n 'code-403':\n '403 Forbidden — the server refused. Many sites answer robots this way: if it opens in a browser, the link is fine.',\n 'code-404': '404 Not Found — the page is gone. Fix or remove the link.',\n 'code-405':\n '405 Method Not Allowed — the address exists but does not answer this kind of request.',\n 'code-406':\n '406 Not Acceptable — the server would not answer in a form the robot asked for; check in a browser.',\n 'code-408': '408 Request Timeout — the server gave up waiting. Usually passes; recheck later.',\n 'code-410': '410 Gone — removed on purpose and not coming back. Remove the link.',\n 'code-415': '415 Unsupported Media Type — the server refused the format of the request.',\n 'code-429':\n '429 Too Many Requests — the server asked the robot to slow down. Not a broken page.',\n 'code-451': \"451 Unavailable For Legal Reasons — blocked by law in the server's region.\",\n 'code-500':\n '500 Internal Server Error — the site behind the link broke. Recheck later; if it stays, the link is dead.',\n 'code-502': '502 Bad Gateway — the server behind a proxy did not answer. Usually temporary.',\n 'code-503': '503 Service Unavailable — overloaded or under maintenance. Usually temporary.',\n 'code-504':\n '504 Gateway Timeout — the server behind a proxy answered too slowly. Usually temporary.',\n 'code-1xx': 'An interim answer — the request is still being handled.',\n 'code-2xx': 'A success — the address answered.',\n 'code-3xx':\n 'A redirect — the address sends elsewhere. Better to link straight to where it leads.',\n 'code-4xx':\n 'A client error — the address cannot be opened as it is: missing, closed or refused.',\n 'code-5xx': 'A server error — the site behind the link failed. Often temporary; recheck later.',\n },\n}\n","import { useAdmin } from '@webx-ui/module-admin'\nimport { auditMessages } from './messages'\n\nconst seeded = new WeakSet<object>()\n\n/** Puts this package's English under the panel's dictionary, once per panel. */\nexport function useAuditMessages(): void {\n try {\n const { i18n } = useAdmin()\n\n if (!seeded.has(i18n)) {\n i18n.defaults('webx-audit', auditMessages)\n seeded.add(i18n)\n }\n } catch {\n // Outside a panel there is no dictionary to seed, and `useTranslate` falls back on its own.\n }\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxTooltip } from '@webx-ui/core'\nimport { useAuditMessages } from './i18n'\n\n/**\n * A link's `target` and `rel`, as they are in the markup: `_blank`, `nofollow`, `noopener`… Nothing\n * when the link has neither — a plain link is the usual case, not an empty cell. `_blank` without\n * `noopener` or `noreferrer` is marked: current browsers add `noopener` themselves, older ones\n * hand the opened page control of this one.\n */\nconst props = defineProps<{ rel?: string | null; target?: string | null }>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst rels = computed(() => (props.rel ?? '').split(/\\s+/).filter(Boolean))\n\nconst opener = computed(\n () =>\n props.target?.toLowerCase() === '_blank' &&\n !rels.value.some((rel) => rel === 'noopener' || rel === 'noreferrer'),\n)\n</script>\n\n<template>\n <span v-if=\"props.target || rels.length\" class=\"wx-audit-attrs\">\n <wx-tooltip v-if=\"props.target && opener\" :content=\"t('page.attrs-opener')\" :max-width=\"320\">\n <wx-badge type=\"warning\" variant=\"outline\" size=\"sm\">{{ props.target }}</wx-badge>\n </wx-tooltip>\n <wx-badge v-else-if=\"props.target\" variant=\"outline\" size=\"sm\">{{ props.target }}</wx-badge>\n <wx-badge v-for=\"value in rels\" :key=\"value\" variant=\"outline\" size=\"sm\">{{ value }}</wx-badge>\n </span>\n</template>\n\n<style scoped>\n.wx-audit-attrs {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n min-width: 0;\n}\n</style>\n","import type { AdminContext } from '@webx-ui/module-admin'\nimport type {\n AuditCheckRow,\n AuditComparison,\n AuditComparisonKind,\n AuditFixOffer,\n AuditFixResult,\n AuditHosts,\n AuditHostClass,\n AuditIgnoreRule,\n AuditIssue,\n AuditIssueQuery,\n AuditLatest,\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditPageQuery,\n AuditPageRow,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditScope,\n} from './types'\n\nexport interface AuditApi {\n /** The run that is going, the last one that finished, and whether the queue can take one. */\n latest(): Promise<AuditLatest>\n run(id: number): Promise<AuditRun>\n /** Every run, newest first — the history. */\n runs(query?: { page?: number; per_page?: number }): Promise<AuditPage<AuditRun>>\n /**\n * Queues a run; refused with 409 on a `sync` queue or while another one is going. A `urls` run\n * is a recheck of the addresses given.\n */\n start(scope: AuditScope, urls?: string[]): Promise<AuditRun>\n cancel(id: number): Promise<AuditRun>\n /** The checks of a run that found something, worst first. */\n checks(run: number, query?: AuditIssueQuery): Promise<AuditCheckRow[]>\n /** The findings of a run — of one check when `check` is given. */\n issues(run: number, query?: AuditIssueQuery): Promise<AuditPage<AuditIssue>>\n /** The crawled pages of a run under the screen's filters. */\n pages(run: number, query?: AuditPageQuery): Promise<AuditPage<AuditPageRow>>\n /** Where the browser downloads the same list as CSV, under the panel's session. */\n pagesFile(run: number, query: AuditPageQuery, columns: string[]): string\n page(run: number, id: number): Promise<AuditPageCard>\n /** The links of a page: `out` — what it points at, `in` — what points at it. */\n links(\n run: number,\n id: number,\n query?: { direction?: 'in' | 'out'; kind?: string; page?: number; per_page?: number },\n ): Promise<AuditPage<AuditLinkRow>>\n /** What a page loads, a tab of the card at a time. */\n resources(\n run: number,\n id: number,\n query: { tab: AuditResourceTab; page?: number; per_page?: number },\n ): Promise<AuditPage<AuditResourceRow>>\n /** The fixes that can close a finding now, each with what it would change. */\n fixes(run: number, issue: number): Promise<AuditFixOffer[]>\n /** Presses a fix — or, with `dryRun`, only asks again what it would change. */\n fix(run: number, issue: number, fix: string, dryRun?: boolean): Promise<AuditFixResult>\n /** Where the browser downloads one page of a run — its snapshot, findings and links. */\n pageFile(run: number, id: number): string\n /** Two runs by fingerprint; without `from`, `to` against the run it was analysed against. */\n compare(to: number, from?: number | null): Promise<AuditComparison>\n /** The findings of one kind of a comparison, of one check when given. */\n compareIssues(query: {\n to: number\n from?: number | null\n kind: AuditComparisonKind\n check?: string\n page?: number\n per_page?: number\n }): Promise<AuditPage<AuditIssue>>\n /** Every host the site points at, by class — stands first; with `host`, where it stands. */\n hosts(query?: {\n class?: AuditHostClass | null\n search?: string\n host?: string\n }): Promise<AuditHosts>\n /** The hiding rules. */\n ignores(): Promise<AuditIgnoreRule[]>\n /** Hides what a rule matches, with the reason. */\n hide(rule: { check: string; pattern: string; reason: string }): Promise<AuditIgnoreRule>\n /** How many findings of the last run a rule would hide — nothing is hidden. */\n hidePreview(rule: { check: string; pattern: string }): Promise<number>\n /** Removes a rule: its findings count again. */\n unhide(id: number): Promise<void>\n /** The section's settings, keyed as the screen names them. */\n settings(): Promise<Record<string, unknown>>\n saveSettings(values: Record<string, unknown>): Promise<Record<string, unknown>>\n}\n\n/** The query of the pages screen as the API reads it: `f[field]=op:value` for each filter. */\nexport function pageParams(query: AuditPageQuery): Record<string, string | number | undefined> {\n const params: Record<string, string | number | undefined> = {\n search: query.search || undefined,\n status: query.status || undefined,\n indexable:\n query.indexable === null || query.indexable === undefined\n ? undefined\n : query.indexable\n ? 1\n : 0,\n check: query.check || undefined,\n sort: query.sort || undefined,\n page: query.page,\n per_page: query.per_page,\n }\n\n for (const filter of query.filters ?? []) {\n params[`f[${filter.field}]`] =\n filter.value === undefined || filter.value === '' ? filter.op : `${filter.op}:${filter.value}`\n }\n\n return params\n}\n\n/** Everything under `/audit`, below the panel's API path. */\nexport function createAuditApi(admin: AdminContext): AuditApi {\n const base = `${admin.apiPath}/audit`\n const data = <T>(body: { data: T }): T => body.data\n\n /* `undefined` drops a parameter; `null` and `''` would be sent as words. */\n const filters = (query: AuditIssueQuery) => ({\n check: query.check || undefined,\n severity: query.severity || undefined,\n group: query.group || undefined,\n state: query.state || undefined,\n page: query.page,\n per_page: query.per_page,\n })\n\n return {\n latest: () => admin.http.get<{ data: AuditLatest }>(`${base}/runs/latest`).then(data),\n\n run: (id) => admin.http.get<{ data: AuditRun }>(`${base}/runs/${id}`).then(data),\n\n runs: (query = {}) =>\n admin.http\n .get<{\n data: AuditRun[]\n meta: Omit<AuditPage<AuditRun>, 'data'>\n }>(`${base}/runs`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n start: (scope, urls) =>\n admin.http\n .post<{ data: AuditRun }>(`${base}/runs`, scope === 'urls' ? { scope, urls } : { scope })\n .then(data),\n\n cancel: (id) => admin.http.post<{ data: AuditRun }>(`${base}/runs/${id}/cancel`, {}).then(data),\n\n checks: (run, query = {}) =>\n admin.http\n .get<{ data: AuditCheckRow[] }>(`${base}/runs/${run}/checks`, { query: filters(query) })\n .then(data),\n\n issues: (run, query = {}) =>\n admin.http\n .get<{\n data: AuditIssue[]\n meta: Omit<AuditPage<AuditIssue>, 'data'>\n }>(`${base}/runs/${run}/issues`, { query: filters(query) })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n pages: (run, query = {}) =>\n admin.http\n .get<{\n data: AuditPageRow[]\n meta: Omit<AuditPage<AuditPageRow>, 'data'>\n }>(`${base}/runs/${run}/pages`, { query: pageParams(query) })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n pagesFile: (run, query, columns) => {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries({\n ...pageParams(query),\n page: undefined,\n per_page: undefined,\n })) {\n if (value !== undefined) params.set(key, String(value))\n }\n\n params.set('columns', columns.join(','))\n\n return `${base}/runs/${run}/pages/export?${params.toString()}`\n },\n\n page: (run, id) =>\n admin.http.get<{ data: AuditPageCard }>(`${base}/runs/${run}/pages/${id}`).then(data),\n\n links: (run, id, query = {}) =>\n admin.http\n .get<{\n data: AuditLinkRow[]\n meta: Omit<AuditPage<AuditLinkRow>, 'data'>\n }>(`${base}/runs/${run}/pages/${id}/links`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n resources: (run, id, query) =>\n admin.http\n .get<{\n data: AuditResourceRow[]\n meta: Omit<AuditPage<AuditResourceRow>, 'data'>\n }>(`${base}/runs/${run}/pages/${id}/resources`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n fixes: (run, issue) =>\n admin.http\n .get<{ data: AuditFixOffer[] }>(`${base}/runs/${run}/issues/${issue}/fixes`)\n .then(data),\n\n fix: (run, issue, fix, dryRun = false) =>\n admin.http\n .post<{\n data: AuditFixResult\n }>(`${base}/runs/${run}/issues/${issue}/fixes/${encodeURIComponent(fix)}`, {\n dry_run: dryRun,\n })\n .then(data),\n\n pageFile: (run, id) => `${base}/runs/${run}/pages/${id}/export`,\n\n compare: (to, from) =>\n admin.http\n .get<{\n data: AuditComparison\n }>(`${base}/runs/compare`, { query: { to, from: from ?? undefined } })\n .then(data),\n\n compareIssues: (query) =>\n admin.http\n .get<{\n data: AuditIssue[]\n meta: Omit<AuditPage<AuditIssue>, 'data'>\n }>(`${base}/runs/compare/issues`, {\n query: { ...query, from: query.from ?? undefined, check: query.check || undefined },\n })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n hosts: (query = {}) =>\n admin.http\n .get<{ data: AuditHosts }>(`${base}/hosts`, {\n query: {\n class: query.class || undefined,\n search: query.search || undefined,\n host: query.host || undefined,\n },\n })\n .then(data),\n\n ignores: () => admin.http.get<{ data: AuditIgnoreRule[] }>(`${base}/ignores`).then(data),\n\n hide: (rule) => admin.http.post<{ data: AuditIgnoreRule }>(`${base}/ignores`, rule).then(data),\n\n hidePreview: (rule) =>\n admin.http\n .post<{ data: { hidden: number } }>(`${base}/ignores`, { ...rule, dry_run: true })\n .then((body) => body.data.hidden),\n\n unhide: (id) => admin.http.delete(`${base}/ignores/${id}`).then(() => undefined),\n\n settings: () =>\n admin.http\n .get<{ data: { values: Record<string, unknown> } }>(`${base}/settings`)\n .then((body) => body.data.values),\n\n saveSettings: (values) =>\n admin.http\n .put<{ data: { values: Record<string, unknown> } }>(`${base}/settings`, { values })\n .then((body) => body.data.values),\n }\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxTooltip, type BadgeSize } from '@webx-ui/core'\nimport { statusKey, statusType } from './addresses'\nimport { useAuditMessages } from './i18n'\n\n/**\n * An answer's code as a badge of its colour, and what it means in the tooltip: the name and what\n * to do about it. A code with no line of its own is explained by its class (4xx…); none at all, or\n * 0, is «no answer».\n */\nconst props = withDefaults(defineProps<{ code: number | null | undefined; size?: BadgeSize }>(), {\n size: 'sm',\n})\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst label = computed(() => (props.code ? String(props.code) : t('page.status-none')))\n</script>\n\n<template>\n <wx-tooltip :content=\"t(`page.${statusKey(props.code)}`)\" :max-width=\"360\">\n <wx-badge :type=\"statusType(props.code ?? 0)\" :size=\"props.size\">{{ label }}</wx-badge>\n </wx-tooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxSkeleton, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { createAuditApi } from './api'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditHostTarget, AuditHosts } from './types'\n\n/**\n * Where one host stands, under its row on «Outgoing»: the addresses on it the pages point at, each\n * a card with the pages under it — a font or a profile link sits in the layout and is on every\n * page, so by page it would be the same line forty times — and the fields of the database that\n * hold it, with «Open in the editor». A link's `target` and `rel` sit beside its address, or\n * beside each page when the pages write it differently. Fifty of each, broken links first; a card counts all its\n * pages and lists fifty.\n */\nconst props = defineProps<{ host: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\nconst router = useRouter()\n\nconst places = ref<AuditHosts | null>(null)\nconst failure = ref<string | null>(null)\n\n/** What the row's «Broken» counts: an error, or no answer at all (0). */\nconst broken = (status: number | null | undefined) =>\n status !== null && status !== undefined && (status >= 400 || status === 0)\n\n/** How many pages a card lists before «Show all». */\nconst FEW = 5\n\nconst open = ref(new Set<string>())\n\nfunction keyOf(target: AuditHostTarget): string {\n return `${target.kind} ${target.url}`\n}\n\nfunction shown(target: AuditHostTarget) {\n return open.value.has(keyOf(target)) ? target.places : target.places.slice(0, FEW)\n}\n\n/* «Show all» turns into «Collapse», so a long card folds back where it is read. */\nfunction toggle(target: AuditHostTarget): void {\n const next = new Set(open.value)\n\n if (!next.delete(keyOf(target))) next.add(keyOf(target))\n open.value = next\n}\n\nonMounted(async () => {\n try {\n places.value = await api.hosts({ host: props.host })\n } catch (error) {\n failure.value = message(error)\n }\n})\n</script>\n\n<template>\n <div class=\"wx-audit-places\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!places\" :rows=\"2\" />\n\n <template v-else>\n <section v-if=\"places.targets?.length\" class=\"wx-audit-places__group\">\n <wx-text size=\"sm\" weight=\"semibold\">{{ t('page.host-pages') }}</wx-text>\n\n <div v-for=\"target in places.targets\" :key=\"keyOf(target)\" class=\"wx-audit-places__card\">\n <div class=\"wx-audit-places__head\">\n <wx-badge type=\"default\" size=\"sm\" class=\"wx-audit-places__fixed\">{{\n target.kind\n }}</wx-badge>\n <audit-address :href=\"target.url\" strong />\n <audit-link-attrs\n v-if=\"target.kind === 'a' && !target.mixed\"\n :rel=\"target.rel\"\n :target=\"target.target\"\n class=\"wx-audit-places__fixed\"\n />\n <audit-status\n v-if=\"broken(target.status)\"\n :code=\"target.status\"\n class=\"wx-audit-places__fixed\"\n />\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-places__count\">{{\n t('page.link-pages', { count: target.pages })\n }}</wx-text>\n </div>\n\n <ul class=\"wx-audit-places__pages\">\n <li v-for=\"(place, index) in shown(target)\" :key=\"index\">\n <audit-address :href=\"place.page\" />\n <wx-text v-if=\"place.anchor\" size=\"sm\" tone=\"muted\" class=\"wx-audit-places__anchor\"\n >«{{ place.anchor }}»</wx-text\n >\n <!-- The pages differ in how they write the link: each says its own. -->\n <audit-link-attrs\n v-if=\"target.kind === 'a' && target.mixed\"\n :rel=\"place.rel\"\n :target=\"place.target\"\n class=\"wx-audit-places__fixed\"\n />\n </li>\n </ul>\n\n <wx-button\n v-if=\"target.places.length > FEW\"\n size=\"sm\"\n variant=\"text\"\n class=\"wx-audit-places__more\"\n @click=\"toggle(target)\"\n >{{\n open.has(keyOf(target)) ? t('page.link-collapse') : t('page.link-show-all')\n }}</wx-button\n >\n </div>\n </section>\n\n <section v-if=\"places.fields?.length\" class=\"wx-audit-places__group\">\n <wx-text size=\"sm\" weight=\"semibold\">{{ t('page.host-fields') }}</wx-text>\n\n <div class=\"wx-audit-places__card\">\n <div v-for=\"(field, index) in places.fields\" :key=\"index\" class=\"wx-audit-places__field\">\n <div class=\"wx-audit-places__record\">\n <wx-text size=\"sm\">{{ field.record_label }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\"\n >{{ field.source }} · {{ field.field\n }}{{ field.locale ? ` · ${field.locale}` : '' }}</wx-text\n >\n <wx-badge v-if=\"!field.published\" size=\"sm\">{{ t('page.unpublished') }}</wx-badge>\n </div>\n <audit-address :href=\"field.url\" />\n <wx-button\n v-if=\"field.edit_url\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n class=\"wx-audit-places__fixed\"\n @click=\"router.push(field.edit_url)\"\n >{{ t('page.open-editor') }}</wx-button\n >\n </div>\n </div>\n </section>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-places {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-places__group {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-places__card {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-places__head {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__fixed {\n flex-shrink: 0;\n}\n\n.wx-audit-places__count {\n flex-shrink: 0;\n margin-inline-start: auto;\n white-space: nowrap;\n}\n\n.wx-audit-places__pages {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n margin: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n list-style: none;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__pages li {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-places__anchor {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wx-audit-places__more {\n margin: 0 var(--wx-space-12) var(--wx-space-8);\n}\n\n/* One grid for every field: the record, where its address is, the editor. */\n.wx-audit-places__field {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 3fr) auto;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-6) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__field:last-child {\n border-bottom: 0;\n}\n\n.wx-audit-places__record {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-4) var(--wx-space-8);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useAdmin, useTranslate, WxListScreen, type ScreenAction } from '@webx-ui/module-admin'\nimport type { TabItem, TabValue } from '@webx-ui/core'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The head of the section: its name, its views — the overview, the findings, the pages, the\n * hosts the site points at and the runs — and the way to the section's own settings.\n */\n/*\n * `card` has its default here and not as `?? true` below: Vue turns a Boolean prop nobody passed\n * into `false`, so the coalescing never fired and every table stood without its card.\n */\nconst props = withDefaults(\n defineProps<{\n base: string\n current: 'overview' | 'issues' | 'pages' | 'hosts' | 'runs' | 'settings'\n /** A card around the slot — the tables want one, the overview draws its own. */\n card?: boolean\n }>(),\n { card: true },\n)\n\ndefineSlots<{ default?: () => unknown }>()\n\nconst context = useAdmin()\nconst router = useRouter()\nconst route = useRoute()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst title = computed(\n () =>\n context.state.manifest?.modules.find((module) => module.id === 'audit')?.title ??\n t('module.title'),\n)\n\nconst views = computed<TabItem[]>(() => [\n { value: 'overview', label: t('page.overview') },\n { value: 'issues', label: t('page.issues') },\n { value: 'pages', label: t('page.pages') },\n { value: 'hosts', label: t('page.hosts') },\n { value: 'runs', label: t('page.runs') },\n])\n\n/* The settings are a view of their own, out of the tabs: opened now and then, not every day. */\nconst actions = computed<ScreenAction[]>(() =>\n props.current === 'settings'\n ? []\n : [\n {\n key: 'settings',\n label: t('page.settings'),\n icon: 'settings',\n run: () => void router.push(`${props.base}/settings`),\n },\n ],\n)\n\nconst where = computed<TabValue>({\n /*\n * The settings belong to no tab, but the tabs need a value of theirs — given one they do not\n * have, they correct it to the first and lead away at once. So «Overview» stays lit, and the\n * settings page has a «Back» of its own beside «Save».\n */\n get: () => (props.current === 'settings' ? 'overview' : props.current),\n set: (next) => {\n const path = next === 'overview' ? props.base : `${props.base}/${String(next)}`\n\n if (path !== route.path) void router.push(path)\n },\n})\n</script>\n\n<template>\n <wx-list-screen\n v-model:view=\"where\"\n :title=\"title\"\n :views=\"views\"\n :actions=\"actions\"\n :card=\"props.card\"\n >\n <slot />\n </wx-list-screen>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type RowKey,\n type SelectValue,\n type TableColumn,\n} from '@webx-ui/core'\nimport AuditHostPlaces from './AuditHostPlaces.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditHostClass, AuditHostRow, AuditHosts } from './types'\n\n/**\n * «Outgoing» (§8): every host the site points at — in the pages of the last full run and in the\n * fields of the database — by class, development stands on top and in red. A row opens into\n * where the host stands: the pages with their anchors, the records with the field and the way to\n * the editor.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst answer = ref<AuditHosts | null>(null)\nconst loading = ref(false)\nconst search = ref('')\nconst hostClass = ref<AuditHostClass | null>(null)\nconst expanded = ref<RowKey[]>([])\n\nconst classes: Record<AuditHostClass, BadgeType> = {\n dev: 'danger',\n own_mirror: 'warning',\n external: 'info',\n own: 'success',\n}\n\nconst columns = computed<TableColumn<AuditHostRow>[]>(() => [\n { key: 'host', label: t('page.host'), minWidth: 220 },\n { key: 'links', label: t('page.links'), width: 90, align: 'right' },\n { key: 'pages', label: t('page.pages'), width: 90, align: 'right', hideBelow: 560 },\n { key: 'broken', label: t('page.broken'), width: 100, align: 'right', hideBelow: 640 },\n { key: 'fields', label: t('page.fields'), width: 120, align: 'right' },\n { key: 'first_seen', label: t('page.first-seen'), minWidth: 140, hideBelow: 760 },\n])\n\nconst classOptions = computed(() =>\n (Object.keys(classes) as AuditHostClass[]).map((value) => ({\n value,\n label: `${t(`page.host-${value}`)}${answer.value?.classes[value] ? ` · ${answer.value.classes[value]}` : ''}`,\n })),\n)\n\nfunction pick(value: SelectValue | SelectValue[] | null | undefined): AuditHostClass | null {\n return typeof value === 'string' && value in classes ? (value as AuditHostClass) : null\n}\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n answer.value = await api.hosts({ class: hostClass.value, search: search.value })\n expanded.value = []\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nwatch([hostClass, search], () => void load())\n\nonMounted(load)\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"hosts\">\n <wx-table\n v-model:expanded=\"expanded\"\n v-model:search=\"search\"\n :data=\"answer?.hosts ?? []\"\n :columns=\"columns\"\n row-key=\"host\"\n expandable\n flush\n searchable\n :search-placeholder=\"t('page.search-host')\"\n :loading=\"loading\"\n :filters-count=\"hostClass ? 1 : 0\"\n :filters-label=\"panel('filters.title')\"\n :row-class=\"(row: AuditHostRow) => (row.class === 'dev' ? 'is-stand' : undefined)\"\n :empty-text=\"t('page.hosts-empty')\"\n >\n <template #filters>\n <wx-select\n :model-value=\"hostClass\"\n :options=\"classOptions\"\n :placeholder=\"t('page.any-class')\"\n clearable\n @update:model-value=\"hostClass = pick($event)\"\n />\n </template>\n\n <template #cell-host=\"{ row }\">\n <span class=\"wx-audit-hosts__host\">\n <wx-badge :type=\"classes[row.class]\" size=\"sm\">{{\n t(`page.host-${row.class}`)\n }}</wx-badge>\n <wx-text size=\"sm\" :tone=\"row.class === 'dev' ? 'danger' : undefined\" weight=\"medium\">{{\n row.host\n }}</wx-text>\n </span>\n </template>\n <template #cell-broken=\"{ row }\">\n <wx-text size=\"sm\" :tone=\"row.broken ? 'danger' : 'muted'\">{{ row.broken }}</wx-text>\n </template>\n <template #cell-fields=\"{ row }\">\n <wx-text size=\"sm\" :tone=\"row.fields && row.class === 'dev' ? 'danger' : undefined\">{{\n row.fields\n }}</wx-text>\n </template>\n <template #cell-first_seen=\"{ row }\">\n <wx-date v-if=\"row.first_seen\" :value=\"row.first_seen\" />\n </template>\n\n <template #expanded=\"{ row }\">\n <audit-host-places :host=\"row.host\" />\n </template>\n </wx-table>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-hosts__host {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n/* A stand is the one class that is always a mistake: a red edge, like an error in a list. */\n:deep(.is-stand > td:first-child) {\n box-shadow: inset 3px 0 0 var(--wx-color-danger);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxIcon, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { differences } from './addresses'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditDetails, AuditDetailsColumn } from './types'\n\n/**\n * The expansion of a finding, for every check alike (§4 of the spec): a summary line and, when\n * the check gave one, a table whose cells are drawn by their type — an address opens, a code is\n * coloured, a missing value is said in red, an editor link goes to the record in the panel, and\n * markup quoted from the page is shown as code.\n *\n * The columns have widths by their type, not by what they hold, so the tables of one check line\n * up under each other. A `location` address beside a `url` is where that address leads: the row\n * reads as from → to, and a difference of a slash, `www.` or `https` is named.\n */\nconst props = defineProps<{\n details: AuditDetails\n /** The count is shown elsewhere (the head of the finding) — the summary line would repeat it. */\n counted?: boolean\n}>()\n\nconst router = useRouter()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst columns = computed(() => props.details.table?.columns ?? [])\n\nconst redirects = computed(\n () =>\n columns.value.some((column) => column.key === 'url' && column.type === 'url') &&\n columns.value.some((column) => column.key === 'location' && column.type === 'url'),\n)\n\nfunction isSource(column: AuditDetailsColumn): boolean {\n return redirects.value && column.key === 'url'\n}\n\nfunction isTarget(column: AuditDetailsColumn): boolean {\n return redirects.value && column.key === 'location'\n}\n\nfunction cell(row: Record<string, unknown>, column: AuditDetailsColumn): unknown {\n return row[column.key]\n}\n\n/** Yes, no — or nothing, when the check could not tell (the other page was not crawled). */\nfunction yesNo(value: unknown): string {\n if (value === null || value === undefined) return ''\n\n return value ? t('page.yes') : t('page.no')\n}\n\nfunction text(value: unknown): string {\n return value === null || value === undefined ? '' : String(value)\n}\n\nfunction changes(row: Record<string, unknown>) {\n return differences(text(row.url), text(row.location))\n}\n</script>\n\n<template>\n <div class=\"wx-audit-details\">\n <wx-text v-if=\"props.details.summary && !props.counted\" size=\"sm\">{{\n props.details.summary\n }}</wx-text>\n\n <div\n v-if=\"props.details.table && props.details.table.rows.length\"\n class=\"wx-audit-details__scroll\"\n >\n <table class=\"wx-audit-details__table\">\n <colgroup>\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n `wx-audit-details__col--${column.type}`,\n `wx-audit-details__col--${column.key}`,\n ]\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-for=\"column in columns\" :key=\"column.key\">\n {{ column.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, index) in props.details.table.rows\" :key=\"index\">\n <td v-for=\"column in columns\" :key=\"column.key\">\n <span v-if=\"isTarget(column) && text(cell(row, column))\" class=\"wx-audit-details__to\">\n <wx-icon\n name=\"arrow-right\"\n size=\"1em\"\n class=\"wx-audit-details__arrow\"\n :label=\"t('page.leads-to')\"\n />\n <audit-address :href=\"text(cell(row, column))\" strong />\n <wx-badge\n v-for=\"change in changes(row)\"\n :key=\"change\"\n type=\"default\"\n size=\"sm\"\n class=\"wx-audit-details__change\"\n >{{ t(`page.change-${change}`) }}</wx-badge\n >\n </span>\n <audit-address\n v-else-if=\"column.type === 'url' && text(cell(row, column))\"\n :href=\"text(cell(row, column))\"\n :type=\"isSource(column) ? 'muted' : undefined\"\n />\n <audit-status\n v-else-if=\"column.type === 'status' && cell(row, column) !== null\"\n :code=\"Number(cell(row, column))\"\n />\n <audit-link-attrs\n v-else-if=\"column.type === 'attrs'\"\n :rel=\"text(row.rel)\"\n :target=\"text(row.target)\"\n />\n <template v-else-if=\"column.type === 'bool'\">\n {{ yesNo(cell(row, column)) }}\n </template>\n <wx-text\n v-else-if=\"column.type === 'missing' && !text(cell(row, column))\"\n size=\"sm\"\n tone=\"danger\"\n >{{ t('page.missing') }}</wx-text\n >\n <wx-button\n v-else-if=\"column.type === 'edit' && text(cell(row, column))\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n @click=\"router.push(text(cell(row, column)))\"\n >{{ t('page.open-editor') }}</wx-button\n >\n <code v-else-if=\"column.type === 'code'\" class=\"wx-audit-details__code\">{{\n text(cell(row, column))\n }}</code>\n <template v-else>{{ text(cell(row, column)) }}</template>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-details {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n/* A wide table scrolls inside itself rather than pushing the panel sideways on a phone. */\n.wx-audit-details__scroll {\n overflow-x: auto;\n}\n\n/*\n * Fixed layout: a column's width comes from its type, never from its longest cell, so every\n * finding of a check draws the same grid.\n */\n.wx-audit-details__table {\n width: 100%;\n min-width: 560px;\n table-layout: fixed;\n border-collapse: collapse;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-details__col--status {\n width: 72px;\n}\n\n.wx-audit-details__col--bool {\n width: 96px;\n}\n\n.wx-audit-details__col--attrs {\n width: 216px;\n}\n\n/* Columns whose values are short by nature — a kind, a size, a type — by their key. */\n.wx-audit-details__col--kind,\n.wx-audit-details__col--line {\n width: 72px;\n}\n\n.wx-audit-details__col--kb,\n.wx-audit-details__col--lang,\n.wx-audit-details__col--locale {\n width: 96px;\n}\n\n.wx-audit-details__col--type {\n width: 140px;\n}\n\n.wx-audit-details__col--edit {\n width: 160px;\n}\n\n.wx-audit-details__table th {\n color: var(--wx-text-muted);\n font-weight: normal;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.wx-audit-details__table th,\n.wx-audit-details__table td {\n padding: var(--wx-space-6) var(--wx-space-8);\n border-bottom: 1px solid var(--wx-border-muted);\n vertical-align: middle;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-details__table tbody tr:last-child td {\n border-bottom: 0;\n}\n\n.wx-audit-details__to {\n display: flex;\n align-items: center;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n.wx-audit-details__arrow {\n flex-shrink: 0;\n color: var(--wx-text-muted);\n}\n\n.wx-audit-details__change {\n flex-shrink: 0;\n}\n\n/* Quoted markup is one long line more often than not; it wraps anywhere rather than scrolling. */\n.wx-audit-details__code {\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxDialog, WxSkeleton, WxText, toast } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditFixOffer, AuditIssue } from './types'\n\n/**\n * The fix button's dialog (§8, decision 4): the fixes that can close one finding, each with what\n * it would change — the records and fields with their counts, or a setting before and after —\n * and \"Apply\" under each. Nothing changes until it is pressed; the finding then waits for the\n * next run, which is the only thing that says it is gone.\n */\nconst props = defineProps<{ run: number; issue: AuditIssue }>()\nconst emit = defineEmits<{ fixed: [fix: string] }>()\nconst open = defineModel<boolean>('open', { default: false })\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\nconst router = useRouter()\n\nconst offers = ref<AuditFixOffer[] | null>(null)\nconst failure = ref<string | null>(null)\nconst applying = ref<string | null>(null)\n\nasync function load(): Promise<void> {\n offers.value = null\n failure.value = null\n\n try {\n offers.value = await api.fixes(props.run, props.issue.id)\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nasync function apply(offer: AuditFixOffer): Promise<void> {\n applying.value = offer.id\n\n try {\n await api.fix(props.run, props.issue.id, offer.id)\n toast.success(t('page.fix-applied'))\n emit('fixed', offer.id)\n open.value = false\n } catch (error) {\n toast.danger(message(error))\n } finally {\n applying.value = null\n }\n}\n\nfunction edit(url: string): void {\n open.value = false\n void router.push(url)\n}\n\n// Immediate: the list mounts the dialog already open, the first time a button is pressed.\nwatch(\n [open, () => props.issue.id],\n ([now]) => {\n if (now) void load()\n },\n { immediate: true },\n)\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('page.fix-button')\" :width=\"640\">\n <div class=\"wx-audit-fix\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!offers\" :rows=\"3\" />\n <wx-text v-else-if=\"offers.length === 0\" size=\"sm\" tone=\"muted\">{{\n t('page.fix-none')\n }}</wx-text>\n\n <section v-for=\"offer in offers ?? []\" :key=\"offer.id\" class=\"wx-audit-fix__offer\">\n <wx-text weight=\"semibold\">{{ offer.title }}</wx-text>\n <wx-text v-if=\"offer.description\" size=\"sm\" tone=\"muted\">{{ offer.description }}</wx-text>\n\n <table class=\"wx-audit-fix__changes\">\n <thead>\n <tr>\n <th>{{ t('page.fix-changes') }}</th>\n <th>{{ t('page.fix-before') }}</th>\n <th>{{ t('page.fix-after') }}</th>\n <th />\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(change, index) in offer.changes\" :key=\"index\">\n <td>\n <div>{{ change.label }}</div>\n <div v-if=\"change.field\" class=\"wx-audit-fix__field\">{{ change.field }}</div>\n </td>\n <td class=\"wx-audit-fix__value\">\n {{ change.before ?? '' }}\n <span v-if=\"change.count\" class=\"wx-audit-fix__count\">× {{ change.count }}</span>\n </td>\n <td class=\"wx-audit-fix__value\">{{ change.after ?? '' }}</td>\n <td>\n <wx-button\n v-if=\"change.edit_url\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n :aria-label=\"t('page.open-editor')\"\n @click=\"edit(change.edit_url)\"\n />\n </td>\n </tr>\n </tbody>\n </table>\n\n <wx-text v-if=\"offer.note\" size=\"sm\" tone=\"muted\">{{ offer.note }}</wx-text>\n\n <div class=\"wx-audit-fix__actions\">\n <wx-button\n type=\"primary\"\n size=\"sm\"\n :loading=\"applying === offer.id\"\n :disabled=\"applying !== null\"\n @click=\"apply(offer)\"\n >{{ t('page.fix-apply') }}</wx-button\n >\n </div>\n </section>\n </div>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-audit-fix {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-fix__offer {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-fix__changes {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-fix__changes th {\n padding: var(--wx-space-4) var(--wx-space-8);\n color: var(--wx-text-muted);\n font-weight: var(--wx-font-weight-medium);\n text-align: start;\n border-bottom: 1px solid var(--wx-border-default);\n}\n\n.wx-audit-fix__changes td {\n padding: var(--wx-space-6) var(--wx-space-8);\n vertical-align: top;\n border-bottom: 1px solid var(--wx-border-default);\n overflow-wrap: anywhere;\n}\n\n.wx-audit-fix__field,\n.wx-audit-fix__count {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-fix__value {\n white-space: pre-line;\n}\n\n.wx-audit-fix__actions {\n display: flex;\n justify-content: flex-end;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxDialog, WxFormItem, WxInput, WxText, WxTextarea, toast } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIgnoreRule, AuditIssue } from './types'\n\n/**\n * «Hide» on a finding (decision 9): which addresses — this one, a mask of them, or the whole\n * check — and why. While the mask is typed the dialog says how many findings of the last run it\n * would hide; nothing is hidden until the button is pressed, and nothing is ever deleted.\n */\nconst props = defineProps<{ issue: AuditIssue; title: string }>()\nconst emit = defineEmits<{ hidden: [rule: AuditIgnoreRule] }>()\nconst open = defineModel<boolean>('open', { default: false })\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst pattern = ref('')\nconst reason = ref('')\nconst count = ref<number | null>(null)\nconst saving = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\n/* The path, not the whole address: a mask of the path hides it on every mirror a run opened. */\nfunction pathOf(url: string | null): string {\n if (!url) return ''\n\n try {\n const parsed = new URL(url)\n\n return parsed.pathname + parsed.search\n } catch {\n return url\n }\n}\n\nconst ready = computed(() => reason.value.trim() !== '')\n\nfunction preview(): void {\n clearTimeout(timer)\n timer = setTimeout(async () => {\n try {\n count.value = await api.hidePreview({ check: props.issue.check, pattern: pattern.value })\n } catch {\n count.value = null\n }\n }, 300)\n}\n\nasync function hide(): Promise<void> {\n saving.value = true\n\n try {\n const rule = await api.hide({\n check: props.issue.check,\n pattern: pattern.value,\n reason: reason.value,\n })\n\n toast.success(t('page.hidden-done'))\n emit('hidden', rule)\n open.value = false\n } catch (error) {\n toast.danger(message(error))\n } finally {\n saving.value = false\n }\n}\n\nwatch(\n [open, () => props.issue.id],\n ([now]) => {\n if (!now) return\n\n pattern.value = pathOf(props.issue.url)\n reason.value = ''\n count.value = null\n preview()\n },\n { immediate: true },\n)\n\nwatch(pattern, () => {\n if (open.value) preview()\n})\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('page.hide-title')\" :width=\"560\">\n <div class=\"wx-audit-hide\">\n <wx-text weight=\"semibold\">{{ props.title }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\">{{ t('page.hide-help') }}</wx-text>\n\n <wx-form-item :label=\"t('page.hide-pattern')\" :help=\"t('page.hide-pattern-help')\">\n <wx-input v-model=\"pattern\" placeholder=\"/search/**\" />\n </wx-form-item>\n\n <wx-form-item :label=\"t('page.hide-reason')\" required>\n <wx-textarea v-model=\"reason\" :rows=\"3\" />\n </wx-form-item>\n\n <wx-text v-if=\"count !== null\" size=\"sm\" tone=\"muted\">{{\n t('page.hide-count', { count })\n }}</wx-text>\n </div>\n\n <template #footer>\n <wx-button @click=\"open = false\">{{ t('page.dismiss') }}</wx-button>\n <wx-button type=\"primary\" :loading=\"saving\" :disabled=\"!ready\" @click=\"hide\">{{\n t('page.hide')\n }}</wx-button>\n </template>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-audit-hide {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxIcon, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { differences } from './addresses'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIssue } from './types'\n\n/**\n * The findings of a redirect check turned inside out: one card per link, the pages it is on\n * under it. A link in the footer or the menu is on every page and is fixed once, in one place —\n * by page, it would be the same row forty times.\n */\nconst props = defineProps<{ issues: AuditIssue[] }>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\ninterface LinkGroup {\n url: string\n location: string\n status: number | null\n pages: LinkPlace[]\n /** The pages write the link with different `rel` or `target`: each says its own. */\n mixed: boolean\n}\n\ninterface LinkPlace {\n page: string\n rel: string | null\n target: string | null\n}\n\n/** How many pages a card lists before «Show all». */\nconst FEW = 5\n\nconst open = ref(new Set<string>())\n\nconst groups = computed<LinkGroup[]>(() => {\n const found = new Map<string, LinkGroup>()\n\n for (const issue of props.issues) {\n for (const row of issue.details.table?.rows ?? []) {\n const url = String(row.url ?? '')\n const location = String(row.location ?? '')\n const key = `${url}\\n${location}`\n const group = found.get(key) ?? { url, location, status: null, pages: [], mixed: false }\n const place = { page: issue.url ?? '', rel: attr(row.rel), target: attr(row.target) }\n const first = group.pages[0]\n\n group.status ??= typeof row.status === 'number' ? row.status : null\n if (first && (first.rel !== place.rel || first.target !== place.target)) group.mixed = true\n if (place.page && !group.pages.some((one) => one.page === place.page)) group.pages.push(place)\n found.set(key, group)\n }\n }\n\n return [...found.values()].sort((a, b) => b.pages.length - a.pages.length)\n})\n\nfunction attr(value: unknown): string | null {\n return typeof value === 'string' && value !== '' ? value : null\n}\n\nfunction keyOf(group: LinkGroup): string {\n return `${group.url}\\n${group.location}`\n}\n\nfunction shown(group: LinkGroup): LinkPlace[] {\n return open.value.has(keyOf(group)) ? group.pages : group.pages.slice(0, FEW)\n}\n\n/* «Show all» turns into «Collapse», so a long card folds back where it is read. */\nfunction toggle(group: LinkGroup): void {\n const next = new Set(open.value)\n\n if (!next.delete(keyOf(group))) next.add(keyOf(group))\n open.value = next\n}\n</script>\n\n<template>\n <div class=\"wx-audit-links\">\n <div v-for=\"group in groups\" :key=\"keyOf(group)\" class=\"wx-audit-links__card\">\n <div class=\"wx-audit-links__head\">\n <audit-address :href=\"group.url\" type=\"muted\" class=\"wx-audit-links__from\" />\n <wx-icon\n name=\"arrow-right\"\n size=\"1em\"\n class=\"wx-audit-links__arrow\"\n :label=\"t('page.leads-to')\"\n />\n <audit-address :href=\"group.location\" strong class=\"wx-audit-links__to\" />\n <wx-badge\n v-for=\"change in differences(group.url, group.location)\"\n :key=\"change\"\n type=\"default\"\n size=\"sm\"\n >{{ t(`page.change-${change}`) }}</wx-badge\n >\n <audit-link-attrs\n v-if=\"!group.mixed && group.pages[0]\"\n :rel=\"group.pages[0].rel\"\n :target=\"group.pages[0].target\"\n class=\"wx-audit-links__fixed\"\n />\n <audit-status v-if=\"group.status !== null\" :code=\"group.status\" />\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-links__count\">{{\n t('page.link-pages', { count: group.pages.length })\n }}</wx-text>\n </div>\n\n <ul class=\"wx-audit-links__pages\">\n <li v-for=\"place in shown(group)\" :key=\"place.page\">\n <audit-address :href=\"place.page\" />\n <audit-link-attrs\n v-if=\"group.mixed\"\n :rel=\"place.rel\"\n :target=\"place.target\"\n class=\"wx-audit-links__fixed\"\n />\n </li>\n </ul>\n\n <wx-button\n v-if=\"group.pages.length > FEW\"\n size=\"sm\"\n variant=\"text\"\n class=\"wx-audit-links__more\"\n @click=\"toggle(group)\"\n >{{ open.has(keyOf(group)) ? t('page.link-collapse') : t('page.link-show-all') }}</wx-button\n >\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-links {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-links__card {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-links__head {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-links__from,\n.wx-audit-links__to {\n flex: 0 1 auto;\n}\n\n.wx-audit-links__arrow {\n flex-shrink: 0;\n color: var(--wx-text-muted);\n}\n\n.wx-audit-links__fixed {\n flex-shrink: 0;\n}\n\n.wx-audit-links__pages li {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-links__count {\n flex-shrink: 0;\n margin-inline-start: auto;\n white-space: nowrap;\n}\n\n.wx-audit-links__pages {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n margin: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n list-style: none;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-links__more {\n margin: 0 var(--wx-space-12) var(--wx-space-8);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { toast, WxBadge, WxButton, WxSegmented, WxSkeleton, WxText, WxTooltip } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditDetails from './AuditDetails.vue'\nimport AuditFixDialog from './AuditFixDialog.vue'\nimport AuditHideDialog from './AuditHideDialog.vue'\nimport AuditLinkGroups from './AuditLinkGroups.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIgnoreRule, AuditIssue, AuditIssueQuery } from './types'\n\n/**\n * The addresses of one check, under its row in the findings table: loaded when the row opens,\n * fifty at a time. A check that has fixes gets a button on each address; the dialog shows what\n * it would change before anything does. «Hide» asks for the reason; on the list of hidden ones\n * each says why, and «Show again» removes the rule.\n *\n * Each finding is a card: the address with its count, the table under it. A check of links that\n * redirect can also be read by link — every page loaded, one card per link with its pages.\n */\nconst props = defineProps<{\n run: number\n query: AuditIssueQuery\n fixable?: boolean\n /** The check's title, for the hiding dialog. */\n title?: string\n}>()\n\nconst emit = defineEmits<{ changed: [] }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\n// A boolean, not a computed: the permissions do not change while the screen is open.\nconst can = context.can('audit.manage')\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst issues = ref<AuditIssue[] | null>(null)\nconst more = ref(false)\nconst page = ref(1)\nconst failure = ref<string | null>(null)\nconst fixing = ref<AuditIssue | null>(null)\nconst dialog = ref(false)\nconst hiding = ref<AuditIssue | null>(null)\nconst hideDialog = ref(false)\n\ntype View = 'pages' | 'links'\n\nconst view = ref<View>('pages')\nconst everything = ref<AuditIssue[] | null>(null)\n\n/** Rows with where each address leads: the findings can be grouped by link. */\nconst byLink = computed(() =>\n (issues.value?.[0]?.details.table?.columns ?? []).some((column) => column.key === 'location'),\n)\n\nconst views = computed(() => [\n { value: 'pages', label: t('page.view-pages') },\n { value: 'links', label: t('page.view-links') },\n])\n\n/* By link needs every page of the check, not the fifty loaded: a link is counted on all of them. */\nasync function loadEverything(): Promise<void> {\n if (everything.value) return\n\n try {\n const all: AuditIssue[] = []\n let next = 1\n let last = 1\n\n do {\n const answer = await api.issues(props.run, { ...props.query, page: next, per_page: 200 })\n\n all.push(...answer.data)\n last = answer.last_page\n next++\n } while (next <= last)\n\n everything.value = all\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nfunction switchView(value: View): void {\n view.value = value\n if (value === 'links') loadEverything()\n}\n\nfunction hide(issue: AuditIssue): void {\n hiding.value = issue\n hideDialog.value = true\n}\n\n/* What the rule hid leaves this list at once; the table above counts again. */\nfunction hidden(rule: AuditIgnoreRule): void {\n if (issues.value && !rule.pattern) issues.value = []\n else if (issues.value && hiding.value)\n issues.value = issues.value.filter((one) => one.id !== hiding.value?.id)\n\n emit('changed')\n}\n\nasync function unhide(issue: AuditIssue): Promise<void> {\n if (!issue.ignore) return\n\n try {\n await api.unhide(issue.ignore.id)\n toast.success(t('page.unhidden'))\n emit('changed')\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction why(issue: AuditIssue): string {\n const rule = issue.ignore\n\n if (!rule) return ''\n\n return rule.created_by\n ? t('page.hidden-by', { who: rule.created_by, reason: rule.reason })\n : t('page.hidden-reason', { reason: rule.reason })\n}\n\nfunction fix(issue: AuditIssue): void {\n fixing.value = issue\n dialog.value = true\n}\n\nfunction fixed(id: string): void {\n if (fixing.value) fixing.value.fixed_with = id\n}\n\nasync function load(next = 1): Promise<void> {\n try {\n const answer = await api.issues(props.run, { ...props.query, page: next, per_page: 50 })\n\n issues.value = next === 1 ? answer.data : [...(issues.value ?? []), ...answer.data]\n page.value = answer.current_page\n more.value = answer.current_page < answer.last_page\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nonMounted(() => load())\n</script>\n\n<template>\n <div class=\"wx-audit-issues\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!issues\" :rows=\"2\" />\n\n <template v-else>\n <wx-segmented\n v-if=\"byLink\"\n :model-value=\"view\"\n :options=\"views\"\n size=\"sm\"\n class=\"wx-audit-issues__view\"\n @update:model-value=\"switchView($event as View)\"\n />\n\n <template v-if=\"view === 'links'\">\n <audit-link-groups v-if=\"everything\" :issues=\"everything\" />\n <wx-skeleton v-else :rows=\"2\" />\n </template>\n\n <template v-else>\n <div v-for=\"issue in issues\" :key=\"issue.id\" class=\"wx-audit-issues__item\">\n <div class=\"wx-audit-issues__head\">\n <audit-address v-if=\"issue.url\" :href=\"issue.url\" strong class=\"wx-audit-issues__url\" />\n <wx-badge v-if=\"issue.state === 'new'\" type=\"primary\" size=\"sm\">{{\n t('page.state-new')\n }}</wx-badge>\n <wx-tooltip\n v-if=\"issue.details.count != null && issue.details.table\"\n :content=\"issue.details.summary ?? undefined\"\n :disabled=\"!issue.details.summary\"\n >\n <wx-badge round size=\"sm\" class=\"wx-audit-issues__count\">{{\n issue.details.count\n }}</wx-badge>\n </wx-tooltip>\n <wx-badge v-if=\"issue.fixed_with\" type=\"success\" size=\"sm\">{{\n t('page.fix-pressed')\n }}</wx-badge>\n <wx-button\n v-else-if=\"fixable && can && !issue.ignored\"\n size=\"sm\"\n variant=\"outline\"\n icon=\"check\"\n class=\"wx-audit-issues__fix\"\n @click=\"fix(issue)\"\n >{{ t('page.fix-button') }}</wx-button\n >\n <wx-button\n v-if=\"can && issue.ignored && issue.ignore\"\n size=\"sm\"\n variant=\"text\"\n icon=\"eye\"\n class=\"wx-audit-issues__end\"\n @click=\"unhide(issue)\"\n >{{ t('page.unhide') }}</wx-button\n >\n <wx-button\n v-else-if=\"can && !issue.ignored\"\n size=\"sm\"\n variant=\"text\"\n icon=\"eye-off\"\n :class=\"{ 'wx-audit-issues__end': !fixable || issue.fixed_with }\"\n @click=\"hide(issue)\"\n >{{ t('page.hide') }}</wx-button\n >\n </div>\n <div class=\"wx-audit-issues__body\">\n <wx-text v-if=\"issue.ignore\" size=\"sm\" tone=\"muted\">{{ why(issue) }}</wx-text>\n <audit-details\n :details=\"issue.details\"\n :counted=\"issue.details.count != null && !!issue.details.table\"\n />\n </div>\n </div>\n\n <wx-button v-if=\"more\" size=\"sm\" variant=\"text\" @click=\"load(page + 1)\">…</wx-button>\n </template>\n </template>\n\n <audit-fix-dialog\n v-if=\"fixing\"\n v-model:open=\"dialog\"\n :run=\"run\"\n :issue=\"fixing\"\n @fixed=\"fixed\"\n />\n\n <audit-hide-dialog\n v-if=\"hiding\"\n v-model:open=\"hideDialog\"\n :issue=\"hiding\"\n :title=\"props.title ?? hiding.check\"\n @hidden=\"hidden\"\n />\n </div>\n</template>\n\n<style scoped>\n.wx-audit-issues {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-issues__view {\n align-self: flex-start;\n}\n\n/* A card per finding: the page is the edge, its addresses are inside. */\n.wx-audit-issues__item {\n display: flex;\n flex-direction: column;\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-issues__head {\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n}\n\n.wx-audit-issues__body {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n}\n\n.wx-audit-issues__body:empty {\n display: none;\n}\n\n.wx-audit-issues__fix,\n.wx-audit-issues__end {\n margin-inline-start: auto;\n}\n\n/* The address gives way to the badges and buttons beside it, one line at any width. */\n.wx-audit-issues__url {\n flex: 0 1 auto;\n}\n\n.wx-audit-issues__count {\n flex-shrink: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxButton,\n WxPopover,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type SelectValue,\n type TableColumn,\n} from '@webx-ui/core'\nimport AuditIssueList from './AuditIssueList.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditCheckRow, AuditSeverity } from './types'\n\n/**\n * The findings of the last finished run (§8): one row per check, worst first; a row opens into\n * its addresses. «Hidden» in the state filter lists what the rules hide, each with its reason. The «?» beside a check says what was found, why it matters and how to fix it —\n * the three texts every check carries.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst run = ref<number | null>(null)\nconst checks = ref<AuditCheckRow[] | null>(null)\nconst loading = ref(false)\nconst expanded = ref<(string | number)[]>([])\n\nconst severity = ref<AuditSeverity | null>(null)\nconst group = ref<string | null>(null)\ntype State = 'new' | 'persisting' | 'hidden'\n\nconst state = ref<State | null>(null)\n\nconst query = computed(() => ({ severity: severity.value, group: group.value, state: state.value }))\nconst filtersCount = computed(\n () => [severity.value, group.value, state.value].filter(Boolean).length,\n)\n\nconst types: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst columns = computed<TableColumn<AuditCheckRow>[]>(() => [\n { key: 'severity', label: t('page.severity'), width: 130 },\n { key: 'title', label: t('page.check') },\n { key: 'count', label: t('page.count'), width: 110, align: 'right' },\n])\n\nconst severityOptions = computed(() =>\n (['error', 'warning', 'notice'] as const).map((value) => ({\n value,\n label: t(`page.severity-${value}`),\n })),\n)\n\nconst groupOptions = computed(() =>\n [\n 'config',\n 'host',\n 'hosts',\n 'indexing',\n 'page',\n 'content',\n 'links',\n 'images',\n 'a11y',\n 'structure',\n ].map((value) => ({ value, label: t(`page.group-${value}`) })),\n)\n\nconst stateOptions = computed(() =>\n (['new', 'persisting', 'hidden'] as const).map((value) => ({\n value,\n label: t(`page.state-${value}`),\n })),\n)\n\n/* The selects hand back `string | number`; the filters only ever hold the values offered. */\nfunction pick<T extends string>(value: SelectValue | SelectValue[] | null | undefined): T | null {\n return typeof value === 'string' && value !== '' ? (value as T) : null\n}\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n if (run.value === null) {\n run.value = (await api.latest()).done?.id ?? null\n }\n\n checks.value = run.value === null ? [] : await api.checks(run.value, query.value)\n expanded.value = []\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nwatch(query, () => void load())\n\nonMounted(load)\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"issues\">\n <wx-table\n v-model:expanded=\"expanded\"\n :data=\"checks ?? []\"\n :columns=\"columns\"\n row-key=\"id\"\n expandable\n flush\n :loading=\"loading\"\n :filters-count=\"filtersCount\"\n :filters-label=\"panel('filters.title')\"\n :empty-text=\"run === null ? t('page.never') : t('page.empty')\"\n >\n <template #filters>\n <div class=\"wx-audit-findings__filters\">\n <wx-select\n :model-value=\"severity\"\n :options=\"severityOptions\"\n :placeholder=\"t('page.any-severity')\"\n clearable\n @update:model-value=\"severity = pick<AuditSeverity>($event)\"\n />\n <wx-select\n :model-value=\"group\"\n :options=\"groupOptions\"\n :placeholder=\"t('page.any-group')\"\n clearable\n @update:model-value=\"group = pick($event)\"\n />\n <wx-select\n :model-value=\"state\"\n :options=\"stateOptions\"\n :placeholder=\"t('page.any-state')\"\n clearable\n @update:model-value=\"state = pick<State>($event)\"\n />\n </div>\n </template>\n\n <template #cell-severity=\"{ row }\">\n <wx-badge :type=\"types[row.severity]\" dot>{{\n t(`page.severity-${row.severity}`)\n }}</wx-badge>\n </template>\n\n <template #cell-title=\"{ row }\">\n <span class=\"wx-audit-findings__title\">\n <wx-text size=\"sm\">{{ row.title }}</wx-text>\n <wx-badge v-if=\"row.new > 0\" type=\"primary\" size=\"sm\">{{ t('page.state-new') }}</wx-badge>\n <wx-popover :title=\"row.title\" width=\"360\">\n <template #trigger>\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"question\"\n :aria-label=\"t('page.explain')\"\n @click.stop\n />\n </template>\n <dl class=\"wx-audit-findings__texts\">\n <dt>{{ t('page.found') }}</dt>\n <dd>{{ row.found }}</dd>\n <dt>{{ t('page.why') }}</dt>\n <dd>{{ row.why }}</dd>\n <dt>{{ t('page.fix') }}</dt>\n <dd>{{ row.fix }}</dd>\n </dl>\n </wx-popover>\n </span>\n </template>\n\n <template #expanded=\"{ row }\">\n <audit-issue-list\n v-if=\"run !== null\"\n :run=\"run\"\n :query=\"{ ...query, check: row.id }\"\n :fixable=\"(row.fixes ?? []).length > 0\"\n :title=\"row.title\"\n @changed=\"load\"\n />\n </template>\n </wx-table>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-findings__filters {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-findings__title {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-findings__texts {\n display: grid;\n gap: var(--wx-space-4);\n margin: 0;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-findings__texts dt {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-findings__texts dd {\n margin: 0 0 var(--wx-space-8);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxButton,\n WxCard,\n WxEmpty,\n WxPopover,\n WxProgress,\n WxSegmented,\n WxSkeleton,\n WxStatistic,\n WxText,\n type ProgressStatus,\n} from '@webx-ui/core'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditLatest, AuditRun, AuditScope, AuditSeverity } from './types'\n\n/**\n * The last run at a glance (§8): health and what it is made of, the counts by severity and by\n * group, what is new and what got fixed since the run before, and the button that starts the next one. While a run is\n * going the page asks for it every couple of seconds and shows the stage it is in.\n */\nconst props = defineProps<{ base: string }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst POLL_MS = 2000\n\nconst latest = ref<AuditLatest | null>(null)\nconst scope = ref<AuditScope>('quick')\nconst starting = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nconst canRun = context.can('audit.run') || context.can('audit.manage')\n\nconst active = computed(() => latest.value?.active ?? null)\nconst done = computed(() => latest.value?.done ?? null)\nconst counts = computed(() => done.value?.counts ?? null)\n\nconst scopes = computed(() => [\n { value: 'quick', label: t('page.scope-quick') },\n { value: 'full', label: t('page.scope-full') },\n])\n\nconst severities: { key: AuditSeverity; label: string; tone: 'danger' | 'warning' | 'info' }[] = [\n { key: 'error', label: 'page.errors', tone: 'danger' },\n { key: 'warning', label: 'page.warnings', tone: 'warning' },\n { key: 'notice', label: 'page.notices', tone: 'info' },\n]\n\nconst parts = computed(() => counts.value?.health_parts ?? null)\n\nconst healthStatus = computed<ProgressStatus>(() => {\n const health = counts.value?.health ?? 0\n\n if (health >= 90) return 'success'\n if (health >= 60) return 'warning'\n\n return 'danger'\n})\n\n/* The groups this package has words for; a module's own group reads as «Other». */\nconst GROUPS = [\n 'config',\n 'host',\n 'hosts',\n 'indexing',\n 'page',\n 'content',\n 'links',\n 'images',\n 'a11y',\n 'structure',\n]\n\nconst groups = computed(() =>\n Object.entries(counts.value?.groups ?? {}).map(([id, bySeverity]) => ({\n id,\n label: t(`page.group-${GROUPS.includes(id) ? id : 'other'}`),\n bySeverity,\n })),\n)\n\nfunction stageLabel(run: AuditRun): string {\n if (run.status === 'queued') return t('page.status-queued')\n\n return run.progress.stage ? t(`page.stage-${run.progress.stage}`) : t('page.status-running')\n}\n\nasync function load(): Promise<void> {\n try {\n latest.value = await api.latest()\n } catch (error) {\n toast.danger(message(error))\n }\n\n clearTimeout(timer)\n\n if (latest.value?.active) {\n timer = setTimeout(() => void load(), POLL_MS)\n }\n}\n\nasync function start(): Promise<void> {\n starting.value = true\n\n try {\n await api.start(scope.value)\n toast.success(t('page.started'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n } finally {\n starting.value = false\n }\n}\n\nasync function cancel(run: AuditRun): Promise<void> {\n try {\n await api.cancel(run.id)\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nonMounted(load)\nonBeforeUnmount(() => clearTimeout(timer))\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"overview\" :card=\"false\">\n <div class=\"wx-audit-overview\">\n <wx-card v-if=\"!latest\"><wx-skeleton :rows=\"4\" /></wx-card>\n\n <template v-else>\n <wx-alert v-if=\"latest.queue.sync\" type=\"warning\" :description=\"t('page.sync-queue')\" />\n\n <wx-alert\n v-if=\"latest.last && latest.last.status === 'failed'\"\n type=\"danger\"\n :description=\"t('page.last-failed', { error: latest.last.error ?? '' })\"\n />\n\n <wx-card v-if=\"active\" class=\"wx-audit-overview__active\">\n <div class=\"wx-audit-overview__row\">\n <wx-text weight=\"semibold\">{{ stageLabel(active) }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-overview__url\">{{\n active.base_url\n }}</wx-text>\n <wx-button\n v-if=\"canRun\"\n size=\"sm\"\n class=\"wx-audit-overview__end\"\n @click=\"cancel(active)\"\n >{{ t('page.cancel') }}</wx-button\n >\n </div>\n <wx-progress indeterminate :aria-label=\"stageLabel(active)\" />\n <wx-text v-if=\"active.progress.resources\" size=\"sm\" tone=\"muted\">{{\n t('page.resources-progress', {\n checked: active.progress.resources.checked,\n total: active.progress.resources.total,\n })\n }}</wx-text>\n <wx-text v-else-if=\"active.progress.stage === 'crawl'\" size=\"sm\" tone=\"muted\">{{\n t('page.pages-progress', {\n crawled: active.progress.pages.crawled,\n limit: active.progress.pages.limit,\n })\n }}</wx-text>\n </wx-card>\n\n <wx-card v-else-if=\"canRun && !latest.queue.sync\">\n <div class=\"wx-audit-overview__row\">\n <wx-segmented v-model=\"scope\" :options=\"scopes\" :aria-label=\"t('page.scope')\" />\n <wx-text size=\"sm\" tone=\"muted\">{{\n scope === 'full' ? t('page.scope-full-help') : t('page.scope-quick-help')\n }}</wx-text>\n <wx-button\n type=\"primary\"\n icon=\"refresh\"\n :loading=\"starting\"\n class=\"wx-audit-overview__end\"\n @click=\"start\"\n >{{ t('page.run') }}</wx-button\n >\n </div>\n </wx-card>\n\n <wx-card v-if=\"!done && !active\">\n <wx-empty\n icon=\"check-circle\"\n :title=\"t('page.never')\"\n :description=\"t('page.never-help')\"\n />\n </wx-card>\n\n <template v-if=\"done && counts\">\n <wx-card>\n <div class=\"wx-audit-overview__summary\">\n <div class=\"wx-audit-overview__health\">\n <wx-progress\n type=\"circle\"\n :value=\"counts.health\"\n :status=\"healthStatus\"\n show-value\n :formatter=\"(value: number) => `${value}%`\"\n :aria-label=\"t('page.health')\"\n />\n <div v-if=\"parts\" class=\"wx-audit-overview__parts\">\n <wx-text v-if=\"parts.pages > 0\" size=\"sm\">{{\n t('page.health-pages', { clean: parts.clean, pages: parts.pages })\n }}</wx-text>\n <wx-text v-if=\"parts.site_errors > 0\" size=\"sm\" tone=\"danger\">{{\n t('page.health-site', { count: parts.site_errors })\n }}</wx-text>\n <wx-text v-if=\"parts.warnings > 0\" size=\"sm\" tone=\"warning\">{{\n t('page.health-warnings', { count: parts.warnings })\n }}</wx-text>\n <wx-text size=\"xs\" tone=\"muted\">{{ t('page.health-help') }}</wx-text>\n </div>\n </div>\n <div class=\"wx-audit-overview__stats\">\n <wx-statistic\n v-for=\"severity in severities\"\n :key=\"severity.key\"\n :title=\"t(severity.label)\"\n :value=\"counts.severity[severity.key] ?? 0\"\n :tone=\"(counts.severity[severity.key] ?? 0) > 0 ? severity.tone : 'muted'\"\n />\n <wx-statistic :title=\"t('page.new')\" :value=\"counts.new\" />\n <wx-statistic :title=\"t('page.fixed')\" :value=\"counts.fixed\" tone=\"success\" />\n </div>\n </div>\n <div class=\"wx-audit-overview__meta\">\n <wx-text size=\"sm\" tone=\"muted\">\n {{ t('page.last-run') }} <wx-date :value=\"done.finished_at\" /> ·\n {{ t(`page.scope-${done.scope}`) }} ·\n </wx-text>\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-overview__url\">{{\n done.base_url\n }}</wx-text>\n </div>\n </wx-card>\n\n <wx-card v-if=\"groups.length\" :title=\"t('page.by-group')\">\n <ul class=\"wx-audit-overview__groups\">\n <li v-for=\"group in groups\" :key=\"group.id\">\n <wx-text size=\"sm\">{{ group.label }}</wx-text>\n <span class=\"wx-audit-overview__badges\">\n <template v-for=\"severity in severities\" :key=\"severity.key\">\n <wx-badge\n v-if=\"(group.bySeverity[severity.key] ?? 0) > 0\"\n :type=\"severity.tone\"\n size=\"sm\"\n >{{ t(severity.label) }} · {{ group.bySeverity[severity.key] }}</wx-badge\n >\n </template>\n </span>\n </li>\n </ul>\n </wx-card>\n\n <wx-card v-else>\n <wx-empty icon=\"check-circle\" :title=\"t('page.clean')\" size=\"sm\" />\n </wx-card>\n\n <wx-card>\n <template #header>\n <span class=\"wx-audit-overview__title\">\n {{ t('page.sources') }}\n <wx-popover :title=\"t('page.sources')\" :width=\"360\" teleport>\n <template #trigger>\n <wx-button\n variant=\"text\"\n size=\"sm\"\n icon=\"question\"\n :aria-label=\"t('page.sources-help-label')\"\n />\n </template>\n <wx-text size=\"sm\">{{ t('page.sources-help') }}</wx-text>\n </wx-popover>\n </span>\n </template>\n <div class=\"wx-audit-overview__badges\">\n <wx-badge v-for=\"source in counts.sources.searched\" :key=\"source\" type=\"success\">{{\n source\n }}</wx-badge>\n </div>\n <div v-if=\"counts.sources.missing.length\" class=\"wx-audit-overview__missing\">\n <wx-text size=\"sm\" tone=\"warning\">{{ t('page.sources-missing') }}</wx-text>\n <wx-badge v-for=\"source in counts.sources.missing\" :key=\"source\" type=\"warning\">{{\n source\n }}</wx-badge>\n </div>\n </wx-card>\n </template>\n </template>\n </div>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-overview {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n container-type: inline-size;\n}\n\n.wx-audit-overview__row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8) var(--wx-space-12);\n margin-bottom: var(--wx-space-8);\n}\n\n.wx-audit-overview__end {\n margin-left: auto;\n}\n\n.wx-audit-overview__summary {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-24);\n}\n\n.wx-audit-overview__health {\n display: flex;\n flex: 1 1 20rem;\n align-items: center;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n/* The help is a sentence; it wraps beside the circle rather than stretching the card. */\n.wx-audit-overview__parts {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n max-width: 36ch;\n min-width: 0;\n}\n\n.wx-audit-overview__stats {\n display: flex;\n flex: 1 1 auto;\n flex-wrap: wrap;\n gap: var(--wx-space-16) var(--wx-space-32);\n}\n\n.wx-audit-overview__meta {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n margin-top: var(--wx-space-16);\n}\n\n/* A long domain breaks rather than pushing the card sideways on a phone. */\n.wx-audit-overview__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-overview__groups {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.wx-audit-overview__groups li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-overview__badges,\n.wx-audit-overview__missing {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-overview__missing {\n margin-top: var(--wx-space-12);\n}\n\n.wx-audit-overview__title {\n display: inline-flex;\n align-items: center;\n gap: var(--wx-space-4);\n}\n</style>\n","/** One heading as the parser kept it: its level and its text. */\nexport type OutlineEntry = [number, string]\n\n/** A row of the drawn tree — a heading, or a level the page jumped over (`missing`). */\nexport interface OutlineRow {\n level: number\n text: string\n missing: boolean\n /** For a missing level: the level the page jumped from. */\n after?: number\n}\n\n/**\n * The tree to draw: every heading, and between two of them the levels skipped on the way down,\n * so a gap stands where the heading should have been.\n */\nexport function outlineRows(outline: OutlineEntry[]): OutlineRow[] {\n const out: OutlineRow[] = []\n let previous = 0\n\n for (const [level, text] of outline) {\n for (let gap = previous + 1; previous > 0 && gap < level; gap++) {\n out.push({ level: gap, text: '', missing: true, after: previous })\n }\n\n out.push({ level, text, missing: false })\n previous = level\n }\n\n return out\n}\n\n/**\n * What breaks the usual order — one H1, first; each level one step below the one above; text in\n * every heading — as sentences in the reader's language. Empty when the order is fine.\n */\nexport function outlineHints(\n outline: OutlineEntry[],\n t: (key: string, params?: Record<string, string | number>) => string,\n): string[] {\n if (!outline.length) return []\n\n const ones = outline.filter(([level]) => level === 1).length\n const jumps = outline.filter(\n ([level], index) => index > 0 && level > outline[index - 1][0] + 1,\n ).length\n const empty = outline.filter(([, text]) => text === '').length\n const out: string[] = []\n\n if (ones === 0) out.push(t('page.headings-no-h1'))\n if (ones > 1) out.push(t('page.headings-many-h1', { count: ones }))\n if (ones > 0 && outline[0][0] !== 1) {\n out.push(t('page.headings-h1-not-first', { level: `H${outline[0][0]}` }))\n }\n if (jumps > 0) out.push(t('page.headings-skipped', { count: jumps }))\n if (empty > 0) out.push(t('page.headings-empty', { count: empty }))\n\n return out\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxAlert, WxBadge, WxText } from '@webx-ui/core'\nimport { outlineHints, outlineRows, type OutlineEntry } from './headings'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The page's headings as a tree: each one indented by its level, in the order the page has them.\n * The indent is the level itself, not the nesting the page managed — so a level the page jumped\n * over is drawn where it should have been, as an empty dashed row, and the gap is seen rather\n * than read about. Above the tree, what departs from the usual order, in plain words.\n */\nconst props = defineProps<{\n /** `[level, text]` in document order; null on a run crawled before the outline was kept. */\n outline: OutlineEntry[] | null\n /** How many headings of each level — to tell «none» from «not kept». */\n counts: Record<string, number>\n}>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst rows = computed(() => outlineRows(props.outline ?? []))\n\nconst hints = computed(() => outlineHints(props.outline ?? [], t))\n\nconst total = computed(() => Object.values(props.counts).reduce((sum, count) => sum + count, 0))\n</script>\n\n<template>\n <div class=\"wx-audit-headings\">\n <wx-text v-if=\"props.outline === null && total > 0\" tone=\"muted\">{{\n t('page.headings-recheck')\n }}</wx-text>\n <wx-text v-else-if=\"!rows.length\" tone=\"muted\">{{ t('page.no-headings') }}</wx-text>\n <template v-else>\n <wx-alert v-if=\"hints.length\" type=\"warning\" variant=\"soft\" :title=\"t('page.headings-hints')\">\n <ul class=\"wx-audit-headings__hints\">\n <li v-for=\"hint in hints\" :key=\"hint\">{{ hint }}</li>\n </ul>\n </wx-alert>\n <wx-alert v-else type=\"success\" variant=\"soft\" :title=\"t('page.headings-fine')\" />\n\n <ol class=\"wx-audit-headings__tree\">\n <li\n v-for=\"(row, index) in rows\"\n :key=\"index\"\n class=\"wx-audit-headings__row\"\n :class=\"{ 'is-missing': row.missing }\"\n >\n <span v-for=\"step in row.level - 1\" :key=\"step\" class=\"wx-audit-headings__guide\" />\n <template v-if=\"row.missing\">\n <span class=\"wx-audit-headings__gap\">H{{ row.level }}</span>\n <wx-text size=\"sm\" tone=\"warning\">{{\n t('page.heading-missing', { level: `H${row.level}`, after: `H${row.after}` })\n }}</wx-text>\n </template>\n <template v-else>\n <wx-badge :type=\"row.level === 1 ? 'primary' : 'info'\" size=\"sm\"\n >H{{ row.level }}</wx-badge\n >\n <span v-if=\"row.text\" class=\"wx-audit-headings__text\">{{ row.text }}</span>\n <wx-text v-else size=\"sm\" tone=\"danger\">{{ t('page.heading-empty') }}</wx-text>\n </template>\n </li>\n </ol>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-headings {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n}\n\n.wx-audit-headings__hints {\n margin: 0;\n padding-inline-start: var(--wx-space-18);\n}\n\n.wx-audit-headings__tree {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.wx-audit-headings__row {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-height: 32px;\n}\n\n/* One step of depth: a thin line down, so the levels read as columns, like a file tree. */\n.wx-audit-headings__guide {\n align-self: stretch;\n flex: none;\n width: var(--wx-space-16);\n background: linear-gradient(var(--wx-border-default), var(--wx-border-default)) no-repeat\n calc(var(--wx-space-12) + 1px) 0 / 1px 100%;\n}\n\n/* The level that should have been here: the badge's outline, empty, in the warning colour. */\n.wx-audit-headings__gap {\n display: inline-flex;\n align-items: center;\n padding: 0 var(--wx-space-6);\n border: 1px dashed var(--wx-color-warning);\n border-radius: var(--wx-radius-sm);\n color: var(--wx-color-warning);\n font-size: var(--wx-font-size-xs);\n line-height: 18px;\n}\n\n.wx-audit-headings__text {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n</style>\n","import type { AuditResourceRow } from './types'\n\n/**\n * Whether the browser is worth asking for a picture of the page: the run reached it and it\n * answered. One past the run's limit or on the stand was never asked, and one that failed for the\n * run would fail here too — the card keeps the placeholder for those, with nothing to open.\n */\nexport function viewable(row: AuditResourceRow): boolean {\n return row.checked && row.status !== null && row.status < 400 && row.error === null\n}\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxButton,\n WxDrawer,\n WxIcon,\n WxImage,\n WxLink,\n WxSkeleton,\n WxTable,\n WxTabs,\n WxText,\n WxTooltip,\n type BadgeType,\n type TabItem,\n type TabValue,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditDetails from './AuditDetails.vue'\nimport AuditHeadings from './AuditHeadings.vue'\nimport { outlineHints, type OutlineEntry } from './headings'\nimport { createAuditApi } from './api'\nimport { viewable } from './resources'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditSeverity,\n} from './types'\n\n/**\n * One page of the snapshot, sliding in from the right (§8): what it answered and what its head\n * says, its findings, the links that lead in and out of it — with the answer of each own page\n * and the class of each host — what it loads (pictures, CSS, JS) with what each answered, and\n * its structured data with what the types lack.\n *\n * «Recheck» asks this one address again (a run of the `urls` scope) and says what of its findings\n * in the last full run are fixed; «Export» downloads the page — snapshot, findings and links.\n */\nconst props = defineProps<{\n run: number\n /** Where the section lives — the recheck's comparison opens on its runs. */\n base?: string\n /** The page to show; null keeps the card closed. */\n pageId: number | null\n /** Check ids and their titles in the reader's language, for the findings tab. */\n titles: Record<string, string>\n}>()\n\nconst emit = defineEmits<{ close: [] }>()\n\n/*\n * The card is wide: a page has long addresses, headers and hreflang lists. Its width is kept under\n * a key of its own, so one remembered from the narrow card of before does not keep it narrow.\n */\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nconst router = useRouter()\nuseAuditMessages()\n\nconst canRun = context.can('audit.run') || context.can('audit.manage')\nconst recheck = ref<AuditRun | null>(null)\nconst rechecking = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nconst POLL_MS = 2000\n\n/* The page in its own words: the run it was crawled in, then one more, of just this address. */\nasync function startRecheck(): Promise<void> {\n if (!card.value) return\n\n rechecking.value = true\n recheck.value = null\n\n try {\n follow(await api.start('urls', [card.value.page.url]))\n } catch (error) {\n rechecking.value = false\n toast.danger(message(error))\n }\n}\n\nfunction follow(run: AuditRun): void {\n clearTimeout(timer)\n\n if (run.status === 'queued' || run.status === 'running') {\n timer = setTimeout(async () => {\n try {\n follow(await api.run(run.id))\n } catch (error) {\n rechecking.value = false\n toast.danger(message(error))\n }\n }, POLL_MS)\n\n return\n }\n\n rechecking.value = false\n recheck.value = run\n}\n\nfunction compareRecheck(): void {\n if (recheck.value && props.base) {\n void router.push({ path: `${props.base}/runs`, query: { to: String(recheck.value.id) } })\n }\n}\n\nonBeforeUnmount(() => clearTimeout(timer))\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst card = ref<AuditPageCard | null>(null)\nconst failure = ref<string | null>(null)\nconst tab = ref<TabValue>('overview')\nconst links = ref<AuditPage<AuditLinkRow> | null>(null)\nconst linksLoading = ref(false)\nconst resources = ref<AuditPage<AuditResourceRow> | null>(null)\nconst resourcesLoading = ref(false)\n\nconst resourceTabs: AuditResourceTab[] = ['images', 'css', 'js']\n\nconst open = computed({\n get: () => props.pageId !== null,\n set: (value) => {\n if (!value) emit('close')\n },\n})\n\nconst tabs = computed<TabItem[]>(() => [\n { value: 'overview', label: t('page.card-overview') },\n { value: 'issues', label: t('page.card-issues'), badge: card.value?.counts.issues || undefined },\n {\n value: 'headings',\n label: t('page.card-headings'),\n badge: outline.value?.length || undefined,\n },\n { value: 'in', label: t('page.card-incoming'), badge: card.value?.counts.incoming || undefined },\n { value: 'out', label: t('page.card-outgoing'), badge: card.value?.counts.outgoing || undefined },\n { value: 'images', label: t('page.card-images'), badge: card.value?.counts.images || undefined },\n { value: 'css', label: t('page.card-css'), badge: card.value?.counts.css || undefined },\n { value: 'js', label: t('page.card-js'), badge: card.value?.counts.js || undefined },\n {\n value: 'microdata',\n label: t('page.card-microdata'),\n badge: card.value?.counts.microdata || undefined,\n },\n])\n\n/** Every heading in order; null on a run crawled before the parser kept them. */\nconst outline = computed(() => {\n const kept = card.value?.page.facts.outline\n\n return Array.isArray(kept) ? (kept as OutlineEntry[]) : null\n})\n\nconst resourceTab = computed<AuditResourceTab | null>(() =>\n resourceTabs.includes(tab.value as AuditResourceTab) ? (tab.value as AuditResourceTab) : null,\n)\n\nconst severities: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst hostTypes: Record<string, BadgeType> = {\n own: 'success',\n own_mirror: 'warning',\n dev: 'danger',\n external: 'info',\n}\n\nconst linkColumns = computed<TableColumn<AuditLinkRow>[]>(() => [\n { key: 'url', label: t('page.address'), minWidth: 220 },\n { key: 'status', label: t('page.field-status'), width: 80 },\n { key: 'kind', label: t('page.kind'), width: 90 },\n { key: 'anchor', label: t('page.anchor'), minWidth: 140 },\n { key: 'host_class', label: t('page.host'), width: 120 },\n])\n\n/** Pictures show their alt; stylesheets and scripts how they are cached and compressed. */\nconst resourceColumns = computed<TableColumn<AuditResourceRow>[]>(() => [\n { key: 'url', label: t('page.address'), minWidth: 220 },\n { key: 'status', label: t('page.field-status'), width: 80 },\n { key: 'bytes', label: t('page.size'), width: 110 },\n ...(resourceTab.value === 'images'\n ? [{ key: 'alt', label: t('page.alt'), minWidth: 120 }]\n : [\n { key: 'cache_control', label: t('page.cache'), minWidth: 120 },\n { key: 'compression', label: t('page.field-compression'), width: 100 },\n ]),\n])\n\n/*\n * The block indented, the way a person reads JSON. One the server cut at its length limit does not\n * parse, and is shown as the page printed it rather than not at all.\n */\nfunction pretty(source: string): string {\n try {\n return JSON.stringify(JSON.parse(source), null, 2)\n } catch {\n return source\n }\n}\n\nfunction size(row: AuditResourceRow): string {\n if (row.bytes === null) return ''\n\n const kb = row.bytes / 1024\n const text = kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${Math.round(kb)} KB`\n\n return row.width && row.height ? `${text} · ${row.width}×${row.height}` : text\n}\n\n/*\n * A fact is a line, or a list: hreflang and Open Graph are key and value per row, the key set apart\n * so the eye does not run it into the value after it; JSON-LD is the types as tags.\n */\ntype Fact =\n | string\n | { pairs: [string, string][] }\n | { tags: string[]; error?: string | null }\n | { headings: number; hints: string[] }\n\n/** The numbers of the page, read at a glance before the details: one tile each. */\ninterface Tile {\n label: string\n value: string\n /** The answer's code is drawn as a badge of its colour. */\n status?: number | null\n danger?: boolean\n}\n\nfunction bytes(value: number): string {\n const kb = value / 1024\n\n return kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${kb.toFixed(1)} KB`\n}\n\nconst tiles = computed<Tile[]>(() => {\n const page = card.value?.page\n\n if (!page) return []\n\n const all: (Tile | null)[] = [\n {\n label: t('page.field-status'),\n value: String(page.status ?? t('page.status-none')),\n status: page.status,\n },\n page.bytes === null ? null : { label: t('page.size'), value: bytes(page.bytes) },\n page.ttfb_ms === null ? null : { label: t('page.field-ttfb_ms'), value: String(page.ttfb_ms) },\n page.total_ms === null\n ? null\n : { label: t('page.field-total_ms'), value: String(page.total_ms) },\n page.word_count === null\n ? null\n : { label: t('page.field-word_count'), value: String(page.word_count) },\n { label: t('page.field-links_in'), value: String(page.links_in) },\n { label: t('page.field-links_out_internal'), value: String(page.links_out_internal) },\n { label: t('page.field-links_out_external'), value: String(page.links_out_external) },\n { label: t('page.field-images'), value: String(page.images) },\n page.images_without_alt\n ? {\n label: t('page.field-images_without_alt'),\n value: String(page.images_without_alt),\n danger: true,\n }\n : null,\n ]\n\n return all.filter((tile): tile is Tile => tile !== null)\n})\n\n/** The rest of what the page answered and says in its head, in sections a reader looks for. */\nconst sections = computed<{ title: string; facts: [string, Fact][] }[]>(() => {\n const page = card.value?.page\n\n if (!page) return []\n\n const groups: [string, [string, unknown][]][] = [\n [\n t('page.section-answer'),\n [\n [t('page.field-final_status'), page.redirect_to ? page.final_status : null],\n [t('page.field-redirect_to'), page.redirect_to],\n [t('page.error'), page.error],\n [t('page.field-content_type'), page.content_type],\n [t('page.field-compression'), page.compression],\n ],\n ],\n [\n t('page.section-crawl'),\n [\n [t('page.field-source'), t(`page.source-${page.source}`)],\n [t('page.field-depth'), page.depth],\n [t('page.field-indexable'), page.indexable ? t('page.yes') : t('page.no')],\n [t('page.field-blocked_by_robots'), page.blocked_by_robots ? t('page.yes') : null],\n ],\n ],\n [\n t('page.section-head'),\n [\n [t('page.field-title'), page.title],\n [t('page.field-description'), page.description],\n [t('page.field-h1'), page.h1.join(' · ') || null],\n [\n t('page.card-headings'),\n outline.value?.length\n ? { headings: outline.value.length, hints: outlineHints(outline.value, t) }\n : null,\n ],\n [t('page.field-canonical'), page.canonical],\n [t('page.field-robots_meta'), page.robots_meta],\n [t('page.field-x_robots_tag'), page.x_robots_tag],\n [t('page.field-lang'), page.lang],\n [\n 'hreflang',\n page.hreflang.length\n ? { pairs: page.hreflang.map((alternate) => [alternate.lang, alternate.url]) }\n : null,\n ],\n ],\n ],\n [\n t('page.section-sharing'),\n [\n [\n 'Open Graph',\n Object.keys(page.og).length\n ? {\n pairs: Object.entries(page.og).map(([key, value]) => [`og:${key}`, String(value)]),\n }\n : null,\n ],\n [\n 'Twitter',\n Object.keys(page.twitter).length\n ? {\n pairs: Object.entries(page.twitter).map(([key, value]) => [\n `twitter:${key}`,\n String(value),\n ]),\n }\n : null,\n ],\n [\n 'JSON-LD',\n page.json_ld.length\n ? {\n tags: page.json_ld.flatMap((block) => block.types),\n error: page.json_ld.find((block) => block.error)?.error ?? null,\n }\n : null,\n ],\n ],\n ],\n ]\n\n return groups\n .map(([title, rows]) => ({\n title,\n facts: rows\n .filter(([, value]) => value !== null && value !== undefined && value !== '')\n .map(\n ([label, value]) =>\n [label, typeof value === 'object' ? (value as Fact) : String(value)] as [string, Fact],\n ),\n }))\n .filter((section) => section.facts.length)\n})\n\nasync function load(id: number): Promise<void> {\n clearTimeout(timer)\n rechecking.value = false\n recheck.value = null\n card.value = null\n failure.value = null\n links.value = null\n resources.value = null\n tab.value = 'overview'\n\n try {\n card.value = await api.page(props.run, id)\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nasync function loadLinks(state: TableState): Promise<void> {\n if (props.pageId === null || (tab.value !== 'in' && tab.value !== 'out')) return\n\n linksLoading.value = true\n\n try {\n links.value = await api.links(props.run, props.pageId, {\n direction: tab.value,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n failure.value = message(error)\n } finally {\n linksLoading.value = false\n }\n}\n\nasync function loadResources(state: TableState): Promise<void> {\n const current = resourceTab.value\n\n if (props.pageId === null || current === null) return\n\n resourcesLoading.value = true\n\n try {\n resources.value = await api.resources(props.run, props.pageId, {\n tab: current,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n failure.value = message(error)\n } finally {\n resourcesLoading.value = false\n }\n}\n\nwatch(\n () => props.pageId,\n (id) => {\n if (id !== null) void load(id)\n },\n { immediate: true },\n)\n\nwatch(tab, () => {\n links.value = null\n resources.value = null\n})\n</script>\n\n<template>\n <wx-drawer\n v-model:open=\"open\"\n size=\"min(1100px, 75vw)\"\n :min-size=\"480\"\n resizable\n persist=\"webx-audit.page-card-wide\"\n >\n <template #title>\n <span class=\"wx-audit-card__title\">\n <audit-status v-if=\"card\" :code=\"card.page.status\" />\n <span class=\"wx-audit-card__url\">{{ card?.page.url ?? '' }}</span>\n </span>\n </template>\n\n <template #extra>\n <span v-if=\"card\" class=\"wx-audit-card__extra\">\n <wx-button\n v-if=\"canRun\"\n size=\"sm\"\n icon=\"refresh\"\n :loading=\"rechecking\"\n @click=\"startRecheck\"\n >{{ t('page.recheck') }}</wx-button\n >\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"download\"\n :href=\"api.pageFile(props.run, card.page.id)\"\n >{{ t('page.export-page') }}</wx-button\n >\n <wx-link :href=\"card.page.url\" target=\"_blank\">{{ t('page.open-page') }}</wx-link>\n </span>\n </template>\n\n <wx-text v-if=\"failure\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!card\" :rows=\"6\" />\n\n <div v-else class=\"wx-audit-card\">\n <wx-alert v-if=\"rechecking\" type=\"info\" :description=\"t('page.recheck-running')\" />\n <wx-alert\n v-else-if=\"recheck && recheck.status === 'done' && recheck.counts\"\n :type=\"recheck.counts.new > 0 ? 'warning' : 'success'\"\n >\n <div class=\"wx-audit-card__recheck\">\n <span>{{ t('page.recheck-fixed', { count: recheck.counts.fixed }) }}</span>\n <span>{{ t('page.recheck-new', { count: recheck.counts.new }) }}</span>\n <wx-button v-if=\"props.base\" size=\"sm\" variant=\"text\" @click=\"compareRecheck\">{{\n t('page.recheck-compare')\n }}</wx-button>\n </div>\n </wx-alert>\n <wx-alert\n v-else-if=\"recheck\"\n type=\"danger\"\n :description=\"recheck.error ?? t(`page.status-${recheck.status}`)\"\n />\n <wx-text v-if=\"card.page.title\" weight=\"semibold\">{{ card.page.title }}</wx-text>\n\n <wx-tabs v-model=\"tab\" :items=\"tabs\">\n <div v-if=\"tab === 'overview'\" class=\"wx-audit-card__overview\">\n <div class=\"wx-audit-card__tiles\">\n <div v-for=\"tile in tiles\" :key=\"tile.label\" class=\"wx-audit-card__tile\">\n <wx-text size=\"sm\" tone=\"muted\">{{ tile.label }}</wx-text>\n <audit-status v-if=\"tile.status !== undefined\" :code=\"tile.status\" size=\"md\" />\n <wx-text\n v-else\n weight=\"semibold\"\n :tone=\"tile.danger ? 'danger' : undefined\"\n class=\"wx-audit-card__number\"\n >{{ tile.value }}</wx-text\n >\n </div>\n </div>\n\n <section v-for=\"section in sections\" :key=\"section.title\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head\">{{ section.title }}</div>\n <dl class=\"wx-audit-card__facts\">\n <template v-for=\"[label, value] in section.facts\" :key=\"label\">\n <dt>{{ label }}</dt>\n <dd v-if=\"typeof value === 'string'\">{{ value }}</dd>\n <dd v-else-if=\"'pairs' in value\" class=\"wx-audit-card__pairs\">\n <template v-for=\"([key, text], index) in value.pairs\" :key=\"index\">\n <code class=\"wx-audit-card__key\">{{ key }}</code>\n <span>{{ text }}</span>\n </template>\n </dd>\n <dd v-else-if=\"'headings' in value\" class=\"wx-audit-card__heading-fact\">\n <span>\n <wx-text :tone=\"value.hints.length ? 'warning' : 'success'\">{{\n value.hints.length\n ? t('page.headings-summary-bad', { count: value.headings })\n : t('page.headings-summary-ok', { count: value.headings })\n }}</wx-text>\n <wx-link\n as=\"button\"\n class=\"wx-audit-card__heading-open\"\n @click=\"tab = 'headings'\"\n >{{ t('page.headings-open') }}</wx-link\n >\n </span>\n <ul v-if=\"value.hints.length\" class=\"wx-audit-card__heading-hints\">\n <li v-for=\"hint in value.hints\" :key=\"hint\">{{ hint }}</li>\n </ul>\n </dd>\n <dd v-else class=\"wx-audit-card__tags\">\n <wx-badge v-for=\"(tag, index) in value.tags\" :key=\"index\" type=\"info\" size=\"sm\">{{\n tag\n }}</wx-badge>\n <wx-text v-if=\"value.error\" size=\"sm\" tone=\"danger\">{{ value.error }}</wx-text>\n </dd>\n </template>\n </dl>\n </section>\n\n <section v-if=\"Object.keys(card.page.headers).length\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head\">{{ t('page.headers') }}</div>\n <dl class=\"wx-audit-card__facts\">\n <template v-for=\"(value, name) in card.page.headers\" :key=\"name\">\n <dt class=\"wx-audit-card__code\">{{ name }}</dt>\n <dd class=\"wx-audit-card__code\">{{ value }}</dd>\n </template>\n </dl>\n </section>\n </div>\n\n <div v-else-if=\"tab === 'headings'\" class=\"wx-audit-card__box wx-audit-card__headings\">\n <audit-headings :outline=\"outline\" :counts=\"card.page.headings\" />\n </div>\n\n <div v-else-if=\"tab === 'issues'\" class=\"wx-audit-card__issues\">\n <wx-text v-if=\"!card.issues.length\" tone=\"muted\">{{ t('page.no-issues') }}</wx-text>\n <div v-for=\"issue in card.issues\" :key=\"issue.id\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head wx-audit-card__issue-head\">\n <wx-badge :type=\"severities[issue.severity]\" dot>{{\n t(`page.severity-${issue.severity}`)\n }}</wx-badge>\n <wx-text size=\"sm\" weight=\"semibold\">{{\n props.titles[issue.check] ?? issue.check\n }}</wx-text>\n <wx-badge v-if=\"issue.state === 'new'\" type=\"primary\" size=\"sm\">{{\n t('page.state-new')\n }}</wx-badge>\n <wx-tooltip\n v-if=\"issue.details.count != null && issue.details.table\"\n :content=\"issue.details.summary ?? undefined\"\n :disabled=\"!issue.details.summary\"\n >\n <wx-badge round size=\"sm\">{{ issue.details.count }}</wx-badge>\n </wx-tooltip>\n </div>\n <div class=\"wx-audit-card__box-body\">\n <audit-details\n :details=\"issue.details\"\n :counted=\"issue.details.count != null && !!issue.details.table\"\n />\n </div>\n </div>\n </div>\n\n <wx-table\n v-else-if=\"resourceTab\"\n :key=\"`resources-${String(tab)}`\"\n :data=\"resources\"\n :columns=\"resourceColumns\"\n row-key=\"id\"\n flush\n :loading=\"resourcesLoading\"\n :per-page-options=\"[]\"\n :empty-text=\"t('page.no-resources')\"\n @state-change=\"loadResources\"\n >\n <template #cell-url=\"{ row }\">\n <span v-if=\"resourceTab === 'images'\" class=\"wx-audit-card__picture\">\n <!-- Only a picture that answered is fetched: the stand's and a broken one keep the\n placeholder rather than a request the browser is sure to lose. -->\n <wx-image\n :src=\"viewable(row) ? row.url : undefined\"\n :alt=\"row.alt ?? ''\"\n :width=\"48\"\n :height=\"48\"\n fit=\"cover\"\n radius=\"var(--wx-radius-sm)\"\n preview\n :preview-label=\"t('page.view-full')\"\n class=\"wx-audit-card__thumb\"\n :class=\"{ 'is-unviewable': !viewable(row) }\"\n >\n <template v-if=\"!viewable(row)\" #placeholder>\n <wx-icon name=\"image\" />\n </template>\n </wx-image>\n <span class=\"wx-audit-card__url\">{{ row.url }}</span>\n </span>\n <span v-else class=\"wx-audit-card__url\">{{ row.url }}</span>\n <wx-text v-if=\"row.location\" size=\"sm\" tone=\"muted\" class=\"wx-audit-card__url\">\n → {{ row.location }}</wx-text\n >\n <wx-text v-if=\"row.error\" size=\"sm\" tone=\"danger\">{{ row.error }}</wx-text>\n </template>\n <template #cell-status=\"{ row }\">\n <audit-status v-if=\"row.status !== null || row.checked\" :code=\"row.status\" />\n <wx-text v-else size=\"sm\" tone=\"muted\">{{ t('page.not-checked') }}</wx-text>\n </template>\n <template #cell-bytes=\"{ row }\">{{ size(row) }}</template>\n <template #cell-alt=\"{ row }\">\n <wx-text v-if=\"row.alt === null && row.kind === 'img'\" size=\"sm\" tone=\"danger\">{{\n t('page.missing')\n }}</wx-text>\n <template v-else>{{ row.alt ?? '' }}</template>\n </template>\n </wx-table>\n\n <div v-else-if=\"tab === 'microdata'\" class=\"wx-audit-card__issues\">\n <wx-text v-if=\"!card.page.json_ld.length\" tone=\"muted\">{{\n t('page.no-json-ld')\n }}</wx-text>\n <div\n v-for=\"(block, index) in card.page.json_ld\"\n :key=\"index\"\n class=\"wx-audit-card__issue\"\n >\n <div class=\"wx-audit-card__issue-head\">\n <wx-text size=\"sm\" weight=\"semibold\">{{\n t('page.jsonld-block', { number: index + 1 })\n }}</wx-text>\n <wx-badge v-for=\"type in block.types\" :key=\"type\" size=\"sm\">{{ type }}</wx-badge>\n </div>\n <wx-text v-if=\"block.error\" size=\"sm\" tone=\"danger\"\n >{{ t('page.jsonld-error') }} {{ block.error }}</wx-text\n >\n <template v-for=\"(item, position) in block.items ?? []\" :key=\"position\">\n <wx-text v-if=\"item.missing.length\" size=\"sm\" tone=\"danger\"\n >{{ item.type }} — {{ t('page.jsonld-required') }}\n {{ item.missing.join(', ') }}</wx-text\n >\n <wx-text v-if=\"item.recommended.length\" size=\"sm\" tone=\"muted\"\n >{{ item.type }} — {{ t('page.jsonld-recommended') }}\n {{ item.recommended.join(', ') }}</wx-text\n >\n <wx-text\n v-if=\"!item.missing.length && !item.recommended.length\"\n size=\"sm\"\n tone=\"success\"\n >{{ item.type }} — {{ t('page.jsonld-complete') }}</wx-text\n >\n </template>\n <pre v-if=\"block.source\" class=\"wx-audit-card__source\">{{ pretty(block.source) }}</pre>\n </div>\n </div>\n\n <wx-table\n v-else\n :key=\"String(tab)\"\n :data=\"links\"\n :columns=\"linkColumns\"\n row-key=\"id\"\n flush\n :loading=\"linksLoading\"\n :per-page-options=\"[]\"\n :empty-text=\"t('page.no-links')\"\n @state-change=\"loadLinks\"\n >\n <template #cell-url=\"{ row }\">\n <span class=\"wx-audit-card__url\">{{ row.url ?? '—' }}</span>\n </template>\n <template #cell-status=\"{ row }\">\n <audit-status v-if=\"row.status !== null\" :code=\"row.status\" />\n </template>\n <template #cell-host_class=\"{ row }\">\n <wx-badge v-if=\"row.host_class\" :type=\"hostTypes[row.host_class] ?? 'info'\" size=\"sm\">{{\n t(`page.host-${row.host_class}`)\n }}</wx-badge>\n </template>\n </wx-table>\n </wx-tabs>\n </div>\n </wx-drawer>\n</template>\n\n<style scoped>\n.wx-audit-card {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n /* The card decides its layout by its own width, not the window's. */\n container-type: inline-size;\n}\n\n.wx-audit-card__title {\n display: inline-flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-card__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-card__overview {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n margin-top: var(--wx-space-12);\n min-width: 0;\n}\n\n/* The numbers first: what a reader compares between pages, at a glance. */\n.wx-audit-card__tiles {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: var(--wx-space-8);\n}\n\n.wx-audit-card__tile {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n /* A label on two lines must not lift its number above its neighbours' — the numbers sit on one line. */\n justify-content: space-between;\n gap: var(--wx-space-4);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n}\n\n.wx-audit-card__number {\n font-size: var(--wx-font-size-lg);\n}\n\n/* A section, or a finding: an edge of its own, a tinted head, the content under it. */\n.wx-audit-card__box {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-card__heading-fact {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n}\n\n.wx-audit-card__heading-open {\n margin-inline-start: var(--wx-space-8);\n}\n\n.wx-audit-card__heading-hints {\n margin: 0;\n padding-inline-start: var(--wx-space-18);\n color: var(--wx-text-muted);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-card__headings {\n padding: var(--wx-space-12) var(--wx-space-16);\n}\n\n.wx-audit-card__box-head {\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n font-weight: var(--wx-font-weight-semibold);\n}\n\n.wx-audit-card__box-body {\n padding: var(--wx-space-8) var(--wx-space-12);\n}\n\n/* One label column for every section, so the values start on one line down the card. */\n.wx-audit-card__facts {\n display: grid;\n grid-template-columns: 200px minmax(0, 1fr);\n gap: var(--wx-space-8) var(--wx-space-16);\n margin: 0;\n padding: var(--wx-space-12);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-card__facts dt {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-card__facts dd {\n margin: 0;\n overflow-wrap: anywhere;\n white-space: pre-line;\n}\n\n/* Key and value in two columns of their own: the keys start on one line, so do the values. */\n.wx-audit-card__pairs {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n gap: var(--wx-space-6) var(--wx-space-12);\n align-items: baseline;\n}\n\n.wx-audit-card__key {\n color: var(--wx-text-muted);\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n}\n\n.wx-audit-card__tags {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-card__code {\n font-family: var(--wx-font-family-mono);\n}\n\n.wx-audit-card__issues {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n margin-top: var(--wx-space-12);\n}\n\n.wx-audit-card__issue {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n/* A picture is recognised by sight faster than by its hashed file name. */\n.wx-audit-card__picture {\n display: flex;\n align-items: center;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-card__thumb {\n flex: none;\n}\n\n/* The same box as a picture that would not load, with the same mark — nothing here to open. */\n.wx-audit-card__thumb.is-unviewable :deep(.wx-image__placeholder .wx-icon) {\n width: 32px;\n height: 32px;\n}\n\n.wx-audit-card__source {\n max-height: 480px;\n margin: 0;\n padding: var(--wx-space-8);\n overflow: auto;\n border-radius: var(--wx-radius-sm);\n background: var(--wx-bg-muted);\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-card__issue-head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n/* A narrow card: the label goes above its value instead of beside it. */\n@container (max-width: 560px) {\n .wx-audit-card__facts {\n grid-template-columns: minmax(0, 1fr);\n row-gap: var(--wx-space-2);\n }\n\n .wx-audit-card__facts dd + dt {\n margin-top: var(--wx-space-8);\n }\n}\n\n.wx-audit-card__extra {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-card__recheck {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-4) var(--wx-space-12);\n}\n</style>\n","import type { AuditFieldType, AuditFilterOp, AuditPageField } from './types'\n\n/**\n * The fields of the snapshot, as `PageColumns` lists them on the server: what the pages screen\n * can show, filter on, sort by and export. Kept in the same order, so the column picker reads\n * like the page's card — address and answer first, markup, then speed and links.\n */\nexport const PAGE_FIELDS: Record<AuditPageField, AuditFieldType> = {\n url: 'url',\n status: 'status',\n final_status: 'status',\n redirect_to: 'url',\n source: 'source',\n depth: 'number',\n indexable: 'bool',\n issues: 'number',\n title: 'text',\n description: 'text',\n h1: 'text',\n canonical: 'url',\n robots_meta: 'text',\n x_robots_tag: 'text',\n lang: 'text',\n content_type: 'text',\n bytes: 'number',\n ttfb_ms: 'number',\n total_ms: 'number',\n compression: 'text',\n word_count: 'number',\n links_in: 'number',\n links_out_internal: 'number',\n links_out_external: 'number',\n images: 'number',\n images_without_alt: 'number',\n in_sitemap: 'bool',\n in_registry: 'bool',\n blocked_by_robots: 'bool',\n}\n\nexport const DEFAULT_COLUMNS: AuditPageField[] = [\n 'url',\n 'status',\n 'indexable',\n 'title',\n 'word_count',\n 'links_in',\n 'issues',\n]\n\n/** `h1` is read out of a JSON list: shown and exported, not filtered or sorted on. */\nexport const COMPUTED_FIELDS: AuditPageField[] = ['h1']\n\n/** What can be asked of a field of each type. */\nexport const OPERATIONS: Record<AuditFieldType, AuditFilterOp[]> = {\n url: ['contains', 'eq', 'empty', 'filled'],\n text: ['contains', 'eq', 'empty', 'filled'],\n number: ['gt', 'lt', 'eq', 'empty'],\n status: ['eq', 'gt', 'lt', 'empty'],\n bool: ['yes', 'no'],\n source: ['eq'],\n}\n\n/** The operations that need a value typed beside them. */\nexport const WITH_VALUE: AuditFilterOp[] = ['contains', 'eq', 'gt', 'lt']\n\nexport const SOURCES = ['home', 'sitemap', 'registry', 'link'] as const\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useDates, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxButton,\n WxCheckboxGroup,\n WxInput,\n WxPopover,\n WxSelect,\n WxTable,\n WxText,\n type SelectValue,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditLayout from './AuditLayout.vue'\nimport AuditPageCard from './AuditPageCard.vue'\nimport { createAuditApi } from './api'\nimport {\n COMPUTED_FIELDS,\n DEFAULT_COLUMNS,\n OPERATIONS,\n PAGE_FIELDS,\n SOURCES,\n WITH_VALUE,\n} from './fields'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditFieldFilter,\n AuditFilterOp,\n AuditPage,\n AuditPageField,\n AuditPageQuery,\n AuditPageRow,\n AuditRun,\n} from './types'\n\n/**\n * Every address the last full run crawled (§8, «Pages»): any field of the snapshot as a column,\n * a filter on any of them, the list as CSV, and a row that opens the page's card.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\nconst dates = useDates()\n\nconst STORAGE = 'webx-audit.pages.columns'\n\nconst run = ref<AuditRun | null>(null)\nconst ready = ref(false)\nconst page = ref<AuditPage<AuditPageRow> | null>(null)\nconst loading = ref(false)\nconst opened = ref<number | null>(null)\nconst titles = ref<Record<string, string>>({})\n\nconst status = ref<string | null>(null)\nconst indexable = ref<string | null>(null)\nconst check = ref<string | null>(null)\nconst filters = ref<AuditFieldFilter[]>([])\nlet last: TableState = { page: 1, perPage: 50, sort: null, search: '' }\n\nconst visible = ref<AuditPageField[]>(restore())\n\nfunction restore(): AuditPageField[] {\n try {\n const saved: unknown = JSON.parse(window.localStorage.getItem(STORAGE) ?? 'null')\n\n if (Array.isArray(saved)) {\n const known = saved.filter((key): key is AuditPageField => key in PAGE_FIELDS)\n\n if (known.length) return known\n }\n } catch {\n // A private window or a broken value: the default columns, as for anyone else.\n }\n\n return [...DEFAULT_COLUMNS]\n}\n\nwatch(visible, (keys) => {\n try {\n window.localStorage.setItem(STORAGE, JSON.stringify(keys))\n } catch {\n // Not remembered — still shown.\n }\n})\n\nconst fields = Object.keys(PAGE_FIELDS) as AuditPageField[]\n\nconst columnOptions = computed(() =>\n fields.map((key) => ({ value: key, label: t(`page.field-${key}`) })),\n)\n\nconst filterFields = computed(() =>\n fields\n .filter((key) => !COMPUTED_FIELDS.includes(key))\n .map((key) => ({ value: key, label: t(`page.field-${key}`) })),\n)\n\nconst columns = computed<TableColumn<AuditPageRow>[]>(() =>\n /* The picker keeps the order things were ticked in; the table keeps the card's order. */\n fields\n .filter((key) => visible.value.includes(key))\n .map((key) => ({\n key,\n label: t(`page.field-${key}`),\n sortable: !COMPUTED_FIELDS.includes(key),\n minWidth: PAGE_FIELDS[key] === 'url' || PAGE_FIELDS[key] === 'text' ? 220 : undefined,\n align: PAGE_FIELDS[key] === 'number' ? 'right' : undefined,\n })),\n)\n\nconst statusOptions = computed(() => [\n ...['2xx', '3xx', '4xx', '5xx'].map((value) => ({ value, label: value })),\n { value: 'none', label: t('page.status-none') },\n])\n\nconst indexableOptions = computed(() => [\n { value: '1', label: t('page.indexable-yes') },\n { value: '0', label: t('page.indexable-no') },\n])\n\nconst checkOptions = computed(() =>\n Object.entries(titles.value).map(([value, label]) => ({ value, label })),\n)\n\nconst filtersCount = computed(\n () =>\n [status.value, indexable.value, check.value].filter(Boolean).length +\n filters.value.filter(complete).length,\n)\n\nconst query = computed<AuditPageQuery>(() => ({\n status: status.value,\n indexable: indexable.value === null ? null : indexable.value === '1',\n check: check.value,\n filters: filters.value.filter(complete),\n}))\n\nfunction complete(filter: AuditFieldFilter): boolean {\n return !WITH_VALUE.includes(filter.op) || (filter.value ?? '').trim() !== ''\n}\n\nfunction pick(value: SelectValue | SelectValue[] | null | undefined): string | null {\n return typeof value === 'string' && value !== '' ? value : null\n}\n\nfunction operations(field: AuditPageField) {\n return OPERATIONS[PAGE_FIELDS[field]].map((op) => ({ value: op, label: t(`page.op-${op}`) }))\n}\n\nfunction addFilter(): void {\n filters.value = [...filters.value, { field: 'title', op: 'empty' }]\n}\n\nfunction setField(index: number, value: SelectValue | SelectValue[] | null | undefined): void {\n const field = pick(value) as AuditPageField | null\n\n if (!field) return\n\n filters.value = filters.value.map((filter, at) =>\n at === index ? { field, op: OPERATIONS[PAGE_FIELDS[field]][0]!, value: '' } : filter,\n )\n}\n\nfunction setOp(index: number, value: SelectValue | SelectValue[] | null | undefined): void {\n const op = pick(value) as AuditFilterOp | null\n\n if (op)\n filters.value = filters.value.map((filter, at) => (at === index ? { ...filter, op } : filter))\n}\n\nfunction setValue(index: number, value: string): void {\n filters.value = filters.value.map((filter, at) => (at === index ? { ...filter, value } : filter))\n}\n\nfunction removeFilter(index: number): void {\n filters.value = filters.value.filter((_, at) => at !== index)\n}\n\nfunction setColumns(keys: unknown[]): void {\n const next = keys.filter((key): key is AuditPageField => String(key) in PAGE_FIELDS)\n\n /* A table without columns is a blank card; the address stays at least. */\n visible.value = next.length ? next : ['url']\n}\n\nfunction text(value: unknown): string {\n return value === null || value === undefined || value === '' ? '—' : String(value)\n}\n\nasync function load(state: TableState = last): Promise<void> {\n last = state\n\n if (run.value === null) return\n\n loading.value = true\n\n try {\n page.value = await api.pages(run.value.id, {\n ...query.value,\n search: state.search,\n sort: state.sort ? `${state.sort.order === 'desc' ? '-' : ''}${state.sort.key}` : null,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nfunction download(): void {\n if (run.value === null) return\n\n window.location.assign(\n api.pagesFile(\n run.value.id,\n { ...query.value, search: last.search },\n columns.value.map((column) => column.key),\n ),\n )\n}\n\nwatch(query, () => void load({ ...last, page: 1 }), { deep: true })\n\nonMounted(async () => {\n try {\n run.value = (await api.latest()).crawled\n\n if (run.value !== null) {\n const checks = await api.checks(run.value.id)\n titles.value = Object.fromEntries(checks.map((row) => [row.id, row.title]))\n }\n } catch (error) {\n toast.danger(message(error))\n } finally {\n ready.value = true\n }\n\n void load()\n})\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"pages\">\n <wx-text v-if=\"ready && run === null\" tone=\"muted\" class=\"wx-audit-pages__none\">{{\n t('page.pages-none')\n }}</wx-text>\n\n <wx-table\n v-else\n :data=\"page\"\n :columns=\"columns\"\n row-key=\"id\"\n searchable\n clickable\n hover\n flush\n :loading=\"loading || !ready\"\n :per-page-options=\"[50, 100, 200]\"\n :search-placeholder=\"t('page.search-url')\"\n :filters-count=\"filtersCount\"\n :filters-label=\"panel('filters.title')\"\n :filters-width=\"420\"\n :empty-text=\"t('page.empty')\"\n @state-change=\"load\"\n @row-click=\"(row) => (opened = row.id)\"\n >\n <template #title>\n <wx-text v-if=\"run\" size=\"sm\" tone=\"muted\">{{\n t('page.pages-run', { date: dates.short(run.finished_at) })\n }}</wx-text>\n </template>\n\n <template #actions>\n <wx-popover :title=\"t('page.columns')\" width=\"300\">\n <template #trigger>\n <wx-button size=\"sm\" variant=\"text\" icon=\"sliders\">{{ t('page.columns') }}</wx-button>\n </template>\n <wx-checkbox-group\n :model-value=\"visible\"\n :options=\"columnOptions\"\n size=\"sm\"\n class=\"wx-audit-pages__picker\"\n @update:model-value=\"setColumns\"\n />\n </wx-popover>\n <wx-button size=\"sm\" variant=\"text\" icon=\"download\" :disabled=\"!run\" @click=\"download\">{{\n t('page.export')\n }}</wx-button>\n </template>\n\n <template #filters>\n <div class=\"wx-audit-pages__filters\">\n <wx-select\n :model-value=\"status\"\n :options=\"statusOptions\"\n :placeholder=\"t('page.any-status')\"\n clearable\n @update:model-value=\"status = pick($event)\"\n />\n <wx-select\n :model-value=\"indexable\"\n :options=\"indexableOptions\"\n :placeholder=\"t('page.any-indexable')\"\n clearable\n @update:model-value=\"indexable = pick($event)\"\n />\n <wx-select\n :model-value=\"check\"\n :options=\"checkOptions\"\n :placeholder=\"t('page.any-check')\"\n clearable\n filterable\n @update:model-value=\"check = pick($event)\"\n />\n\n <div v-for=\"(filter, index) in filters\" :key=\"index\" class=\"wx-audit-pages__filter\">\n <wx-select\n :model-value=\"filter.field\"\n :options=\"filterFields\"\n filterable\n size=\"sm\"\n @update:model-value=\"setField(index, $event)\"\n />\n <wx-select\n :model-value=\"filter.op\"\n :options=\"operations(filter.field)\"\n size=\"sm\"\n @update:model-value=\"setOp(index, $event)\"\n />\n <wx-select\n v-if=\"WITH_VALUE.includes(filter.op) && PAGE_FIELDS[filter.field] === 'source'\"\n :model-value=\"filter.value ?? null\"\n :options=\"SOURCES.map((value) => ({ value, label: t(`page.source-${value}`) }))\"\n size=\"sm\"\n @update:model-value=\"setValue(index, pick($event) ?? '')\"\n />\n <wx-input\n v-else-if=\"WITH_VALUE.includes(filter.op)\"\n :model-value=\"filter.value ?? ''\"\n :placeholder=\"t('page.value')\"\n size=\"sm\"\n @update:model-value=\"setValue(index, String($event ?? ''))\"\n />\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"close\"\n :aria-label=\"t('page.remove-filter')\"\n @click=\"removeFilter(index)\"\n />\n </div>\n\n <wx-button size=\"sm\" variant=\"text\" icon=\"plus\" @click=\"addFilter\">{{\n t('page.add-filter')\n }}</wx-button>\n </div>\n </template>\n\n <template v-for=\"key in visible\" :key=\"key\" #[`cell-${key}`]=\"{ row }\">\n <audit-status\n v-if=\"PAGE_FIELDS[key] === 'status' && row[key] !== null\"\n :code=\"Number(row[key])\"\n />\n <wx-text v-else-if=\"PAGE_FIELDS[key] === 'status'\" size=\"sm\" tone=\"danger\">{{\n t('page.status-none')\n }}</wx-text>\n <template v-else-if=\"PAGE_FIELDS[key] === 'bool'\">{{\n row[key] ? t('page.yes') : t('page.no')\n }}</template>\n <template v-else-if=\"PAGE_FIELDS[key] === 'source'\">{{\n t(`page.source-${row[key]}`)\n }}</template>\n <wx-badge v-else-if=\"key === 'issues' && row.issues > 0\" type=\"warning\" size=\"sm\">{{\n row.issues\n }}</wx-badge>\n <span v-else :class=\"{ 'wx-audit-pages__long': PAGE_FIELDS[key] === 'url' }\">{{\n text(row[key])\n }}</span>\n </template>\n </wx-table>\n\n <audit-page-card\n v-if=\"run\"\n :run=\"run.id\"\n :base=\"props.base\"\n :page-id=\"opened\"\n :titles=\"titles\"\n @close=\"opened = null\"\n />\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-pages__none {\n display: block;\n padding: var(--wx-space-24);\n}\n\n.wx-audit-pages__filters {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-pages__filter {\n display: grid;\n grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr) auto;\n gap: var(--wx-space-4);\n align-items: center;\n}\n\n.wx-audit-pages__picker {\n max-height: 360px;\n overflow-y: auto;\n}\n\n.wx-audit-pages__long {\n overflow-wrap: anywhere;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxLink, WxSegmented, WxSkeleton, WxText } from '@webx-ui/core'\nimport AuditDetails from './AuditDetails.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditComparisonKind, AuditComparisonRow, AuditIssue } from './types'\n\n/**\n * One check of a comparison opened: its new, fixed or persisting findings, fifty at a time —\n * fixed ones as the earlier run stored them, the others from the later run.\n */\nconst props = defineProps<{ from: number; to: number; row: AuditComparisonRow }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst KINDS: AuditComparisonKind[] = ['new', 'fixed', 'persisting']\n\n/* Open on what changed: new first, then fixed — persisting only when nothing else is there. */\nconst kind = ref<AuditComparisonKind>(KINDS.find((one) => props.row[one] > 0) ?? 'new')\nconst issues = ref<AuditIssue[] | null>(null)\nconst page = ref(1)\nconst more = ref(false)\nconst failure = ref<string | null>(null)\n\nconst options = computed(() =>\n KINDS.map((value) => ({\n value,\n label: `${t(`page.kind-${value}`)} · ${props.row[value]}`,\n disabled: props.row[value] === 0,\n })),\n)\n\nasync function load(next = 1): Promise<void> {\n failure.value = null\n\n try {\n const answer = await api.compareIssues({\n from: props.from,\n to: props.to,\n kind: kind.value,\n check: props.row.check,\n page: next,\n per_page: 50,\n })\n\n issues.value = next === 1 ? answer.data : [...(issues.value ?? []), ...answer.data]\n page.value = answer.current_page\n more.value = answer.current_page < answer.last_page\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nwatch(\n kind,\n () => {\n issues.value = null\n void load()\n },\n { immediate: true },\n)\n</script>\n\n<template>\n <div class=\"wx-audit-compare\">\n <wx-segmented v-model=\"kind\" :options=\"options\" size=\"sm\" :aria-label=\"t('page.compare')\" />\n\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!issues\" :rows=\"2\" />\n\n <template v-else>\n <div v-for=\"issue in issues\" :key=\"issue.id\" class=\"wx-audit-compare__item\">\n <wx-link v-if=\"issue.url\" :href=\"issue.url\" target=\"_blank\" class=\"wx-audit-compare__url\">{{\n issue.url\n }}</wx-link>\n <audit-details :details=\"issue.details\" />\n </div>\n\n <wx-button v-if=\"more\" size=\"sm\" variant=\"text\" @click=\"load(page + 1)\">…</wx-button>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-compare {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-compare__item {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n.wx-audit-compare__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useRoute } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxCard,\n WxTable,\n WxText,\n type BadgeType,\n type RowKey,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditCompareIssues from './AuditCompareIssues.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditComparison,\n AuditComparisonRow,\n AuditPage,\n AuditRun,\n AuditRunStatus,\n AuditSeverity,\n} from './types'\n\n/**\n * The history (§8 «Runs»): every run kept, newest first, with its health and counts. Ticking a\n * run compares it with the one it was analysed against; ticking two compares those two — by\n * fingerprint (decision 8): what is new in the later one, what both have, what is gone. `?to=`\n * opens on one run already ticked — the way the page card's recheck leads here.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nconst route = useRoute()\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst runs = ref<AuditPage<AuditRun> | null>(null)\nconst loading = ref(false)\nconst selected = ref<RowKey[]>([])\nconst comparison = ref<AuditComparison | null>(null)\nconst comparing = ref(false)\nconst expanded = ref<RowKey[]>([])\n\nconst statuses: Record<AuditRunStatus, BadgeType> = {\n queued: 'info',\n running: 'primary',\n done: 'success',\n failed: 'danger',\n cancelled: 'warning',\n}\n\nconst severities: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst columns = computed<TableColumn<AuditRun>[]>(() => [\n { key: 'id', label: t('page.run-id'), width: 90 },\n { key: 'created_at', label: t('page.started-at'), minWidth: 160 },\n { key: 'scope', label: t('page.scope'), width: 120 },\n { key: 'status', label: t('page.status'), width: 130 },\n { key: 'health', label: t('page.health'), width: 100, align: 'right' },\n { key: 'severity', label: t('page.severity'), minWidth: 170, hideBelow: 640 },\n { key: 'started_by', label: t('page.started-by'), minWidth: 130, hideBelow: 760 },\n])\n\nconst compareColumns = computed<TableColumn<AuditComparisonRow>[]>(() => [\n { key: 'severity', label: t('page.severity'), width: 130 },\n { key: 'title', label: t('page.check') },\n { key: 'new', label: t('page.kind-new'), width: 90, align: 'right' },\n { key: 'fixed', label: t('page.kind-fixed'), width: 100, align: 'right' },\n { key: 'persisting', label: t('page.kind-persisting'), width: 120, align: 'right' },\n])\n\n/* What the selection means: one run against its own previous, or two against each other. */\nconst pair = computed<{ to: number; from: number | null } | null>(() => {\n const ids = selected.value.map(Number).sort((a, b) => a - b)\n\n if (ids.length === 0) return null\n\n return ids.length === 1\n ? { to: ids[0]!, from: null }\n : { to: ids[ids.length - 1]!, from: ids[0]! }\n})\n\nconst scopesDiffer = computed(\n () => comparison.value !== null && comparison.value.from.scope !== comparison.value.to.scope,\n)\n\nfunction who(run: AuditRun): string {\n if (run.started_by === 'schedule') return t('page.by-schedule')\n if (run.started_by === 'mcp') return t('page.by-mcp')\n if (run.started_by === 'console') return t('page.by-console')\n\n return run.started_by ? t('page.by-person') : ''\n}\n\nasync function load(state?: TableState): Promise<void> {\n loading.value = true\n\n try {\n runs.value = await api.runs({ page: state?.page ?? 1, per_page: state?.perPage ?? 20 })\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nasync function compare(): Promise<void> {\n const current = pair.value\n\n comparison.value = null\n expanded.value = []\n\n if (!current) return\n\n comparing.value = true\n\n try {\n comparison.value = await api.compare(current.to, current.from)\n } catch (error) {\n toast.danger(message(error))\n } finally {\n comparing.value = false\n }\n}\n\nonMounted(() => {\n const to = Number(route.query.to)\n\n if (Number.isInteger(to) && to > 0) selected.value = [to]\n})\n\nwatch(selected, (keys) => {\n /* Two at most: a third tick replaces the oldest one. */\n if (keys.length > 2) selected.value = keys.slice(-2)\n else void compare()\n})\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"runs\" :card=\"false\">\n <div class=\"wx-audit-runs\">\n <wx-card>\n <wx-table\n v-model:selected=\"selected\"\n :data=\"runs\"\n :columns=\"columns\"\n row-key=\"id\"\n selectable\n :selectable-if=\"(row: AuditRun) => row.status === 'done'\"\n flush\n :loading=\"loading\"\n :empty-text=\"t('page.runs-empty')\"\n @state-change=\"load\"\n >\n <template #cell-created_at=\"{ row }\"><wx-date :value=\"row.created_at\" /></template>\n <template #cell-scope=\"{ row }\">{{ t(`page.scope-${row.scope}`) }}</template>\n <template #cell-status=\"{ row }\">\n <wx-badge :type=\"statuses[row.status]\" dot>{{\n t(`page.status-${row.status}`)\n }}</wx-badge>\n </template>\n <template #cell-health=\"{ row }\">{{\n row.counts ? `${row.counts.health}%` : ''\n }}</template>\n <template #cell-severity=\"{ row }\">\n <span v-if=\"row.counts\" class=\"wx-audit-runs__counts\">\n <template v-for=\"(type, key) in severities\" :key=\"key\">\n <wx-badge v-if=\"row.counts.severity[key]\" :type=\"type\" size=\"sm\">{{\n row.counts.severity[key]\n }}</wx-badge>\n </template>\n </span>\n </template>\n <template #cell-started_by=\"{ row }\">{{ who(row) }}</template>\n </wx-table>\n </wx-card>\n\n <wx-text v-if=\"!pair\" size=\"sm\" tone=\"muted\">{{ t('page.compare-help') }}</wx-text>\n\n <wx-card v-else :title=\"t('page.compare')\">\n <wx-text v-if=\"comparison\" size=\"sm\" tone=\"muted\" class=\"wx-audit-runs__pair\">\n {{ t('page.compare-from') }} #{{ comparison.from.id }} ·\n <wx-date :value=\"comparison.from.created_at\" /> → {{ t('page.compare-to') }} #{{\n comparison.to.id\n }}\n · <wx-date :value=\"comparison.to.created_at\" />\n </wx-text>\n\n <wx-alert\n v-if=\"scopesDiffer\"\n type=\"info\"\n :description=\"t('page.compare-scopes')\"\n class=\"wx-audit-runs__note\"\n />\n\n <wx-table\n v-model:expanded=\"expanded\"\n :data=\"comparison?.checks ?? []\"\n :columns=\"compareColumns\"\n row-key=\"check\"\n expandable\n flush\n :pagination=\"false\"\n :loading=\"comparing\"\n :empty-text=\"t('page.compare-none')\"\n >\n <template #cell-severity=\"{ row }\">\n <wx-badge :type=\"severities[row.severity]\" dot>{{\n t(`page.severity-${row.severity}`)\n }}</wx-badge>\n </template>\n <template #cell-new=\"{ row }\">\n <wx-text :tone=\"row.new ? 'danger' : 'muted'\" size=\"sm\">{{ row.new }}</wx-text>\n </template>\n <template #cell-fixed=\"{ row }\">\n <wx-text :tone=\"row.fixed ? 'success' : 'muted'\" size=\"sm\">{{ row.fixed }}</wx-text>\n </template>\n <template #expanded=\"{ row }\">\n <audit-compare-issues\n v-if=\"comparison\"\n :from=\"comparison.from.id\"\n :to=\"comparison.to.id\"\n :row=\"row\"\n />\n </template>\n </wx-table>\n </wx-card>\n </div>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-runs {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-runs__counts {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n}\n\n.wx-audit-runs__pair {\n display: block;\n margin-bottom: var(--wx-space-12);\n}\n\n.wx-audit-runs__note {\n margin-bottom: var(--wx-space-12);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate, WxScreen } from '@webx-ui/module-admin'\nimport { toast, WxActionBar, WxButton, WxSkeleton } from '@webx-ui/core'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The section's settings (§8): where the site is and which hosts are its stands, the limits of\n * the crawl and the paths it leaves out, the thresholds, the nightly run and how much history\n * to keep. The form is the screen the server describes (`audit.settings`), so a project patches\n * a field in the way it does everywhere else; saving is this page's own. «Back» beside «Save» returns\n * to the overview — the tabs above cannot, their «Overview» is already the lit one.\n */\nconst props = defineProps<{ base: string }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst router = useRouter()\nconst message = useErrorText()\n\nconst values = ref<ScreenModel>({})\nconst errors = ref<Record<string, string[]>>({})\nconst loading = ref(true)\nconst saving = ref(false)\n\n// A boolean, not a computed: the permissions do not change while the screen is open.\nconst canManage = context.can('audit.manage')\n\nonMounted(async () => {\n try {\n values.value = (await api.settings()) as ScreenModel\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n})\n\nasync function save(): Promise<void> {\n saving.value = true\n errors.value = {}\n\n try {\n values.value = (await api.saveSettings(values.value)) as ScreenModel\n toast.success(t('page.saved'))\n } catch (error) {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n if (body?.errors) errors.value = body.errors\n\n toast.danger(message(error))\n } finally {\n saving.value = false\n }\n}\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"settings\" :card=\"false\">\n <div class=\"wx-audit-settings\">\n <wx-skeleton v-if=\"loading\" :rows=\"6\" />\n <wx-screen\n v-else\n v-model=\"values\"\n name=\"audit.settings\"\n :errors=\"errors\"\n :disabled=\"!canManage\"\n />\n\n <wx-action-bar v-if=\"!loading\">\n <wx-button icon=\"arrow-left\" @click=\"router.push(props.base)\">{{\n panel('editor.back')\n }}</wx-button>\n <wx-button v-if=\"canManage\" type=\"primary\" :loading=\"saving\" @click=\"save\">{{\n t('page.save')\n }}</wx-button>\n </wx-action-bar>\n </div>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-settings {\n display: flex;\n flex-direction: column;\n gap: var(--wx-gap, var(--wx-space-16));\n}\n</style>\n","import type { AdminModule } from '@webx-ui/module-admin'\nimport AuditHostsPage from './AuditHostsPage.vue'\nimport AuditIssuesPage from './AuditIssuesPage.vue'\nimport AuditOverviewPage from './AuditOverviewPage.vue'\nimport AuditPagesPage from './AuditPagesPage.vue'\nimport AuditRunsPage from './AuditRunsPage.vue'\nimport AuditSettingsPage from './AuditSettingsPage.vue'\n\nexport interface AuditOptions {\n /** Where the section lives inside the panel. */\n path?: string\n /**\n * @deprecated The audit's settings are a view of the section itself (`<path>/settings`); the\n * option is read by nothing and stays only so that a panel which passed it still compiles.\n */\n settingsPath?: string\n}\n\n/**\n * «System → Audit» as a section of the panel: the overview of the last run, its findings, the\n * pages the last full run crawled, the hosts the site points at, the history of runs with two of\n * them compared, and the section's settings.\n *\n * The id matches the module the server reports, which is what makes the entry appear in the\n * navigation: the section shows up when both halves are installed.\n */\nexport function audit(options: AuditOptions = {}): AdminModule {\n const path = options.path ?? '/audit'\n const props = { base: path }\n\n return {\n id: 'audit',\n path,\n routes: [\n { path, name: 'webx.audit', component: AuditOverviewPage, props },\n { path: `${path}/issues`, name: 'webx.audit.issues', component: AuditIssuesPage, props },\n { path: `${path}/pages`, name: 'webx.audit.pages', component: AuditPagesPage, props },\n { path: `${path}/hosts`, name: 'webx.audit.hosts', component: AuditHostsPage, props },\n { path: `${path}/runs`, name: 'webx.audit.runs', component: AuditRunsPage, props },\n {\n path: `${path}/settings`,\n name: 'webx.audit.settings',\n component: AuditSettingsPage,\n props,\n },\n ],\n }\n}\n"],"names":["differences","from","to","source","target","found","bare","host","trimmed","path","TAIL","splitMiddle","text","statusType","value","code","EXPLAINED","statusKey","props","__props","parts","computed","_createBlock","_unref","WxTooltip","_createElementVNode","_hoisted_3","_toDisplayString","_createVNode","WxLink","_hoisted_1","_createElementBlock","_hoisted_2","auditMessages","seeded","useAuditMessages","i18n","useAdmin","t","useTranslate","rels","opener","rel","_openBlock","WxBadge","_createTextVNode","_Fragment","_renderList","pageParams","query","params","filter","createAuditApi","admin","base","data","body","filters","id","scope","urls","run","columns","key","issue","fix","dryRun","rule","values","label","FEW","api","message","useErrorText","router","useRouter","places","ref","failure","broken","status","open","keyOf","shown","toggle","next","onMounted","error","WxText","AuditAddress","AuditLinkAttrs","AuditStatus","_hoisted_4","place","index","WxButton","$event","_hoisted_5","_hoisted_6","field","_hoisted_7","WxSkeleton","context","route","useRoute","title","module","views","actions","where","WxListScreen","_renderSlot","_ctx","panel","answer","loading","search","hostClass","expanded","classes","classOptions","pick","load","toast","watch","AuditLayout","WxTable","row","WxSelect","_cache","_withCtx","WxDate","AuditHostPlaces","redirects","column","isSource","isTarget","cell","yesNo","changes","_normalizeClass","WxIcon","change","emit","__emit","_useModel","offers","applying","apply","offer","edit","url","now","WxDialog","pattern","reason","count","saving","timer","pathOf","parsed","ready","preview","hide","WxFormItem","WxInput","WxTextarea","groups","location","group","attr","first","one","a","b","can","issues","more","page","fixing","dialog","hiding","hideDialog","view","everything","byLink","loadEverything","all","last","switchView","hidden","unhide","why","fixed","WxSegmented","AuditLinkGroups","AuditDetails","AuditFixDialog","AuditHideDialog","checks","severity","state","filtersCount","types","severityOptions","groupOptions","stateOptions","WxPopover","AuditIssueList","POLL_MS","latest","starting","canRun","active","done","counts","scopes","severities","healthStatus","health","GROUPS","bySeverity","stageLabel","start","cancel","onBeforeUnmount","WxAlert","WxCard","WxProgress","WxEmpty","WxStatistic","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","outlineRows","outline","out","previous","level","gap","outlineHints","ones","jumps","empty","rows","hints","total","sum","hint","step","viewable","recheck","rechecking","startRecheck","card","follow","compareRecheck","tab","links","linksLoading","resources","resourcesLoading","resourceTabs","tabs","kept","resourceTab","hostTypes","linkColumns","resourceColumns","pretty","size","kb","bytes","tiles","tile","sections","alternate","block","section","loadLinks","loadResources","current","WxDrawer","WxTabs","_hoisted_14","_hoisted_15","tag","_hoisted_16","_hoisted_17","_hoisted_18","name","_hoisted_19","_hoisted_20","_hoisted_21","AuditHeadings","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","WxImage","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","type","item","position","_hoisted_30","_hoisted_31","PAGE_FIELDS","DEFAULT_COLUMNS","COMPUTED_FIELDS","OPERATIONS","WITH_VALUE","SOURCES","STORAGE","dates","useDates","opened","titles","indexable","check","visible","restore","saved","known","keys","fields","columnOptions","filterFields","statusOptions","indexableOptions","checkOptions","complete","operations","op","addFilter","setField","at","setOp","setValue","removeFilter","_","setColumns","download","WxCheckboxGroup","AuditPageCard","KINDS","kind","options","runs","selected","comparison","comparing","statuses","compareColumns","pair","ids","scopesDiffer","who","compare","AuditCompareIssues","errors","canManage","save","WxScreen","WxActionBar","audit","AuditOverviewPage","AuditIssuesPage","AuditPagesPage","AuditHostsPage","AuditRunsPage","AuditSettingsPage"],"mappings":"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"}