@aglyn/aglyn 1.0.0-beta.143
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/LICENSE +201 -0
- package/README.md +11 -0
- package/package.json +66 -0
- package/src/index.d.ts +25 -0
- package/src/index.js +26 -0
- package/src/index.js.map +1 -0
- package/src/lib/aglyn.d.ts +31 -0
- package/src/lib/aglyn.js +114 -0
- package/src/lib/aglyn.js.map +1 -0
- package/src/lib/app-utils/abuse-report.d.ts +193 -0
- package/src/lib/app-utils/abuse-report.js +321 -0
- package/src/lib/app-utils/abuse-report.js.map +1 -0
- package/src/lib/app-utils/accept-negotiation.d.ts +129 -0
- package/src/lib/app-utils/accept-negotiation.js +266 -0
- package/src/lib/app-utils/accept-negotiation.js.map +1 -0
- package/src/lib/app-utils/account-emails.d.ts +263 -0
- package/src/lib/app-utils/account-emails.js +264 -0
- package/src/lib/app-utils/account-emails.js.map +1 -0
- package/src/lib/app-utils/actions.d.ts +717 -0
- package/src/lib/app-utils/actions.js +1031 -0
- package/src/lib/app-utils/actions.js.map +1 -0
- package/src/lib/app-utils/activity-presenter.d.ts +152 -0
- package/src/lib/app-utils/activity-presenter.js +326 -0
- package/src/lib/app-utils/activity-presenter.js.map +1 -0
- package/src/lib/app-utils/advertising-tag-mounts.d.ts +133 -0
- package/src/lib/app-utils/advertising-tag-mounts.js +118 -0
- package/src/lib/app-utils/advertising-tag-mounts.js.map +1 -0
- package/src/lib/app-utils/advertising-tags.d.ts +307 -0
- package/src/lib/app-utils/advertising-tags.js +525 -0
- package/src/lib/app-utils/advertising-tags.js.map +1 -0
- package/src/lib/app-utils/agent-api-catalog.d.ts +94 -0
- package/src/lib/app-utils/agent-api-catalog.js +106 -0
- package/src/lib/app-utils/agent-api-catalog.js.map +1 -0
- package/src/lib/app-utils/agent-openapi.d.ts +103 -0
- package/src/lib/app-utils/agent-openapi.js +1128 -0
- package/src/lib/app-utils/agent-openapi.js.map +1 -0
- package/src/lib/app-utils/analytics-beacon.d.ts +154 -0
- package/src/lib/app-utils/analytics-beacon.js +152 -0
- package/src/lib/app-utils/analytics-beacon.js.map +1 -0
- package/src/lib/app-utils/analytics-environment.d.ts +133 -0
- package/src/lib/app-utils/analytics-environment.js +152 -0
- package/src/lib/app-utils/analytics-environment.js.map +1 -0
- package/src/lib/app-utils/analytics-events.d.ts +744 -0
- package/src/lib/app-utils/analytics-events.js +650 -0
- package/src/lib/app-utils/analytics-events.js.map +1 -0
- package/src/lib/app-utils/analytics-link-clicks.d.ts +102 -0
- package/src/lib/app-utils/analytics-link-clicks.js +267 -0
- package/src/lib/app-utils/analytics-link-clicks.js.map +1 -0
- package/src/lib/app-utils/analytics-path-key.d.ts +46 -0
- package/src/lib/app-utils/analytics-path-key.js +46 -0
- package/src/lib/app-utils/analytics-path-key.js.map +1 -0
- package/src/lib/app-utils/api-adapter.d.ts +47 -0
- package/src/lib/app-utils/api-adapter.js +367 -0
- package/src/lib/app-utils/api-adapter.js.map +1 -0
- package/src/lib/app-utils/api-idempotency.d.ts +169 -0
- package/src/lib/app-utils/api-idempotency.js +213 -0
- package/src/lib/app-utils/api-idempotency.js.map +1 -0
- package/src/lib/app-utils/api-plugins.d.ts +210 -0
- package/src/lib/app-utils/api-plugins.js +221 -0
- package/src/lib/app-utils/api-plugins.js.map +1 -0
- package/src/lib/app-utils/assist-credits.d.ts +482 -0
- package/src/lib/app-utils/assist-credits.js +509 -0
- package/src/lib/app-utils/assist-credits.js.map +1 -0
- package/src/lib/app-utils/attribution-attribute.d.ts +34 -0
- package/src/lib/app-utils/attribution-attribute.js +34 -0
- package/src/lib/app-utils/attribution-attribute.js.map +1 -0
- package/src/lib/app-utils/attribution-guard.d.ts +130 -0
- package/src/lib/app-utils/attribution-guard.js +410 -0
- package/src/lib/app-utils/attribution-guard.js.map +1 -0
- package/src/lib/app-utils/author-css.d.ts +123 -0
- package/src/lib/app-utils/author-css.js +275 -0
- package/src/lib/app-utils/author-css.js.map +1 -0
- package/src/lib/app-utils/author-html-markdown.d.ts +31 -0
- package/src/lib/app-utils/author-html-markdown.js +497 -0
- package/src/lib/app-utils/author-html-markdown.js.map +1 -0
- package/src/lib/app-utils/author-html.d.ts +135 -0
- package/src/lib/app-utils/author-html.js +1037 -0
- package/src/lib/app-utils/author-html.js.map +1 -0
- package/src/lib/app-utils/automation-placeholders.d.ts +72 -0
- package/src/lib/app-utils/automation-placeholders.js +207 -0
- package/src/lib/app-utils/automation-placeholders.js.map +1 -0
- package/src/lib/app-utils/bandwidth-cap.d.ts +183 -0
- package/src/lib/app-utils/bandwidth-cap.js +193 -0
- package/src/lib/app-utils/bandwidth-cap.js.map +1 -0
- package/src/lib/app-utils/binding-token-catalog.d.ts +82 -0
- package/src/lib/app-utils/binding-token-catalog.js +293 -0
- package/src/lib/app-utils/binding-token-catalog.js.map +1 -0
- package/src/lib/app-utils/binding-tokens.d.ts +157 -0
- package/src/lib/app-utils/binding-tokens.js +251 -0
- package/src/lib/app-utils/binding-tokens.js.map +1 -0
- package/src/lib/app-utils/breadcrumb-json-ld.d.ts +57 -0
- package/src/lib/app-utils/breadcrumb-json-ld.js +67 -0
- package/src/lib/app-utils/breadcrumb-json-ld.js.map +1 -0
- package/src/lib/app-utils/campaign-attribution.d.ts +117 -0
- package/src/lib/app-utils/campaign-attribution.js +162 -0
- package/src/lib/app-utils/campaign-attribution.js.map +1 -0
- package/src/lib/app-utils/campaign-forwarding.d.ts +220 -0
- package/src/lib/app-utils/campaign-forwarding.js +332 -0
- package/src/lib/app-utils/campaign-forwarding.js.map +1 -0
- package/src/lib/app-utils/campaign-membership.d.ts +109 -0
- package/src/lib/app-utils/campaign-membership.js +176 -0
- package/src/lib/app-utils/campaign-membership.js.map +1 -0
- package/src/lib/app-utils/campaign-touch.d.ts +206 -0
- package/src/lib/app-utils/campaign-touch.js +326 -0
- package/src/lib/app-utils/campaign-touch.js.map +1 -0
- package/src/lib/app-utils/child-contract-compose.d.ts +28 -0
- package/src/lib/app-utils/child-contract-compose.js +140 -0
- package/src/lib/app-utils/child-contract-compose.js.map +1 -0
- package/src/lib/app-utils/child-contract.d.ts +129 -0
- package/src/lib/app-utils/child-contract.js +153 -0
- package/src/lib/app-utils/child-contract.js.map +1 -0
- package/src/lib/app-utils/collection-delete.d.ts +113 -0
- package/src/lib/app-utils/collection-delete.js +120 -0
- package/src/lib/app-utils/collection-delete.js.map +1 -0
- package/src/lib/app-utils/collection-entries.d.ts +833 -0
- package/src/lib/app-utils/collection-entries.js +1285 -0
- package/src/lib/app-utils/collection-entries.js.map +1 -0
- package/src/lib/app-utils/collection-entry-date.d.ts +129 -0
- package/src/lib/app-utils/collection-entry-date.js +183 -0
- package/src/lib/app-utils/collection-entry-date.js.map +1 -0
- package/src/lib/app-utils/collection-kind.d.ts +55 -0
- package/src/lib/app-utils/collection-kind.js +69 -0
- package/src/lib/app-utils/collection-kind.js.map +1 -0
- package/src/lib/app-utils/collection-slug.d.ts +79 -0
- package/src/lib/app-utils/collection-slug.js +70 -0
- package/src/lib/app-utils/collection-slug.js.map +1 -0
- package/src/lib/app-utils/compose-layout-nodes.d.ts +147 -0
- package/src/lib/app-utils/compose-layout-nodes.js +261 -0
- package/src/lib/app-utils/compose-layout-nodes.js.map +1 -0
- package/src/lib/app-utils/compose-layout-props.d.ts +71 -0
- package/src/lib/app-utils/compose-layout-props.js +61 -0
- package/src/lib/app-utils/compose-layout-props.js.map +1 -0
- package/src/lib/app-utils/compose-reusable-components.d.ts +504 -0
- package/src/lib/app-utils/compose-reusable-components.js +1366 -0
- package/src/lib/app-utils/compose-reusable-components.js.map +1 -0
- package/src/lib/app-utils/compress.d.ts +35 -0
- package/src/lib/app-utils/compress.js +38 -0
- package/src/lib/app-utils/compress.js.map +1 -0
- package/src/lib/app-utils/consent-banner-ui.d.ts +226 -0
- package/src/lib/app-utils/consent-banner-ui.js +583 -0
- package/src/lib/app-utils/consent-banner-ui.js.map +1 -0
- package/src/lib/app-utils/consent-groups.d.ts +189 -0
- package/src/lib/app-utils/consent-groups.js +219 -0
- package/src/lib/app-utils/consent-groups.js.map +1 -0
- package/src/lib/app-utils/consent-preferences-dialog.d.ts +58 -0
- package/src/lib/app-utils/consent-preferences-dialog.js +106 -0
- package/src/lib/app-utils/consent-preferences-dialog.js.map +1 -0
- package/src/lib/app-utils/console-record-links.d.ts +163 -0
- package/src/lib/app-utils/console-record-links.js +178 -0
- package/src/lib/app-utils/console-record-links.js.map +1 -0
- package/src/lib/app-utils/console-routes.d.ts +658 -0
- package/src/lib/app-utils/console-routes.js +489 -0
- package/src/lib/app-utils/console-routes.js.map +1 -0
- package/src/lib/app-utils/console-widget-slot-context.d.ts +46 -0
- package/src/lib/app-utils/console-widget-slot-context.js +23 -0
- package/src/lib/app-utils/console-widget-slot-context.js.map +1 -0
- package/src/lib/app-utils/contact-custom-fields.d.ts +191 -0
- package/src/lib/app-utils/contact-custom-fields.js +349 -0
- package/src/lib/app-utils/contact-custom-fields.js.map +1 -0
- package/src/lib/app-utils/contact-holder.d.ts +52 -0
- package/src/lib/app-utils/contact-holder.js +98 -0
- package/src/lib/app-utils/contact-holder.js.map +1 -0
- package/src/lib/app-utils/contact-merge.d.ts +136 -0
- package/src/lib/app-utils/contact-merge.js +379 -0
- package/src/lib/app-utils/contact-merge.js.map +1 -0
- package/src/lib/app-utils/contacts.d.ts +554 -0
- package/src/lib/app-utils/contacts.js +401 -0
- package/src/lib/app-utils/contacts.js.map +1 -0
- package/src/lib/app-utils/content-author-profile.d.ts +68 -0
- package/src/lib/app-utils/content-author-profile.js +118 -0
- package/src/lib/app-utils/content-author-profile.js.map +1 -0
- package/src/lib/app-utils/content-authors.d.ts +662 -0
- package/src/lib/app-utils/content-authors.js +771 -0
- package/src/lib/app-utils/content-authors.js.map +1 -0
- package/src/lib/app-utils/content-schema-type.d.ts +81 -0
- package/src/lib/app-utils/content-schema-type.js +87 -0
- package/src/lib/app-utils/content-schema-type.js.map +1 -0
- package/src/lib/app-utils/contexts.d.ts +35 -0
- package/src/lib/app-utils/contexts.js +35 -0
- package/src/lib/app-utils/contexts.js.map +1 -0
- package/src/lib/app-utils/create-resource-uid.d.ts +18 -0
- package/src/lib/app-utils/create-resource-uid.js +23 -0
- package/src/lib/app-utils/create-resource-uid.js.map +1 -0
- package/src/lib/app-utils/crm-booking.d.ts +75 -0
- package/src/lib/app-utils/crm-booking.js +133 -0
- package/src/lib/app-utils/crm-booking.js.map +1 -0
- package/src/lib/app-utils/crm-csv.d.ts +232 -0
- package/src/lib/app-utils/crm-csv.js +432 -0
- package/src/lib/app-utils/crm-csv.js.map +1 -0
- package/src/lib/app-utils/crm-digest.d.ts +179 -0
- package/src/lib/app-utils/crm-digest.js +271 -0
- package/src/lib/app-utils/crm-digest.js.map +1 -0
- package/src/lib/app-utils/crm-email-templates.d.ts +172 -0
- package/src/lib/app-utils/crm-email-templates.js +382 -0
- package/src/lib/app-utils/crm-email-templates.js.map +1 -0
- package/src/lib/app-utils/crm-inbound.d.ts +245 -0
- package/src/lib/app-utils/crm-inbound.js +407 -0
- package/src/lib/app-utils/crm-inbound.js.map +1 -0
- package/src/lib/app-utils/crm-kinds.d.ts +73 -0
- package/src/lib/app-utils/crm-kinds.js +92 -0
- package/src/lib/app-utils/crm-kinds.js.map +1 -0
- package/src/lib/app-utils/crm-next-activity.d.ts +107 -0
- package/src/lib/app-utils/crm-next-activity.js +140 -0
- package/src/lib/app-utils/crm-next-activity.js.map +1 -0
- package/src/lib/app-utils/crm-reports.d.ts +479 -0
- package/src/lib/app-utils/crm-reports.js +680 -0
- package/src/lib/app-utils/crm-reports.js.map +1 -0
- package/src/lib/app-utils/crm-task-reminders.d.ts +129 -0
- package/src/lib/app-utils/crm-task-reminders.js +139 -0
- package/src/lib/app-utils/crm-task-reminders.js.map +1 -0
- package/src/lib/app-utils/crm.d.ts +1546 -0
- package/src/lib/app-utils/crm.js +1814 -0
- package/src/lib/app-utils/crm.js.map +1 -0
- package/src/lib/app-utils/csp-report.d.ts +84 -0
- package/src/lib/app-utils/csp-report.js +177 -0
- package/src/lib/app-utils/csp-report.js.map +1 -0
- package/src/lib/app-utils/csv-import.d.ts +192 -0
- package/src/lib/app-utils/csv-import.js +279 -0
- package/src/lib/app-utils/csv-import.js.map +1 -0
- package/src/lib/app-utils/dataset-csv.d.ts +109 -0
- package/src/lib/app-utils/dataset-csv.js +235 -0
- package/src/lib/app-utils/dataset-csv.js.map +1 -0
- package/src/lib/app-utils/dataset-models.d.ts +194 -0
- package/src/lib/app-utils/dataset-models.js +409 -0
- package/src/lib/app-utils/dataset-models.js.map +1 -0
- package/src/lib/app-utils/dataset-query.d.ts +57 -0
- package/src/lib/app-utils/dataset-query.js +126 -0
- package/src/lib/app-utils/dataset-query.js.map +1 -0
- package/src/lib/app-utils/datasets.d.ts +136 -0
- package/src/lib/app-utils/datasets.js +177 -0
- package/src/lib/app-utils/datasets.js.map +1 -0
- package/src/lib/app-utils/decompress.d.ts +36 -0
- package/src/lib/app-utils/decompress.js +32 -0
- package/src/lib/app-utils/decompress.js.map +1 -0
- package/src/lib/app-utils/dedicated-sending-domain.d.ts +47 -0
- package/src/lib/app-utils/dedicated-sending-domain.js +114 -0
- package/src/lib/app-utils/dedicated-sending-domain.js.map +1 -0
- package/src/lib/app-utils/deferred-image.d.ts +86 -0
- package/src/lib/app-utils/deferred-image.js +83 -0
- package/src/lib/app-utils/deferred-image.js.map +1 -0
- package/src/lib/app-utils/definition-canvas-tree.d.ts +61 -0
- package/src/lib/app-utils/definition-canvas-tree.js +126 -0
- package/src/lib/app-utils/definition-canvas-tree.js.map +1 -0
- package/src/lib/app-utils/deployment-shape.d.ts +167 -0
- package/src/lib/app-utils/deployment-shape.js +238 -0
- package/src/lib/app-utils/deployment-shape.js.map +1 -0
- package/src/lib/app-utils/detect-template-placeholders.d.ts +30 -0
- package/src/lib/app-utils/detect-template-placeholders.js +53 -0
- package/src/lib/app-utils/detect-template-placeholders.js.map +1 -0
- package/src/lib/app-utils/dmca-counter-notice.d.ts +185 -0
- package/src/lib/app-utils/dmca-counter-notice.js +277 -0
- package/src/lib/app-utils/dmca-counter-notice.js.map +1 -0
- package/src/lib/app-utils/docs-deflection.d.ts +156 -0
- package/src/lib/app-utils/docs-deflection.js +547 -0
- package/src/lib/app-utils/docs-deflection.js.map +1 -0
- package/src/lib/app-utils/docs-help.d.ts +57 -0
- package/src/lib/app-utils/docs-help.generated.d.ts +303 -0
- package/src/lib/app-utils/docs-help.generated.js +867 -0
- package/src/lib/app-utils/docs-help.generated.js.map +1 -0
- package/src/lib/app-utils/docs-help.js +46 -0
- package/src/lib/app-utils/docs-help.js.map +1 -0
- package/src/lib/app-utils/docs-index.generated.d.ts +29 -0
- package/src/lib/app-utils/docs-index.generated.js +8388 -0
- package/src/lib/app-utils/docs-index.generated.js.map +1 -0
- package/src/lib/app-utils/docs-retrieval.d.ts +67 -0
- package/src/lib/app-utils/docs-retrieval.js +188 -0
- package/src/lib/app-utils/docs-retrieval.js.map +1 -0
- package/src/lib/app-utils/document-landmark.d.ts +50 -0
- package/src/lib/app-utils/document-landmark.js +100 -0
- package/src/lib/app-utils/document-landmark.js.map +1 -0
- package/src/lib/app-utils/duplicate-resource.d.ts +101 -0
- package/src/lib/app-utils/duplicate-resource.js +206 -0
- package/src/lib/app-utils/duplicate-resource.js.map +1 -0
- package/src/lib/app-utils/dynamic-list-rule.d.ts +471 -0
- package/src/lib/app-utils/dynamic-list-rule.js +914 -0
- package/src/lib/app-utils/dynamic-list-rule.js.map +1 -0
- package/src/lib/app-utils/element-animation.d.ts +200 -0
- package/src/lib/app-utils/element-animation.js +233 -0
- package/src/lib/app-utils/element-animation.js.map +1 -0
- package/src/lib/app-utils/element-hidden-style.d.ts +46 -0
- package/src/lib/app-utils/element-hidden-style.js +48 -0
- package/src/lib/app-utils/element-hidden-style.js.map +1 -0
- package/src/lib/app-utils/element-ui.d.ts +243 -0
- package/src/lib/app-utils/element-ui.js +459 -0
- package/src/lib/app-utils/element-ui.js.map +1 -0
- package/src/lib/app-utils/email-starter-policy.d.ts +160 -0
- package/src/lib/app-utils/email-starter-policy.js +327 -0
- package/src/lib/app-utils/email-starter-policy.js.map +1 -0
- package/src/lib/app-utils/email-topics.d.ts +310 -0
- package/src/lib/app-utils/email-topics.js +336 -0
- package/src/lib/app-utils/email-topics.js.map +1 -0
- package/src/lib/app-utils/enabled-plugins-context.d.ts +100 -0
- package/src/lib/app-utils/enabled-plugins-context.js +113 -0
- package/src/lib/app-utils/enabled-plugins-context.js.map +1 -0
- package/src/lib/app-utils/ensure-canvas-root.d.ts +38 -0
- package/src/lib/app-utils/ensure-canvas-root.js +61 -0
- package/src/lib/app-utils/ensure-canvas-root.js.map +1 -0
- package/src/lib/app-utils/entity-picker-context.d.ts +199 -0
- package/src/lib/app-utils/entity-picker-context.js +93 -0
- package/src/lib/app-utils/entity-picker-context.js.map +1 -0
- package/src/lib/app-utils/error-beacon.d.ts +107 -0
- package/src/lib/app-utils/error-beacon.js +296 -0
- package/src/lib/app-utils/error-beacon.js.map +1 -0
- package/src/lib/app-utils/expand-repeatables.d.ts +172 -0
- package/src/lib/app-utils/expand-repeatables.js +299 -0
- package/src/lib/app-utils/expand-repeatables.js.map +1 -0
- package/src/lib/app-utils/foreign-script.d.ts +82 -0
- package/src/lib/app-utils/foreign-script.js +102 -0
- package/src/lib/app-utils/foreign-script.js.map +1 -0
- package/src/lib/app-utils/form-abuse-ceiling.d.ts +146 -0
- package/src/lib/app-utils/form-abuse-ceiling.js +158 -0
- package/src/lib/app-utils/form-abuse-ceiling.js.map +1 -0
- package/src/lib/app-utils/form-contract.d.ts +198 -0
- package/src/lib/app-utils/form-contract.js +282 -0
- package/src/lib/app-utils/form-contract.js.map +1 -0
- package/src/lib/app-utils/form-dataset-binding.d.ts +50 -0
- package/src/lib/app-utils/form-dataset-binding.js +74 -0
- package/src/lib/app-utils/form-dataset-binding.js.map +1 -0
- package/src/lib/app-utils/forms.d.ts +727 -0
- package/src/lib/app-utils/forms.js +777 -0
- package/src/lib/app-utils/forms.js.map +1 -0
- package/src/lib/app-utils/functions.d.ts +188 -0
- package/src/lib/app-utils/functions.js +529 -0
- package/src/lib/app-utils/functions.js.map +1 -0
- package/src/lib/app-utils/guarded-version-save.d.ts +91 -0
- package/src/lib/app-utils/guarded-version-save.js +131 -0
- package/src/lib/app-utils/guarded-version-save.js.map +1 -0
- package/src/lib/app-utils/health-report.d.ts +1766 -0
- package/src/lib/app-utils/health-report.js +2072 -0
- package/src/lib/app-utils/health-report.js.map +1 -0
- package/src/lib/app-utils/host-naming.d.ts +135 -0
- package/src/lib/app-utils/host-naming.js +188 -0
- package/src/lib/app-utils/host-naming.js.map +1 -0
- package/src/lib/app-utils/host-permissions.d.ts +76 -0
- package/src/lib/app-utils/host-permissions.js +119 -0
- package/src/lib/app-utils/host-permissions.js.map +1 -0
- package/src/lib/app-utils/host-tokens.d.ts +228 -0
- package/src/lib/app-utils/host-tokens.js +304 -0
- package/src/lib/app-utils/host-tokens.js.map +1 -0
- package/src/lib/app-utils/idp-profile.d.ts +83 -0
- package/src/lib/app-utils/idp-profile.js +268 -0
- package/src/lib/app-utils/idp-profile.js.map +1 -0
- package/src/lib/app-utils/image-upload-types.d.ts +49 -0
- package/src/lib/app-utils/image-upload-types.js +86 -0
- package/src/lib/app-utils/image-upload-types.js.map +1 -0
- package/src/lib/app-utils/index.d.ts +18 -0
- package/src/lib/app-utils/index.js +23 -0
- package/src/lib/app-utils/index.js.map +1 -0
- package/src/lib/app-utils/internal-traffic.d.ts +197 -0
- package/src/lib/app-utils/internal-traffic.js +288 -0
- package/src/lib/app-utils/internal-traffic.js.map +1 -0
- package/src/lib/app-utils/lineal-order.d.ts +62 -0
- package/src/lib/app-utils/lineal-order.js +65 -0
- package/src/lib/app-utils/lineal-order.js.map +1 -0
- package/src/lib/app-utils/link-references.d.ts +36 -0
- package/src/lib/app-utils/link-references.js +89 -0
- package/src/lib/app-utils/link-references.js.map +1 -0
- package/src/lib/app-utils/link-target-search-context.d.ts +123 -0
- package/src/lib/app-utils/link-target-search-context.js +221 -0
- package/src/lib/app-utils/link-target-search-context.js.map +1 -0
- package/src/lib/app-utils/list-assignment-policy.d.ts +169 -0
- package/src/lib/app-utils/list-assignment-policy.js +170 -0
- package/src/lib/app-utils/list-assignment-policy.js.map +1 -0
- package/src/lib/app-utils/list-import.d.ts +158 -0
- package/src/lib/app-utils/list-import.js +332 -0
- package/src/lib/app-utils/list-import.js.map +1 -0
- package/src/lib/app-utils/llms-txt.d.ts +104 -0
- package/src/lib/app-utils/llms-txt.js +144 -0
- package/src/lib/app-utils/llms-txt.js.map +1 -0
- package/src/lib/app-utils/local-storage-budget.d.ts +75 -0
- package/src/lib/app-utils/local-storage-budget.js +153 -0
- package/src/lib/app-utils/local-storage-budget.js.map +1 -0
- package/src/lib/app-utils/lockdown.d.ts +698 -0
- package/src/lib/app-utils/lockdown.js +929 -0
- package/src/lib/app-utils/lockdown.js.map +1 -0
- package/src/lib/app-utils/margin-utilization.d.ts +267 -0
- package/src/lib/app-utils/margin-utilization.js +351 -0
- package/src/lib/app-utils/margin-utilization.js.map +1 -0
- package/src/lib/app-utils/markdown-lite.d.ts +297 -0
- package/src/lib/app-utils/markdown-lite.js +705 -0
- package/src/lib/app-utils/markdown-lite.js.map +1 -0
- package/src/lib/app-utils/marketing-consent.d.ts +704 -0
- package/src/lib/app-utils/marketing-consent.js +783 -0
- package/src/lib/app-utils/marketing-consent.js.map +1 -0
- package/src/lib/app-utils/marketplace-listing-visibility.d.ts +120 -0
- package/src/lib/app-utils/marketplace-listing-visibility.js +139 -0
- package/src/lib/app-utils/marketplace-listing-visibility.js.map +1 -0
- package/src/lib/app-utils/marketplace-overrides.d.ts +271 -0
- package/src/lib/app-utils/marketplace-overrides.js +462 -0
- package/src/lib/app-utils/marketplace-overrides.js.map +1 -0
- package/src/lib/app-utils/marketplace-provenance.d.ts +150 -0
- package/src/lib/app-utils/marketplace-provenance.js +136 -0
- package/src/lib/app-utils/marketplace-provenance.js.map +1 -0
- package/src/lib/app-utils/marketplace-theme.d.ts +237 -0
- package/src/lib/app-utils/marketplace-theme.js +525 -0
- package/src/lib/app-utils/marketplace-theme.js.map +1 -0
- package/src/lib/app-utils/marketplace-update-state.d.ts +119 -0
- package/src/lib/app-utils/marketplace-update-state.js +132 -0
- package/src/lib/app-utils/marketplace-update-state.js.map +1 -0
- package/src/lib/app-utils/marketplace-verification.d.ts +95 -0
- package/src/lib/app-utils/marketplace-verification.js +81 -0
- package/src/lib/app-utils/marketplace-verification.js.map +1 -0
- package/src/lib/app-utils/measure-node-map.d.ts +76 -0
- package/src/lib/app-utils/measure-node-map.js +111 -0
- package/src/lib/app-utils/measure-node-map.js.map +1 -0
- package/src/lib/app-utils/media-alt.d.ts +55 -0
- package/src/lib/app-utils/media-alt.js +58 -0
- package/src/lib/app-utils/media-alt.js.map +1 -0
- package/src/lib/app-utils/media-asset-facts.d.ts +125 -0
- package/src/lib/app-utils/media-asset-facts.js +467 -0
- package/src/lib/app-utils/media-asset-facts.js.map +1 -0
- package/src/lib/app-utils/media-cdn-scope.d.ts +65 -0
- package/src/lib/app-utils/media-cdn-scope.js +75 -0
- package/src/lib/app-utils/media-cdn-scope.js.map +1 -0
- package/src/lib/app-utils/media-folders.d.ts +161 -0
- package/src/lib/app-utils/media-folders.js +230 -0
- package/src/lib/app-utils/media-folders.js.map +1 -0
- package/src/lib/app-utils/media-metadata.d.ts +277 -0
- package/src/lib/app-utils/media-metadata.js +388 -0
- package/src/lib/app-utils/media-metadata.js.map +1 -0
- package/src/lib/app-utils/media-picker-context.d.ts +93 -0
- package/src/lib/app-utils/media-picker-context.js +26 -0
- package/src/lib/app-utils/media-picker-context.js.map +1 -0
- package/src/lib/app-utils/media-quarantine.d.ts +247 -0
- package/src/lib/app-utils/media-quarantine.js +323 -0
- package/src/lib/app-utils/media-quarantine.js.map +1 -0
- package/src/lib/app-utils/media-ref.d.ts +661 -0
- package/src/lib/app-utils/media-ref.js +1055 -0
- package/src/lib/app-utils/media-ref.js.map +1 -0
- package/src/lib/app-utils/media-takedown-reach.d.ts +126 -0
- package/src/lib/app-utils/media-takedown-reach.js +143 -0
- package/src/lib/app-utils/media-takedown-reach.js.map +1 -0
- package/src/lib/app-utils/member-email-aliases.d.ts +180 -0
- package/src/lib/app-utils/member-email-aliases.js +217 -0
- package/src/lib/app-utils/member-email-aliases.js.map +1 -0
- package/src/lib/app-utils/merge-node-sx.d.ts +47 -0
- package/src/lib/app-utils/merge-node-sx.js +123 -0
- package/src/lib/app-utils/merge-node-sx.js.map +1 -0
- package/src/lib/app-utils/name-match.d.ts +155 -0
- package/src/lib/app-utils/name-match.js +175 -0
- package/src/lib/app-utils/name-match.js.map +1 -0
- package/src/lib/app-utils/name-search.d.ts +117 -0
- package/src/lib/app-utils/name-search.js +145 -0
- package/src/lib/app-utils/name-search.js.map +1 -0
- package/src/lib/app-utils/node-capabilities.d.ts +85 -0
- package/src/lib/app-utils/node-capabilities.js +88 -0
- package/src/lib/app-utils/node-capabilities.js.map +1 -0
- package/src/lib/app-utils/node-definition-sanitizer.d.ts +164 -0
- package/src/lib/app-utils/node-definition-sanitizer.js +402 -0
- package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -0
- package/src/lib/app-utils/node-identity.d.ts +47 -0
- package/src/lib/app-utils/node-identity.js +50 -0
- package/src/lib/app-utils/node-identity.js.map +1 -0
- package/src/lib/app-utils/node-interactions.d.ts +102 -0
- package/src/lib/app-utils/node-interactions.js +192 -0
- package/src/lib/app-utils/node-interactions.js.map +1 -0
- package/src/lib/app-utils/node-url-policy.d.ts +54 -0
- package/src/lib/app-utils/node-url-policy.js +72 -0
- package/src/lib/app-utils/node-url-policy.js.map +1 -0
- package/src/lib/app-utils/notifications.d.ts +71 -0
- package/src/lib/app-utils/notifications.js +101 -0
- package/src/lib/app-utils/notifications.js.map +1 -0
- package/src/lib/app-utils/onboarding-deep-link.d.ts +120 -0
- package/src/lib/app-utils/onboarding-deep-link.js +142 -0
- package/src/lib/app-utils/onboarding-deep-link.js.map +1 -0
- package/src/lib/app-utils/operator-identity.d.ts +207 -0
- package/src/lib/app-utils/operator-identity.js +186 -0
- package/src/lib/app-utils/operator-identity.js.map +1 -0
- package/src/lib/app-utils/org-billing-doc.d.ts +231 -0
- package/src/lib/app-utils/org-billing-doc.js +238 -0
- package/src/lib/app-utils/org-billing-doc.js.map +1 -0
- package/src/lib/app-utils/org-override-reason.d.ts +100 -0
- package/src/lib/app-utils/org-override-reason.js +116 -0
- package/src/lib/app-utils/org-override-reason.js.map +1 -0
- package/src/lib/app-utils/org-permissions.d.ts +194 -0
- package/src/lib/app-utils/org-permissions.js +357 -0
- package/src/lib/app-utils/org-permissions.js.map +1 -0
- package/src/lib/app-utils/org-roles.d.ts +72 -0
- package/src/lib/app-utils/org-roles.js +131 -0
- package/src/lib/app-utils/org-roles.js.map +1 -0
- package/src/lib/app-utils/organizations.d.ts +407 -0
- package/src/lib/app-utils/organizations.js +511 -0
- package/src/lib/app-utils/organizations.js.map +1 -0
- package/src/lib/app-utils/page-header-actions-context.d.ts +83 -0
- package/src/lib/app-utils/page-header-actions-context.js +58 -0
- package/src/lib/app-utils/page-header-actions-context.js.map +1 -0
- package/src/lib/app-utils/page-header-record-context.d.ts +80 -0
- package/src/lib/app-utils/page-header-record-context.js +64 -0
- package/src/lib/app-utils/page-header-record-context.js.map +1 -0
- package/src/lib/app-utils/page-markdown.d.ts +103 -0
- package/src/lib/app-utils/page-markdown.js +385 -0
- package/src/lib/app-utils/page-markdown.js.map +1 -0
- package/src/lib/app-utils/paid-media-source.d.ts +90 -0
- package/src/lib/app-utils/paid-media-source.js +184 -0
- package/src/lib/app-utils/paid-media-source.js.map +1 -0
- package/src/lib/app-utils/palette-sx.d.ts +34 -0
- package/src/lib/app-utils/palette-sx.js +150 -0
- package/src/lib/app-utils/palette-sx.js.map +1 -0
- package/src/lib/app-utils/password-policy.d.ts +47 -0
- package/src/lib/app-utils/password-policy.js +46 -0
- package/src/lib/app-utils/password-policy.js.map +1 -0
- package/src/lib/app-utils/payments-configured.d.ts +84 -0
- package/src/lib/app-utils/payments-configured.js +88 -0
- package/src/lib/app-utils/payments-configured.js.map +1 -0
- package/src/lib/app-utils/person-erasure.d.ts +126 -0
- package/src/lib/app-utils/person-erasure.js +121 -0
- package/src/lib/app-utils/person-erasure.js.map +1 -0
- package/src/lib/app-utils/person-key.d.ts +32 -0
- package/src/lib/app-utils/person-key.js +62 -0
- package/src/lib/app-utils/person-key.js.map +1 -0
- package/src/lib/app-utils/plan-entitlements.d.ts +2756 -0
- package/src/lib/app-utils/plan-entitlements.js +4085 -0
- package/src/lib/app-utils/plan-entitlements.js.map +1 -0
- package/src/lib/app-utils/platform-ad-conversions.d.ts +122 -0
- package/src/lib/app-utils/platform-ad-conversions.js +174 -0
- package/src/lib/app-utils/platform-ad-conversions.js.map +1 -0
- package/src/lib/app-utils/platform-advertising-tags.d.ts +139 -0
- package/src/lib/app-utils/platform-advertising-tags.js +203 -0
- package/src/lib/app-utils/platform-advertising-tags.js.map +1 -0
- package/src/lib/app-utils/platform-brand.d.ts +151 -0
- package/src/lib/app-utils/platform-brand.js +175 -0
- package/src/lib/app-utils/platform-brand.js.map +1 -0
- package/src/lib/app-utils/platform-consent-default.d.ts +142 -0
- package/src/lib/app-utils/platform-consent-default.js +295 -0
- package/src/lib/app-utils/platform-consent-default.js.map +1 -0
- package/src/lib/app-utils/platform-marketing-consent.d.ts +151 -0
- package/src/lib/app-utils/platform-marketing-consent.js +182 -0
- package/src/lib/app-utils/platform-marketing-consent.js.map +1 -0
- package/src/lib/app-utils/platform-marketing-host.d.ts +33 -0
- package/src/lib/app-utils/platform-marketing-host.js +97 -0
- package/src/lib/app-utils/platform-marketing-host.js.map +1 -0
- package/src/lib/app-utils/platform-visitor-consent.d.ts +252 -0
- package/src/lib/app-utils/platform-visitor-consent.js +533 -0
- package/src/lib/app-utils/platform-visitor-consent.js.map +1 -0
- package/src/lib/app-utils/plugin-api-cross-origin.d.ts +61 -0
- package/src/lib/app-utils/plugin-api-cross-origin.js +202 -0
- package/src/lib/app-utils/plugin-api-cross-origin.js.map +1 -0
- package/src/lib/app-utils/plugin-api-rate-limit.d.ts +192 -0
- package/src/lib/app-utils/plugin-api-rate-limit.js +270 -0
- package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -0
- package/src/lib/app-utils/plugin-artifact-path.d.ts +32 -0
- package/src/lib/app-utils/plugin-artifact-path.js +33 -0
- package/src/lib/app-utils/plugin-artifact-path.js.map +1 -0
- package/src/lib/app-utils/plugin-bundle-checks.d.ts +148 -0
- package/src/lib/app-utils/plugin-bundle-checks.js +989 -0
- package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -0
- package/src/lib/app-utils/plugin-manifest.d.ts +516 -0
- package/src/lib/app-utils/plugin-manifest.js +687 -0
- package/src/lib/app-utils/plugin-manifest.js.map +1 -0
- package/src/lib/app-utils/published-legal-pages.d.ts +71 -0
- package/src/lib/app-utils/published-legal-pages.js +90 -0
- package/src/lib/app-utils/published-legal-pages.js.map +1 -0
- package/src/lib/app-utils/publisher-agreement.d.ts +254 -0
- package/src/lib/app-utils/publisher-agreement.js +274 -0
- package/src/lib/app-utils/publisher-agreement.js.map +1 -0
- package/src/lib/app-utils/publisher-attestation.d.ts +99 -0
- package/src/lib/app-utils/publisher-attestation.js +158 -0
- package/src/lib/app-utils/publisher-attestation.js.map +1 -0
- package/src/lib/app-utils/recipient-email-render.d.ts +216 -0
- package/src/lib/app-utils/recipient-email-render.js +221 -0
- package/src/lib/app-utils/recipient-email-render.js.map +1 -0
- package/src/lib/app-utils/redispatch-caught-error.d.ts +38 -0
- package/src/lib/app-utils/redispatch-caught-error.js +46 -0
- package/src/lib/app-utils/redispatch-caught-error.js.map +1 -0
- package/src/lib/app-utils/registering-plugin.d.ts +19 -0
- package/src/lib/app-utils/registering-plugin.js +38 -0
- package/src/lib/app-utils/registering-plugin.js.map +1 -0
- package/src/lib/app-utils/release-flags.d.ts +283 -0
- package/src/lib/app-utils/release-flags.js +518 -0
- package/src/lib/app-utils/release-flags.js.map +1 -0
- package/src/lib/app-utils/repair-canvas-nodes.d.ts +130 -0
- package/src/lib/app-utils/repair-canvas-nodes.js +298 -0
- package/src/lib/app-utils/repair-canvas-nodes.js.map +1 -0
- package/src/lib/app-utils/repeat-infringer.d.ts +166 -0
- package/src/lib/app-utils/repeat-infringer.js +188 -0
- package/src/lib/app-utils/repeat-infringer.js.map +1 -0
- package/src/lib/app-utils/repeat-sources.d.ts +115 -0
- package/src/lib/app-utils/repeat-sources.js +86 -0
- package/src/lib/app-utils/repeat-sources.js.map +1 -0
- package/src/lib/app-utils/request-geo.d.ts +114 -0
- package/src/lib/app-utils/request-geo.js +247 -0
- package/src/lib/app-utils/request-geo.js.map +1 -0
- package/src/lib/app-utils/request-ip.d.ts +213 -0
- package/src/lib/app-utils/request-ip.js +344 -0
- package/src/lib/app-utils/request-ip.js.map +1 -0
- package/src/lib/app-utils/resolve-named-tokens.d.ts +26 -0
- package/src/lib/app-utils/resolve-named-tokens.js +59 -0
- package/src/lib/app-utils/resolve-named-tokens.js.map +1 -0
- package/src/lib/app-utils/responsive-typography-sx.d.ts +77 -0
- package/src/lib/app-utils/responsive-typography-sx.js +122 -0
- package/src/lib/app-utils/responsive-typography-sx.js.map +1 -0
- package/src/lib/app-utils/reusable-component-keys.d.ts +135 -0
- package/src/lib/app-utils/reusable-component-keys.js +140 -0
- package/src/lib/app-utils/reusable-component-keys.js.map +1 -0
- package/src/lib/app-utils/reusable-prop-values.d.ts +199 -0
- package/src/lib/app-utils/reusable-prop-values.js +494 -0
- package/src/lib/app-utils/reusable-prop-values.js.map +1 -0
- package/src/lib/app-utils/safe-json-ld.d.ts +29 -0
- package/src/lib/app-utils/safe-json-ld.js +37 -0
- package/src/lib/app-utils/safe-json-ld.js.map +1 -0
- package/src/lib/app-utils/sanitize-svg.d.ts +55 -0
- package/src/lib/app-utils/sanitize-svg.js +460 -0
- package/src/lib/app-utils/sanitize-svg.js.map +1 -0
- package/src/lib/app-utils/scheme-sx.d.ts +84 -0
- package/src/lib/app-utils/scheme-sx.js +148 -0
- package/src/lib/app-utils/scheme-sx.js.map +1 -0
- package/src/lib/app-utils/scope-tokens.d.ts +249 -0
- package/src/lib/app-utils/scope-tokens.js +331 -0
- package/src/lib/app-utils/scope-tokens.js.map +1 -0
- package/src/lib/app-utils/screen-link-context-value.d.ts +57 -0
- package/src/lib/app-utils/screen-link-context-value.js +43 -0
- package/src/lib/app-utils/screen-link-context-value.js.map +1 -0
- package/src/lib/app-utils/screen-link-context.d.ts +185 -0
- package/src/lib/app-utils/screen-link-context.js +304 -0
- package/src/lib/app-utils/screen-link-context.js.map +1 -0
- package/src/lib/app-utils/screen-link-value.d.ts +269 -0
- package/src/lib/app-utils/screen-link-value.js +384 -0
- package/src/lib/app-utils/screen-link-value.js.map +1 -0
- package/src/lib/app-utils/screen-route.d.ts +669 -0
- package/src/lib/app-utils/screen-route.js +751 -0
- package/src/lib/app-utils/screen-route.js.map +1 -0
- package/src/lib/app-utils/screen-seo-fields.d.ts +37 -0
- package/src/lib/app-utils/screen-seo-fields.js +42 -0
- package/src/lib/app-utils/screen-seo-fields.js.map +1 -0
- package/src/lib/app-utils/search-indexing.d.ts +162 -0
- package/src/lib/app-utils/search-indexing.js +207 -0
- package/src/lib/app-utils/search-indexing.js.map +1 -0
- package/src/lib/app-utils/seo-listing-fields.d.ts +70 -0
- package/src/lib/app-utils/seo-listing-fields.js +75 -0
- package/src/lib/app-utils/seo-listing-fields.js.map +1 -0
- package/src/lib/app-utils/seo-locale.d.ts +119 -0
- package/src/lib/app-utils/seo-locale.js +133 -0
- package/src/lib/app-utils/seo-locale.js.map +1 -0
- package/src/lib/app-utils/seo-title-variables.d.ts +149 -0
- package/src/lib/app-utils/seo-title-variables.js +190 -0
- package/src/lib/app-utils/seo-title-variables.js.map +1 -0
- package/src/lib/app-utils/seo-title.d.ts +70 -0
- package/src/lib/app-utils/seo-title.js +117 -0
- package/src/lib/app-utils/seo-title.js.map +1 -0
- package/src/lib/app-utils/server.d.ts +174 -0
- package/src/lib/app-utils/server.js +314 -0
- package/src/lib/app-utils/server.js.map +1 -0
- package/src/lib/app-utils/site-context.d.ts +106 -0
- package/src/lib/app-utils/site-context.js +100 -0
- package/src/lib/app-utils/site-context.js.map +1 -0
- package/src/lib/app-utils/sitemap.d.ts +117 -0
- package/src/lib/app-utils/sitemap.js +183 -0
- package/src/lib/app-utils/sitemap.js.map +1 -0
- package/src/lib/app-utils/social-image.d.ts +112 -0
- package/src/lib/app-utils/social-image.js +191 -0
- package/src/lib/app-utils/social-image.js.map +1 -0
- package/src/lib/app-utils/starter-templates.d.ts +99 -0
- package/src/lib/app-utils/starter-templates.js +579 -0
- package/src/lib/app-utils/starter-templates.js.map +1 -0
- package/src/lib/app-utils/stored-nodes.d.ts +120 -0
- package/src/lib/app-utils/stored-nodes.js +174 -0
- package/src/lib/app-utils/stored-nodes.js.map +1 -0
- package/src/lib/app-utils/strip-undefined.d.ts +59 -0
- package/src/lib/app-utils/strip-undefined.js +95 -0
- package/src/lib/app-utils/strip-undefined.js.map +1 -0
- package/src/lib/app-utils/stripe-deployment-mode.d.ts +47 -0
- package/src/lib/app-utils/stripe-deployment-mode.js +70 -0
- package/src/lib/app-utils/stripe-deployment-mode.js.map +1 -0
- package/src/lib/app-utils/support-tiers.d.ts +108 -0
- package/src/lib/app-utils/support-tiers.js +201 -0
- package/src/lib/app-utils/support-tiers.js.map +1 -0
- package/src/lib/app-utils/timezone-geo-hint.d.ts +36 -0
- package/src/lib/app-utils/timezone-geo-hint.js +180 -0
- package/src/lib/app-utils/timezone-geo-hint.js.map +1 -0
- package/src/lib/app-utils/upload-cors.d.ts +155 -0
- package/src/lib/app-utils/upload-cors.js +254 -0
- package/src/lib/app-utils/upload-cors.js.map +1 -0
- package/src/lib/app-utils/upload-inspection.d.ts +159 -0
- package/src/lib/app-utils/upload-inspection.js +539 -0
- package/src/lib/app-utils/upload-inspection.js.map +1 -0
- package/src/lib/app-utils/url-slug.d.ts +40 -0
- package/src/lib/app-utils/url-slug.js +42 -0
- package/src/lib/app-utils/url-slug.js.map +1 -0
- package/src/lib/app-utils/usage-budget.d.ts +429 -0
- package/src/lib/app-utils/usage-budget.js +421 -0
- package/src/lib/app-utils/usage-budget.js.map +1 -0
- package/src/lib/app-utils/variables.d.ts +96 -0
- package/src/lib/app-utils/variables.js +233 -0
- package/src/lib/app-utils/variables.js.map +1 -0
- package/src/lib/app-utils/video-asset-facts.d.ts +61 -0
- package/src/lib/app-utils/video-asset-facts.js +70 -0
- package/src/lib/app-utils/video-asset-facts.js.map +1 -0
- package/src/lib/app-utils/video-object.d.ts +89 -0
- package/src/lib/app-utils/video-object.js +245 -0
- package/src/lib/app-utils/video-object.js.map +1 -0
- package/src/lib/app-utils/visitor-consent.d.ts +757 -0
- package/src/lib/app-utils/visitor-consent.js +981 -0
- package/src/lib/app-utils/visitor-consent.js.map +1 -0
- package/src/lib/app-utils/visitor-record-ceiling.d.ts +223 -0
- package/src/lib/app-utils/visitor-record-ceiling.js +215 -0
- package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -0
- package/src/lib/app-utils/web-vitals-rum.d.ts +53 -0
- package/src/lib/app-utils/web-vitals-rum.js +278 -0
- package/src/lib/app-utils/web-vitals-rum.js.map +1 -0
- package/src/lib/app-utils/webhook-delivery.d.ts +324 -0
- package/src/lib/app-utils/webhook-delivery.js +413 -0
- package/src/lib/app-utils/webhook-delivery.js.map +1 -0
- package/src/lib/app-utils/where-used.d.ts +57 -0
- package/src/lib/app-utils/where-used.js +59 -0
- package/src/lib/app-utils/where-used.js.map +1 -0
- package/src/lib/app-utils/wistia-embed.d.ts +86 -0
- package/src/lib/app-utils/wistia-embed.js +119 -0
- package/src/lib/app-utils/wistia-embed.js.map +1 -0
- package/src/lib/app-utils/workflows.d.ts +136 -0
- package/src/lib/app-utils/workflows.js +346 -0
- package/src/lib/app-utils/workflows.js.map +1 -0
- package/src/lib/canvas-manager/canvas-manager-tree.d.ts +109 -0
- package/src/lib/canvas-manager/canvas-manager-tree.js +139 -0
- package/src/lib/canvas-manager/canvas-manager-tree.js.map +1 -0
- package/src/lib/canvas-manager/canvas-manager.d.ts +549 -0
- package/src/lib/canvas-manager/canvas-manager.js +1311 -0
- package/src/lib/canvas-manager/canvas-manager.js.map +1 -0
- package/src/lib/canvas-manager/index.d.ts +20 -0
- package/src/lib/canvas-manager/index.js +21 -0
- package/src/lib/canvas-manager/index.js.map +1 -0
- package/src/lib/canvas-manager/stores/index.d.ts +17 -0
- package/src/lib/canvas-manager/stores/index.js +18 -0
- package/src/lib/canvas-manager/stores/index.js.map +1 -0
- package/src/lib/canvas-manager/stores/node.store.d.ts +30 -0
- package/src/lib/canvas-manager/stores/node.store.js +45 -0
- package/src/lib/canvas-manager/stores/node.store.js.map +1 -0
- package/src/lib/components-manager/components-manager.d.ts +56 -0
- package/src/lib/components-manager/components-manager.js +191 -0
- package/src/lib/components-manager/components-manager.js.map +1 -0
- package/src/lib/components-manager/index.d.ts +18 -0
- package/src/lib/components-manager/index.js +19 -0
- package/src/lib/components-manager/index.js.map +1 -0
- package/src/lib/emit-manager/emit-manager.d.ts +56 -0
- package/src/lib/emit-manager/emit-manager.js +60 -0
- package/src/lib/emit-manager/emit-manager.js.map +1 -0
- package/src/lib/emit-manager/index.d.ts +18 -0
- package/src/lib/emit-manager/index.js +19 -0
- package/src/lib/emit-manager/index.js.map +1 -0
- package/src/lib/foundation/constants/_internal.d.ts +18 -0
- package/src/lib/foundation/constants/_internal.js +62 -0
- package/src/lib/foundation/constants/_internal.js.map +1 -0
- package/src/lib/foundation/constants/app.d.ts +23 -0
- package/src/lib/foundation/constants/app.js +25 -0
- package/src/lib/foundation/constants/app.js.map +1 -0
- package/src/lib/foundation/constants/canvas.d.ts +18 -0
- package/src/lib/foundation/constants/canvas.js +18 -0
- package/src/lib/foundation/constants/canvas.js.map +1 -0
- package/src/lib/foundation/constants/components.d.ts +54 -0
- package/src/lib/foundation/constants/components.js +61 -0
- package/src/lib/foundation/constants/components.js.map +1 -0
- package/src/lib/foundation/constants/shared.d.ts +50 -0
- package/src/lib/foundation/constants/shared.js +49 -0
- package/src/lib/foundation/constants/shared.js.map +1 -0
- package/src/lib/foundation/constants/symbol.d.ts +63 -0
- package/src/lib/foundation/constants/symbol.js +75 -0
- package/src/lib/foundation/constants/symbol.js.map +1 -0
- package/src/lib/foundation/definitions/components.types.d.ts +372 -0
- package/src/lib/foundation/definitions/components.types.js +180 -0
- package/src/lib/foundation/definitions/components.types.js.map +1 -0
- package/src/lib/foundation/definitions/contact.types.d.ts +73 -0
- package/src/lib/foundation/definitions/contact.types.js +107 -0
- package/src/lib/foundation/definitions/contact.types.js.map +1 -0
- package/src/lib/foundation/definitions/host-content-collections.d.ts +137 -0
- package/src/lib/foundation/definitions/host-content-collections.js +219 -0
- package/src/lib/foundation/definitions/host-content-collections.js.map +1 -0
- package/src/lib/foundation/definitions/org-billing.types.d.ts +1361 -0
- package/src/lib/foundation/definitions/org-billing.types.js +77 -0
- package/src/lib/foundation/definitions/org-billing.types.js.map +1 -0
- package/src/lib/foundation/definitions/organization.types.d.ts +307 -0
- package/src/lib/foundation/definitions/organization.types.js +42 -0
- package/src/lib/foundation/definitions/organization.types.js.map +1 -0
- package/src/lib/foundation/definitions/platform.types.d.ts +1326 -0
- package/src/lib/foundation/definitions/platform.types.js +124 -0
- package/src/lib/foundation/definitions/platform.types.js.map +1 -0
- package/src/lib/foundation/definitions/property-kinds.d.ts +189 -0
- package/src/lib/foundation/definitions/property-kinds.js +565 -0
- package/src/lib/foundation/definitions/property-kinds.js.map +1 -0
- package/src/lib/foundation/definitions/shared.d.ts +23 -0
- package/src/lib/foundation/definitions/shared.js +18 -0
- package/src/lib/foundation/definitions/shared.js.map +1 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +249 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js +499 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -0
- package/src/lib/foundation/index.d.ts +32 -0
- package/src/lib/foundation/index.js +67 -0
- package/src/lib/foundation/index.js.map +1 -0
- package/src/lib/lifecycle.d.ts +24 -0
- package/src/lib/lifecycle.js +39 -0
- package/src/lib/lifecycle.js.map +1 -0
- package/src/lib/mst/common.d.ts +17 -0
- package/src/lib/mst/common.js +23 -0
- package/src/lib/mst/common.js.map +1 -0
- package/src/lib/mst/index.d.ts +19 -0
- package/src/lib/mst/index.js +20 -0
- package/src/lib/mst/index.js.map +1 -0
- package/src/lib/mst/json.d.ts +22 -0
- package/src/lib/mst/json.js +23 -0
- package/src/lib/mst/json.js.map +1 -0
- package/src/lib/mst/types.d.ts +20 -0
- package/src/lib/mst/types.js +18 -0
- package/src/lib/mst/types.js.map +1 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.d.ts +77 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.js +55 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.js.map +1 -0
- package/src/lib/plugin-manager/commerce-zone-props.d.ts +172 -0
- package/src/lib/plugin-manager/commerce-zone-props.js +31 -0
- package/src/lib/plugin-manager/commerce-zone-props.js.map +1 -0
- package/src/lib/plugin-manager/custom-fields.d.ts +60 -0
- package/src/lib/plugin-manager/custom-fields.js +39 -0
- package/src/lib/plugin-manager/custom-fields.js.map +1 -0
- package/src/lib/plugin-manager/editor-sessions.d.ts +109 -0
- package/src/lib/plugin-manager/editor-sessions.js +137 -0
- package/src/lib/plugin-manager/editor-sessions.js.map +1 -0
- package/src/lib/plugin-manager/enabled-plugins.d.ts +438 -0
- package/src/lib/plugin-manager/enabled-plugins.js +403 -0
- package/src/lib/plugin-manager/enabled-plugins.js.map +1 -0
- package/src/lib/plugin-manager/feature-plugins.d.ts +1314 -0
- package/src/lib/plugin-manager/feature-plugins.js +609 -0
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +11 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js +149 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -0
- package/src/lib/plugin-manager/index.d.ts +42 -0
- package/src/lib/plugin-manager/index.js +46 -0
- package/src/lib/plugin-manager/index.js.map +1 -0
- package/src/lib/plugin-manager/install-presets.d.ts +93 -0
- package/src/lib/plugin-manager/install-presets.js +86 -0
- package/src/lib/plugin-manager/install-presets.js.map +1 -0
- package/src/lib/plugin-manager/media-delivery-provider.d.ts +124 -0
- package/src/lib/plugin-manager/media-delivery-provider.js +53 -0
- package/src/lib/plugin-manager/media-delivery-provider.js.map +1 -0
- package/src/lib/plugin-manager/order-fulfilment.d.ts +142 -0
- package/src/lib/plugin-manager/order-fulfilment.js +104 -0
- package/src/lib/plugin-manager/order-fulfilment.js.map +1 -0
- package/src/lib/plugin-manager/plugin-activity-actions.d.ts +122 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js +140 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-bridge.d.ts +98 -0
- package/src/lib/plugin-manager/plugin-bridge.js +154 -0
- package/src/lib/plugin-manager/plugin-bridge.js.map +1 -0
- package/src/lib/plugin-manager/plugin-config.d.ts +148 -0
- package/src/lib/plugin-manager/plugin-config.js +228 -0
- package/src/lib/plugin-manager/plugin-config.js.map +1 -0
- package/src/lib/plugin-manager/plugin-console-crons.d.ts +139 -0
- package/src/lib/plugin-manager/plugin-console-crons.js +177 -0
- package/src/lib/plugin-manager/plugin-console-crons.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contact-capture.d.ts +220 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js +89 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contributions.d.ts +244 -0
- package/src/lib/plugin-manager/plugin-contributions.js +283 -0
- package/src/lib/plugin-manager/plugin-contributions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.d.ts +169 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.js +84 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlements.d.ts +181 -0
- package/src/lib/plugin-manager/plugin-entitlements.js +188 -0
- package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -0
- package/src/lib/plugin-manager/plugin-events.d.ts +145 -0
- package/src/lib/plugin-manager/plugin-events.js +79 -0
- package/src/lib/plugin-manager/plugin-events.js.map +1 -0
- package/src/lib/plugin-manager/plugin-figures.d.ts +251 -0
- package/src/lib/plugin-manager/plugin-figures.js +252 -0
- package/src/lib/plugin-manager/plugin-figures.js.map +1 -0
- package/src/lib/plugin-manager/plugin-host-collections.d.ts +146 -0
- package/src/lib/plugin-manager/plugin-host-collections.js +116 -0
- package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -0
- package/src/lib/plugin-manager/plugin-jobs.d.ts +130 -0
- package/src/lib/plugin-manager/plugin-jobs.js +182 -0
- package/src/lib/plugin-manager/plugin-jobs.js.map +1 -0
- package/src/lib/plugin-manager/plugin-loader.d.ts +86 -0
- package/src/lib/plugin-manager/plugin-loader.js +223 -0
- package/src/lib/plugin-manager/plugin-loader.js.map +1 -0
- package/src/lib/plugin-manager/plugin-manager.d.ts +95 -0
- package/src/lib/plugin-manager/plugin-manager.js +343 -0
- package/src/lib/plugin-manager/plugin-manager.js.map +1 -0
- package/src/lib/plugin-manager/plugin-metered-lines.d.ts +97 -0
- package/src/lib/plugin-manager/plugin-metered-lines.js +123 -0
- package/src/lib/plugin-manager/plugin-metered-lines.js.map +1 -0
- package/src/lib/plugin-manager/plugin-org-erasure.d.ts +52 -0
- package/src/lib/plugin-manager/plugin-org-erasure.js +100 -0
- package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-permissions.d.ts +69 -0
- package/src/lib/plugin-manager/plugin-permissions.js +77 -0
- package/src/lib/plugin-manager/plugin-permissions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-person-erasure.d.ts +58 -0
- package/src/lib/plugin-manager/plugin-person-erasure.js +109 -0
- package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-cards.d.ts +99 -0
- package/src/lib/plugin-manager/plugin-record-cards.js +59 -0
- package/src/lib/plugin-manager/plugin-record-cards.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-facts.d.ts +111 -0
- package/src/lib/plugin-manager/plugin-record-facts.js +51 -0
- package/src/lib/plugin-manager/plugin-record-facts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-routes.d.ts +129 -0
- package/src/lib/plugin-manager/plugin-record-routes.js +93 -0
- package/src/lib/plugin-manager/plugin-record-routes.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-timeline.d.ts +147 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js +39 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +137 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.js +51 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-services.d.ts +94 -0
- package/src/lib/plugin-manager/plugin-services.js +153 -0
- package/src/lib/plugin-manager/plugin-services.js.map +1 -0
- package/src/lib/plugin-manager/plugin-styles-ui.d.ts +71 -0
- package/src/lib/plugin-manager/plugin-styles-ui.js +80 -0
- package/src/lib/plugin-manager/plugin-styles-ui.js.map +1 -0
- package/src/lib/plugin-manager/plugin-styles.d.ts +176 -0
- package/src/lib/plugin-manager/plugin-styles.js +186 -0
- package/src/lib/plugin-manager/plugin-styles.js.map +1 -0
- package/src/lib/plugin-manager/plugin-subprocessors.d.ts +135 -0
- package/src/lib/plugin-manager/plugin-subprocessors.js +129 -0
- package/src/lib/plugin-manager/plugin-subprocessors.js.map +1 -0
- package/src/lib/plugin-manager/plugin-tax-profile.d.ts +84 -0
- package/src/lib/plugin-manager/plugin-tax-profile.js +39 -0
- package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -0
- package/src/lib/plugin-manager/plugin-user-erasure.d.ts +53 -0
- package/src/lib/plugin-manager/plugin-user-erasure.js +84 -0
- package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-zones.d.ts +121 -0
- package/src/lib/plugin-manager/plugin-zones.js +74 -0
- package/src/lib/plugin-manager/plugin-zones.js.map +1 -0
- package/src/lib/plugin-manager/realm-plugins.d.ts +112 -0
- package/src/lib/plugin-manager/realm-plugins.js +196 -0
- package/src/lib/plugin-manager/realm-plugins.js.map +1 -0
- package/src/lib/plugin-manager/realm-server.d.ts +54 -0
- package/src/lib/plugin-manager/realm-server.js +88 -0
- package/src/lib/plugin-manager/realm-server.js.map +1 -0
- package/src/lib/plugin-manager/record-zone-props.d.ts +126 -0
- package/src/lib/plugin-manager/record-zone-props.js +31 -0
- package/src/lib/plugin-manager/record-zone-props.js.map +1 -0
- package/src/lib/plugin-manager/site-page-hooks.d.ts +102 -0
- package/src/lib/plugin-manager/site-page-hooks.js +114 -0
- package/src/lib/plugin-manager/site-page-hooks.js.map +1 -0
- package/src/lib/plugin-manager/site-runtime.d.ts +57 -0
- package/src/lib/plugin-manager/site-runtime.js +25 -0
- package/src/lib/plugin-manager/site-runtime.js.map +1 -0
- package/src/lib/plugin-manager/usage-alert-contributors.d.ts +115 -0
- package/src/lib/plugin-manager/usage-alert-contributors.js +106 -0
- package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -0
- package/src/lib/types/ast.d.ts +199 -0
- package/src/lib/types/ast.js +20 -0
- package/src/lib/types/ast.js.map +1 -0
- package/src/lib/types/index.d.ts +20 -0
- package/src/lib/types/index.js +21 -0
- package/src/lib/types/index.js.map +1 -0
- package/src/lib/types/nodes.d.ts +608 -0
- package/src/lib/types/nodes.js +28 -0
- package/src/lib/types/nodes.js.map +1 -0
- package/src/lib/types/routing.d.ts +17 -0
- package/src/lib/types/routing.js +18 -0
- package/src/lib/types/routing.js.map +1 -0
- package/src/lib/types/screen.d.ts +23 -0
- package/src/lib/types/screen.js +18 -0
- package/src/lib/types/screen.js.map +1 -0
- package/src/lib/utils.d.ts +25 -0
- package/src/lib/utils.js +42 -0
- package/src/lib/utils.js.map +1 -0
- package/src/server.d.ts +37 -0
- package/src/server.js +55 -0
- package/src/server.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/consent-banner-ui.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Deliberately NO 'use client' directive: inside @aglyn/aglyn the directive\n// splits the bundler into a duplicate module graph, and the second\n// canvas/emitter singleton renders the tenant site blank (AGL-52 — the\n// lint rule that enforces this). It is also unnecessary: every importer\n// (the tenant catch-all, the console preview simulator) is itself a\n// 'use client' module, so this file is already inside the client graph. A\n// future import from a SERVER component fails loudly at build time\n// (\"useState only works in a client component\"), not silently.\n\nimport { Box, Button, Paper, Stack, Typography } from '@mui/material'\nimport {\n type ReactElement,\n type ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport type { ConsentPreferencesDialog } from './consent-preferences-dialog'\nimport {\n readStoredVisitorConsent,\n refusalStatusFor,\n type StoredVisitorConsent,\n storeVisitorConsent,\n VISITOR_CONSENT_OPEN_EVENT,\n type VisitorConsentPosture,\n type VisitorConsentStatus,\n} from './visitor-consent'\n\n/**\n * The visitor consent surfaces (AGL-1498) — UI over the enforcement layer,\n * never the enforcement itself: the GA script stays unloaded until a\n * granting state is recorded, whether or not this component ever rendered.\n *\n * Three surfaces in one component, driven by the resolved state:\n *\n * - **The prior-consent banner** (opt-in posture, undecided visitor):\n * symmetric Allow / Decline plus Preferences — the peer benchmark's\n * credible shape; Decline is never buried.\n * - **The \"Your Privacy Choices\" pill**: a small, persistent, fixed control on\n * EVERY page whenever the consent machinery is active. In the implied\n * posture no banner and no notice ever renders (the Squarespace shape),\n * which makes this pill the ONE discoverable opt-out surface — that is\n * why it is platform-mounted rather than a per-template footer link a\n * theme could drop. Sites can additionally link any element to\n * `#aglyn-consent`; both open the same panel.\n * - **The preferences panel**: change the state in EITHER direction at any\n * time — accept after declining, opt out after being defaulted in.\n *\n * ## EVERY surface renders this component\n *\n * Published customer sites, the console — signed in and signed out — and the\n * console preview's region simulator. There were two implementations of these\n * three surfaces and they had already drifted into two different designs: a\n * plain card with bare checkboxes on one side, a MUI dialog with switches and\n * descriptions on the other. The dialog is the design that survived, and the\n * differences that were real turned out to be STRINGS — \"this site\" against\n * \"this console\", carts against signing in — which is what {@link ConsentCopy}\n * is for. A string is not a reason for a second component.\n *\n * MUI is available on both: the tenant runtime renders it through\n * `HostThemeProvider`, under the same `AppRouterCacheProvider` emotion cache\n * the console uses, and `membership-page.tsx` already draws MUI components a\n * folder away from the call site here. The unlayered-cache hazard is the\n * BESIGNER canvas, which no published page and no consent surface goes\n * through.\n *\n * Palette and type come from whichever theme is in scope, which on a customer\n * site is the site's own — the control belongs to the page it is asked on. The\n * two things that must NOT follow a theme are the §7015 mark, which is\n * transcribed artwork, and {@link CONSENT_OVERLAY_Z_INDEX}, which has to\n * outrank a popup backdrop no theme knows about.\n */\n\n/**\n * The title of the persistent opt-out control — **fixed by regulation, not a\n * copy choice**.\n *\n * Once a business \"shares\" personal information for cross-context behavioral\n * advertising, CCPA §1798.135(b) requires a clear and conspicuous opt-out\n * link, and CCPA regs §7015 permit a SINGLE combined link only when it is\n * titled with these exact words. Aglyn crossed that line when advertising\n * technology went onto aglyn.com, so the pill's previous label — \"Privacy\n * choices\" — stopped being compliant the moment the tag shipped.\n *\n * Capitalisation is part of the specified title. Do not sentence-case it to\n * match the rest of the overlay copy, do not shorten it to fit a narrow\n * viewport, and do not translate it away on a US-facing site: it is pinned by\n * `consent-opt-out-title.spec.tsx`, which renders the real control and reads\n * the text back.\n */\nexport const CONSENT_OPT_OUT_TITLE = 'Your Privacy Choices'\n\n/**\n * The official CCPA **opt-out icon** — the other half of §7015, and the half\n * AGL-2011's title commit deliberately left undone.\n *\n * §7015(a) requires the icon *\"in approximately the same size as any other\n * icons\"* and §7015(c) requires it to *\"be approximately the same size as\n * other icons on the business's webpage\"* and to appear immediately to the\n * left of the \"Your Privacy Choices\" text. §7015(f) is the reason the shapes\n * below are transcribed rather than drawn: the regulation points at\n * *published artwork*, not at a description of a toggle, so an approximation\n * that reads as \"close enough\" is not the mark the regulation names.\n *\n * ## Provenance — read this before touching a single coordinate\n *\n * Downloaded from the California Attorney General's own icon page,\n * `oag.ca.gov/privacy/ccpa/icons-download`, by two independent routes that\n * agree byte for byte: the `ccpa-icons.zip` bundle that page offers, and the\n * standalone `privacyoptions.svg` that page displays inline. Both are\n * sha256 `86f2eb97cc1f3909c12e4512de9e267215d94ac5aaee9393d0f007f18c34e8ba`.\n * The unmodified file is committed at\n * `apps/tenant/public/_static/images/legal/ccpa-opt-out-icon.svg` — diff it\n * against the AG's copy to re-verify at any time.\n *\n * ## Why the paths are inlined here and not `<img src>`-ed\n *\n * The AGL-1810 duplicate-with-pointer pattern, for the same reason the admin\n * bar uses it: this component renders on **every published customer site**\n * and inside the console's preview simulator, and neither an extra fetch nor\n * a broken-image glyph is acceptable where a regulator's mark is supposed to\n * be. A self-hosted deployment gets the mark with no asset pipeline at all.\n * If the AG ever republishes the artwork, change the committed file AND\n * these four constants.\n *\n * ## What was changed in transcription, and what was not\n *\n * The coordinates and the two colours are verbatim. The only change is that\n * the AG file carries its fills in a `<style>` block of `.st0`–`.st3`\n * classes, and an inline `<style>` inside a shared overlay is **document-\n * global CSS**: shipping it would define `.st0`/`.st1` on every customer's\n * page and restyle any element of theirs that happens to use those names. So\n * each class is expanded to the presentation attributes it stood for —\n * `.st0`/`.st1` are `fill-rule:evenodd; clip-rule:evenodd` plus the fill,\n * `.st2`/`.st3` are the fill alone. Paint order is the file's own; the white\n * left-hand fill is painted before the blue shell that rings it.\n */\n/** `.st0` — the white field behind the check, inside the shell's cut-out. */\nconst OPT_OUT_ICON_LEFT_FIELD_PATH =\n 'M7.4,12.8h6.8l3.1-11.6H7.4C4.2,1.2,1.6,3.8,1.6,7S4.2,12.8,7.4,12.8z'\n/** `.st1` — the blue toggle shell, evenodd so the left half reads through. */\nconst OPT_OUT_ICON_SHELL_PATH =\n 'M22.6,0H7.4c-3.9,0-7,3.1-7,7s3.1,7,7,7h15.2c3.9,0,7-3.1,7-7S26.4,0,22.6,0z M1.6,7c0-3.2,2.6-5.8,5.8-5.8' +\n ' h9.9l-3.1,11.6H7.4C4.2,12.8,1.6,10.2,1.6,7z'\n/** `.st2` (`id=\"x\"`) — the white cross on the blue half. */\nconst OPT_OUT_ICON_CROSS_PATH =\n 'M24.6,4c0.2,0.2,0.2,0.6,0,0.8l0,0L22.5,7l2.2,2.2c0.2,0.2,0.2,0.6,0,0.8c-0.2,0.2-0.6,0.2-0.8,0' +\n ' l0,0l-2.2-2.2L19.5,10c-0.2,0.2-0.6,0.2-0.8,0c-0.2-0.2-0.2-0.6,0-0.8l0,0L20.8,7l-2.2-2.2c-0.2-0.2-0.2-0.6,0-0.8' +\n ' c0.2-0.2,0.6-0.2,0.8,0l0,0l2.2,2.2L23.8,4C24,3.8,24.4,3.8,24.6,4z'\n/** `.st3` (`id=\"y\"`) — the blue check on the white half. */\nconst OPT_OUT_ICON_CHECK_PATH =\n 'M12.7,4.1c0.2,0.2,0.3,0.6,0.1,0.8l0,0L8.6,9.8C8.5,9.9,8.4,10,8.3,10c-0.2,0.1-0.5,0.1-0.7-0.1l0,0' +\n ' L5.4,7.7c-0.2-0.2-0.2-0.6,0-0.8c0.2-0.2,0.6-0.2,0.8,0l0,0L8,8.6l3.8-4.5C12,3.9,12.4,3.9,12.7,4.1z'\n\n/** The mark's own colours. Not themeable — see {@link CcpaOptOutIcon}. */\nconst OPT_OUT_ICON_BLUE = '#0066FF'\nconst OPT_OUT_ICON_WHITE = '#FFFFFF'\n\n/**\n * The opt-out icon, sized for the pill.\n *\n * `aria-hidden`, because it sits beside the words it stands for: the pill\n * already announces \"Your Privacy Choices\" as its accessible name, and a\n * labelled icon next to identical visible text makes a screen reader say the\n * title twice. Same treatment as the admin bar's mark.\n *\n * 26 × 12 against the file's own `0 0 30 14` viewBox, so the default\n * `preserveAspectRatio` scales the drawing to the 12px height — one line of\n * the pill's 12px/1.4 text — and centres it. That is what §7015's \"the same\n * size as other icons\" asks for here: the pill has no other icons, so the\n * text is the scale to match.\n *\n * **The colours are the regulation's, not the theme's.** The pill's own\n * background is a fixed near-white that no tenant palette reaches, which is\n * exactly the surface this artwork was published against — so it needs no\n * light/dark variant and must not be given one.\n */\n/**\n * Exported so a surface that renders its own opt-out control gets the\n * REGULATOR'S artwork rather than an approximation of it. §7015(f) points at\n * published artwork, and the console's unauthenticated pages need the same\n * mark this overlay draws — a second, hand-drawn toggle would be a different\n * mark wearing the same name.\n */\nexport function CcpaOptOutIcon(): ReactElement {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 30 14\"\n width={26}\n height={12}\n aria-hidden=\"true\"\n focusable=\"false\"\n style={{ flexShrink: 0, display: 'block' }}\n data-aglyn-consent-optout-icon=\"\"\n >\n <path\n d={OPT_OUT_ICON_LEFT_FIELD_PATH}\n fill={OPT_OUT_ICON_WHITE}\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n <path\n d={OPT_OUT_ICON_SHELL_PATH}\n fill={OPT_OUT_ICON_BLUE}\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n <path d={OPT_OUT_ICON_CROSS_PATH} fill={OPT_OUT_ICON_WHITE} />\n <path d={OPT_OUT_ICON_CHECK_PATH} fill={OPT_OUT_ICON_BLUE} />\n </svg>\n )\n}\n/**\n * The stacking context the consent surfaces must win, and why it is a number\n * rather than a theme token.\n *\n * `theme.zIndex.modal` is 1300, and on a published site the consent card has\n * to sit above the popup backdrop at 2147483200 — the consent question\n * outranks a promotional popup, and the popup's own GA mirrors are waiting on\n * the answer. Exported so the console preview's own panel can be raised\n * against the real value instead of a copy of it.\n */\nexport const CONSENT_OVERLAY_Z_INDEX = 2147483400\n\n/** The persistent control sits just below the card it can be replaced by. */\nexport const CONSENT_PILL_Z_INDEX = 2147483390\n\n/** The card both the banner and the preferences panel are drawn on. */\nconst CARD_WIDTH = 'min(680px, calc(100vw - 24px))'\n\n/** Breathing room kept between the pill and the last row it must not cover. */\nconst PILL_CLEARANCE = 8\n\n/**\n * Selector for \"the end of the page\" — the footer landmark, however the\n * template spells it. A besigner-authored footer renders as `<footer>`;\n * `[role=contentinfo]` catches a hand-rolled one. `body` is the fallback so\n * a site with no footer at all still reserves the room.\n */\nconst FOOTER_SELECTOR = 'footer, [role=\"contentinfo\"]'\n\n/**\n * Bottom padding the end of the page needs so the fixed pill cannot land on\n * top of it (AGL-2205).\n *\n * Derived from the pill's MEASURED box rather than from `PILL_STYLE`: the\n * label wraps to two lines in a narrow viewport and in a translated locale,\n * and a clearance computed from the constants would be exactly one line\n * short in precisely the case where the copyright row is already tightest.\n *\n * Pure, and exported, because the geometry is the whole fix: a spec can pin\n * \"51px of room for a 30.8px pill sitting 12px off the bottom\" without a\n * layout engine, which is the half a jsdom render cannot check.\n */\nexport function consentPillClearance(\n viewportHeight: number,\n pillTop: number,\n): number {\n if (!Number.isFinite(viewportHeight) || !Number.isFinite(pillTop)) return 0\n return Math.max(0, Math.ceil(viewportHeight - pillTop) + PILL_CLEARANCE)\n}\n\n/**\n * Reserves that room at the foot of the document while the pill is up.\n *\n * The pill is `position: fixed`, so scrolling to the end of the page parks\n * it directly on the footer's bottom row — which on every Aglyn marketing\n * page is the \"© 2026 Aglyn LLC\" line, the one piece of footer content that\n * is there for legal reasons. Measured on aglyn.com/pricing before this: the\n * pill occupied 12–126 × 680–711 and the copyright row 24–258 × 669–689, a\n * 102 × 9 px overlap at 1440 and the same again at 375.\n *\n * AGL-2205 proposed docking the pill above the footer instead. Measuring the\n * real footer ruled that out: it is 490px tall at 1440 and 1375px at 375,\n * against an 812px viewport — docking above it puts the pill in the middle\n * of the screen on desktop and clean off it on mobile, and the pill is the\n * ONLY opt-out surface a visitor in the implied posture ever sees, so it may\n * not scroll away. Reserving the pill's own footprint keeps it where people\n * expect it, costs nothing to anyone who never scrolls that far, and the\n * room appears INSIDE the footer's own background band rather than as a\n * strip of body colour underneath it.\n *\n * Only the DEFICIT is added: a template that already leaves enough room is\n * left exactly as it was, which is why the site's own padding is re-read\n * (with ours removed) on every pass instead of being captured once — it is\n * responsive, and a value cached at mount is wrong after the first resize.\n */\nfunction useConsentPillClearance(\n pillRef: { current: HTMLElement | null },\n active: boolean,\n): void {\n useEffect(() => {\n const pill = pillRef.current\n if (!active || !pill) return\n const doc = pill.ownerDocument\n const view = doc?.defaultView\n // `ownerDocument`, never the global `document`: the console preview\n // mounts this same component, and reserving room in the CONSOLE's\n // chrome because the preview happens to share its document would be a\n // fix applied to the wrong page.\n if (!doc || !view) return\n const target: HTMLElement | null =\n doc.querySelector<HTMLElement>(FOOTER_SELECTOR) ?? doc.body\n if (!target) return\n\n const previous = target.style.getPropertyValue('padding-bottom')\n const previousPriority = target.style.getPropertyPriority('padding-bottom')\n const restore = () => {\n if (previous) {\n target.style.setProperty('padding-bottom', previous, previousPriority)\n } else {\n target.style.removeProperty('padding-bottom')\n }\n }\n\n const apply = () => {\n // Ours off first: `getComputedStyle` would otherwise read back the\n // value this effect wrote on the previous pass and ratchet it upward.\n // Safe to do mid-measurement — the pill is fixed, so the reflow this\n // causes cannot move it.\n restore()\n const natural =\n Number.parseFloat(view.getComputedStyle(target).paddingBottom) || 0\n const needed = consentPillClearance(\n view.innerHeight,\n pill.getBoundingClientRect().top,\n )\n if (needed > natural) {\n target.style.setProperty('padding-bottom', `${needed}px`)\n }\n }\n\n apply()\n view.addEventListener('resize', apply)\n // The pill's own box changes without the viewport changing — a font\n // finishing loading re-wraps the label.\n const observer =\n typeof view.ResizeObserver === 'function'\n ? new view.ResizeObserver(apply)\n : undefined\n observer?.observe(pill)\n return () => {\n view.removeEventListener('resize', apply)\n observer?.disconnect()\n restore()\n }\n }, [pillRef, active])\n}\n\n/**\n * The words each surface uses, so one component serves them all.\n *\n * A console says \"this console\" and a published site says \"this site\"; the\n * strictly-necessary sentence names shopping carts on a customer site and\n * signing in on the console. Those are STRINGS, and a string is not a reason\n * for a second component — which is what the two implementations this replaces\n * had become. Every field defaults to the published-site wording, so a caller\n * that has nothing to say differently passes nothing.\n */\nexport interface ConsentCopy {\n /** Opens the preferences panel. */\n panelIntro?: string\n /** Names what runs regardless, and why it is not being asked about. */\n strictlyNecessary?: string\n /** The ask, on a site that runs analytics only. */\n bannerAnalyticsOnly?: string\n /** The ask, on a site that also asks about advertising. */\n bannerWithAdvertising?: string\n /** The analytics control's label and the line under it. */\n analyticsLabel?: string\n analyticsDetail?: string\n /** The advertising control's, where the surface asks about it. */\n advertisingLabel?: string\n advertisingDetail?: string\n}\n\nconst DEFAULT_COPY: Required<ConsentCopy> = {\n panelIntro: 'Choose what this site may use.',\n strictlyNecessary:\n 'Strictly necessary features — like shopping carts, sign-in, and ' +\n 'remembering this choice — are always on because the site cannot work ' +\n 'without them.',\n bannerAnalyticsOnly:\n 'This site would like to use analytics (Google Analytics) to understand ' +\n 'how it is used. Analytics only runs if you allow it — everything else ' +\n 'works either way.',\n bannerWithAdvertising:\n 'This site would like to use analytics (Google Analytics) to understand ' +\n 'how it is used, and advertising cookies to personalize ads and measure ' +\n 'how they perform. Neither runs unless you allow it — everything else ' +\n 'works either way. Use Preferences to choose them separately.',\n analyticsLabel: 'Analytics',\n analyticsDetail: 'Google Analytics — how the site is used.',\n advertisingLabel: 'Advertising',\n advertisingDetail: 'Personalized ads and measuring how they perform.',\n}\n\nexport interface ConsentBannerUiProps {\n hostId: string\n /** The visitor's recorded state; null means undecided. */\n stored: StoredVisitorConsent | null\n /** The resolved posture; only consulted while undecided. */\n posture: VisitorConsentPosture | null\n /** Region at decision time, recorded onto explicit choices. */\n country?: string | null\n /**\n * Whether this surface asks about advertising storage. Resolved by the\n * caller — from the host document on a published site, from the platform's\n * own consent declaration on the console.\n */\n advertising?: boolean\n /** Per-surface wording; see {@link ConsentCopy}. */\n copy?: ConsentCopy\n /**\n * Links to the policies behind the choice, rendered under the copy on both\n * the banner and the panel.\n *\n * A node rather than a pair of URLs: the console links its own published\n * Privacy and Cookie policies through its route constants, and a published\n * site links whatever its owner has. A choice offered with no way to read\n * what is being chosen is not an informed one, but neither surface's links\n * are this component's to know.\n */\n policyLinks?: ReactNode\n /**\n * Whether the persistent \"Your Privacy Choices\" control may render here.\n *\n * `true` — the default, and every published site — draws the pill whenever\n * no other surface is up. It is the ONLY opt-out surface a visitor in the\n * implied posture ever sees, so it is platform-mounted rather than left to\n * a template that could drop it.\n *\n * `false` for a page that already carries the control somewhere better. The\n * console's signed-in pages put it in the account menu, where a person looks\n * for their own settings; floating a second copy over the page would be the\n * same control drawn twice.\n */\n showPill?: boolean\n /**\n * The caller owns what a decision DOES.\n *\n * Unset — a published site — persists through `storeVisitorConsent`, which\n * is where the withdrawal behaviour lives: it re-derives both grants from\n * the status, silences any resident tag, sweeps the analytics and\n * advertising cookies and dispatches the change event.\n *\n * Set, and the caller writes instead. The console writes through\n * `storePlatformConsent` so the record also mirrors across its hostnames;\n * the console's region simulator writes nothing at all, which is what keeps\n * previewing as-if-from-the-EU from recording a real consent record.\n */\n onDecision?: (status: VisitorConsentStatus, advertising?: boolean) => void\n}\n\n/** The card both overlays are drawn on — fixed, centred, above everything. */\nconst overlayCardSx = {\n position: 'fixed',\n left: '50%',\n bottom: 16,\n transform: 'translateX(-50%)',\n zIndex: CONSENT_OVERLAY_Z_INDEX,\n width: CARD_WIDTH,\n p: 2,\n borderRadius: 3,\n textAlign: 'left',\n} as const\n\n/**\n * The preferences panel, once its module has arrived.\n *\n * The panel is the one consent surface a visit has to ask for, and its MUI\n * dialog, modal, focus trap, transitions and switches weigh more than the\n * banner and the pill together. So it is a module of its own, fetched when\n * the panel is asked for — or when the pointer or focus reaches a control\n * that opens it — rather than with the banner every first-time visitor sees.\n *\n * Module scope, not a `React.lazy`: once loaded, every later render draws it\n * synchronously, with no Suspense boundary and no fallback frame.\n */\nlet loadedPreferencesDialog: typeof ConsentPreferencesDialog | undefined\nlet preferencesDialogLoad: Promise<void> | undefined\n\n/**\n * Fetches the preferences panel's module, once. A failed fetch is forgotten\n * so the next attempt can retry it.\n *\n * Exported for callers that know the panel is about to be needed, and for\n * specs that open it and read it back in the same tick.\n */\nexport function preloadConsentPreferences(): Promise<void> {\n preferencesDialogLoad ??= import('./consent-preferences-dialog')\n .then((module) => {\n loadedPreferencesDialog = module.ConsentPreferencesDialog\n })\n .catch((error: unknown) => {\n preferencesDialogLoad = undefined\n throw error\n })\n return preferencesDialogLoad\n}\n\n/** Starts the panel's fetch on a sign of intent; a failure surfaces on open. */\nfunction warmPreferences(): void {\n preloadConsentPreferences().catch((): void => undefined)\n}\n\nexport function ConsentBannerUi(props: ConsentBannerUiProps): ReactElement | null {\n const {\n hostId,\n stored,\n posture,\n country,\n advertising,\n copy,\n policyLinks,\n showPill = true,\n onDecision,\n } = props\n const words = { ...DEFAULT_COPY, ...copy }\n const [preferencesOpen, setPreferencesOpen] = useState(false)\n const [analyticsChecked, setAnalyticsChecked] = useState(\n stored?.analytics === true,\n )\n // Starts UNTICKED unless the visitor previously said yes to this exact\n // category (AGL-1649). A pre-ticked advertising box is consent by\n // inattention, which is the thing a banner is supposed to replace.\n const [adsChecked, setAdsChecked] = useState(stored?.advertising === true)\n\n // The change-your-mind paths: the window event, and a `#aglyn-consent`\n // link click anywhere in the page (capture, so canvas link handling that\n // stops propagation cannot swallow it).\n useEffect(() => {\n const open = () => {\n const current = readStoredVisitorConsent(hostId)\n setAnalyticsChecked(current?.analytics === true)\n setAdsChecked(current?.advertising === true)\n setPreferencesOpen(true)\n }\n const onClick = (event: MouseEvent) => {\n const target = event.target as Element | null\n const anchor = target?.closest?.('a[href]')\n if (\n anchor &&\n (anchor.getAttribute('href') ?? '').endsWith('#aglyn-consent')\n ) {\n event.preventDefault()\n open()\n }\n }\n window.addEventListener(VISITOR_CONSENT_OPEN_EVENT, open)\n document.addEventListener('click', onClick, true)\n return () => {\n window.removeEventListener(VISITOR_CONSENT_OPEN_EVENT, open)\n document.removeEventListener('click', onClick, true)\n }\n }, [hostId])\n\n // `ads` is only ever passed through; `storeVisitorConsent` re-derives it\n // against the status, so a refusal cannot carry a grant however this is\n // called.\n const decide = (status: VisitorConsentStatus, ads = false) => {\n const granted = advertising === true && ads\n if (onDecision) {\n onDecision(status, granted)\n } else {\n storeVisitorConsent(hostId, { status, country, advertising: granted })\n }\n setPreferencesOpen(false)\n }\n\n // Same gate either way, distinct record — see `refusalStatusFor`.\n const refusalStatus = refusalStatusFor(stored, posture)\n\n // The panel is drawn only once its module is here. Until then the surface\n // that asked for it stays up, so a slow fetch never blanks the banner or\n // the pill; a fetch that fails puts the request down, and the next click\n // retries it.\n const [, setPreferencesArrived] = useState(false)\n useEffect(() => {\n if (!preferencesOpen || loadedPreferencesDialog) return undefined\n let active = true\n preloadConsentPreferences().then(\n () => {\n if (active) setPreferencesArrived(true)\n },\n () => {\n if (active) setPreferencesOpen(false)\n },\n )\n return () => {\n active = false\n }\n }, [preferencesOpen])\n const PreferencesDialog = preferencesOpen ? loadedPreferencesDialog : undefined\n\n const askBanner = !stored && posture === 'opt-in' && !PreferencesDialog\n\n // Before the early returns below, so the hook order never depends on which\n // of the three surfaces is up. The banner and the panel are centred cards\n // that reserve nothing — only the pill parks itself on the footer.\n const pillRef = useRef<HTMLButtonElement | null>(null)\n useConsentPillClearance(pillRef, showPill && !PreferencesDialog && !askBanner)\n\n if (PreferencesDialog) {\n return (\n <PreferencesDialog\n title={CONSENT_OPT_OUT_TITLE}\n zIndex={CONSENT_OVERLAY_Z_INDEX}\n words={words}\n advertising={advertising}\n policyLinks={policyLinks}\n analyticsChecked={analyticsChecked}\n onAnalyticsChange={setAnalyticsChecked}\n adsChecked={adsChecked}\n onAdsChange={setAdsChecked}\n onClose={() => setPreferencesOpen(false)}\n onDeclineAll={() => decide(refusalStatus)}\n onSave={() =>\n decide(\n analyticsChecked ? 'accepted' : refusalStatus,\n // Advertising cannot outlive analytics: unticking analytics and\n // leaving advertising ticked is a refusal of both, which\n // `consentModeSignals` also clamps independently.\n analyticsChecked && adsChecked,\n )\n }\n />\n )\n }\n\n if (askBanner) {\n return (\n <Paper\n elevation={8}\n role=\"region\"\n aria-label=\"Privacy choices\"\n data-aglyn-consent-banner=\"\"\n sx={overlayCardSx}\n >\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1.5}\n sx={{ alignItems: { xs: 'stretch', sm: 'center' } }}\n >\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography variant=\"body2\">\n {advertising\n ? words.bannerWithAdvertising\n : words.bannerAnalyticsOnly}\n </Typography>\n {policyLinks ? <Box sx={{ mt: 0.5 }}>{policyLinks}</Box> : null}\n </Box>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexShrink: 0, flexWrap: 'wrap' }}\n >\n <Button\n size=\"small\"\n onPointerEnter={warmPreferences}\n onFocus={warmPreferences}\n onClick={() => {\n setAnalyticsChecked(stored != null && stored.analytics)\n setAdsChecked(stored != null && stored.advertising === true)\n setPreferencesOpen(true)\n }}\n >\n {'Preferences'}\n </Button>\n <Button\n size=\"small\"\n variant=\"outlined\"\n onClick={() => decide('declined')}\n >\n {'Decline'}\n </Button>\n <Button\n size=\"small\"\n variant=\"contained\"\n onClick={() => decide('accepted', advertising === true)}\n >\n {advertising ? 'Allow all' : 'Allow'}\n </Button>\n </Stack>\n </Stack>\n </Paper>\n )\n }\n\n if (!showPill) return null\n\n // The pill renders whenever no other surface is up — INCLUDING the\n // implied posture, where it is the only opt-out surface there is.\n return (\n <Button\n ref={pillRef}\n type=\"button\"\n // No ripple, and it is not cosmetic: `consent-opt-out-title.spec.tsx`\n // reads the control's LAST child to prove the §7015 title is the text\n // immediately right of the §7015 mark, and a ripple span would be the\n // last child instead.\n disableRipple\n data-aglyn-consent-pill=\"\"\n aria-label={CONSENT_OPT_OUT_TITLE}\n variant=\"outlined\"\n size=\"small\"\n onPointerEnter={warmPreferences}\n onFocus={warmPreferences}\n onClick={() => {\n const current = onDecision ? stored : readStoredVisitorConsent(hostId)\n setAnalyticsChecked(current?.analytics === true)\n setAdsChecked(current?.advertising === true)\n setPreferencesOpen(true)\n }}\n sx={{\n position: 'fixed',\n left: 12,\n bottom: 12,\n zIndex: CONSENT_PILL_Z_INDEX,\n gap: 0.75,\n flexWrap: 'wrap',\n maxWidth: 'calc(100vw - 24px)',\n borderRadius: 999,\n textTransform: 'none',\n color: 'text.secondary',\n borderColor: 'divider',\n backgroundColor: 'background.paper',\n }}\n >\n {/*\n Icon FIRST: §7015 places the opt-out icon immediately to the left of\n the title, and this is the control the regulation is about. The\n prior-consent banner deliberately gets neither the title nor the icon\n — it is a consent solicitation that disappears once answered, so\n dressing it in the regulation's mark would advertise it as the\n persistent opt-out link it cannot be.\n */}\n <CcpaOptOutIcon />\n {CONSENT_OPT_OUT_TITLE}\n </Button>\n )\n}\n\nexport default ConsentBannerUi\n"],"names":["Box","Button","Paper","Stack","Typography","useEffect","useRef","useState","readStoredVisitorConsent","refusalStatusFor","storeVisitorConsent","VISITOR_CONSENT_OPEN_EVENT","CONSENT_OPT_OUT_TITLE","OPT_OUT_ICON_LEFT_FIELD_PATH","OPT_OUT_ICON_SHELL_PATH","OPT_OUT_ICON_CROSS_PATH","OPT_OUT_ICON_CHECK_PATH","OPT_OUT_ICON_BLUE","OPT_OUT_ICON_WHITE","CcpaOptOutIcon","svg","xmlns","viewBox","width","height","aria-hidden","focusable","style","flexShrink","display","data-aglyn-consent-optout-icon","path","d","fill","fillRule","clipRule","CONSENT_OVERLAY_Z_INDEX","CONSENT_PILL_Z_INDEX","CARD_WIDTH","PILL_CLEARANCE","FOOTER_SELECTOR","consentPillClearance","viewportHeight","pillTop","Number","isFinite","Math","max","ceil","useConsentPillClearance","pillRef","active","doc","pill","current","ownerDocument","view","defaultView","target","querySelector","body","previous","getPropertyValue","previousPriority","getPropertyPriority","restore","setProperty","removeProperty","apply","natural","parseFloat","getComputedStyle","paddingBottom","needed","innerHeight","getBoundingClientRect","top","addEventListener","observer","ResizeObserver","undefined","observe","removeEventListener","disconnect","DEFAULT_COPY","panelIntro","strictlyNecessary","bannerAnalyticsOnly","bannerWithAdvertising","analyticsLabel","analyticsDetail","advertisingLabel","advertisingDetail","overlayCardSx","position","left","bottom","transform","zIndex","p","borderRadius","textAlign","loadedPreferencesDialog","preferencesDialogLoad","preloadConsentPreferences","then","module","ConsentPreferencesDialog","catch","error","warmPreferences","ConsentBannerUi","props","hostId","stored","posture","country","advertising","copy","policyLinks","showPill","onDecision","words","preferencesOpen","setPreferencesOpen","analyticsChecked","setAnalyticsChecked","analytics","adsChecked","setAdsChecked","open","onClick","event","anchor","closest","getAttribute","endsWith","preventDefault","window","document","decide","status","ads","granted","refusalStatus","setPreferencesArrived","PreferencesDialog","askBanner","title","onAnalyticsChange","onAdsChange","onClose","onDeclineAll","onSave","elevation","role","aria-label","data-aglyn-consent-banner","sx","direction","xs","sm","spacing","alignItems","flex","minWidth","variant","mt","flexWrap","size","onPointerEnter","onFocus","ref","type","disableRipple","data-aglyn-consent-pill","gap","maxWidth","textTransform","color","borderColor","backgroundColor"],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* CONSENT GROUPS — the declared unit a marketing basis is given to.
|
|
19
|
+
*
|
|
20
|
+
* ## The two organizations this exists to serve at once
|
|
21
|
+
*
|
|
22
|
+
* An AGENCY runs twelve unrelated client brands out of one account. A person
|
|
23
|
+
* who ticked a box on one client's form has agreed to hear from that client
|
|
24
|
+
* and from nobody else, and mailing them on behalf of the other eleven is a
|
|
25
|
+
* consent violation whatever the account structure says.
|
|
26
|
+
*
|
|
27
|
+
* A SINGLE BUSINESS runs three sites — a shop, a booking page, a blog — under
|
|
28
|
+
* one name. It collects addresses on all three and mails them from any of
|
|
29
|
+
* them, because there is one controller and one brand and the visitor knows
|
|
30
|
+
* it. Refusing that is not caution, it is a product that cannot serve a
|
|
31
|
+
* perfectly ordinary customer.
|
|
32
|
+
*
|
|
33
|
+
* The org boundary cannot tell them apart, and neither can anything else the
|
|
34
|
+
* database already holds. So the difference is DECLARED: a group names the
|
|
35
|
+
* sites that are one sender. Undeclared, every site is its own group of one,
|
|
36
|
+
* which is the agency's answer and costs the agency nothing to get right.
|
|
37
|
+
*
|
|
38
|
+
* ## ⛔ NOTHING HERE IS INFERRED
|
|
39
|
+
*
|
|
40
|
+
* Not from shared ownership, not from a shared org, not from a shared sending
|
|
41
|
+
* domain, not from a shared theme. Sharing an account is a billing fact.
|
|
42
|
+
* There is exactly one input — {@link CONSENT_GROUPS_FIELD} on the org — and
|
|
43
|
+
* a site that is not named in it is alone.
|
|
44
|
+
*
|
|
45
|
+
* ## A group must be DISCLOSABLE, so it must have a NAME
|
|
46
|
+
*
|
|
47
|
+
* Pooling is only legitimate if the person was told about it: the checkbox
|
|
48
|
+
* has to say who they will hear from. A group with no display name cannot be
|
|
49
|
+
* rendered on a capture surface, so it cannot be disclosed, so it does not
|
|
50
|
+
* pool — {@link consentGroupForHost} returns the group of one for every site
|
|
51
|
+
* in a nameless group rather than pooling silently. That refusal is the whole
|
|
52
|
+
* mechanism by which "declared" is stronger than "configured".
|
|
53
|
+
*
|
|
54
|
+
* ## Pooling applies FORWARD only
|
|
55
|
+
*
|
|
56
|
+
* A grant records the group AS DISCLOSED at the moment it was given, in the
|
|
57
|
+
* entry itself, and every covered site gets its own entry. Adding a site to a
|
|
58
|
+
* group therefore reaches captures made after the change and none made
|
|
59
|
+
* before. An org-level switch that widened existing grants would be the leak
|
|
60
|
+
* wearing a different hat: the people already on the list were told a
|
|
61
|
+
* different thing.
|
|
62
|
+
*
|
|
63
|
+
* OPT-OUT runs the other way — read against the CURRENT group, so a site
|
|
64
|
+
* joining a group inherits every refusal already standing against it. The
|
|
65
|
+
* asymmetry is the same one the rest of this area keeps: a permissive fact is
|
|
66
|
+
* written narrowly and read exactly, a restrictive fact is read as broadly as
|
|
67
|
+
* it could possibly apply.
|
|
68
|
+
*
|
|
69
|
+
* ## VISIBILITY IS A SEPARATE AXIS
|
|
70
|
+
*
|
|
71
|
+
* Seeing a contact is not permission to mail them. A group decides consent
|
|
72
|
+
* and opt-out; `visibleTo` decides who can read the row, and an org may
|
|
73
|
+
* widen that for reporting while consent stays where it was given. The two
|
|
74
|
+
* are resolved by different functions on purpose, and neither reads the
|
|
75
|
+
* other.
|
|
76
|
+
*/
|
|
77
|
+
import { type ScopeToken } from './scope-tokens';
|
|
78
|
+
/**
|
|
79
|
+
* The org field holding the declarations:
|
|
80
|
+
* `{ [groupId]: { name, hostIds } }`.
|
|
81
|
+
*
|
|
82
|
+
* On the org rather than on each host, because a group is a statement ABOUT
|
|
83
|
+
* a set and a set stored as N per-host pointers can disagree with itself —
|
|
84
|
+
* site A naming a group that site B has left is a half-declared controller,
|
|
85
|
+
* and there is no reading of that which is safe to pool on.
|
|
86
|
+
*/
|
|
87
|
+
export declare const CONSENT_GROUPS_FIELD = "consentGroups";
|
|
88
|
+
/**
|
|
89
|
+
* The most sites one group may name.
|
|
90
|
+
*
|
|
91
|
+
* The same ceiling `visibleTo` carries, and for a related reason: the send
|
|
92
|
+
* path reads a group's opt-out lists in one `getAll`, so the group multiplies
|
|
93
|
+
* that round trip's size. It is also a sanity bound on a disclosure — a
|
|
94
|
+
* checkbox that has to name forty brands has not disclosed anything.
|
|
95
|
+
*/
|
|
96
|
+
export declare const MAX_CONSENT_GROUP_HOSTS = 30;
|
|
97
|
+
/** One declared group, as stored. */
|
|
98
|
+
export interface StoredConsentGroup {
|
|
99
|
+
/** Shown on the capture surface. Without it the group cannot pool. */
|
|
100
|
+
name: string;
|
|
101
|
+
/** The sites that are one sender. */
|
|
102
|
+
hostIds: string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The group a host belongs to, resolved FOR that host.
|
|
106
|
+
*
|
|
107
|
+
* It carries the asking site as well as the set, which is what lets one value
|
|
108
|
+
* be passed where both are needed. Every consent read needs both — the grant
|
|
109
|
+
* is looked up under the asking site, while a refusal is honored across the
|
|
110
|
+
* whole group — and two arguments that must agree is two arguments that can
|
|
111
|
+
* disagree.
|
|
112
|
+
*/
|
|
113
|
+
export interface ConsentGroup {
|
|
114
|
+
/** The site this was resolved for. Always a member of {@link hostIds}. */
|
|
115
|
+
hostId: string;
|
|
116
|
+
/**
|
|
117
|
+
* The group's id, or the host's own id for an undeclared site.
|
|
118
|
+
*
|
|
119
|
+
* Recorded on every grant so a stored basis says which controller it was
|
|
120
|
+
* given to even after the declaration changes.
|
|
121
|
+
*/
|
|
122
|
+
groupId: string;
|
|
123
|
+
/**
|
|
124
|
+
* What the capture surface must display. `null` for a group of one, where
|
|
125
|
+
* the site's own name is what a form already shows and inventing a second
|
|
126
|
+
* one would put a name in front of a person that nothing else uses.
|
|
127
|
+
*/
|
|
128
|
+
name: string | null;
|
|
129
|
+
/** Every site covered, sorted, always including the host asked about. */
|
|
130
|
+
hostIds: string[];
|
|
131
|
+
/** False for the implicit group of one. */
|
|
132
|
+
declared: boolean;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The group of one — a site that has declared no pooling.
|
|
136
|
+
*
|
|
137
|
+
* Exported because it is a value callers state deliberately: a writer that
|
|
138
|
+
* means "this site only" says so, rather than passing a host id and letting
|
|
139
|
+
* a helper decide what it covers.
|
|
140
|
+
*/
|
|
141
|
+
export declare function soloConsentGroup(hostId: string): ConsentGroup;
|
|
142
|
+
/**
|
|
143
|
+
* Reads the declared groups off an org document, dropping every entry that
|
|
144
|
+
* cannot be honored.
|
|
145
|
+
*
|
|
146
|
+
* A malformed declaration reads as ABSENT, never as a wider group: the whole
|
|
147
|
+
* value of this field is that pooling is deliberate, and a corrupt value must
|
|
148
|
+
* not be a way to reach an audience nobody declared.
|
|
149
|
+
*
|
|
150
|
+
* The four refusals, each of which would otherwise pool without a disclosure:
|
|
151
|
+
*
|
|
152
|
+
* - **no usable name** — cannot be shown on a form, so cannot be disclosed;
|
|
153
|
+
* - **fewer than two sites** — not a pooling declaration, and a group of one
|
|
154
|
+
* is what an undeclared site already gets;
|
|
155
|
+
* - **over {@link MAX_CONSENT_GROUP_HOSTS}** — see that constant;
|
|
156
|
+
* - **a site claimed by two groups** — two controllers claiming one site is
|
|
157
|
+
* a contradiction, not a wider group, so BOTH claims are dropped and the
|
|
158
|
+
* site falls back to being alone.
|
|
159
|
+
*/
|
|
160
|
+
export declare function readConsentGroups(org: Record<string, unknown> | null | undefined): Record<string, StoredConsentGroup>;
|
|
161
|
+
/**
|
|
162
|
+
* The group `hostId` belongs to — the declared one, or the group of one.
|
|
163
|
+
*
|
|
164
|
+
* The ONLY way any caller learns what a site's consent covers. A caller that
|
|
165
|
+
* built its own set from `org.hosts`, or from a sending domain, or from a
|
|
166
|
+
* theme, would be inferring a controller, which is the thing this module
|
|
167
|
+
* exists to make impossible.
|
|
168
|
+
*/
|
|
169
|
+
export declare function consentGroupForHost(org: Record<string, unknown> | null | undefined, hostId: string): ConsentGroup;
|
|
170
|
+
/**
|
|
171
|
+
* The `visibleTo` a resource captured by this group starts with.
|
|
172
|
+
*
|
|
173
|
+
* A separate function from anything above, called by the capture doors and
|
|
174
|
+
* by nothing that decides mailability, because visibility and consent are
|
|
175
|
+
* different questions with different answers. A group of one produces
|
|
176
|
+
* `['host:{id}']` — the isolation an agency needs, arrived at without the
|
|
177
|
+
* agency configuring anything.
|
|
178
|
+
*/
|
|
179
|
+
export declare function consentGroupScope(group: ConsentGroup): ScopeToken[];
|
|
180
|
+
/**
|
|
181
|
+
* The sentence a capture surface must show beside the checkbox, or `null`
|
|
182
|
+
* when the site's own name already says it.
|
|
183
|
+
*
|
|
184
|
+
* Returned as text rather than a boolean so that the disclosure and the
|
|
185
|
+
* grant come from ONE resolved group: a form that rendered its own wording
|
|
186
|
+
* from a separate lookup could show one set of brands and record another,
|
|
187
|
+
* and the recorded set is the one that decides who mails this person.
|
|
188
|
+
*/
|
|
189
|
+
export declare function consentGroupDisclosure(group: ConsentGroup): string | null;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ /**
|
|
17
|
+
* CONSENT GROUPS — the declared unit a marketing basis is given to.
|
|
18
|
+
*
|
|
19
|
+
* ## The two organizations this exists to serve at once
|
|
20
|
+
*
|
|
21
|
+
* An AGENCY runs twelve unrelated client brands out of one account. A person
|
|
22
|
+
* who ticked a box on one client's form has agreed to hear from that client
|
|
23
|
+
* and from nobody else, and mailing them on behalf of the other eleven is a
|
|
24
|
+
* consent violation whatever the account structure says.
|
|
25
|
+
*
|
|
26
|
+
* A SINGLE BUSINESS runs three sites — a shop, a booking page, a blog — under
|
|
27
|
+
* one name. It collects addresses on all three and mails them from any of
|
|
28
|
+
* them, because there is one controller and one brand and the visitor knows
|
|
29
|
+
* it. Refusing that is not caution, it is a product that cannot serve a
|
|
30
|
+
* perfectly ordinary customer.
|
|
31
|
+
*
|
|
32
|
+
* The org boundary cannot tell them apart, and neither can anything else the
|
|
33
|
+
* database already holds. So the difference is DECLARED: a group names the
|
|
34
|
+
* sites that are one sender. Undeclared, every site is its own group of one,
|
|
35
|
+
* which is the agency's answer and costs the agency nothing to get right.
|
|
36
|
+
*
|
|
37
|
+
* ## ⛔ NOTHING HERE IS INFERRED
|
|
38
|
+
*
|
|
39
|
+
* Not from shared ownership, not from a shared org, not from a shared sending
|
|
40
|
+
* domain, not from a shared theme. Sharing an account is a billing fact.
|
|
41
|
+
* There is exactly one input — {@link CONSENT_GROUPS_FIELD} on the org — and
|
|
42
|
+
* a site that is not named in it is alone.
|
|
43
|
+
*
|
|
44
|
+
* ## A group must be DISCLOSABLE, so it must have a NAME
|
|
45
|
+
*
|
|
46
|
+
* Pooling is only legitimate if the person was told about it: the checkbox
|
|
47
|
+
* has to say who they will hear from. A group with no display name cannot be
|
|
48
|
+
* rendered on a capture surface, so it cannot be disclosed, so it does not
|
|
49
|
+
* pool — {@link consentGroupForHost} returns the group of one for every site
|
|
50
|
+
* in a nameless group rather than pooling silently. That refusal is the whole
|
|
51
|
+
* mechanism by which "declared" is stronger than "configured".
|
|
52
|
+
*
|
|
53
|
+
* ## Pooling applies FORWARD only
|
|
54
|
+
*
|
|
55
|
+
* A grant records the group AS DISCLOSED at the moment it was given, in the
|
|
56
|
+
* entry itself, and every covered site gets its own entry. Adding a site to a
|
|
57
|
+
* group therefore reaches captures made after the change and none made
|
|
58
|
+
* before. An org-level switch that widened existing grants would be the leak
|
|
59
|
+
* wearing a different hat: the people already on the list were told a
|
|
60
|
+
* different thing.
|
|
61
|
+
*
|
|
62
|
+
* OPT-OUT runs the other way — read against the CURRENT group, so a site
|
|
63
|
+
* joining a group inherits every refusal already standing against it. The
|
|
64
|
+
* asymmetry is the same one the rest of this area keeps: a permissive fact is
|
|
65
|
+
* written narrowly and read exactly, a restrictive fact is read as broadly as
|
|
66
|
+
* it could possibly apply.
|
|
67
|
+
*
|
|
68
|
+
* ## VISIBILITY IS A SEPARATE AXIS
|
|
69
|
+
*
|
|
70
|
+
* Seeing a contact is not permission to mail them. A group decides consent
|
|
71
|
+
* and opt-out; `visibleTo` decides who can read the row, and an org may
|
|
72
|
+
* widen that for reporting while consent stays where it was given. The two
|
|
73
|
+
* are resolved by different functions on purpose, and neither reads the
|
|
74
|
+
* other.
|
|
75
|
+
*/ import { hostScopeToken, MAX_SCOPE_HOSTS } from "./scope-tokens.js";
|
|
76
|
+
/**
|
|
77
|
+
* The org field holding the declarations:
|
|
78
|
+
* `{ [groupId]: { name, hostIds } }`.
|
|
79
|
+
*
|
|
80
|
+
* On the org rather than on each host, because a group is a statement ABOUT
|
|
81
|
+
* a set and a set stored as N per-host pointers can disagree with itself —
|
|
82
|
+
* site A naming a group that site B has left is a half-declared controller,
|
|
83
|
+
* and there is no reading of that which is safe to pool on.
|
|
84
|
+
*/ export const CONSENT_GROUPS_FIELD = 'consentGroups';
|
|
85
|
+
/**
|
|
86
|
+
* The most sites one group may name.
|
|
87
|
+
*
|
|
88
|
+
* The same ceiling `visibleTo` carries, and for a related reason: the send
|
|
89
|
+
* path reads a group's opt-out lists in one `getAll`, so the group multiplies
|
|
90
|
+
* that round trip's size. It is also a sanity bound on a disclosure — a
|
|
91
|
+
* checkbox that has to name forty brands has not disclosed anything.
|
|
92
|
+
*/ export const MAX_CONSENT_GROUP_HOSTS = MAX_SCOPE_HOSTS;
|
|
93
|
+
/**
|
|
94
|
+
* The group of one — a site that has declared no pooling.
|
|
95
|
+
*
|
|
96
|
+
* Exported because it is a value callers state deliberately: a writer that
|
|
97
|
+
* means "this site only" says so, rather than passing a host id and letting
|
|
98
|
+
* a helper decide what it covers.
|
|
99
|
+
*/ export function soloConsentGroup(hostId) {
|
|
100
|
+
if (!hostId) {
|
|
101
|
+
throw new Error('[consent-groups] a consent group must name a site');
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
hostId,
|
|
105
|
+
groupId: hostId,
|
|
106
|
+
name: null,
|
|
107
|
+
hostIds: [
|
|
108
|
+
hostId
|
|
109
|
+
],
|
|
110
|
+
declared: false
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Reads the declared groups off an org document, dropping every entry that
|
|
115
|
+
* cannot be honored.
|
|
116
|
+
*
|
|
117
|
+
* A malformed declaration reads as ABSENT, never as a wider group: the whole
|
|
118
|
+
* value of this field is that pooling is deliberate, and a corrupt value must
|
|
119
|
+
* not be a way to reach an audience nobody declared.
|
|
120
|
+
*
|
|
121
|
+
* The four refusals, each of which would otherwise pool without a disclosure:
|
|
122
|
+
*
|
|
123
|
+
* - **no usable name** — cannot be shown on a form, so cannot be disclosed;
|
|
124
|
+
* - **fewer than two sites** — not a pooling declaration, and a group of one
|
|
125
|
+
* is what an undeclared site already gets;
|
|
126
|
+
* - **over {@link MAX_CONSENT_GROUP_HOSTS}** — see that constant;
|
|
127
|
+
* - **a site claimed by two groups** — two controllers claiming one site is
|
|
128
|
+
* a contradiction, not a wider group, so BOTH claims are dropped and the
|
|
129
|
+
* site falls back to being alone.
|
|
130
|
+
*/ export function readConsentGroups(org) {
|
|
131
|
+
const raw = (org != null ? org : {})[CONSENT_GROUPS_FIELD];
|
|
132
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {};
|
|
133
|
+
const usable = {};
|
|
134
|
+
for (const [groupId, value] of Object.entries(raw)){
|
|
135
|
+
if (!groupId || !value || typeof value !== 'object') continue;
|
|
136
|
+
const group = value;
|
|
137
|
+
const name = typeof group['name'] === 'string' ? group['name'].trim() : '';
|
|
138
|
+
if (!name) continue;
|
|
139
|
+
const hostIds = Array.isArray(group['hostIds']) ? [
|
|
140
|
+
...new Set(group['hostIds'].map((id)=>String(id != null ? id : '').trim()).filter(Boolean))
|
|
141
|
+
].sort() : [];
|
|
142
|
+
if (hostIds.length < 2 || hostIds.length > MAX_CONSENT_GROUP_HOSTS) continue;
|
|
143
|
+
usable[groupId] = {
|
|
144
|
+
name,
|
|
145
|
+
hostIds
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/*
|
|
149
|
+
* The overlap pass, second because it needs every survivor of the first.
|
|
150
|
+
* A site named by two groups is dropped from BOTH — the alternative is
|
|
151
|
+
* picking one, and a coin flip is not a declaration.
|
|
152
|
+
*/ const claims = new Map();
|
|
153
|
+
for (const group of Object.values(usable)){
|
|
154
|
+
for (const hostId of group.hostIds){
|
|
155
|
+
var _claims_get;
|
|
156
|
+
claims.set(hostId, ((_claims_get = claims.get(hostId)) != null ? _claims_get : 0) + 1);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const contested = new Set([
|
|
160
|
+
...claims.entries()
|
|
161
|
+
].filter(([, count])=>count > 1).map(([id])=>id));
|
|
162
|
+
if (!contested.size) return usable;
|
|
163
|
+
const settled = {};
|
|
164
|
+
for (const [groupId, group] of Object.entries(usable)){
|
|
165
|
+
if (group.hostIds.some((hostId)=>contested.has(hostId))) continue;
|
|
166
|
+
settled[groupId] = group;
|
|
167
|
+
}
|
|
168
|
+
return settled;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The group `hostId` belongs to — the declared one, or the group of one.
|
|
172
|
+
*
|
|
173
|
+
* The ONLY way any caller learns what a site's consent covers. A caller that
|
|
174
|
+
* built its own set from `org.hosts`, or from a sending domain, or from a
|
|
175
|
+
* theme, would be inferring a controller, which is the thing this module
|
|
176
|
+
* exists to make impossible.
|
|
177
|
+
*/ export function consentGroupForHost(org, hostId) {
|
|
178
|
+
if (!hostId) {
|
|
179
|
+
throw new Error('[consent-groups] a consent group must name a site');
|
|
180
|
+
}
|
|
181
|
+
for (const [groupId, group] of Object.entries(readConsentGroups(org))){
|
|
182
|
+
if (!group.hostIds.includes(hostId)) continue;
|
|
183
|
+
return {
|
|
184
|
+
hostId,
|
|
185
|
+
groupId,
|
|
186
|
+
name: group.name,
|
|
187
|
+
hostIds: [
|
|
188
|
+
...group.hostIds
|
|
189
|
+
],
|
|
190
|
+
declared: true
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return soloConsentGroup(hostId);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The `visibleTo` a resource captured by this group starts with.
|
|
197
|
+
*
|
|
198
|
+
* A separate function from anything above, called by the capture doors and
|
|
199
|
+
* by nothing that decides mailability, because visibility and consent are
|
|
200
|
+
* different questions with different answers. A group of one produces
|
|
201
|
+
* `['host:{id}']` — the isolation an agency needs, arrived at without the
|
|
202
|
+
* agency configuring anything.
|
|
203
|
+
*/ export function consentGroupScope(group) {
|
|
204
|
+
return group.hostIds.map(hostScopeToken);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* The sentence a capture surface must show beside the checkbox, or `null`
|
|
208
|
+
* when the site's own name already says it.
|
|
209
|
+
*
|
|
210
|
+
* Returned as text rather than a boolean so that the disclosure and the
|
|
211
|
+
* grant come from ONE resolved group: a form that rendered its own wording
|
|
212
|
+
* from a separate lookup could show one set of brands and record another,
|
|
213
|
+
* and the recorded set is the one that decides who mails this person.
|
|
214
|
+
*/ export function consentGroupDisclosure(group) {
|
|
215
|
+
if (!group.declared || !group.name) return null;
|
|
216
|
+
return `You'll receive marketing email from ${group.name}, which covers ${group.hostIds.length} sites.`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//# sourceMappingURL=consent-groups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/consent-groups.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * CONSENT GROUPS — the declared unit a marketing basis is given to.\n *\n * ## The two organizations this exists to serve at once\n *\n * An AGENCY runs twelve unrelated client brands out of one account. A person\n * who ticked a box on one client's form has agreed to hear from that client\n * and from nobody else, and mailing them on behalf of the other eleven is a\n * consent violation whatever the account structure says.\n *\n * A SINGLE BUSINESS runs three sites — a shop, a booking page, a blog — under\n * one name. It collects addresses on all three and mails them from any of\n * them, because there is one controller and one brand and the visitor knows\n * it. Refusing that is not caution, it is a product that cannot serve a\n * perfectly ordinary customer.\n *\n * The org boundary cannot tell them apart, and neither can anything else the\n * database already holds. So the difference is DECLARED: a group names the\n * sites that are one sender. Undeclared, every site is its own group of one,\n * which is the agency's answer and costs the agency nothing to get right.\n *\n * ## ⛔ NOTHING HERE IS INFERRED\n *\n * Not from shared ownership, not from a shared org, not from a shared sending\n * domain, not from a shared theme. Sharing an account is a billing fact.\n * There is exactly one input — {@link CONSENT_GROUPS_FIELD} on the org — and\n * a site that is not named in it is alone.\n *\n * ## A group must be DISCLOSABLE, so it must have a NAME\n *\n * Pooling is only legitimate if the person was told about it: the checkbox\n * has to say who they will hear from. A group with no display name cannot be\n * rendered on a capture surface, so it cannot be disclosed, so it does not\n * pool — {@link consentGroupForHost} returns the group of one for every site\n * in a nameless group rather than pooling silently. That refusal is the whole\n * mechanism by which \"declared\" is stronger than \"configured\".\n *\n * ## Pooling applies FORWARD only\n *\n * A grant records the group AS DISCLOSED at the moment it was given, in the\n * entry itself, and every covered site gets its own entry. Adding a site to a\n * group therefore reaches captures made after the change and none made\n * before. An org-level switch that widened existing grants would be the leak\n * wearing a different hat: the people already on the list were told a\n * different thing.\n *\n * OPT-OUT runs the other way — read against the CURRENT group, so a site\n * joining a group inherits every refusal already standing against it. The\n * asymmetry is the same one the rest of this area keeps: a permissive fact is\n * written narrowly and read exactly, a restrictive fact is read as broadly as\n * it could possibly apply.\n *\n * ## VISIBILITY IS A SEPARATE AXIS\n *\n * Seeing a contact is not permission to mail them. A group decides consent\n * and opt-out; `visibleTo` decides who can read the row, and an org may\n * widen that for reporting while consent stays where it was given. The two\n * are resolved by different functions on purpose, and neither reads the\n * other.\n */\n\nimport { hostScopeToken, MAX_SCOPE_HOSTS, type ScopeToken } from './scope-tokens'\n\n/**\n * The org field holding the declarations:\n * `{ [groupId]: { name, hostIds } }`.\n *\n * On the org rather than on each host, because a group is a statement ABOUT\n * a set and a set stored as N per-host pointers can disagree with itself —\n * site A naming a group that site B has left is a half-declared controller,\n * and there is no reading of that which is safe to pool on.\n */\nexport const CONSENT_GROUPS_FIELD = 'consentGroups'\n\n/**\n * The most sites one group may name.\n *\n * The same ceiling `visibleTo` carries, and for a related reason: the send\n * path reads a group's opt-out lists in one `getAll`, so the group multiplies\n * that round trip's size. It is also a sanity bound on a disclosure — a\n * checkbox that has to name forty brands has not disclosed anything.\n */\nexport const MAX_CONSENT_GROUP_HOSTS = MAX_SCOPE_HOSTS\n\n/** One declared group, as stored. */\nexport interface StoredConsentGroup {\n /** Shown on the capture surface. Without it the group cannot pool. */\n name: string\n /** The sites that are one sender. */\n hostIds: string[]\n}\n\n/**\n * The group a host belongs to, resolved FOR that host.\n *\n * It carries the asking site as well as the set, which is what lets one value\n * be passed where both are needed. Every consent read needs both — the grant\n * is looked up under the asking site, while a refusal is honored across the\n * whole group — and two arguments that must agree is two arguments that can\n * disagree.\n */\nexport interface ConsentGroup {\n /** The site this was resolved for. Always a member of {@link hostIds}. */\n hostId: string\n /**\n * The group's id, or the host's own id for an undeclared site.\n *\n * Recorded on every grant so a stored basis says which controller it was\n * given to even after the declaration changes.\n */\n groupId: string\n /**\n * What the capture surface must display. `null` for a group of one, where\n * the site's own name is what a form already shows and inventing a second\n * one would put a name in front of a person that nothing else uses.\n */\n name: string | null\n /** Every site covered, sorted, always including the host asked about. */\n hostIds: string[]\n /** False for the implicit group of one. */\n declared: boolean\n}\n\n/**\n * The group of one — a site that has declared no pooling.\n *\n * Exported because it is a value callers state deliberately: a writer that\n * means \"this site only\" says so, rather than passing a host id and letting\n * a helper decide what it covers.\n */\nexport function soloConsentGroup(hostId: string): ConsentGroup {\n if (!hostId) {\n throw new Error('[consent-groups] a consent group must name a site')\n }\n return {\n hostId,\n groupId: hostId,\n name: null,\n hostIds: [hostId],\n declared: false,\n }\n}\n\n/**\n * Reads the declared groups off an org document, dropping every entry that\n * cannot be honored.\n *\n * A malformed declaration reads as ABSENT, never as a wider group: the whole\n * value of this field is that pooling is deliberate, and a corrupt value must\n * not be a way to reach an audience nobody declared.\n *\n * The four refusals, each of which would otherwise pool without a disclosure:\n *\n * - **no usable name** — cannot be shown on a form, so cannot be disclosed;\n * - **fewer than two sites** — not a pooling declaration, and a group of one\n * is what an undeclared site already gets;\n * - **over {@link MAX_CONSENT_GROUP_HOSTS}** — see that constant;\n * - **a site claimed by two groups** — two controllers claiming one site is\n * a contradiction, not a wider group, so BOTH claims are dropped and the\n * site falls back to being alone.\n */\nexport function readConsentGroups(\n org: Record<string, unknown> | null | undefined,\n): Record<string, StoredConsentGroup> {\n const raw = (org ?? {})[CONSENT_GROUPS_FIELD]\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {}\n const usable: Record<string, StoredConsentGroup> = {}\n for (const [groupId, value] of Object.entries(raw as Record<string, unknown>)) {\n if (!groupId || !value || typeof value !== 'object') continue\n const group = value as Record<string, unknown>\n const name = typeof group['name'] === 'string' ? group['name'].trim() : ''\n if (!name) continue\n const hostIds = Array.isArray(group['hostIds'])\n ? [\n ...new Set(\n (group['hostIds'] as unknown[])\n .map((id) => String(id ?? '').trim())\n .filter(Boolean),\n ),\n ].sort()\n : []\n if (hostIds.length < 2 || hostIds.length > MAX_CONSENT_GROUP_HOSTS) continue\n usable[groupId] = { name, hostIds }\n }\n /*\n * The overlap pass, second because it needs every survivor of the first.\n * A site named by two groups is dropped from BOTH — the alternative is\n * picking one, and a coin flip is not a declaration.\n */\n const claims = new Map<string, number>()\n for (const group of Object.values(usable)) {\n for (const hostId of group.hostIds) {\n claims.set(hostId, (claims.get(hostId) ?? 0) + 1)\n }\n }\n const contested = new Set(\n [...claims.entries()].filter(([, count]) => count > 1).map(([id]) => id),\n )\n if (!contested.size) return usable\n const settled: Record<string, StoredConsentGroup> = {}\n for (const [groupId, group] of Object.entries(usable)) {\n if (group.hostIds.some((hostId) => contested.has(hostId))) continue\n settled[groupId] = group\n }\n return settled\n}\n\n/**\n * The group `hostId` belongs to — the declared one, or the group of one.\n *\n * The ONLY way any caller learns what a site's consent covers. A caller that\n * built its own set from `org.hosts`, or from a sending domain, or from a\n * theme, would be inferring a controller, which is the thing this module\n * exists to make impossible.\n */\nexport function consentGroupForHost(\n org: Record<string, unknown> | null | undefined,\n hostId: string,\n): ConsentGroup {\n if (!hostId) {\n throw new Error('[consent-groups] a consent group must name a site')\n }\n for (const [groupId, group] of Object.entries(readConsentGroups(org))) {\n if (!group.hostIds.includes(hostId)) continue\n return {\n hostId,\n groupId,\n name: group.name,\n hostIds: [...group.hostIds],\n declared: true,\n }\n }\n return soloConsentGroup(hostId)\n}\n\n/**\n * The `visibleTo` a resource captured by this group starts with.\n *\n * A separate function from anything above, called by the capture doors and\n * by nothing that decides mailability, because visibility and consent are\n * different questions with different answers. A group of one produces\n * `['host:{id}']` — the isolation an agency needs, arrived at without the\n * agency configuring anything.\n */\nexport function consentGroupScope(group: ConsentGroup): ScopeToken[] {\n return group.hostIds.map(hostScopeToken)\n}\n\n/**\n * The sentence a capture surface must show beside the checkbox, or `null`\n * when the site's own name already says it.\n *\n * Returned as text rather than a boolean so that the disclosure and the\n * grant come from ONE resolved group: a form that rendered its own wording\n * from a separate lookup could show one set of brands and record another,\n * and the recorded set is the one that decides who mails this person.\n */\nexport function consentGroupDisclosure(group: ConsentGroup): string | null {\n if (!group.declared || !group.name) return null\n return `You'll receive marketing email from ${group.name}, which covers ${group.hostIds.length} sites.`\n}\n"],"names":["hostScopeToken","MAX_SCOPE_HOSTS","CONSENT_GROUPS_FIELD","MAX_CONSENT_GROUP_HOSTS","soloConsentGroup","hostId","Error","groupId","name","hostIds","declared","readConsentGroups","org","raw","Array","isArray","usable","value","Object","entries","group","trim","Set","map","id","String","filter","Boolean","sort","length","claims","Map","values","set","get","contested","count","size","settled","some","has","consentGroupForHost","includes","consentGroupScope","consentGroupDisclosure"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
18
|
+
/**
|
|
19
|
+
* The visitor consent preferences panel: one switch per category, and refuse
|
|
20
|
+
* and save as the same control at the same level.
|
|
21
|
+
*
|
|
22
|
+
* Its own module because it is the one consent surface a visit has to ASK
|
|
23
|
+
* for. The banner and the pill are drawn without a click; this panel opens
|
|
24
|
+
* only from Preferences, the pill or a `#aglyn-consent` link, and MUI's
|
|
25
|
+
* `Dialog`, `Modal`, focus trap, transitions and `Switch` are the larger half
|
|
26
|
+
* of what the consent surfaces weigh. `consent-banner-ui.tsx` loads this file
|
|
27
|
+
* when the panel is asked for (or looks about to be) and draws it from there;
|
|
28
|
+
* it holds the state, and this file only draws it.
|
|
29
|
+
*/
|
|
30
|
+
/** The words the panel shows — the `ConsentCopy` fields it reads, resolved. */
|
|
31
|
+
export interface ConsentPreferencesWords {
|
|
32
|
+
panelIntro: string;
|
|
33
|
+
strictlyNecessary: string;
|
|
34
|
+
analyticsLabel: string;
|
|
35
|
+
analyticsDetail: string;
|
|
36
|
+
advertisingLabel: string;
|
|
37
|
+
advertisingDetail: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ConsentPreferencesDialogProps {
|
|
40
|
+
/** The panel's title, fixed by regulation (`CONSENT_OPT_OUT_TITLE`). */
|
|
41
|
+
title: string;
|
|
42
|
+
/** Stacking order; it has to outrank any popup backdrop on the page. */
|
|
43
|
+
zIndex: number;
|
|
44
|
+
words: ConsentPreferencesWords;
|
|
45
|
+
/** Whether the surface asks about advertising storage at all. */
|
|
46
|
+
advertising?: boolean;
|
|
47
|
+
/** Links to the policies behind the choice, under the copy. */
|
|
48
|
+
policyLinks?: ReactNode;
|
|
49
|
+
analyticsChecked: boolean;
|
|
50
|
+
onAnalyticsChange: (checked: boolean) => void;
|
|
51
|
+
adsChecked: boolean;
|
|
52
|
+
onAdsChange: (checked: boolean) => void;
|
|
53
|
+
onClose: () => void;
|
|
54
|
+
onDeclineAll: () => void;
|
|
55
|
+
onSave: () => void;
|
|
56
|
+
}
|
|
57
|
+
export declare function ConsentPreferencesDialog(props: ConsentPreferencesDialogProps): ReactElement;
|
|
58
|
+
export default ConsentPreferencesDialog;
|