@ohhwells/bridge 0.1.150 → 0.1.151-next.406

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { Ref, ReactNode, DragEvent, PointerEvent } from 'react';
3
+ import { Ref, CSSProperties, ReactNode, DragEvent, PointerEvent } from 'react';
4
4
  import * as class_variance_authority_types from 'class-variance-authority/types';
5
5
  import { VariantProps } from 'class-variance-authority';
6
6
  import { Toggle as Toggle$1, DropdownMenu as DropdownMenu$1, Tooltip as Tooltip$1 } from 'radix-ui';
@@ -686,6 +686,19 @@ declare function SchedulingWidget({ notifyOnConnect, initialScheduleId, insertAf
686
686
  insertAfter?: string;
687
687
  }): react_jsx_runtime.JSX.Element;
688
688
 
689
+ declare const OHW_LOADER_STYLE: CSSProperties;
690
+ declare function OhwLoaderSpinner(): react_jsx_runtime.JSX.Element;
691
+ declare const OHW_LOADER_PREHYDRATE_SCRIPT = "(function(){try{var fromGlobal=typeof window!==\"undefined\"&&window.__OHW_SUBDOMAIN__?String(window.__OHW_SUBDOMAIN__):\"\";var p=location.hostname.split(\".\");var fromHost=location.hostname.endsWith(\".ohhwells.site\")&&p[0]&&p[0]!==\"www\"?p[0]:\"\";var fromQuery=new URLSearchParams(location.search).get(\"subdomain\")||\"\";var fromCookie=(document.cookie.match(/(?:^|; )ohw-subdomain=([^;]*)/)||[])[1];fromCookie=fromCookie?decodeURIComponent(fromCookie):\"\";if(!fromGlobal&&!fromHost&&!fromQuery&&!fromCookie)return;var e=document.getElementById(\"ohw-loader\");if(e)e.style.display=\"flex\"}catch(e){}})();";
692
+ /**
693
+ * The loader div plus the script that reveals it before hydration.
694
+ *
695
+ * Render it from a template's root layout, outside <Suspense> and before {children}. It starts
696
+ * hidden, so a non-customer page (a raw template preview URL) never shows it: the script above
697
+ * only reveals it once it has found a site identity. The bridge hides it again from a
698
+ * useLayoutEffect once the site's content is applied.
699
+ */
700
+ declare function OhwLoaderSurface(): react_jsx_runtime.JSX.Element;
701
+
689
702
  declare const DragHandle: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & React.RefAttributes<HTMLButtonElement>>;
690
703
 
691
704
  /**
@@ -853,6 +866,89 @@ declare function EmptySection({ title, homeHref, eyebrowKey, titleKey, subtitleK
853
866
 
854
867
  declare function isEditSessionActive(): boolean;
855
868
 
869
+ declare const BRAND_TITLE_KEY = "__ohw_site_title";
870
+ declare const SITE_OG_IMAGE_KEY = "__ohw_og_image";
871
+ /**
872
+ * Apply the reserved brand-chrome keys from a hydrated content payload. Safe to call on every
873
+ * hydrate: each write guards on its current value. Missing keys are simply skipped, so a site
874
+ * without the business-name path / Site Settings overrides is untouched. Description applies
875
+ * only when non-empty. Og:image applies when the key is present — empty string clears it
876
+ * (Site Settings Remove).
877
+ */
878
+ declare function applyBrandChrome(content: Record<string, string>): void;
879
+
880
+ /**
881
+ * Telling a page's content mounting apart from incidental DOM churn, so the hydration pass can run
882
+ * before the browser paints in the first case and stay debounced in the second.
883
+ *
884
+ * Measured on a client-side nav from `/` to `/about`: the page's DOM commits at +376ms showing the
885
+ * template's own default copy, and the stored content only replaces it at +523ms when the debounced
886
+ * observer pass runs — ~150ms of visibly wrong text on every page-to-page click. The content was
887
+ * already in the cache the whole time (blocking the per-path fetch changed nothing), so that window
888
+ * was pure timer latency. A hard refresh never showed it because the loader covers the first paint,
889
+ * and the loader does not come back for client-side navigation.
890
+ *
891
+ * The fix rests on when a MutationObserver callback runs: it is queued as a microtask and drains at
892
+ * the end of the task that mutated the DOM, which is before the browser's next rendering
893
+ * opportunity. Applying synchronously from the callback therefore makes the new page's *first*
894
+ * paint correct, where a `setTimeout` — at any delay, including 0 — necessarily lands a frame later.
895
+ *
896
+ * The debounce still earns its keep for everything else, so this is a discriminator rather than a
897
+ * removal: only a batch that actually mounted content the bridge writes into skips the timer.
898
+ */
899
+ /**
900
+ * Did this batch of mutations add content the bridge is responsible for hydrating?
901
+ *
902
+ * Deliberately cheap: it stops at the first match, and the observer watches `childList` only, so
903
+ * attribute-driven churn (carousel fades, hover states, the style store) never reaches it at all.
904
+ */
905
+ declare function hasMountedContentNodes(records: MutationRecord[]): boolean;
906
+
907
+ /**
908
+ * Deciding when a client-side page switch actually needs to ask the backend for content.
909
+ *
910
+ * A site's content is stored as one site-wide blob, so the payload the content endpoint returns is
911
+ * identical for every ordinary page. The exception is a duplicated page: it shares its source
912
+ * page's `data-ohw-key` strings but stores different values against them, which the backend merges
913
+ * in per path. The bridge used to be unable to tell the two apart, so it fetched once per distinct
914
+ * path visited — meaning every page switch on a normal site re-downloaded a byte-identical blob.
915
+ *
916
+ * The content response now carries `overriddenPaths`, the paths that genuinely diverge, which
917
+ * reduces that to: fetch on the first load, then only when entering a page that is actually a
918
+ * duplicate. An older backend omits the field, and since there is no other way to recognise a
919
+ * duplicate from the client, that case keeps the previous fetch-per-path behaviour rather than
920
+ * risking a duplicated page silently showing its source page's content.
921
+ */
922
+ /** Record what a content response said, including that it said nothing. */
923
+ declare function recordOverriddenPaths(subdomain: string, raw: unknown): void;
924
+ /** Should navigating to `path` trigger a content fetch? */
925
+ declare function shouldFetchContentForPath(subdomain: string, path: string): boolean;
926
+ /** Test seam: the cache is module state that would otherwise leak between cases. */
927
+ declare function resetOverriddenPathsCache(): void;
928
+
929
+ declare function isStickySearchParam(name: string): boolean;
930
+ /**
931
+ * Copy the sticky params of `currentSearch` onto `target`, and report whether anything changed.
932
+ *
933
+ * A param already present on `target` wins — an author who wrote `/pricing?ref=footer` meant that
934
+ * `ref`, so it is not overwritten by the one the visitor arrived with.
935
+ */
936
+ declare function applyStickySearchParams(target: URL, currentSearch: string): boolean;
937
+ /**
938
+ * Whether a click should be turned into an in-page navigation at all.
939
+ *
940
+ * The modifier checks are the reason this exists as a named helper: a handler that calls
941
+ * preventDefault() on every click silently breaks cmd/ctrl-click (open in new tab), shift-click
942
+ * (new window) and middle-click, which is a far worse regression than the dropped param it was
943
+ * trying to fix.
944
+ */
945
+ declare function isPlainLeftClick(e: MouseEvent): boolean;
946
+ /**
947
+ * Given a clicked anchor, the page's current search string and the origin, work out the URL the
948
+ * bridge should navigate to instead — or null to let the browser handle the click untouched.
949
+ */
950
+ declare function resolveStickyNavigation(anchor: HTMLAnchorElement, currentSearch: string, origin: string): string | null;
951
+
856
952
  type CarouselSlide = {
857
953
  src: string;
858
954
  alt: string;
@@ -874,4 +970,4 @@ declare function useOhwCarousel(key: string, initial: CarouselSlide[]): {
874
970
  bind: Record<string, string>;
875
971
  };
876
972
 
877
- export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, type CarouselSlide, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OhhwellsBridge, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, insertFooterHours, isEditSessionActive, isRenderableFooterTree, isRenderableTree, isValidUrl, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, removeFooterBlock, resolveFooterCopyright, serializeAiFooterState, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
973
+ export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, BRAND_TITLE_KEY, type CarouselSlide, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OHW_LOADER_PREHYDRATE_SCRIPT, OHW_LOADER_STYLE, OhhwellsBridge, OhwLoaderSpinner, OhwLoaderSurface, SITE_OG_IMAGE_KEY, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, applyBrandChrome, applyStickySearchParams, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, hasMountedContentNodes, insertFooterHours, isEditSessionActive, isPlainLeftClick, isRenderableFooterTree, isRenderableTree, isStickySearchParam, isValidUrl, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, recordOverriddenPaths, removeFooterBlock, resetOverriddenPathsCache, resolveFooterCopyright, resolveStickyNavigation, serializeAiFooterState, shouldFetchContentForPath, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { Ref, ReactNode, DragEvent, PointerEvent } from 'react';
3
+ import { Ref, CSSProperties, ReactNode, DragEvent, PointerEvent } from 'react';
4
4
  import * as class_variance_authority_types from 'class-variance-authority/types';
5
5
  import { VariantProps } from 'class-variance-authority';
6
6
  import { Toggle as Toggle$1, DropdownMenu as DropdownMenu$1, Tooltip as Tooltip$1 } from 'radix-ui';
@@ -686,6 +686,19 @@ declare function SchedulingWidget({ notifyOnConnect, initialScheduleId, insertAf
686
686
  insertAfter?: string;
687
687
  }): react_jsx_runtime.JSX.Element;
688
688
 
689
+ declare const OHW_LOADER_STYLE: CSSProperties;
690
+ declare function OhwLoaderSpinner(): react_jsx_runtime.JSX.Element;
691
+ declare const OHW_LOADER_PREHYDRATE_SCRIPT = "(function(){try{var fromGlobal=typeof window!==\"undefined\"&&window.__OHW_SUBDOMAIN__?String(window.__OHW_SUBDOMAIN__):\"\";var p=location.hostname.split(\".\");var fromHost=location.hostname.endsWith(\".ohhwells.site\")&&p[0]&&p[0]!==\"www\"?p[0]:\"\";var fromQuery=new URLSearchParams(location.search).get(\"subdomain\")||\"\";var fromCookie=(document.cookie.match(/(?:^|; )ohw-subdomain=([^;]*)/)||[])[1];fromCookie=fromCookie?decodeURIComponent(fromCookie):\"\";if(!fromGlobal&&!fromHost&&!fromQuery&&!fromCookie)return;var e=document.getElementById(\"ohw-loader\");if(e)e.style.display=\"flex\"}catch(e){}})();";
692
+ /**
693
+ * The loader div plus the script that reveals it before hydration.
694
+ *
695
+ * Render it from a template's root layout, outside <Suspense> and before {children}. It starts
696
+ * hidden, so a non-customer page (a raw template preview URL) never shows it: the script above
697
+ * only reveals it once it has found a site identity. The bridge hides it again from a
698
+ * useLayoutEffect once the site's content is applied.
699
+ */
700
+ declare function OhwLoaderSurface(): react_jsx_runtime.JSX.Element;
701
+
689
702
  declare const DragHandle: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & React.RefAttributes<HTMLButtonElement>>;
690
703
 
691
704
  /**
@@ -853,6 +866,89 @@ declare function EmptySection({ title, homeHref, eyebrowKey, titleKey, subtitleK
853
866
 
854
867
  declare function isEditSessionActive(): boolean;
855
868
 
869
+ declare const BRAND_TITLE_KEY = "__ohw_site_title";
870
+ declare const SITE_OG_IMAGE_KEY = "__ohw_og_image";
871
+ /**
872
+ * Apply the reserved brand-chrome keys from a hydrated content payload. Safe to call on every
873
+ * hydrate: each write guards on its current value. Missing keys are simply skipped, so a site
874
+ * without the business-name path / Site Settings overrides is untouched. Description applies
875
+ * only when non-empty. Og:image applies when the key is present — empty string clears it
876
+ * (Site Settings Remove).
877
+ */
878
+ declare function applyBrandChrome(content: Record<string, string>): void;
879
+
880
+ /**
881
+ * Telling a page's content mounting apart from incidental DOM churn, so the hydration pass can run
882
+ * before the browser paints in the first case and stay debounced in the second.
883
+ *
884
+ * Measured on a client-side nav from `/` to `/about`: the page's DOM commits at +376ms showing the
885
+ * template's own default copy, and the stored content only replaces it at +523ms when the debounced
886
+ * observer pass runs — ~150ms of visibly wrong text on every page-to-page click. The content was
887
+ * already in the cache the whole time (blocking the per-path fetch changed nothing), so that window
888
+ * was pure timer latency. A hard refresh never showed it because the loader covers the first paint,
889
+ * and the loader does not come back for client-side navigation.
890
+ *
891
+ * The fix rests on when a MutationObserver callback runs: it is queued as a microtask and drains at
892
+ * the end of the task that mutated the DOM, which is before the browser's next rendering
893
+ * opportunity. Applying synchronously from the callback therefore makes the new page's *first*
894
+ * paint correct, where a `setTimeout` — at any delay, including 0 — necessarily lands a frame later.
895
+ *
896
+ * The debounce still earns its keep for everything else, so this is a discriminator rather than a
897
+ * removal: only a batch that actually mounted content the bridge writes into skips the timer.
898
+ */
899
+ /**
900
+ * Did this batch of mutations add content the bridge is responsible for hydrating?
901
+ *
902
+ * Deliberately cheap: it stops at the first match, and the observer watches `childList` only, so
903
+ * attribute-driven churn (carousel fades, hover states, the style store) never reaches it at all.
904
+ */
905
+ declare function hasMountedContentNodes(records: MutationRecord[]): boolean;
906
+
907
+ /**
908
+ * Deciding when a client-side page switch actually needs to ask the backend for content.
909
+ *
910
+ * A site's content is stored as one site-wide blob, so the payload the content endpoint returns is
911
+ * identical for every ordinary page. The exception is a duplicated page: it shares its source
912
+ * page's `data-ohw-key` strings but stores different values against them, which the backend merges
913
+ * in per path. The bridge used to be unable to tell the two apart, so it fetched once per distinct
914
+ * path visited — meaning every page switch on a normal site re-downloaded a byte-identical blob.
915
+ *
916
+ * The content response now carries `overriddenPaths`, the paths that genuinely diverge, which
917
+ * reduces that to: fetch on the first load, then only when entering a page that is actually a
918
+ * duplicate. An older backend omits the field, and since there is no other way to recognise a
919
+ * duplicate from the client, that case keeps the previous fetch-per-path behaviour rather than
920
+ * risking a duplicated page silently showing its source page's content.
921
+ */
922
+ /** Record what a content response said, including that it said nothing. */
923
+ declare function recordOverriddenPaths(subdomain: string, raw: unknown): void;
924
+ /** Should navigating to `path` trigger a content fetch? */
925
+ declare function shouldFetchContentForPath(subdomain: string, path: string): boolean;
926
+ /** Test seam: the cache is module state that would otherwise leak between cases. */
927
+ declare function resetOverriddenPathsCache(): void;
928
+
929
+ declare function isStickySearchParam(name: string): boolean;
930
+ /**
931
+ * Copy the sticky params of `currentSearch` onto `target`, and report whether anything changed.
932
+ *
933
+ * A param already present on `target` wins — an author who wrote `/pricing?ref=footer` meant that
934
+ * `ref`, so it is not overwritten by the one the visitor arrived with.
935
+ */
936
+ declare function applyStickySearchParams(target: URL, currentSearch: string): boolean;
937
+ /**
938
+ * Whether a click should be turned into an in-page navigation at all.
939
+ *
940
+ * The modifier checks are the reason this exists as a named helper: a handler that calls
941
+ * preventDefault() on every click silently breaks cmd/ctrl-click (open in new tab), shift-click
942
+ * (new window) and middle-click, which is a far worse regression than the dropped param it was
943
+ * trying to fix.
944
+ */
945
+ declare function isPlainLeftClick(e: MouseEvent): boolean;
946
+ /**
947
+ * Given a clicked anchor, the page's current search string and the origin, work out the URL the
948
+ * bridge should navigate to instead — or null to let the browser handle the click untouched.
949
+ */
950
+ declare function resolveStickyNavigation(anchor: HTMLAnchorElement, currentSearch: string, origin: string): string | null;
951
+
856
952
  type CarouselSlide = {
857
953
  src: string;
858
954
  alt: string;
@@ -874,4 +970,4 @@ declare function useOhwCarousel(key: string, initial: CarouselSlide[]): {
874
970
  bind: Record<string, string>;
875
971
  };
876
972
 
877
- export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, type CarouselSlide, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OhhwellsBridge, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, insertFooterHours, isEditSessionActive, isRenderableFooterTree, isRenderableTree, isValidUrl, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, removeFooterBlock, resolveFooterCopyright, serializeAiFooterState, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
973
+ export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, BRAND_TITLE_KEY, type CarouselSlide, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OHW_LOADER_PREHYDRATE_SCRIPT, OHW_LOADER_STYLE, OhhwellsBridge, OhwLoaderSpinner, OhwLoaderSurface, SITE_OG_IMAGE_KEY, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, applyBrandChrome, applyStickySearchParams, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, hasMountedContentNodes, insertFooterHours, isEditSessionActive, isPlainLeftClick, isRenderableFooterTree, isRenderableTree, isStickySearchParam, isValidUrl, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, recordOverriddenPaths, removeFooterBlock, resetOverriddenPathsCache, resolveFooterCopyright, resolveStickyNavigation, serializeAiFooterState, shouldFetchContentForPath, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };