@kywi-software/core 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT-PATTERNS.md +153 -17
- package/README.md +38 -12
- package/dist/admin/chrome.d.ts.map +1 -1
- package/dist/admin/chrome.js +57 -8
- package/dist/admin/chrome.js.map +1 -1
- package/dist/admin/field-components.d.ts.map +1 -1
- package/dist/admin/field-components.js +27 -1
- package/dist/admin/field-components.js.map +1 -1
- package/dist/admin/form-helpers.d.ts.map +1 -1
- package/dist/admin/form-helpers.js +6 -1
- package/dist/admin/form-helpers.js.map +1 -1
- package/dist/admin/index.d.ts +1 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/layout-editor/chrome-env.d.ts +35 -0
- package/dist/admin/layout-editor/chrome-env.d.ts.map +1 -0
- package/dist/admin/layout-editor/chrome-env.js +13 -0
- package/dist/admin/layout-editor/chrome-env.js.map +1 -0
- package/dist/admin/layout-editor/component-actions.d.ts +58 -7
- package/dist/admin/layout-editor/component-actions.d.ts.map +1 -1
- package/dist/admin/layout-editor/component-actions.js +131 -5
- package/dist/admin/layout-editor/component-actions.js.map +1 -1
- package/dist/admin/layout-editor/component-fork.d.ts +4 -4
- package/dist/admin/layout-editor/component-fork.d.ts.map +1 -1
- package/dist/admin/layout-editor/component-fork.js +76 -10
- package/dist/admin/layout-editor/component-fork.js.map +1 -1
- package/dist/admin/layout-editor/component-picker-field.d.ts +17 -3
- package/dist/admin/layout-editor/component-picker-field.d.ts.map +1 -1
- package/dist/admin/layout-editor/component-picker-field.js +5 -2
- package/dist/admin/layout-editor/component-picker-field.js.map +1 -1
- package/dist/admin/layout-editor/drag-feedback.d.ts +25 -1
- package/dist/admin/layout-editor/drag-feedback.d.ts.map +1 -1
- package/dist/admin/layout-editor/drag-feedback.js +9 -0
- package/dist/admin/layout-editor/drag-feedback.js.map +1 -1
- package/dist/admin/layout-editor/drag-utils.d.ts +103 -5
- package/dist/admin/layout-editor/drag-utils.d.ts.map +1 -1
- package/dist/admin/layout-editor/drag-utils.js +131 -4
- package/dist/admin/layout-editor/drag-utils.js.map +1 -1
- package/dist/admin/layout-editor/editor-canvas.d.ts +11 -0
- package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-canvas.js +134 -20
- package/dist/admin/layout-editor/editor-canvas.js.map +1 -1
- package/dist/admin/layout-editor/editor-dialog.d.ts +58 -3
- package/dist/admin/layout-editor/editor-dialog.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-dialog.js +71 -9
- package/dist/admin/layout-editor/editor-dialog.js.map +1 -1
- package/dist/admin/layout-editor/editor-state.d.ts +119 -0
- package/dist/admin/layout-editor/editor-state.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-state.js +188 -6
- package/dist/admin/layout-editor/editor-state.js.map +1 -1
- package/dist/admin/layout-editor/editor-toolbar.d.ts +10 -1
- package/dist/admin/layout-editor/editor-toolbar.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-toolbar.js +2 -2
- package/dist/admin/layout-editor/editor-toolbar.js.map +1 -1
- package/dist/admin/layout-editor/editor.css +216 -8
- package/dist/admin/layout-editor/inline-text.d.ts +15 -1
- package/dist/admin/layout-editor/inline-text.d.ts.map +1 -1
- package/dist/admin/layout-editor/inline-text.js +30 -2
- package/dist/admin/layout-editor/inline-text.js.map +1 -1
- package/dist/admin/layout-editor/layout-editor.d.ts +21 -16
- package/dist/admin/layout-editor/layout-editor.d.ts.map +1 -1
- package/dist/admin/layout-editor/layout-editor.js +40 -17
- package/dist/admin/layout-editor/layout-editor.js.map +1 -1
- package/dist/admin/layout-editor/linked-component-notes.d.ts +88 -0
- package/dist/admin/layout-editor/linked-component-notes.d.ts.map +1 -0
- package/dist/admin/layout-editor/linked-component-notes.js +88 -0
- package/dist/admin/layout-editor/linked-component-notes.js.map +1 -0
- package/dist/admin/layout-editor/module-overlay.d.ts +23 -4
- package/dist/admin/layout-editor/module-overlay.d.ts.map +1 -1
- package/dist/admin/layout-editor/module-overlay.js +56 -10
- package/dist/admin/layout-editor/module-overlay.js.map +1 -1
- package/dist/admin/layout-editor/module-variant-container-config.d.ts.map +1 -1
- package/dist/admin/layout-editor/module-variant-container-config.js +9 -2
- package/dist/admin/layout-editor/module-variant-container-config.js.map +1 -1
- package/dist/admin/layout-editor/module-variant-container-panel.d.ts +75 -0
- package/dist/admin/layout-editor/module-variant-container-panel.d.ts.map +1 -0
- package/dist/admin/layout-editor/module-variant-container-panel.js +29 -0
- package/dist/admin/layout-editor/module-variant-container-panel.js.map +1 -0
- package/dist/admin/layout-editor/node-lookup.d.ts.map +1 -1
- package/dist/admin/layout-editor/node-lookup.js +33 -3
- package/dist/admin/layout-editor/node-lookup.js.map +1 -1
- package/dist/admin/layout-editor/overlay-shell.d.ts.map +1 -1
- package/dist/admin/layout-editor/overlay-shell.js +19 -4
- package/dist/admin/layout-editor/overlay-shell.js.map +1 -1
- package/dist/admin/layout-editor/props-panel.d.ts +28 -11
- package/dist/admin/layout-editor/props-panel.d.ts.map +1 -1
- package/dist/admin/layout-editor/props-panel.js +75 -125
- package/dist/admin/layout-editor/props-panel.js.map +1 -1
- package/dist/admin/layout-editor/section-variant-container-config.d.ts.map +1 -1
- package/dist/admin/layout-editor/section-variant-container-config.js +11 -2
- package/dist/admin/layout-editor/section-variant-container-config.js.map +1 -1
- package/dist/admin/layout-editor/use-chrome-flip.d.ts +99 -11
- package/dist/admin/layout-editor/use-chrome-flip.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-chrome-flip.js +268 -97
- package/dist/admin/layout-editor/use-chrome-flip.js.map +1 -1
- package/dist/admin/layout-editor/use-component-connect.d.ts +13 -0
- package/dist/admin/layout-editor/use-component-connect.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-component-connect.js +116 -20
- package/dist/admin/layout-editor/use-component-connect.js.map +1 -1
- package/dist/admin/layout-editor/use-component-fork.d.ts +49 -19
- package/dist/admin/layout-editor/use-component-fork.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-component-fork.js +28 -19
- package/dist/admin/layout-editor/use-component-fork.js.map +1 -1
- package/dist/admin/layout-editor/use-component-library.d.ts +4 -4
- package/dist/admin/layout-editor/use-component-library.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-component-library.js +1 -1
- package/dist/admin/layout-editor/use-component-library.js.map +1 -1
- package/dist/admin/layout-editor/use-editor-dnd.d.ts +10 -0
- package/dist/admin/layout-editor/use-editor-dnd.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-editor-dnd.js +234 -14
- package/dist/admin/layout-editor/use-editor-dnd.js.map +1 -1
- package/dist/admin/layout-editor/variant-container-config.d.ts.map +1 -1
- package/dist/admin/layout-editor/variant-container-config.js +1 -1
- package/dist/admin/layout-editor/variant-container-config.js.map +1 -1
- package/dist/admin/layout-editor/variant-editor.d.ts +16 -15
- package/dist/admin/layout-editor/variant-editor.d.ts.map +1 -1
- package/dist/admin/layout-editor/variant-editor.js +16 -5
- package/dist/admin/layout-editor/variant-editor.js.map +1 -1
- package/dist/admin/primitives.d.ts.map +1 -1
- package/dist/admin/primitives.js +1 -1
- package/dist/admin/primitives.js.map +1 -1
- package/dist/admin/registry.d.ts +24 -2
- package/dist/admin/registry.d.ts.map +1 -1
- package/dist/admin/registry.js +27 -0
- package/dist/admin/registry.js.map +1 -1
- package/dist/admin/server.d.ts +10 -1
- package/dist/admin/server.d.ts.map +1 -1
- package/dist/admin/server.js +4 -1
- package/dist/admin/server.js.map +1 -1
- package/dist/admin/site-switcher.d.ts +16 -3
- package/dist/admin/site-switcher.d.ts.map +1 -1
- package/dist/admin/site-switcher.js +18 -3
- package/dist/admin/site-switcher.js.map +1 -1
- package/dist/admin/styles/admin.css +0 -3
- package/dist/admin/surface-matcher.d.ts +6 -2
- package/dist/admin/surface-matcher.d.ts.map +1 -1
- package/dist/admin/surface-matcher.js +42 -5
- package/dist/admin/surface-matcher.js.map +1 -1
- package/dist/admin/surfaces/account/account-password.d.ts +3 -0
- package/dist/admin/surfaces/account/account-password.d.ts.map +1 -0
- package/dist/admin/surfaces/account/account-password.js +58 -0
- package/dist/admin/surfaces/account/account-password.js.map +1 -0
- package/dist/admin/surfaces/components/components-data.d.ts +31 -11
- package/dist/admin/surfaces/components/components-data.d.ts.map +1 -1
- package/dist/admin/surfaces/components/components-data.js +17 -4
- package/dist/admin/surfaces/components/components-data.js.map +1 -1
- package/dist/admin/surfaces/components/components-list.d.ts.map +1 -1
- package/dist/admin/surfaces/components/components-list.js +20 -7
- package/dist/admin/surfaces/components/components-list.js.map +1 -1
- package/dist/admin/surfaces/components/definition-canvas.d.ts +11 -3
- package/dist/admin/surfaces/components/definition-canvas.d.ts.map +1 -1
- package/dist/admin/surfaces/components/definition-canvas.js +138 -17
- package/dist/admin/surfaces/components/definition-canvas.js.map +1 -1
- package/dist/admin/surfaces/dashboard/dashboard-index.d.ts.map +1 -1
- package/dist/admin/surfaces/dashboard/dashboard-index.js +2 -2
- package/dist/admin/surfaces/dashboard/dashboard-index.js.map +1 -1
- package/dist/admin/surfaces/layouts/layout-editor-client.d.ts.map +1 -1
- package/dist/admin/surfaces/layouts/layout-editor-client.js +12 -11
- package/dist/admin/surfaces/layouts/layout-editor-client.js.map +1 -1
- package/dist/admin/surfaces/login.d.ts.map +1 -1
- package/dist/admin/surfaces/login.js +13 -1
- package/dist/admin/surfaces/login.js.map +1 -1
- package/dist/admin/surfaces/menus/menu-editor.d.ts.map +1 -1
- package/dist/admin/surfaces/menus/menu-editor.js +17 -4
- package/dist/admin/surfaces/menus/menu-editor.js.map +1 -1
- package/dist/admin/surfaces/menus/menu-tree.d.ts +18 -4
- package/dist/admin/surfaces/menus/menu-tree.d.ts.map +1 -1
- package/dist/admin/surfaces/menus/menu-tree.js +18 -3
- package/dist/admin/surfaces/menus/menu-tree.js.map +1 -1
- package/dist/admin/surfaces/menus/menus-data.d.ts +18 -0
- package/dist/admin/surfaces/menus/menus-data.d.ts.map +1 -1
- package/dist/admin/surfaces/menus/menus-data.js +4 -0
- package/dist/admin/surfaces/menus/menus-data.js.map +1 -1
- package/dist/admin/surfaces/menus/menus-list.d.ts.map +1 -1
- package/dist/admin/surfaces/menus/menus-list.js +2 -12
- package/dist/admin/surfaces/menus/menus-list.js.map +1 -1
- package/dist/admin/surfaces/settings/admin-features.d.ts.map +1 -1
- package/dist/admin/surfaces/settings/admin-features.js +12 -1
- package/dist/admin/surfaces/settings/admin-features.js.map +1 -1
- package/dist/admin/surfaces/users/users-data.d.ts +16 -0
- package/dist/admin/surfaces/users/users-data.d.ts.map +1 -1
- package/dist/admin/surfaces/users/users-data.js +19 -0
- package/dist/admin/surfaces/users/users-data.js.map +1 -1
- package/dist/admin/surfaces/users/users-detail.d.ts.map +1 -1
- package/dist/admin/surfaces/users/users-detail.js +87 -6
- package/dist/admin/surfaces/users/users-detail.js.map +1 -1
- package/dist/admin/surfaces/users/users-new.d.ts.map +1 -1
- package/dist/admin/surfaces/users/users-new.js +9 -5
- package/dist/admin/surfaces/users/users-new.js.map +1 -1
- package/dist/admin/user-form.d.ts +13 -2
- package/dist/admin/user-form.d.ts.map +1 -1
- package/dist/admin/user-form.js +3 -2
- package/dist/admin/user-form.js.map +1 -1
- package/dist/api/admin-features-routes.js +2 -2
- package/dist/api/admin-features-routes.js.map +1 -1
- package/dist/api/audience-preview-routes.d.ts +7 -0
- package/dist/api/audience-preview-routes.d.ts.map +1 -1
- package/dist/api/audience-preview-routes.js +4 -4
- package/dist/api/audience-preview-routes.js.map +1 -1
- package/dist/api/audience-routes.d.ts +7 -0
- package/dist/api/audience-routes.d.ts.map +1 -1
- package/dist/api/audience-routes.js +21 -15
- package/dist/api/audience-routes.js.map +1 -1
- package/dist/api/audience-runtime-routes.d.ts +6 -0
- package/dist/api/audience-runtime-routes.d.ts.map +1 -1
- package/dist/api/audience-runtime-routes.js +38 -3
- package/dist/api/audience-runtime-routes.js.map +1 -1
- package/dist/api/auth-routes.d.ts.map +1 -1
- package/dist/api/auth-routes.js +33 -4
- package/dist/api/auth-routes.js.map +1 -1
- package/dist/api/auth.d.ts +1 -0
- package/dist/api/auth.d.ts.map +1 -1
- package/dist/api/auth.js +43 -3
- package/dist/api/auth.js.map +1 -1
- package/dist/api/bulk-routes.d.ts.map +1 -1
- package/dist/api/bulk-routes.js +7 -7
- package/dist/api/bulk-routes.js.map +1 -1
- package/dist/api/category-routes.js +3 -3
- package/dist/api/category-routes.js.map +1 -1
- package/dist/api/comment-routes.js +8 -8
- package/dist/api/comment-routes.js.map +1 -1
- package/dist/api/component-routes.d.ts +25 -0
- package/dist/api/component-routes.d.ts.map +1 -1
- package/dist/api/component-routes.js +41 -16
- package/dist/api/component-routes.js.map +1 -1
- package/dist/api/content-routes.js +13 -13
- package/dist/api/content-routes.js.map +1 -1
- package/dist/api/dashboard-routes.js +1 -1
- package/dist/api/dashboard-routes.js.map +1 -1
- package/dist/api/experiment-routes.d.ts +7 -0
- package/dist/api/experiment-routes.d.ts.map +1 -1
- package/dist/api/experiment-routes.js +8 -8
- package/dist/api/experiment-routes.js.map +1 -1
- package/dist/api/experiment-runtime-routes.d.ts +6 -0
- package/dist/api/experiment-runtime-routes.d.ts.map +1 -1
- package/dist/api/experiment-runtime-routes.js +47 -11
- package/dist/api/experiment-runtime-routes.js.map +1 -1
- package/dist/api/feed-routes.d.ts +2 -2
- package/dist/api/feed-routes.js +3 -3
- package/dist/api/feed-routes.js.map +1 -1
- package/dist/api/form-routes.js +4 -4
- package/dist/api/form-routes.js.map +1 -1
- package/dist/api/graphql/resolvers.d.ts +1 -1
- package/dist/api/graphql/resolvers.d.ts.map +1 -1
- package/dist/api/graphql/resolvers.js +68 -33
- package/dist/api/graphql/resolvers.js.map +1 -1
- package/dist/api/group-routes.js +6 -6
- package/dist/api/group-routes.js.map +1 -1
- package/dist/api/index.d.ts +10 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +97 -7
- package/dist/api/index.js.map +1 -1
- package/dist/api/layout-routes.d.ts.map +1 -1
- package/dist/api/layout-routes.js +27 -3
- package/dist/api/layout-routes.js.map +1 -1
- package/dist/api/media-routes.d.ts.map +1 -1
- package/dist/api/media-routes.js +50 -26
- package/dist/api/media-routes.js.map +1 -1
- package/dist/api/menu-routes.d.ts +9 -1
- package/dist/api/menu-routes.d.ts.map +1 -1
- package/dist/api/menu-routes.js +44 -10
- package/dist/api/menu-routes.js.map +1 -1
- package/dist/api/nav-routes.d.ts +6 -0
- package/dist/api/nav-routes.d.ts.map +1 -1
- package/dist/api/nav-routes.js +24 -3
- package/dist/api/nav-routes.js.map +1 -1
- package/dist/api/openapi.d.ts.map +1 -1
- package/dist/api/openapi.js +68 -33
- package/dist/api/openapi.js.map +1 -1
- package/dist/api/password-gate.d.ts +23 -0
- package/dist/api/password-gate.d.ts.map +1 -0
- package/dist/api/password-gate.js +41 -0
- package/dist/api/password-gate.js.map +1 -0
- package/dist/api/password-reset-routes.d.ts.map +1 -1
- package/dist/api/password-reset-routes.js +13 -6
- package/dist/api/password-reset-routes.js.map +1 -1
- package/dist/api/search-routes.js +2 -2
- package/dist/api/search-routes.js.map +1 -1
- package/dist/api/section-template-routes.d.ts.map +1 -1
- package/dist/api/section-template-routes.js +35 -18
- package/dist/api/section-template-routes.js.map +1 -1
- package/dist/api/site-admin-routes.d.ts +10 -1
- package/dist/api/site-admin-routes.d.ts.map +1 -1
- package/dist/api/site-admin-routes.js +21 -1
- package/dist/api/site-admin-routes.js.map +1 -1
- package/dist/api/site-context.d.ts +35 -5
- package/dist/api/site-context.d.ts.map +1 -1
- package/dist/api/site-context.js +21 -6
- package/dist/api/site-context.js.map +1 -1
- package/dist/api/tag-routes.js +3 -3
- package/dist/api/tag-routes.js.map +1 -1
- package/dist/api/translation-routes.js +5 -5
- package/dist/api/translation-routes.js.map +1 -1
- package/dist/api/user-routes.d.ts +4 -0
- package/dist/api/user-routes.d.ts.map +1 -1
- package/dist/api/user-routes.js +240 -17
- package/dist/api/user-routes.js.map +1 -1
- package/dist/api/webhook-routes.js +5 -5
- package/dist/api/webhook-routes.js.map +1 -1
- package/dist/api/workflow-routes.js +8 -8
- package/dist/api/workflow-routes.js.map +1 -1
- package/dist/audiences/collectors/identity.d.ts +14 -1
- package/dist/audiences/collectors/identity.d.ts.map +1 -1
- package/dist/audiences/collectors/identity.js +16 -3
- package/dist/audiences/collectors/identity.js.map +1 -1
- package/dist/audiences/collectors/index.d.ts +12 -2
- package/dist/audiences/collectors/index.d.ts.map +1 -1
- package/dist/audiences/collectors/index.js +16 -5
- package/dist/audiences/collectors/index.js.map +1 -1
- package/dist/audiences/collectors/pinned-audience.d.ts +28 -2
- package/dist/audiences/collectors/pinned-audience.d.ts.map +1 -1
- package/dist/audiences/collectors/pinned-audience.js +35 -5
- package/dist/audiences/collectors/pinned-audience.js.map +1 -1
- package/dist/audiences/collectors/utm.d.ts +15 -1
- package/dist/audiences/collectors/utm.d.ts.map +1 -1
- package/dist/audiences/collectors/utm.js +16 -2
- package/dist/audiences/collectors/utm.js.map +1 -1
- package/dist/audiences/consent-config.d.ts +21 -0
- package/dist/audiences/consent-config.d.ts.map +1 -0
- package/dist/audiences/consent-config.js +15 -0
- package/dist/audiences/consent-config.js.map +1 -0
- package/dist/audiences/consent-startup.d.ts +39 -0
- package/dist/audiences/consent-startup.d.ts.map +1 -0
- package/dist/audiences/consent-startup.js +105 -0
- package/dist/audiences/consent-startup.js.map +1 -0
- package/dist/audiences/consent.d.ts +192 -0
- package/dist/audiences/consent.d.ts.map +1 -0
- package/dist/audiences/consent.js +322 -0
- package/dist/audiences/consent.js.map +1 -0
- package/dist/audiences/engine.d.ts +7 -0
- package/dist/audiences/engine.d.ts.map +1 -1
- package/dist/audiences/engine.js +6 -2
- package/dist/audiences/engine.js.map +1 -1
- package/dist/audiences/index.d.ts +3 -0
- package/dist/audiences/index.d.ts.map +1 -1
- package/dist/audiences/index.js +6 -0
- package/dist/audiences/index.js.map +1 -1
- package/dist/audiences/server-eval.d.ts +13 -1
- package/dist/audiences/server-eval.d.ts.map +1 -1
- package/dist/audiences/server-eval.js +18 -2
- package/dist/audiences/server-eval.js.map +1 -1
- package/dist/audiences/ssr.d.ts +18 -1
- package/dist/audiences/ssr.d.ts.map +1 -1
- package/dist/audiences/ssr.js +18 -1
- package/dist/audiences/ssr.js.map +1 -1
- package/dist/audiences/utm-persistence.d.ts +20 -7
- package/dist/audiences/utm-persistence.d.ts.map +1 -1
- package/dist/audiences/utm-persistence.js +20 -7
- package/dist/audiences/utm-persistence.js.map +1 -1
- package/dist/auth/roles.d.ts +11 -0
- package/dist/auth/roles.d.ts.map +1 -1
- package/dist/auth/roles.js +13 -0
- package/dist/auth/roles.js.map +1 -1
- package/dist/auth/tokens.d.ts +7 -0
- package/dist/auth/tokens.d.ts.map +1 -1
- package/dist/auth/tokens.js +24 -2
- package/dist/auth/tokens.js.map +1 -1
- package/dist/config/types.d.ts +50 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/config/validate.d.ts.map +1 -1
- package/dist/config/validate.js +3 -0
- package/dist/config/validate.js.map +1 -1
- package/dist/db/apply-snapshot.d.ts +18 -0
- package/dist/db/apply-snapshot.d.ts.map +1 -1
- package/dist/db/apply-snapshot.js +41 -16
- package/dist/db/apply-snapshot.js.map +1 -1
- package/dist/db/component-instance-queries.d.ts +79 -19
- package/dist/db/component-instance-queries.d.ts.map +1 -1
- package/dist/db/component-instance-queries.js +266 -83
- package/dist/db/component-instance-queries.js.map +1 -1
- package/dist/db/component-queries.d.ts +1 -16
- package/dist/db/component-queries.d.ts.map +1 -1
- package/dist/db/component-queries.js +7 -56
- package/dist/db/component-queries.js.map +1 -1
- package/dist/db/content-queries.d.ts.map +1 -1
- package/dist/db/content-queries.js +1 -2
- package/dist/db/content-queries.js.map +1 -1
- package/dist/db/extension-queries.d.ts +2 -2
- package/dist/db/feed-queries.d.ts +3 -3
- package/dist/db/index.d.ts +1 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/layout-queries.d.ts +2 -1
- package/dist/db/layout-queries.d.ts.map +1 -1
- package/dist/db/layout-queries.js +3 -3
- package/dist/db/layout-queries.js.map +1 -1
- package/dist/db/menu-queries.d.ts +69 -5
- package/dist/db/menu-queries.d.ts.map +1 -1
- package/dist/db/menu-queries.js +120 -13
- package/dist/db/menu-queries.js.map +1 -1
- package/dist/db/section-template-queries.d.ts +62 -0
- package/dist/db/section-template-queries.d.ts.map +1 -0
- package/dist/db/section-template-queries.js +178 -0
- package/dist/db/section-template-queries.js.map +1 -0
- package/dist/db/site-plugin-queries.d.ts +2 -2
- package/dist/db/tree-queries.d.ts.map +1 -1
- package/dist/db/tree-queries.js +5 -0
- package/dist/db/tree-queries.js.map +1 -1
- package/dist/db/user-queries.d.ts +28 -1
- package/dist/db/user-queries.d.ts.map +1 -1
- package/dist/db/user-queries.js +49 -1
- package/dist/db/user-queries.js.map +1 -1
- package/dist/db/webhook-queries.d.ts +3 -3
- package/dist/db/workflow-queries.d.ts.map +1 -1
- package/dist/db/workflow-queries.js +5 -20
- package/dist/db/workflow-queries.js.map +1 -1
- package/dist/experiments/runtime.d.ts +21 -3
- package/dist/experiments/runtime.d.ts.map +1 -1
- package/dist/experiments/runtime.js +21 -3
- package/dist/experiments/runtime.js.map +1 -1
- package/dist/host/index.d.ts +1 -0
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +12 -0
- package/dist/host/index.js.map +1 -1
- package/dist/layout/component-refs.d.ts +90 -2
- package/dist/layout/component-refs.d.ts.map +1 -1
- package/dist/layout/component-refs.js +293 -16
- package/dist/layout/component-refs.js.map +1 -1
- package/dist/layout/index.d.ts +4 -3
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +3 -2
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/legacy-variant-container.d.ts +123 -0
- package/dist/layout/legacy-variant-container.d.ts.map +1 -0
- package/dist/layout/legacy-variant-container.js +397 -0
- package/dist/layout/legacy-variant-container.js.map +1 -0
- package/dist/layout/module-permissions.d.ts.map +1 -1
- package/dist/layout/module-permissions.js +25 -1
- package/dist/layout/module-permissions.js.map +1 -1
- package/dist/layout/modules-extended.d.ts +28 -1
- package/dist/layout/modules-extended.d.ts.map +1 -1
- package/dist/layout/modules-extended.js +73 -1
- package/dist/layout/modules-extended.js.map +1 -1
- package/dist/layout/modules.d.ts.map +1 -1
- package/dist/layout/modules.js +9 -1
- package/dist/layout/modules.js.map +1 -1
- package/dist/layout/personalization.d.ts +83 -0
- package/dist/layout/personalization.d.ts.map +1 -1
- package/dist/layout/personalization.js +250 -4
- package/dist/layout/personalization.js.map +1 -1
- package/dist/layout/registry.d.ts.map +1 -1
- package/dist/layout/registry.js +20 -0
- package/dist/layout/registry.js.map +1 -1
- package/dist/layout/renderer.d.ts +29 -2
- package/dist/layout/renderer.d.ts.map +1 -1
- package/dist/layout/renderer.js +23 -6
- package/dist/layout/renderer.js.map +1 -1
- package/dist/layout/types.d.ts +17 -0
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/layout/types.js +7 -0
- package/dist/layout/types.js.map +1 -1
- package/dist/media/inline-risk.d.ts +26 -0
- package/dist/media/inline-risk.d.ts.map +1 -0
- package/dist/media/inline-risk.js +142 -0
- package/dist/media/inline-risk.js.map +1 -0
- package/dist/nav/builder.d.ts.map +1 -1
- package/dist/nav/builder.js +15 -3
- package/dist/nav/builder.js.map +1 -1
- package/dist/nav/index.d.ts +1 -1
- package/dist/nav/index.d.ts.map +1 -1
- package/dist/nav/index.js +1 -1
- package/dist/nav/index.js.map +1 -1
- package/dist/nav/menu-resolver.d.ts +11 -0
- package/dist/nav/menu-resolver.d.ts.map +1 -1
- package/dist/nav/menu-resolver.js +49 -9
- package/dist/nav/menu-resolver.js.map +1 -1
- package/dist/nav/paths.d.ts +37 -0
- package/dist/nav/paths.d.ts.map +1 -0
- package/dist/nav/paths.js +48 -0
- package/dist/nav/paths.js.map +1 -0
- package/dist/nav/types.d.ts +6 -0
- package/dist/nav/types.d.ts.map +1 -1
- package/dist/nav/url-resolver.d.ts +1 -5
- package/dist/nav/url-resolver.d.ts.map +1 -1
- package/dist/nav/url-resolver.js +6 -12
- package/dist/nav/url-resolver.js.map +1 -1
- package/dist/schema/base.d.ts +41 -4
- package/dist/schema/base.d.ts.map +1 -1
- package/dist/schema/base.js +23 -4
- package/dist/schema/base.js.map +1 -1
- package/dist/schema/components.d.ts +90 -9
- package/dist/schema/components.d.ts.map +1 -1
- package/dist/schema/components.js +113 -22
- package/dist/schema/components.js.map +1 -1
- package/dist/schema/mysql-tables.d.ts +5775 -48
- package/dist/schema/mysql-tables.d.ts.map +1 -1
- package/dist/schema/mysql-tables.js +621 -46
- package/dist/schema/mysql-tables.js.map +1 -1
- package/dist/scope/kywi-form.d.ts +11 -0
- package/dist/scope/kywi-form.d.ts.map +1 -1
- package/dist/scope/kywi-form.js +11 -1
- package/dist/scope/kywi-form.js.map +1 -1
- package/dist/scope/kywi-wizard-form.d.ts.map +1 -1
- package/dist/scope/kywi-wizard-form.js +76 -2
- package/dist/scope/kywi-wizard-form.js.map +1 -1
- package/dist/scope/sticky-offset.d.ts +34 -13
- package/dist/scope/sticky-offset.d.ts.map +1 -1
- package/dist/scope/sticky-offset.js +236 -43
- package/dist/scope/sticky-offset.js.map +1 -1
- package/dist/site/styles.css +61 -15
- package/dist/versioning/scheduler.d.ts +28 -0
- package/dist/versioning/scheduler.d.ts.map +1 -1
- package/dist/versioning/scheduler.js +50 -3
- package/dist/versioning/scheduler.js.map +1 -1
- package/package.json +7 -2
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Keep this module dependency-free beyond `./types.js`.
|
|
13
13
|
*/
|
|
14
|
-
import type { LayoutDocument, LayoutSection, ModuleNode, VariantContainer } from './types.js';
|
|
15
|
-
export type ComponentRefKind = 'module' | 'section' | 'variantContainer';
|
|
14
|
+
import type { LayoutDocument, LayoutSection, ModuleNode, ModuleVariantContainer, VariantContainer } from './types.js';
|
|
15
|
+
export type ComponentRefKind = 'module' | 'section' | 'variantContainer' | 'moduleVariantContainer';
|
|
16
16
|
/** One placement of a linked component inside a layout document. */
|
|
17
17
|
export interface ComponentRef {
|
|
18
18
|
componentId: string;
|
|
@@ -46,6 +46,11 @@ export type ComponentInstance = {
|
|
|
46
46
|
nodeId: string;
|
|
47
47
|
kind: 'variantContainer';
|
|
48
48
|
node: VariantContainer;
|
|
49
|
+
} | {
|
|
50
|
+
componentId: string;
|
|
51
|
+
nodeId: string;
|
|
52
|
+
kind: 'moduleVariantContainer';
|
|
53
|
+
node: ModuleVariantContainer;
|
|
49
54
|
};
|
|
50
55
|
/**
|
|
51
56
|
* Identity of a placement: the same component in the same node is one instance.
|
|
@@ -103,6 +108,14 @@ export declare function diffComponentRefs(before: LayoutDocument | null | undefi
|
|
|
103
108
|
* already applies to connected sections (`${localId}:${storedId}`), lifted out
|
|
104
109
|
* of `renderer.tsx` so the server-side detach produces *byte-identical* ids to
|
|
105
110
|
* what the page was already rendering — `renderer.tsx` imports this one.
|
|
111
|
+
*
|
|
112
|
+
* KNOWN, ACCEPTED RISK (kywi-cms#77): the `:` delimiter is not reserved. An
|
|
113
|
+
* API-authored node id that happens to start with `<scope>:` could fool the
|
|
114
|
+
* `unrekey`/`unscope` heuristics. A charset ban was tried and rejected because
|
|
115
|
+
* `validateLayoutDocument` must accept the engine's own rekeyed documents
|
|
116
|
+
* (they round-trip through the editor and PUT /layout). Owner decision
|
|
117
|
+
* 2026-08-26: document rather than redesign the scope key; revisit only if a
|
|
118
|
+
* real collision is observed.
|
|
106
119
|
*/
|
|
107
120
|
export declare function rekeyResolvedSection(resolved: LayoutSection, localId: string): LayoutSection;
|
|
108
121
|
/**
|
|
@@ -133,6 +146,31 @@ export declare function rekeyResolvedSection(resolved: LayoutSection, localId: s
|
|
|
133
146
|
* migration, so it changes only for a bug of this class.
|
|
134
147
|
*/
|
|
135
148
|
export declare function rekeyResolvedVariantContainer(resolved: VariantContainer, localId: string): VariantContainer;
|
|
149
|
+
/**
|
|
150
|
+
* The MODULE-level container's {@link rekeyResolvedVariantContainer}
|
|
151
|
+
* (kywi-cms#170): the local container id is kept and everything underneath —
|
|
152
|
+
* arm ids, the Default arm's module, each variant arm's module — is re-derived
|
|
153
|
+
* from it.
|
|
154
|
+
*
|
|
155
|
+
* The arm id is folded in for exactly the reason it is one level up: a
|
|
156
|
+
* container's arms are near-copies by construction ("the same hero, two
|
|
157
|
+
* headlines"), so the same stored module id appearing in the Default arm and in
|
|
158
|
+
* arm B is the NORMAL case. Scoping both by the container id alone would give
|
|
159
|
+
* them one id, one `data-instance-id`, and one React key.
|
|
160
|
+
*
|
|
161
|
+
* - a Default-arm module becomes `${containerId}:${moduleId}`;
|
|
162
|
+
* - a variant-arm module becomes `${containerId}:${armId}:${moduleId}`;
|
|
163
|
+
* - the arm itself becomes `${containerId}:${armId}`.
|
|
164
|
+
*
|
|
165
|
+
* `instanceId` is scoped with the same key as `id`: it is what the front-edit
|
|
166
|
+
* overlay and the analytics DOM address a rendered module by, so two placements
|
|
167
|
+
* sharing one would be two nodes the editor cannot tell apart.
|
|
168
|
+
*
|
|
169
|
+
* Same COMPATIBILITY SURFACE caveat as the section-level scheme: detaching
|
|
170
|
+
* persists these ids into the page's stored layout, so changing the scheme
|
|
171
|
+
* re-keys previously detached containers.
|
|
172
|
+
*/
|
|
173
|
+
export declare function rekeyResolvedModuleVariantContainer(resolved: ModuleVariantContainer, localId: string): ModuleVariantContainer;
|
|
136
174
|
/** A resolved module component, in the shape the renderer's resolver returns. */
|
|
137
175
|
export interface ResolvedModuleDefinition {
|
|
138
176
|
moduleType: string;
|
|
@@ -196,6 +234,21 @@ export declare function applySectionPlacement(resolved: LayoutSection, placement
|
|
|
196
234
|
* keeps working when placed as-is.
|
|
197
235
|
*/
|
|
198
236
|
export declare function applyVariantContainerPlacement(resolved: VariantContainer, placement: Pick<VariantContainer, 'id' | 'experimentId' | 'winnerId'>): VariantContainer;
|
|
237
|
+
/**
|
|
238
|
+
* The MODULE-level counterpart of {@link applyVariantContainerPlacement}
|
|
239
|
+
* (kywi-cms#170), rule for rule: the definition's arms, re-keyed off the
|
|
240
|
+
* placement's id, with the PLACEMENT's experiment binding winning over the
|
|
241
|
+
* definition's.
|
|
242
|
+
*
|
|
243
|
+
* The binding rule is the same one and it is here for the same reason —
|
|
244
|
+
* `experimentId`/`winnerId` say which run THIS page's arms report to and which
|
|
245
|
+
* arm has been locked in, which is a fact about the page, not about the shared
|
|
246
|
+
* component. A placement naming neither inherits the definition's, so a
|
|
247
|
+
* container saved with its binding intact keeps working when placed as-is; the
|
|
248
|
+
* editor mints a fresh one per placement precisely so that inheritance is never
|
|
249
|
+
* what a real placement relies on.
|
|
250
|
+
*/
|
|
251
|
+
export declare function applyModuleVariantContainerPlacement(resolved: ModuleVariantContainer, placement: Pick<ModuleVariantContainer, 'id' | 'experimentId' | 'winnerId'>): ModuleVariantContainer;
|
|
199
252
|
/**
|
|
200
253
|
* The inverse of {@link rekeyResolvedSection}: strip the scope that section's own
|
|
201
254
|
* id imposed on its columns and modules, and give the result `rootId`.
|
|
@@ -208,6 +261,17 @@ export declare function applyVariantContainerPlacement(resolved: VariantContaine
|
|
|
208
261
|
* must keep it.
|
|
209
262
|
*/
|
|
210
263
|
export declare function unrekeyResolvedSection(resolved: LayoutSection, rootId: string): LayoutSection;
|
|
264
|
+
/**
|
|
265
|
+
* The inverse of {@link rekeyResolvedModuleVariantContainer}: unwind the scope
|
|
266
|
+
* the container's own id imposed on its arms and their modules, and give the
|
|
267
|
+
* result `rootId`.
|
|
268
|
+
*
|
|
269
|
+
* `${containerId}:${armId}:${moduleId}` unwinds one level at a time, exactly as
|
|
270
|
+
* {@link unapplyVariantContainerPlacement} unwinds the section-level scheme. Ids
|
|
271
|
+
* that do NOT carry the prefix are left alone — a module the author swapped into
|
|
272
|
+
* an arm has a freshly generated id and no scope, and must keep it.
|
|
273
|
+
*/
|
|
274
|
+
export declare function unrekeyResolvedModuleVariantContainer(resolved: ModuleVariantContainer, rootId: string): ModuleVariantContainer;
|
|
211
275
|
/**
|
|
212
276
|
* What this placement would be as a DEFINITION: the inverse of
|
|
213
277
|
* {@link applySectionPlacement}.
|
|
@@ -231,6 +295,18 @@ export declare function unapplySectionPlacement(placement: LayoutSection, defini
|
|
|
231
295
|
* stored row); this returns a container with no binding at all.
|
|
232
296
|
*/
|
|
233
297
|
export declare function unapplyVariantContainerPlacement(placement: VariantContainer, definitionId?: string | null | undefined): VariantContainer;
|
|
298
|
+
/**
|
|
299
|
+
* The MODULE-level counterpart of {@link unapplyVariantContainerPlacement}
|
|
300
|
+
* (kywi-cms#170) — what this placement would be as a DEFINITION, and the exact
|
|
301
|
+
* inverse of {@link applyModuleVariantContainerPlacement}.
|
|
302
|
+
*
|
|
303
|
+
* The placement's `experimentId`/`winnerId` are DROPPED rather than inverted,
|
|
304
|
+
* for the reason its section-level twin drops them: they are this page's run of
|
|
305
|
+
* the experiment, and letting them travel into the definition is how one page's
|
|
306
|
+
* A/B test would enrol every other page placing the component. Restoring the
|
|
307
|
+
* definition's own binding is the caller's business — it holds the stored row.
|
|
308
|
+
*/
|
|
309
|
+
export declare function unapplyModuleVariantContainerPlacement(placement: ModuleVariantContainer, definitionId?: string | null | undefined): ModuleVariantContainer;
|
|
234
310
|
/**
|
|
235
311
|
* A component's stored definition, projected into the shape detaching needs.
|
|
236
312
|
* `unresolvable` covers a component row whose definition doesn't match its
|
|
@@ -248,6 +324,9 @@ export type ComponentDetachSource = {
|
|
|
248
324
|
} | {
|
|
249
325
|
kind: 'variantContainer';
|
|
250
326
|
container: VariantContainer;
|
|
327
|
+
} | {
|
|
328
|
+
kind: 'moduleVariantContainer';
|
|
329
|
+
container: ModuleVariantContainer;
|
|
251
330
|
} | {
|
|
252
331
|
kind: 'unresolvable';
|
|
253
332
|
};
|
|
@@ -325,12 +404,20 @@ export declare function materializeModuleNode(node: ModuleNode, source: Componen
|
|
|
325
404
|
export declare function materializeSectionNode(section: LayoutSection, source: ComponentDetachSource, link?: LinkDisposition): LayoutSection;
|
|
326
405
|
/** The variant-container equivalent of {@link materializeSectionNode}. */
|
|
327
406
|
export declare function materializeVariantContainerNode(container: VariantContainer, source: ComponentDetachSource, link?: LinkDisposition): VariantContainer;
|
|
407
|
+
/**
|
|
408
|
+
* The MODULE-level container equivalent (kywi-cms#170), delegating to
|
|
409
|
+
* {@link applyModuleVariantContainerPlacement} so what the renderer draws, what
|
|
410
|
+
* detaching bakes in and what pre-resolution ships are one function's output.
|
|
411
|
+
*/
|
|
412
|
+
export declare function materializeModuleVariantContainerNode(container: ModuleVariantContainer, source: ComponentDetachSource, link?: LinkDisposition): ModuleVariantContainer;
|
|
328
413
|
/** Materialise a connected module node into an INDEPENDENT one (link dropped). */
|
|
329
414
|
export declare function detachModuleNode(node: ModuleNode, source: ComponentDetachSource): ModuleNode;
|
|
330
415
|
/** Materialise a connected section into an INDEPENDENT one (link dropped). */
|
|
331
416
|
export declare function detachSectionNode(section: LayoutSection, source: ComponentDetachSource): LayoutSection;
|
|
332
417
|
/** Materialise a connected container into an INDEPENDENT one (link dropped). */
|
|
333
418
|
export declare function detachVariantContainerNode(container: VariantContainer, source: ComponentDetachSource): VariantContainer;
|
|
419
|
+
/** {@link detachVariantContainerNode} for a MODULE-level container (kywi-cms#170). */
|
|
420
|
+
export declare function detachModuleVariantContainerNode(container: ModuleVariantContainer, source: ComponentDetachSource): ModuleVariantContainer;
|
|
334
421
|
/**
|
|
335
422
|
* Rewrite linked placements anywhere in a document, one kind at a time.
|
|
336
423
|
*
|
|
@@ -350,6 +437,7 @@ export interface ComponentInstanceRewrite {
|
|
|
350
437
|
module?: (node: ModuleNode, ref: ComponentRef) => ModuleNode;
|
|
351
438
|
section?: (section: LayoutSection, ref: ComponentRef) => LayoutSection;
|
|
352
439
|
variantContainer?: (container: VariantContainer, ref: ComponentRef) => VariantContainer;
|
|
440
|
+
moduleVariantContainer?: (container: ModuleVariantContainer, ref: ComponentRef) => ModuleVariantContainer;
|
|
353
441
|
}
|
|
354
442
|
export declare function rewriteComponentInstances(layout: LayoutDocument, rewrite: ComponentInstanceRewrite): LayoutDocument;
|
|
355
443
|
export interface DetachResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-refs.d.ts","sourceRoot":"","sources":["../../src/layout/component-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"component-refs.d.ts","sourceRoot":"","sources":["../../src/layout/component-refs.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Keep this module dependency-free beyond `./types.js`.
|
|
13
13
|
*/
|
|
14
|
-
import { columnModules, mapColumnNode, validateLayoutSection, validateVariantContainer } from './types.js';
|
|
14
|
+
import { columnModules, isModuleVariantContainer, mapColumnNode, validateLayoutSection, validateModuleVariantContainer, validateVariantContainer, } from './types.js';
|
|
15
15
|
/**
|
|
16
16
|
* Identity of a placement: the same component in the same node is one instance.
|
|
17
17
|
*
|
|
@@ -36,14 +36,42 @@ function record(out, instance) {
|
|
|
36
36
|
}
|
|
37
37
|
function collectFromColumns(columns, out) {
|
|
38
38
|
for (const column of columns ?? []) {
|
|
39
|
-
for (const node of
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
for (const node of column.nodes ?? []) {
|
|
40
|
+
// A LINKED module-level container resolves WHOLESALE (kywi-cms#170), so
|
|
41
|
+
// stop here rather than descending through `columnModules` — the same rule
|
|
42
|
+
// `collectFromSection` applies one level up, and for the same two reasons:
|
|
43
|
+
// an arm module's grandfathered `componentId` is a link this page never
|
|
44
|
+
// renders (the placement helpers strip it), and counting it would
|
|
45
|
+
// double-count what the component definition owns.
|
|
46
|
+
//
|
|
47
|
+
// Arms are never independently linkable in the first place (#170 D1), so
|
|
48
|
+
// what this skips is only ever a grandfathered link or one written straight
|
|
49
|
+
// over the API — never a placement the editor could mint.
|
|
50
|
+
if (isModuleVariantContainer(node)) {
|
|
51
|
+
const containerLink = readComponentId(node);
|
|
52
|
+
if (containerLink) {
|
|
53
|
+
record(out, {
|
|
54
|
+
componentId: containerLink,
|
|
55
|
+
nodeId: node.id,
|
|
56
|
+
kind: 'moduleVariantContainer',
|
|
57
|
+
node,
|
|
58
|
+
});
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
for (const module of mapColumnNodeToModules(node)) {
|
|
63
|
+
const componentId = readComponentId(module);
|
|
64
|
+
if (componentId) {
|
|
65
|
+
record(out, { componentId, nodeId: module.id, kind: 'module', node: module });
|
|
66
|
+
}
|
|
43
67
|
}
|
|
44
68
|
}
|
|
45
69
|
}
|
|
46
70
|
}
|
|
71
|
+
/** Every ModuleNode one column node holds — `columnModules` for a single node. */
|
|
72
|
+
function mapColumnNodeToModules(node) {
|
|
73
|
+
return columnModules({ id: '', width: 12, nodes: [node] });
|
|
74
|
+
}
|
|
47
75
|
function collectFromSection(section, out) {
|
|
48
76
|
const componentId = readComponentId(section);
|
|
49
77
|
if (componentId) {
|
|
@@ -155,6 +183,14 @@ export function diffComponentRefs(before, after) {
|
|
|
155
183
|
* already applies to connected sections (`${localId}:${storedId}`), lifted out
|
|
156
184
|
* of `renderer.tsx` so the server-side detach produces *byte-identical* ids to
|
|
157
185
|
* what the page was already rendering — `renderer.tsx` imports this one.
|
|
186
|
+
*
|
|
187
|
+
* KNOWN, ACCEPTED RISK (kywi-cms#77): the `:` delimiter is not reserved. An
|
|
188
|
+
* API-authored node id that happens to start with `<scope>:` could fool the
|
|
189
|
+
* `unrekey`/`unscope` heuristics. A charset ban was tried and rejected because
|
|
190
|
+
* `validateLayoutDocument` must accept the engine's own rekeyed documents
|
|
191
|
+
* (they round-trip through the editor and PUT /layout). Owner decision
|
|
192
|
+
* 2026-08-26: document rather than redesign the scope key; revisit only if a
|
|
193
|
+
* real collision is observed.
|
|
158
194
|
*/
|
|
159
195
|
export function rekeyResolvedSection(resolved, localId) {
|
|
160
196
|
const scope = (storedId) => `${localId}:${storedId}`;
|
|
@@ -164,10 +200,33 @@ export function rekeyResolvedSection(resolved, localId) {
|
|
|
164
200
|
columns: (resolved.columns ?? []).map(col => ({
|
|
165
201
|
...col,
|
|
166
202
|
id: scope(col.id),
|
|
167
|
-
nodes: (col.nodes ?? []).map(node =>
|
|
203
|
+
nodes: (col.nodes ?? []).map(node => rekeyColumnNode(node, scope)),
|
|
168
204
|
})),
|
|
169
205
|
};
|
|
170
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Re-key one column node under a section's scope.
|
|
209
|
+
*
|
|
210
|
+
* A plain module is just its two ids. A MODULE-LEVEL variant container is a
|
|
211
|
+
* subtree with an identity of its own — the container id the renderer stamps as
|
|
212
|
+
* `data-module-variant-container-id`, and arm ids the selector matches on — so it
|
|
213
|
+
* goes through {@link rekeyResolvedModuleVariantContainer} rather than through
|
|
214
|
+
* `mapColumnNode`, which deliberately touches only the modules and leaves the
|
|
215
|
+
* container's identity alone (kywi-cms#170).
|
|
216
|
+
*
|
|
217
|
+
* WHY THAT MATTERS NOW. Until #170 a section definition could not hold a
|
|
218
|
+
* promoted module at all, so `mapColumnNode` was enough. It can now, and a
|
|
219
|
+
* section component placed twice would otherwise emit two containers with the
|
|
220
|
+
* same id and the same arm ids — the exact duplicate-id class
|
|
221
|
+
* {@link rekeyResolvedVariantContainer} folds the arm id in to avoid, one level
|
|
222
|
+
* further down.
|
|
223
|
+
*/
|
|
224
|
+
function rekeyColumnNode(node, scope) {
|
|
225
|
+
if (isModuleVariantContainer(node)) {
|
|
226
|
+
return rekeyResolvedModuleVariantContainer(node, scope(node.id));
|
|
227
|
+
}
|
|
228
|
+
return mapColumnNode(node, m => ({ ...m, id: scope(m.id), instanceId: scope(m.instanceId) }));
|
|
229
|
+
}
|
|
171
230
|
/**
|
|
172
231
|
* The variant-container equivalent of {@link rekeyResolvedSection}: the local
|
|
173
232
|
* container id is kept (stable keys, `data-*` hooks, style scoping) and every
|
|
@@ -209,6 +268,47 @@ export function rekeyResolvedVariantContainer(resolved, localId) {
|
|
|
209
268
|
})),
|
|
210
269
|
};
|
|
211
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* The MODULE-level container's {@link rekeyResolvedVariantContainer}
|
|
273
|
+
* (kywi-cms#170): the local container id is kept and everything underneath —
|
|
274
|
+
* arm ids, the Default arm's module, each variant arm's module — is re-derived
|
|
275
|
+
* from it.
|
|
276
|
+
*
|
|
277
|
+
* The arm id is folded in for exactly the reason it is one level up: a
|
|
278
|
+
* container's arms are near-copies by construction ("the same hero, two
|
|
279
|
+
* headlines"), so the same stored module id appearing in the Default arm and in
|
|
280
|
+
* arm B is the NORMAL case. Scoping both by the container id alone would give
|
|
281
|
+
* them one id, one `data-instance-id`, and one React key.
|
|
282
|
+
*
|
|
283
|
+
* - a Default-arm module becomes `${containerId}:${moduleId}`;
|
|
284
|
+
* - a variant-arm module becomes `${containerId}:${armId}:${moduleId}`;
|
|
285
|
+
* - the arm itself becomes `${containerId}:${armId}`.
|
|
286
|
+
*
|
|
287
|
+
* `instanceId` is scoped with the same key as `id`: it is what the front-edit
|
|
288
|
+
* overlay and the analytics DOM address a rendered module by, so two placements
|
|
289
|
+
* sharing one would be two nodes the editor cannot tell apart.
|
|
290
|
+
*
|
|
291
|
+
* Same COMPATIBILITY SURFACE caveat as the section-level scheme: detaching
|
|
292
|
+
* persists these ids into the page's stored layout, so changing the scheme
|
|
293
|
+
* re-keys previously detached containers.
|
|
294
|
+
*/
|
|
295
|
+
export function rekeyResolvedModuleVariantContainer(resolved, localId) {
|
|
296
|
+
const rekeyModule = (module, armScope) => ({
|
|
297
|
+
...module,
|
|
298
|
+
id: armScope(module.id),
|
|
299
|
+
instanceId: armScope(module.instanceId),
|
|
300
|
+
});
|
|
301
|
+
return {
|
|
302
|
+
...resolved,
|
|
303
|
+
id: localId,
|
|
304
|
+
defaultModule: rekeyModule(resolved.defaultModule, storedId => `${localId}:${storedId}`),
|
|
305
|
+
variants: (resolved.variants ?? []).map((variant) => ({
|
|
306
|
+
...variant,
|
|
307
|
+
id: `${localId}:${variant.id}`,
|
|
308
|
+
module: rekeyModule(variant.module, storedId => `${localId}:${variant.id}:${storedId}`),
|
|
309
|
+
})),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
212
312
|
/**
|
|
213
313
|
* Is this a *clean* linked instance — one that carries no local content of its
|
|
214
314
|
* own and therefore renders its component's definition strictly (kywi-cms#147)?
|
|
@@ -276,7 +376,32 @@ function stripLinksInSection(section) {
|
|
|
276
376
|
...section,
|
|
277
377
|
columns: (section.columns ?? []).map(column => ({
|
|
278
378
|
...column,
|
|
279
|
-
nodes: (column.nodes ?? []).map(
|
|
379
|
+
nodes: (column.nodes ?? []).map(stripLinksInColumnNode),
|
|
380
|
+
})),
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* {@link stripLinksInSection} for one column node — the modules, and since
|
|
385
|
+
* kywi-cms#170 a module-level container's OWN link as well.
|
|
386
|
+
*
|
|
387
|
+
* `mapColumnNode` reaches the arm modules but never the container itself, so
|
|
388
|
+
* before this a linked container buried in a section definition would have
|
|
389
|
+
* survived the strip and been promoted into a live link the moment the
|
|
390
|
+
* definition was materialised into a page. That is precisely the promotion
|
|
391
|
+
* {@link stripLinksInSection}'s docstring says can never happen.
|
|
392
|
+
*/
|
|
393
|
+
function stripLinksInColumnNode(node) {
|
|
394
|
+
const stripped = mapColumnNode(node, withoutComponentId);
|
|
395
|
+
return isModuleVariantContainer(stripped) ? withoutComponentId(stripped) : stripped;
|
|
396
|
+
}
|
|
397
|
+
/** {@link stripLinksInColumnNode}, for a module container resolved on its own. */
|
|
398
|
+
function stripLinksInModuleVariantContainer(container) {
|
|
399
|
+
return withoutComponentId({
|
|
400
|
+
...container,
|
|
401
|
+
defaultModule: withoutComponentId(container.defaultModule),
|
|
402
|
+
variants: (container.variants ?? []).map((variant) => ({
|
|
403
|
+
...variant,
|
|
404
|
+
module: withoutComponentId(variant.module),
|
|
280
405
|
})),
|
|
281
406
|
});
|
|
282
407
|
}
|
|
@@ -325,6 +450,28 @@ export function applyVariantContainerPlacement(resolved, placement) {
|
|
|
325
450
|
...(placement.winnerId !== undefined ? { winnerId: placement.winnerId } : {}),
|
|
326
451
|
});
|
|
327
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* The MODULE-level counterpart of {@link applyVariantContainerPlacement}
|
|
455
|
+
* (kywi-cms#170), rule for rule: the definition's arms, re-keyed off the
|
|
456
|
+
* placement's id, with the PLACEMENT's experiment binding winning over the
|
|
457
|
+
* definition's.
|
|
458
|
+
*
|
|
459
|
+
* The binding rule is the same one and it is here for the same reason —
|
|
460
|
+
* `experimentId`/`winnerId` say which run THIS page's arms report to and which
|
|
461
|
+
* arm has been locked in, which is a fact about the page, not about the shared
|
|
462
|
+
* component. A placement naming neither inherits the definition's, so a
|
|
463
|
+
* container saved with its binding intact keeps working when placed as-is; the
|
|
464
|
+
* editor mints a fresh one per placement precisely so that inheritance is never
|
|
465
|
+
* what a real placement relies on.
|
|
466
|
+
*/
|
|
467
|
+
export function applyModuleVariantContainerPlacement(resolved, placement) {
|
|
468
|
+
const materialised = rekeyResolvedModuleVariantContainer(resolved, placement.id);
|
|
469
|
+
return stripLinksInModuleVariantContainer({
|
|
470
|
+
...materialised,
|
|
471
|
+
...(placement.experimentId !== undefined ? { experimentId: placement.experimentId } : {}),
|
|
472
|
+
...(placement.winnerId !== undefined ? { winnerId: placement.winnerId } : {}),
|
|
473
|
+
});
|
|
474
|
+
}
|
|
328
475
|
// ── Un-applying a placement (the inverse) ────────────────────────────────────
|
|
329
476
|
//
|
|
330
477
|
// THE PAIR THAT MAKES "UPDATE ALL" NON-DESTRUCTIVE (kywi-cms#147 T4 review, C1).
|
|
@@ -364,10 +511,52 @@ export function unrekeyResolvedSection(resolved, rootId) {
|
|
|
364
511
|
columns: (resolved.columns ?? []).map(col => ({
|
|
365
512
|
...col,
|
|
366
513
|
id: unscope(col.id, scope),
|
|
367
|
-
nodes: (col.nodes ?? []).map(node =>
|
|
514
|
+
nodes: (col.nodes ?? []).map(node => unrekeyColumnNode(node, scope)),
|
|
368
515
|
})),
|
|
369
516
|
};
|
|
370
517
|
}
|
|
518
|
+
/** The inverse of {@link rekeyColumnNode}, undoing one section-level scope. */
|
|
519
|
+
function unrekeyColumnNode(node, scope) {
|
|
520
|
+
if (isModuleVariantContainer(node)) {
|
|
521
|
+
return unrekeyResolvedModuleVariantContainer(node, unscope(node.id, scope));
|
|
522
|
+
}
|
|
523
|
+
return mapColumnNode(node, m => ({
|
|
524
|
+
...m,
|
|
525
|
+
id: unscope(m.id, scope),
|
|
526
|
+
instanceId: unscope(m.instanceId, scope),
|
|
527
|
+
}));
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* The inverse of {@link rekeyResolvedModuleVariantContainer}: unwind the scope
|
|
531
|
+
* the container's own id imposed on its arms and their modules, and give the
|
|
532
|
+
* result `rootId`.
|
|
533
|
+
*
|
|
534
|
+
* `${containerId}:${armId}:${moduleId}` unwinds one level at a time, exactly as
|
|
535
|
+
* {@link unapplyVariantContainerPlacement} unwinds the section-level scheme. Ids
|
|
536
|
+
* that do NOT carry the prefix are left alone — a module the author swapped into
|
|
537
|
+
* an arm has a freshly generated id and no scope, and must keep it.
|
|
538
|
+
*/
|
|
539
|
+
export function unrekeyResolvedModuleVariantContainer(resolved, rootId) {
|
|
540
|
+
const scope = resolved.id;
|
|
541
|
+
const unscopeModule = (module, armScope) => ({
|
|
542
|
+
...module,
|
|
543
|
+
id: unscope(module.id, armScope),
|
|
544
|
+
instanceId: unscope(module.instanceId, armScope),
|
|
545
|
+
});
|
|
546
|
+
return {
|
|
547
|
+
...resolved,
|
|
548
|
+
id: rootId,
|
|
549
|
+
defaultModule: unscopeModule(resolved.defaultModule, scope),
|
|
550
|
+
variants: (resolved.variants ?? []).map((variant) => {
|
|
551
|
+
const armId = unscope(variant.id, scope);
|
|
552
|
+
return {
|
|
553
|
+
...variant,
|
|
554
|
+
id: armId,
|
|
555
|
+
module: unscopeModule(variant.module, `${scope}:${armId}`),
|
|
556
|
+
};
|
|
557
|
+
}),
|
|
558
|
+
};
|
|
559
|
+
}
|
|
371
560
|
/**
|
|
372
561
|
* What this placement would be as a DEFINITION: the inverse of
|
|
373
562
|
* {@link applySectionPlacement}.
|
|
@@ -409,6 +598,21 @@ export function unapplyVariantContainerPlacement(placement, definitionId) {
|
|
|
409
598
|
}),
|
|
410
599
|
});
|
|
411
600
|
}
|
|
601
|
+
/**
|
|
602
|
+
* The MODULE-level counterpart of {@link unapplyVariantContainerPlacement}
|
|
603
|
+
* (kywi-cms#170) — what this placement would be as a DEFINITION, and the exact
|
|
604
|
+
* inverse of {@link applyModuleVariantContainerPlacement}.
|
|
605
|
+
*
|
|
606
|
+
* The placement's `experimentId`/`winnerId` are DROPPED rather than inverted,
|
|
607
|
+
* for the reason its section-level twin drops them: they are this page's run of
|
|
608
|
+
* the experiment, and letting them travel into the definition is how one page's
|
|
609
|
+
* A/B test would enrol every other page placing the component. Restoring the
|
|
610
|
+
* definition's own binding is the caller's business — it holds the stored row.
|
|
611
|
+
*/
|
|
612
|
+
export function unapplyModuleVariantContainerPlacement(placement, definitionId) {
|
|
613
|
+
const { experimentId: _thisPagesRun, winnerId: _thisPagesWinner, ...rest } = placement;
|
|
614
|
+
return withoutComponentId(unrekeyResolvedModuleVariantContainer(rest, definitionId ?? placement.id));
|
|
615
|
+
}
|
|
412
616
|
function isPlainObject(value) {
|
|
413
617
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
414
618
|
}
|
|
@@ -472,6 +676,18 @@ export function validateComponentDefinition(component) {
|
|
|
472
676
|
return { success: false, error: result.error };
|
|
473
677
|
return rejectNestedComponentLinks(result.data);
|
|
474
678
|
}
|
|
679
|
+
if (type === 'moduleVariantContainer') {
|
|
680
|
+
const result = validateModuleVariantContainer(definition);
|
|
681
|
+
if (!result.success)
|
|
682
|
+
return { success: false, error: result.error };
|
|
683
|
+
// Wrapped in the shape a module container really lives in, because that is
|
|
684
|
+
// the shape every walker downstream knows how to read: a one-column section
|
|
685
|
+
// holding it. The wrapper is thrown away — only the verdict is kept — but it
|
|
686
|
+
// is what makes the ADMIN-ONLY arm-module walk and the nested-link refusal
|
|
687
|
+
// reach a promoted module's arms through exactly the same code that reaches
|
|
688
|
+
// a plain module beside it (kywi-cms#170).
|
|
689
|
+
return rejectNestedComponentLinks(wrapModuleVariantContainer(result.data));
|
|
690
|
+
}
|
|
475
691
|
return { success: false, error: `Unknown component type '${type}'` };
|
|
476
692
|
}
|
|
477
693
|
/**
|
|
@@ -501,6 +717,19 @@ export function validateComponentDefinition(component) {
|
|
|
501
717
|
* strip any link they find in a definition anyway ({@link stripLinksInSection}),
|
|
502
718
|
* so a row that predates this rule still cannot promote one.
|
|
503
719
|
*/
|
|
720
|
+
/**
|
|
721
|
+
* A module-level container as the one-column section it lives inside, so the
|
|
722
|
+
* document-shaped walkers can read it (kywi-cms#170). Ids are synthetic and
|
|
723
|
+
* discarded with the wrapper; the container keeps its own.
|
|
724
|
+
*/
|
|
725
|
+
function wrapModuleVariantContainer(container) {
|
|
726
|
+
return {
|
|
727
|
+
id: `${container.id}-definition-section`,
|
|
728
|
+
type: 'section',
|
|
729
|
+
style: {},
|
|
730
|
+
columns: [{ id: `${container.id}-definition-column`, width: 12, nodes: [container] }],
|
|
731
|
+
};
|
|
732
|
+
}
|
|
504
733
|
function rejectNestedComponentLinks(definition) {
|
|
505
734
|
const refs = collectComponentRefs({ regions: { definition: [definition] } });
|
|
506
735
|
const nested = refs[0];
|
|
@@ -548,6 +777,14 @@ export function componentDetachSource(component) {
|
|
|
548
777
|
return { kind: 'unresolvable' };
|
|
549
778
|
return { kind: 'variantContainer', container: def };
|
|
550
779
|
}
|
|
780
|
+
if (component.type === 'moduleVariantContainer') {
|
|
781
|
+
if (def['type'] !== 'moduleVariantContainer')
|
|
782
|
+
return { kind: 'unresolvable' };
|
|
783
|
+
return {
|
|
784
|
+
kind: 'moduleVariantContainer',
|
|
785
|
+
container: def,
|
|
786
|
+
};
|
|
787
|
+
}
|
|
551
788
|
return { kind: 'unresolvable' };
|
|
552
789
|
}
|
|
553
790
|
function applyLink(materialised, original, link) {
|
|
@@ -587,6 +824,16 @@ export function materializeVariantContainerNode(container, source, link = 'drop'
|
|
|
587
824
|
return applyLink(container, container, link);
|
|
588
825
|
return applyLink(applyVariantContainerPlacement(source.container, container), container, link);
|
|
589
826
|
}
|
|
827
|
+
/**
|
|
828
|
+
* The MODULE-level container equivalent (kywi-cms#170), delegating to
|
|
829
|
+
* {@link applyModuleVariantContainerPlacement} so what the renderer draws, what
|
|
830
|
+
* detaching bakes in and what pre-resolution ships are one function's output.
|
|
831
|
+
*/
|
|
832
|
+
export function materializeModuleVariantContainerNode(container, source, link = 'drop') {
|
|
833
|
+
if (source.kind !== 'moduleVariantContainer')
|
|
834
|
+
return applyLink(container, container, link);
|
|
835
|
+
return applyLink(applyModuleVariantContainerPlacement(source.container, container), container, link);
|
|
836
|
+
}
|
|
590
837
|
/** Materialise a connected module node into an INDEPENDENT one (link dropped). */
|
|
591
838
|
export function detachModuleNode(node, source) {
|
|
592
839
|
return materializeModuleNode(node, source, 'drop');
|
|
@@ -599,6 +846,10 @@ export function detachSectionNode(section, source) {
|
|
|
599
846
|
export function detachVariantContainerNode(container, source) {
|
|
600
847
|
return materializeVariantContainerNode(container, source, 'drop');
|
|
601
848
|
}
|
|
849
|
+
/** {@link detachVariantContainerNode} for a MODULE-level container (kywi-cms#170). */
|
|
850
|
+
export function detachModuleVariantContainerNode(container, source) {
|
|
851
|
+
return materializeModuleVariantContainerNode(container, source, 'drop');
|
|
852
|
+
}
|
|
602
853
|
/**
|
|
603
854
|
* THE traversal for "visit every linked placement in a document".
|
|
604
855
|
*
|
|
@@ -628,14 +879,29 @@ function mapLinkedPlacements(layout, mapper) {
|
|
|
628
879
|
let columnsChanged = false;
|
|
629
880
|
const columns = (section.columns ?? []).map(col => {
|
|
630
881
|
let nodesChanged = false;
|
|
631
|
-
const nodes = (col.nodes ?? []).map(node =>
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
882
|
+
const nodes = (col.nodes ?? []).map(node => {
|
|
883
|
+
// A LINKED module-level container resolves wholesale, so its inline arms
|
|
884
|
+
// are fallback copy and nothing inside them is a placement of this
|
|
885
|
+
// page's — the same rule a linked section gets, one level down
|
|
886
|
+
// (kywi-cms#170). Descending would rewrite an arm module's grandfathered
|
|
887
|
+
// link that the page never renders.
|
|
888
|
+
const containerLink = isModuleVariantContainer(node) ? readComponentId(node) : undefined;
|
|
889
|
+
if (containerLink) {
|
|
890
|
+
if (!mapper.matches(containerLink, 'moduleVariantContainer'))
|
|
891
|
+
return node;
|
|
892
|
+
changed++;
|
|
893
|
+
nodesChanged = true;
|
|
894
|
+
return mapper.moduleVariantContainer(node, containerLink);
|
|
895
|
+
}
|
|
896
|
+
return mapColumnNode(node, m => {
|
|
897
|
+
const link = readComponentId(m);
|
|
898
|
+
if (!link || !mapper.matches(link, 'module'))
|
|
899
|
+
return m;
|
|
900
|
+
changed++;
|
|
901
|
+
nodesChanged = true;
|
|
902
|
+
return mapper.module(m, link);
|
|
903
|
+
});
|
|
904
|
+
});
|
|
639
905
|
if (!nodesChanged)
|
|
640
906
|
return col;
|
|
641
907
|
columnsChanged = true;
|
|
@@ -692,6 +958,11 @@ export function rewriteComponentInstances(layout, rewrite) {
|
|
|
692
958
|
nodeId: container.id,
|
|
693
959
|
kind: 'variantContainer',
|
|
694
960
|
}) ?? container,
|
|
961
|
+
moduleVariantContainer: (container, componentId) => rewrite.moduleVariantContainer?.(container, {
|
|
962
|
+
componentId,
|
|
963
|
+
nodeId: container.id,
|
|
964
|
+
kind: 'moduleVariantContainer',
|
|
965
|
+
}) ?? container,
|
|
695
966
|
});
|
|
696
967
|
return next;
|
|
697
968
|
}
|
|
@@ -707,6 +978,7 @@ export function detachComponentFromLayout(layout, componentId, source) {
|
|
|
707
978
|
module: node => materializeModuleNode(node, source, 'drop'),
|
|
708
979
|
section: section => materializeSectionNode(section, source, 'drop'),
|
|
709
980
|
variantContainer: container => materializeVariantContainerNode(container, source, 'drop'),
|
|
981
|
+
moduleVariantContainer: container => materializeModuleVariantContainerNode(container, source, 'drop'),
|
|
710
982
|
});
|
|
711
983
|
return { layout: next, detached: changed };
|
|
712
984
|
}
|
|
@@ -768,6 +1040,7 @@ export function resolveComponentPlacements(layout, lookup) {
|
|
|
768
1040
|
module: (node, id) => materializeModuleNode(node, sourceOf(id, 'module'), 'keep'),
|
|
769
1041
|
section: (section, id) => materializeSectionNode(section, sourceOf(id, 'section'), 'keep'),
|
|
770
1042
|
variantContainer: (container, id) => materializeVariantContainerNode(container, sourceOf(id, 'variantContainer'), 'keep'),
|
|
1043
|
+
moduleVariantContainer: (container, id) => materializeModuleVariantContainerNode(container, sourceOf(id, 'moduleVariantContainer'), 'keep'),
|
|
771
1044
|
});
|
|
772
1045
|
return next;
|
|
773
1046
|
}
|
|
@@ -829,6 +1102,10 @@ export function refreshComponentCopies(layout, lookup) {
|
|
|
829
1102
|
module: node => node,
|
|
830
1103
|
section: (section, id) => materializeSectionNode(section, sourceOf(id, 'section'), 'keep'),
|
|
831
1104
|
variantContainer: (container, id) => materializeVariantContainerNode(container, sourceOf(id, 'variantContainer'), 'keep'),
|
|
1105
|
+
// A module-level container carries a fallback copy just as its section-level
|
|
1106
|
+
// sibling does, so it is refreshed for the same reason (kywi-cms#170) — the
|
|
1107
|
+
// `kind !== 'module'` predicate above already picks it up.
|
|
1108
|
+
moduleVariantContainer: (container, id) => materializeModuleVariantContainerNode(container, sourceOf(id, 'moduleVariantContainer'), 'keep'),
|
|
832
1109
|
});
|
|
833
1110
|
if (next === layout)
|
|
834
1111
|
return layout;
|