@syntrologie/runtime-sdk 2.2.0-canary.8 → 2.2.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.
Files changed (45) hide show
  1. package/README.md +2 -1
  2. package/dist/actions/types.d.ts +7 -0
  3. package/dist/antiFlicker.d.ts +2 -0
  4. package/dist/apps/builtinRuntimeModules.generated.d.ts +20 -0
  5. package/dist/{chunk-MEBUEMEZ.js → chunk-V4MDQX67.js} +2868 -1417
  6. package/dist/chunk-V4MDQX67.js.map +7 -0
  7. package/dist/configFetcher.d.ts +3 -1
  8. package/dist/context/ContextManager.d.ts +4 -0
  9. package/dist/diagnostics/service-worker-check.d.ts +23 -0
  10. package/dist/editorLoader.d.ts +8 -2
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.js +1563 -12
  13. package/dist/index.js.map +4 -4
  14. package/dist/integrations/gtm-bridge.d.ts +36 -0
  15. package/dist/navigation/NavigationMonitor.d.ts +45 -0
  16. package/dist/overlays/runtime/utils/AnchorWatcher.d.ts +22 -0
  17. package/dist/overlays/types.d.ts +2 -0
  18. package/dist/react.js +1 -1
  19. package/dist/runtime.d.ts +3 -0
  20. package/dist/smart-canvas.esm.js +62 -36
  21. package/dist/smart-canvas.esm.js.map +4 -4
  22. package/dist/smart-canvas.js +15828 -23049
  23. package/dist/smart-canvas.js.map +4 -4
  24. package/dist/smart-canvas.min.js +62 -36
  25. package/dist/smart-canvas.min.js.map +4 -4
  26. package/dist/telemetry/adapters/posthog.d.ts +19 -0
  27. package/dist/telemetry/consent.d.ts +62 -0
  28. package/dist/version.d.ts +1 -1
  29. package/dist/widgets/WidgetRegistry.d.ts +10 -0
  30. package/package.json +13 -4
  31. package/schema/canvas-config.schema.json +124 -22
  32. package/scripts/syntroReactPlugin.mjs +113 -0
  33. package/dist/adaptives/adaptive-chatbot/index.js +0 -9
  34. package/dist/adaptives/adaptive-chatbot/index.js.map +0 -7
  35. package/dist/adaptives/adaptive-content/index.js +0 -22
  36. package/dist/adaptives/adaptive-content/index.js.map +0 -7
  37. package/dist/adaptives/adaptive-faq/index.js +0 -28
  38. package/dist/adaptives/adaptive-faq/index.js.map +0 -7
  39. package/dist/adaptives/adaptive-gamification/index.js +0 -2
  40. package/dist/adaptives/adaptive-gamification/index.js.map +0 -7
  41. package/dist/adaptives/adaptive-nav/index.js +0 -27
  42. package/dist/adaptives/adaptive-nav/index.js.map +0 -7
  43. package/dist/adaptives/adaptive-overlays/index.js +0 -94
  44. package/dist/adaptives/adaptive-overlays/index.js.map +0 -7
  45. package/dist/chunk-MEBUEMEZ.js.map +0 -7
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../shared-editor-ui/dist/cn.js", "syntro-react:react/jsx-runtime", "syntro-react:react", "syntro-react:react-dom", "../../../../../node_modules/css-selector-generator/src/types.ts", "../../../../../node_modules/css-selector-generator/src/utilities-messages.ts", "../../../../../node_modules/css-selector-generator/src/utilities-options.ts", "../../../../../node_modules/css-selector-generator/src/utilities-data.ts", "../../../../../node_modules/css-selector-generator/src/constants.ts", "../../../../../node_modules/css-selector-generator/src/selector-attribute.ts", "../../../../../node_modules/css-selector-generator/src/utilities-selectors.ts", "../../../../../node_modules/shared/src/utils.ts", "../../../../../node_modules/lucide-react/src/defaultAttributes.ts", "../../../../../node_modules/lucide-react/src/Icon.ts", "../../../../../node_modules/lucide-react/src/createLucideIcon.ts", "../../../../../node_modules/lucide-react/src/icons/check.ts", "../../../../../node_modules/lucide-react/src/icons/clock.ts", "../../../../../node_modules/lucide-react/src/icons/x.ts", "../../../../shared-editor-ui/dist/components/ConditionStatusLine.js", "../../../../shared-editor-ui/dist/components/DetectionBadge.js", "../../../../shared-editor-ui/dist/components/DismissedSection.js", "../../../../shared-editor-ui/dist/components/EditorBody.js", "../../../../shared-editor-ui/dist/components/EditorCard.js", "../../../../shared-editor-ui/dist/components/EditorFooter.js", "../../../../shared-editor-ui/dist/components/EditorHeader.js", "../../../../shared-editor-ui/dist/components/EditorInput.js", "../../../../shared-editor-ui/dist/components/EditorLayout.js", "../../../../shared-editor-ui/dist/components/EditorTextarea.js", "../../../../shared-editor-ui/dist/components/EmptyState.js", "../../../../shared-editor-ui/dist/components/TriggerJourney.js", "../../../../shared-editor-ui/dist/components/GroupHeader.js", "../../../../shared-editor-ui/dist/formatConditionLabel.js", "../../../../shared-editor-ui/dist/hooks/useShowWhenStatus.js", "../../../../adaptives/adaptive-faq/src/summarize.ts", "../../../../adaptives/adaptive-faq/src/types.ts", "../../../../adaptives/adaptive-faq/src/editor.tsx", "../../../../adaptives/adaptive-faq/src/executors.ts", "../../../../design-system/dist/tokens/colors.js", "syntro-react:react-dom/client", "../../../../adaptives/adaptive-faq/src/FAQWidget.tsx", "../../../../adaptives/adaptive-faq/src/runtime.ts", "../../../../adaptives/adaptive-faq/src/cdn.ts"],
4
- "sourcesContent": ["export function cn(...classes) {\n return classes.filter(Boolean).join(' ');\n}\n", "\n function _R() {\n return (typeof SynOS !== 'undefined' && SynOS.React) || {};\n }\n function _jsx(type, props, key) {\n var R = _R();\n var p = props || {};\n var c = p.children;\n delete p.children;\n if (key !== undefined) p.key = key;\n return Array.isArray(c)\n ? R.createElement.apply(null, [type, p].concat(c))\n : c !== undefined\n ? R.createElement(type, p, c)\n : R.createElement(type, p);\n }\n export var jsx = _jsx;\n export var jsxs = _jsx;\n export var Fragment = _R().Fragment;\n ", "\n function _R() {\n return (typeof SynOS !== 'undefined' && SynOS.React) || {};\n }\n\n // Default export \u2014 lazy proxy for React.* access\n export default new Proxy({}, { get: function(_, k) { return _R()[k]; } });\n\n // Hooks \u2014 lazy function wrappers (resolve at call time)\n export function useState() { return _R().useState.apply(null, arguments); }\n export function useEffect() { return _R().useEffect.apply(null, arguments); }\n export function useMemo() { return _R().useMemo.apply(null, arguments); }\n export function useCallback() { return _R().useCallback.apply(null, arguments); }\n export function useRef() { return _R().useRef.apply(null, arguments); }\n export function useContext() { return _R().useContext.apply(null, arguments); }\n export function useReducer() { return _R().useReducer.apply(null, arguments); }\n export function useLayoutEffect() { return _R().useLayoutEffect.apply(null, arguments); }\n export function useId() { return _R().useId.apply(null, arguments); }\n\n // Creation APIs \u2014 lazy function wrappers\n export function createElement() { return _R().createElement.apply(null, arguments); }\n export function createContext() { return _R().createContext.apply(null, arguments); }\n export function forwardRef() { return _R().forwardRef.apply(null, arguments); }\n export function memo() { return _R().memo.apply(null, arguments); }\n export function lazy() { return _R().lazy.apply(null, arguments); }\n export function isValidElement() { return _R().isValidElement.apply(null, arguments); }\n export function cloneElement() { return _R().cloneElement.apply(null, arguments); }\n\n // Component types \u2014 resolved at module eval (runtime loads first)\n var _r = _R();\n export var Fragment = _r.Fragment;\n export var Suspense = _r.Suspense;\n export var Children = _r.Children;\n export var Component = _r.Component;\n export var PureComponent = _r.PureComponent;\n ", "\n function _RD() {\n return (typeof SynOS !== 'undefined' && SynOS.ReactDOM) || {};\n }\n export default new Proxy({}, { get: function(_, k) { return _RD()[k]; } });\n export function createRoot() { return _RD().createRoot.apply(null, arguments); }\n export function hydrateRoot() { return _RD().hydrateRoot.apply(null, arguments); }\n export function createPortal() { return _RD().createPortal.apply(null, arguments); }\n export function flushSync() { return _RD().flushSync.apply(null, arguments); }\n ", "declare const opaqueId: unique symbol;\n\ndeclare interface Tagged<Token> {\n readonly [opaqueId]: Token;\n}\n\nexport type Opaque<Type, Token = unknown> = Type & Tagged<Token>;\n\nexport type ObjectValues<T> = T[keyof T];\n\n// TODO rename to \"CssSelector\"\nexport type CssSelectorGenerated = Opaque<string, \"CssSelector\">;\n\nexport const OPERATOR = {\n NONE: \"\",\n DESCENDANT: \" \",\n CHILD: \" > \",\n} as const;\n\nexport type OperatorValue = ObjectValues<typeof OPERATOR>;\n\nexport interface ElementSelectorData {\n value: CssSelectorGenerated;\n include: boolean;\n}\n\nexport interface ElementData {\n element: Element;\n operator: OperatorValue;\n selectors: Partial<Record<CssSelectorType, ElementSelectorData[]>>;\n}\n\nexport type CssSelector = string;\nexport type CssSelectors = CssSelector[];\n\ntype CssSelectorMatchFn = (input: string) => boolean;\nexport type CssSelectorMatch = RegExp | string | CssSelectorMatchFn;\n\nexport const CSS_SELECTOR_TYPE = {\n id: \"id\",\n class: \"class\",\n tag: \"tag\",\n attribute: \"attribute\",\n nthchild: \"nthchild\",\n nthoftype: \"nthoftype\",\n} as const;\n\nexport type CssSelectorType = ObjectValues<typeof CSS_SELECTOR_TYPE>;\nexport type CssSelectorTypes = CssSelectorType[];\n\nexport type CssSelectorsByType = Partial<Record<CssSelectorType, CssSelectors>>;\n\nexport type CssSelectorData = Partial<\n Record<CssSelectorType, string[] | string[][]>\n>;\n\nexport type CssSelectorGeneratorOptionsInput = Partial<{\n // List of selector types to use. They will be prioritised by their order.\n selectors: CssSelectorTypes;\n // List of selectors that should be prioritised.\n whitelist: CssSelectorMatch[];\n // List of selectors that should be ignored.\n blacklist: CssSelectorMatch[];\n // Root element inside which the selector will be generated. If not set, the document root will be used.\n root: ParentNode | null;\n // If set to `true`, the generator will test combinations of selectors of single type (e.g. multiple class selectors).\n combineWithinSelector: boolean;\n // If set to `true`, the generator will try to test combinations of selectors of different types (e.g. tag + class name).\n combineBetweenSelectors: boolean;\n // If set to `true`, all generated selectors will include the TAG part. Even if tag selector type is not included in `selectors` option.\n includeTag: boolean;\n // Maximum number of combinations of a selector type. This is handy for performance reasons, e.g. when elements have too many classnames.\n maxCombinations: number;\n // Maximum number of selector candidates to be tested for each element. This is handy for performance reasons, e.g. when elements can produce large number of combinations of various types of selectors.\n maxCandidates: number;\n // Experimental. If set to `true` and the \"root\" option is set, the fallback selectors will use \":scope\" pseudo-class to make the selectors shorter and simpler.\n useScope: boolean;\n // Limits the number of results (selectors) to be generated.\n maxResults: number;\n}>;\n\nexport type CssSelectorGeneratorOptions = Required<\n Omit<CssSelectorGeneratorOptionsInput, \"selectors\"> & {\n selectors: CssSelectorTypes;\n }\n>;\n\nexport interface IdentifiableParent {\n foundElements: Element[];\n selector: CssSelector;\n}\n\nexport type PatternMatcher = (input: string) => boolean;\n", "const libraryName = \"CssSelectorGenerator\";\n\n/**\n * Convenient wrapper for `console.warn` using consistent formatting.\n */\nexport function showWarning(id = \"unknown problem\", ...args: unknown[]): void {\n // eslint-disable-next-line no-console\n console.warn(`${libraryName}: ${id}`, ...args);\n}\n", "import {\n CSS_SELECTOR_TYPE,\n CssSelectorGeneratorOptions,\n CssSelectorMatch,\n CssSelectorTypes,\n} from \"./types.js\";\nimport { getRootNode } from \"./utilities-dom.js\";\nimport { isEnumValue } from \"./utilities-typescript.js\";\nimport { showWarning } from \"./utilities-messages.js\";\n\nexport const DEFAULT_OPTIONS = {\n selectors: [\n CSS_SELECTOR_TYPE.id,\n CSS_SELECTOR_TYPE.class,\n CSS_SELECTOR_TYPE.tag,\n CSS_SELECTOR_TYPE.attribute,\n ] as CssSelectorTypes,\n // if set to true, always include tag name\n includeTag: false,\n whitelist: [] as CssSelectorMatch[],\n blacklist: [] as CssSelectorMatch[],\n combineWithinSelector: true,\n combineBetweenSelectors: true,\n root: null,\n maxCombinations: Number.POSITIVE_INFINITY,\n maxCandidates: Number.POSITIVE_INFINITY,\n useScope: false,\n} as CssSelectorGeneratorOptions;\n\n/**\n * Makes sure returned value is a list containing only valid selector types.\n * @param input\n */\nexport function sanitizeSelectorTypes(input: unknown): CssSelectorTypes {\n if (!Array.isArray(input)) {\n return [];\n }\n return input.filter((item) => isEnumValue(CSS_SELECTOR_TYPE, item));\n}\n\n/**\n * Checks whether provided value is of type RegExp.\n */\nexport function isRegExp(input: unknown): input is RegExp {\n return input instanceof RegExp;\n}\n\n/**\n * Checks whether provided value is usable in whitelist or blacklist.\n * @param input\n */\nexport function isCssSelectorMatch(input: unknown): input is CssSelectorMatch {\n return [\"string\", \"function\"].includes(typeof input) || isRegExp(input);\n}\n\n/**\n * Converts input to a list of valid values for whitelist or blacklist.\n */\nexport function sanitizeCssSelectorMatchList(\n input: unknown,\n): CssSelectorMatch[] {\n if (!Array.isArray(input)) {\n return [];\n }\n return input.filter(isCssSelectorMatch);\n}\n\n/**\n * Checks whether provided value is valid Node.\n */\nexport function isNode(input: unknown): input is Node {\n return input instanceof Node;\n}\n\n/**\n * Checks whether provided value is valid ParentNode.\n */\nexport function isParentNode(input: unknown): input is ParentNode {\n const validParentNodeTypes: number[] = [\n Node.DOCUMENT_NODE,\n Node.DOCUMENT_FRAGMENT_NODE, // this includes Shadow DOM root\n Node.ELEMENT_NODE,\n ];\n\n return isNode(input) && validParentNodeTypes.includes(input.nodeType);\n}\n\n/**\n * Makes sure that the root node in options is valid.\n */\nexport function sanitizeRoot(input: unknown, element: Element): ParentNode {\n if (isParentNode(input)) {\n if (!input.contains(element)) {\n showWarning(\n \"element root mismatch\",\n \"Provided root does not contain the element. This will most likely result in producing a fallback selector using element's real root node. If you plan to use the selector using provided root (e.g. `root.querySelector`), it will not work as intended.\",\n );\n }\n return input;\n }\n\n const rootNode = element.getRootNode({ composed: false });\n if (isParentNode(rootNode)) {\n if (rootNode !== document) {\n showWarning(\n \"shadow root inferred\",\n \"You did not provide a root and the element is a child of Shadow DOM. This will produce a selector using ShadowRoot as a root. If you plan to use the selector using document as a root (e.g. `document.querySelector`), it will not work as intended.\",\n );\n }\n return rootNode;\n }\n\n return getRootNode(element);\n}\n\n/**\n * Makes sure that the output is a number, usable as `maxResults` option in\n * powerset generator.\n */\nexport function sanitizeMaxNumber(input?: unknown): number {\n return typeof input === \"number\" ? input : Number.POSITIVE_INFINITY;\n}\n\n/**\n * Makes sure the options object contains all required keys.\n */\nexport function sanitizeOptions(\n element: Element,\n custom_options = {},\n): CssSelectorGeneratorOptions {\n const options = {\n ...DEFAULT_OPTIONS,\n ...custom_options,\n };\n\n return {\n selectors: sanitizeSelectorTypes(options.selectors),\n whitelist: sanitizeCssSelectorMatchList(options.whitelist),\n blacklist: sanitizeCssSelectorMatchList(options.blacklist),\n root: sanitizeRoot(options.root, element),\n combineWithinSelector: !!options.combineWithinSelector,\n combineBetweenSelectors: !!options.combineBetweenSelectors,\n includeTag: !!options.includeTag,\n maxCombinations: sanitizeMaxNumber(options.maxCombinations),\n maxCandidates: sanitizeMaxNumber(options.maxCandidates),\n useScope: !!options.useScope,\n maxResults: sanitizeMaxNumber(options.maxResults),\n };\n}\n", "import { CssSelectorMatch, PatternMatcher } from \"./types.js\";\nimport { isRegExp } from \"./utilities-options.js\";\nimport { showWarning } from \"./utilities-messages.js\";\n\n/**\n * Creates array containing only items included in all input arrays.\n */\nexport function getIntersection<T>(items: T[][] = []): T[] {\n const [firstItem = [], ...otherItems] = items;\n if (otherItems.length === 0) {\n return firstItem;\n }\n return otherItems.reduce((accumulator, currentValue) => {\n return accumulator.filter((item) => currentValue.includes(item));\n }, firstItem);\n}\n\n/**\n * Converts array of arrays into a flat array.\n */\nexport function flattenArray<T>(input: T[][]): T[] {\n return ([] as T[]).concat(...input);\n}\n\n/**\n * Convert string that can contain wildcards (asterisks) to RegExp source.\n */\nexport function wildcardToRegExp(input: string): string {\n return (\n input\n // convert all special characters used by RegExp, except an asterisk\n .replace(/[|\\\\{}()[\\]^$+?.]/g, \"\\\\$&\")\n // convert asterisk to pattern that matches anything\n .replace(/\\*/g, \".+\")\n );\n}\n\n/**\n * Creates function that will test list of provided matchers against input.\n * Used for white/blacklist functionality.\n */\nexport function createPatternMatcher(list: CssSelectorMatch[]): PatternMatcher {\n const matchFunctions = list.map((item) => {\n if (isRegExp(item)) {\n return (input: string) => item.test(input);\n }\n\n if (typeof item === \"function\") {\n return (input: string) => {\n const result = item(input);\n if (typeof result !== \"boolean\") {\n showWarning(\n \"pattern matcher function invalid\",\n \"Provided pattern matching function does not return boolean. It's result will be ignored.\",\n item,\n );\n return false;\n }\n return result;\n };\n }\n\n if (typeof item === \"string\") {\n const re = new RegExp(\"^\" + wildcardToRegExp(item) + \"$\");\n return (input: string) => re.test(input);\n }\n\n showWarning(\n \"pattern matcher invalid\",\n \"Pattern matching only accepts strings, regular expressions and/or functions. This item is invalid and will be ignored.\",\n item,\n );\n return () => false;\n });\n\n return (input: string) =>\n matchFunctions.some((matchFunction) => matchFunction(input));\n}\n", "import { CSS_SELECTOR_TYPE } from \"./types.js\";\n\nexport const SELECTOR_SEPARATOR = \", \";\n\n// RegExp that will match invalid patterns that can be used in ID attribute.\nexport const INVALID_ID_RE = new RegExp(\n [\n \"^$\", // empty or not set\n \"\\\\s\", // contains whitespace\n ].join(\"|\"),\n);\n\n// RegExp that will match invalid patterns that can be used in class attribute.\nexport const INVALID_CLASS_RE = new RegExp(\n [\n \"^$\", // empty or not set\n ].join(\"|\"),\n);\n\n// Order in which a combined selector is constructed.\nexport const SELECTOR_PATTERN = [\n CSS_SELECTOR_TYPE.nthoftype,\n CSS_SELECTOR_TYPE.tag,\n CSS_SELECTOR_TYPE.id,\n CSS_SELECTOR_TYPE.class,\n CSS_SELECTOR_TYPE.attribute,\n CSS_SELECTOR_TYPE.nthchild,\n];\n", "import { sanitizeSelectorItem } from \"./utilities-selectors.js\";\nimport { createPatternMatcher, getIntersection } from \"./utilities-data.js\";\nimport { CssSelectorGenerated } from \"./types.js\";\n\ninterface AttributeData {\n name: string;\n value: string;\n}\n\n// List of attributes to be ignored. These are handled by different selector types.\nexport const attributeBlacklistMatch = createPatternMatcher([\n \"class\",\n \"id\",\n // Angular attributes\n \"ng-*\",\n]);\n\n/**\n * Get simplified attribute selector for an element.\n */\nexport function attributeNodeToSimplifiedSelector({\n name,\n}: AttributeData): CssSelectorGenerated {\n return `[${name}]` as CssSelectorGenerated;\n}\n\n/**\n * Get attribute selector for an element.\n */\nexport function attributeNodeToSelector({\n name,\n value,\n}: AttributeData): CssSelectorGenerated {\n return `[${name}='${value}']` as CssSelectorGenerated;\n}\n\n/**\n * Checks whether an attribute should be used as a selector.\n */\nexport function isValidAttributeNode(\n { nodeName, nodeValue }: Node,\n element: Element,\n): boolean {\n // form input value should not be used as a selector\n const tagName = element.tagName.toLowerCase();\n if ([\"input\", \"option\"].includes(tagName) && nodeName === \"value\") {\n return false;\n }\n\n // ignore Base64-encoded strings as 'src' attribute values (e.g. in tags like img, audio, video, iframe, object, embed).\n if (nodeName === \"src\" && nodeValue?.startsWith(\"data:\")) {\n return false;\n }\n\n return !attributeBlacklistMatch(nodeName);\n}\n\n/**\n * Sanitize all attribute data. We want to do it once, before we start to generate simplified/full selectors from the same data.\n */\nfunction sanitizeAttributeData({ nodeName, nodeValue }: Node): AttributeData {\n return {\n name: sanitizeSelectorItem(nodeName),\n value: sanitizeSelectorItem(nodeValue ?? undefined),\n };\n}\n\n/**\n * Get attribute selectors for an element.\n */\nexport function getElementAttributeSelectors(\n element: Element,\n): CssSelectorGenerated[] {\n const validAttributes = Array.from(element.attributes)\n .filter((attributeNode) => isValidAttributeNode(attributeNode, element))\n .map(sanitizeAttributeData);\n return [\n ...validAttributes.map(attributeNodeToSimplifiedSelector),\n ...validAttributes.map(attributeNodeToSelector),\n ];\n}\n\n/**\n * Get attribute selectors matching all elements.\n */\nexport function getAttributeSelectors(\n elements: Element[],\n): CssSelectorGenerated[] {\n const elementSelectors = elements.map(getElementAttributeSelectors);\n return getIntersection(elementSelectors);\n}\n", "import { SELECTOR_PATTERN } from \"./constants.js\";\nimport {\n getAttributeSelectors,\n getElementAttributeSelectors,\n} from \"./selector-attribute.js\";\nimport {\n getClassSelectors,\n getElementClassSelectors,\n} from \"./selector-class.js\";\nimport { getElementIdSelectors, getIdSelector } from \"./selector-id.js\";\nimport {\n getElementNthChildSelector,\n getNthChildSelector,\n} from \"./selector-nth-child.js\";\nimport {\n getElementNthOfTypeSelector,\n getNthOfTypeSelector,\n} from \"./selector-nth-of-type.js\";\nimport { getElementTagSelectors, getTagSelector } from \"./selector-tag.js\";\nimport { createPatternMatcher } from \"./utilities-data.js\";\nimport { getParents, testSelector } from \"./utilities-dom.js\";\nimport {\n CSS_SELECTOR_TYPE,\n CssSelector,\n CssSelectorData,\n CssSelectorGenerated,\n CssSelectorGeneratorOptions,\n CssSelectorType,\n CssSelectorTypes,\n IdentifiableParent,\n OPERATOR,\n PatternMatcher,\n} from \"./types.js\";\nimport { isElement } from \"./utilities-iselement.js\";\nimport { getPowerSet, powerSetGenerator } from \"./utilities-powerset.js\";\nimport { cartesianProductGenerator } from \"./utilities-cartesian.js\";\n\nexport const ESCAPED_COLON = \":\".charCodeAt(0).toString(16).toUpperCase();\n\n// Square brackets need to be escaped, but eslint has a problem with that.\n/* eslint-disable-next-line no-useless-escape */\nexport const SPECIAL_CHARACTERS_RE = /[ !\"#$%&'()\\[\\]{|}<>*+,./;=?@^`~\\\\]/;\n\n/**\n * Escapes special characters used by CSS selector items.\n */\nexport function sanitizeSelectorItem(input = \"\"): string {\n // This should not be necessary, but just to be sure, let's keep the legacy sanitizer in place, for backwards compatibility.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return CSS ? CSS.escape(input) : legacySanitizeSelectorItem(input);\n}\n\n/**\n * Legacy version of escaping utility, originally used for IE11-. Should\n * probably be replaced by a polyfill:\n * https://github.com/mathiasbynens/CSS.escape\n */\nexport function legacySanitizeSelectorItem(input = \"\"): string {\n return input\n .split(\"\")\n .map((character) => {\n if (character === \":\") {\n return `\\\\${ESCAPED_COLON} `;\n }\n if (SPECIAL_CHARACTERS_RE.test(character)) {\n return `\\\\${character}`;\n }\n\n // needed for backwards compatibility\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n return escape(character).replace(/%/g, \"\\\\\");\n })\n .join(\"\");\n}\n\nexport const SELECTOR_TYPE_GETTERS: Record<\n CssSelectorType,\n (elements: Element[]) => CssSelector[]\n> = {\n tag: getTagSelector,\n id: getIdSelector,\n class: getClassSelectors,\n attribute: getAttributeSelectors,\n nthchild: getNthChildSelector,\n nthoftype: getNthOfTypeSelector,\n} as const;\n\nexport const ELEMENT_SELECTOR_TYPE_GETTERS: Record<\n CssSelectorType,\n (element: Element) => CssSelectorGenerated[]\n> = {\n tag: getElementTagSelectors,\n id: getElementIdSelectors,\n class: getElementClassSelectors,\n attribute: getElementAttributeSelectors,\n nthchild: getElementNthChildSelector,\n nthoftype: getElementNthOfTypeSelector,\n} as const;\n\n/**\n * Creates selector of given type for single element.\n */\nexport function getElementSelectorsByType(\n element: Element,\n selectorType: CssSelectorType,\n): CssSelectorGenerated[] {\n return ELEMENT_SELECTOR_TYPE_GETTERS[selectorType](element);\n}\n\n/**\n * Returns list of selectors of given type for the element.\n */\nexport function getSelectorsByType(\n elements: Element[],\n selector_type: CssSelectorType,\n): CssSelector[] {\n const getter = SELECTOR_TYPE_GETTERS[selector_type];\n return getter(elements);\n}\n\n/**\n * Remove blacklisted selectors from list.\n */\nexport function filterSelectors(\n list: CssSelector[] = [],\n matchBlacklist: PatternMatcher,\n matchWhitelist: PatternMatcher,\n): CssSelector[] {\n return list.filter((item) => matchWhitelist(item) || !matchBlacklist(item));\n}\n\n/**\n * Prioritise whitelisted selectors in list.\n */\nexport function orderSelectors(\n list: CssSelector[] = [],\n matchWhitelist: PatternMatcher,\n): CssSelector[] {\n return list.sort((a, b) => {\n const a_is_whitelisted = matchWhitelist(a);\n const b_is_whitelisted = matchWhitelist(b);\n if (a_is_whitelisted && !b_is_whitelisted) {\n return -1;\n }\n if (!a_is_whitelisted && b_is_whitelisted) {\n return 1;\n }\n return 0;\n });\n}\n\n/**\n * Yields list of unique selectors applicable to given element.\n */\nexport function* allSelectorsGenerator(\n elements: Element[],\n options: CssSelectorGeneratorOptions,\n): IterableIterator<CssSelector> {\n const yieldedSelectors = new Set<string>();\n const selectors_list = getSelectorsList(elements, options);\n for (const selector of selectorTypeCombinationsGenerator(\n selectors_list,\n options,\n )) {\n if (!yieldedSelectors.has(selector)) {\n yieldedSelectors.add(selector);\n yield selector;\n }\n }\n}\n\n/**\n * Creates object containing all selector types and their potential values.\n */\nexport function getSelectorsList(\n elements: Element[],\n options: CssSelectorGeneratorOptions,\n): CssSelectorData {\n const { blacklist, whitelist, combineWithinSelector, maxCombinations } =\n options;\n\n const matchBlacklist = createPatternMatcher(blacklist);\n const matchWhitelist = createPatternMatcher(whitelist);\n\n const reducer = (data: CssSelectorData, selector_type: CssSelectorType) => {\n const selectors_by_type = getSelectorsByType(elements, selector_type);\n const filtered_selectors = filterSelectors(\n selectors_by_type,\n matchBlacklist,\n matchWhitelist,\n );\n const found_selectors = orderSelectors(filtered_selectors, matchWhitelist);\n\n // Use Array.from with a length limit to avoid materializing huge power sets\n // This provides lazy evaluation while respecting maxCombinations\n data[selector_type] = combineWithinSelector\n ? Array.from(\n powerSetGenerator(found_selectors, { maxResults: maxCombinations }),\n )\n : found_selectors.map((item) => [item]);\n\n return data;\n };\n\n return getSelectorsToGet(options).reduce(reducer, {});\n}\n\n/**\n * Creates list of selector types that we will need to generate the selector.\n */\nexport function getSelectorsToGet(\n options: CssSelectorGeneratorOptions,\n): CssSelectorTypes {\n const { selectors, includeTag } = options;\n\n const selectors_to_get = [...selectors];\n if (includeTag && !selectors_to_get.includes(\"tag\")) {\n selectors_to_get.push(\"tag\");\n }\n return selectors_to_get;\n}\n\n/**\n * Adds \"tag\" to a list, if it does not contain it. Used to modify selectors\n * list when includeTag option is enabled to make sure all results contain the\n * TAG part.\n */\nfunction addTagTypeIfNeeded(list: CssSelectorTypes): CssSelectorTypes {\n return list.includes(CSS_SELECTOR_TYPE.tag) ||\n list.includes(CSS_SELECTOR_TYPE.nthoftype)\n ? [...list]\n : [...list, CSS_SELECTOR_TYPE.tag];\n}\n\n/**\n * Generates list of possible selector type combinations.\n */\nexport function combineSelectorTypes(\n options: CssSelectorGeneratorOptions,\n): CssSelectorTypes[] {\n const { selectors, combineBetweenSelectors, includeTag, maxCandidates } =\n options;\n\n const combinations = combineBetweenSelectors\n ? getPowerSet(selectors, { maxResults: maxCandidates })\n : selectors.map((item) => [item]);\n\n return includeTag ? combinations.map(addTagTypeIfNeeded) : combinations;\n}\n\n/**\n * Generates list of combined CSS selectors.\n */\nexport function* selectorTypeCombinationsGenerator(\n selectors_list: CssSelectorData,\n options: CssSelectorGeneratorOptions,\n): IterableIterator<CssSelector> {\n for (const item of combineSelectorTypes(options)) {\n yield* constructedSelectorsGenerator(item, selectors_list);\n }\n}\n\n/**\n * Generates all variations of possible selectors from provided data.\n */\nexport function* constructedSelectorsGenerator(\n selector_types: CssSelectorTypes,\n selectors_by_type: CssSelectorData,\n): IterableIterator<CssSelector> {\n const data: CssSelectorData = {};\n\n for (const selector_type of selector_types) {\n const selector_variants = selectors_by_type[selector_type];\n if (selector_variants && selector_variants.length > 0) {\n data[selector_type] = selector_variants;\n }\n }\n\n for (const combination of cartesianProductGenerator<string | string[]>(\n data,\n )) {\n yield constructSelector(combination);\n }\n}\n\n/**\n * Creates selector for given selector type. Combines several parts if needed.\n */\nexport function constructSelectorType(\n selector_type: CssSelectorType,\n selectors_data: CssSelectorData,\n): CssSelector {\n return selectors_data[selector_type]\n ? selectors_data[selector_type].join(\"\")\n : \"\";\n}\n\n/**\n * Converts selector data object to a selector.\n */\nexport function constructSelector(\n selectorData: CssSelectorData = {},\n): CssSelector {\n const pattern = [...SELECTOR_PATTERN];\n // selector \"nthoftype\" already contains \"tag\"\n if (\n selectorData[CSS_SELECTOR_TYPE.tag] &&\n selectorData[CSS_SELECTOR_TYPE.nthoftype]\n ) {\n pattern.splice(pattern.indexOf(CSS_SELECTOR_TYPE.tag), 1);\n }\n\n return pattern\n .map((type) => constructSelectorType(type, selectorData))\n .join(\"\");\n}\n\n/**\n * Generates combinations of child and descendant selectors within root\n * selector.\n */\nfunction generateCandidateCombinations(\n selectors: CssSelector[],\n rootSelector: CssSelector,\n): CssSelector[] {\n return [\n ...selectors.map(\n (selector) => rootSelector + OPERATOR.DESCENDANT + selector,\n ),\n ...selectors.map((selector) => rootSelector + OPERATOR.CHILD + selector),\n ];\n}\n\n/**\n * Generates a list of selector candidates that can potentially match target\n * element.\n */\nfunction* candidatesGenerator(\n selectors: IterableIterator<CssSelector>,\n rootSelector: CssSelector,\n): IterableIterator<CssSelector> {\n if (rootSelector === \"\") {\n yield* selectors;\n } else {\n for (const selector of selectors) {\n yield* generateCandidateCombinations([selector], rootSelector);\n }\n }\n}\n\n/**\n * Tries to find unique CSS selectors for element within given parent.\n */\nexport function* selectorWithinRootGenerator(\n elements: Element[],\n root: ParentNode,\n rootSelector: CssSelector = \"\",\n options: CssSelectorGeneratorOptions,\n): IterableIterator<CssSelector, undefined> {\n const elementSelectorsIterator = allSelectorsGenerator(elements, options);\n for (const candidateSelector of candidatesGenerator(\n elementSelectorsIterator,\n rootSelector,\n )) {\n if (testSelector(elements, candidateSelector, root)) {\n yield candidateSelector;\n }\n }\n // TODO remove the `undefined` return value when the main function is rewritten to use the generator directly\n return;\n}\n/**\n * Climbs through parents of the element and finds the ones that are identifiable by unique CSS selector.\n */\nexport function* closestIdentifiableParentGenerator(\n elements: Element[],\n root: ParentNode,\n rootSelector: CssSelector = \"\",\n options: CssSelectorGeneratorOptions,\n): IterableIterator<IdentifiableParent> {\n if (elements.length === 0) {\n return null;\n }\n\n const candidatesList = [\n elements.length > 1 ? elements : [],\n ...getParents(elements, root).map((element) => [element]),\n ];\n\n for (const currentElements of candidatesList) {\n for (const selectorWithinRoot of selectorWithinRootGenerator(\n currentElements,\n root,\n rootSelector,\n options,\n )) {\n yield {\n foundElements: currentElements,\n selector: selectorWithinRoot,\n };\n }\n }\n}\n\ninterface SelectorGeneratorProps {\n elements: Element[];\n root: ParentNode;\n rootSelector: CssSelector;\n options: CssSelectorGeneratorOptions;\n}\n\n/**\n * Recursively travels through parents, finds the ones that are identifiable and then tries to find a unique selector within that context.\n */\nexport function* selectorGenerator({\n elements,\n root,\n rootSelector = \"\",\n options,\n}: SelectorGeneratorProps): IterableIterator<CssSelector> {\n let currentRoot = root;\n let partialSelector = rootSelector;\n let shouldContinue = true;\n\n while (shouldContinue) {\n let foundAny = false;\n\n for (const item of closestIdentifiableParentGenerator(\n elements,\n currentRoot,\n partialSelector,\n options,\n )) {\n const { foundElements, selector } = item;\n foundAny = true;\n\n if (testSelector(elements, selector, root)) {\n yield selector;\n } else {\n // First non-matching selector - use its parent for next iteration\n currentRoot = foundElements[0];\n partialSelector = selector;\n break; // Try from this parent in next iteration\n }\n }\n\n if (!foundAny) {\n shouldContinue = false;\n }\n }\n}\n\n/**\n * Converts input into list of elements, removing duplicates and non-elements.\n */\nexport function sanitizeSelectorNeedle(needle: unknown): Element[] {\n if (needle instanceof NodeList || needle instanceof HTMLCollection) {\n needle = Array.from(needle);\n }\n const elements = (Array.isArray(needle) ? needle : [needle]).filter(\n isElement,\n );\n return [...new Set(elements)];\n}\n", "import { CamelToPascal } from './utility-types';\n\n/**\n * Converts string to kebab case\n *\n * @param {string} string\n * @returns {string} A kebabized string\n */\nexport const toKebabCase = (string: string) =>\n string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Converts string to camel case\n *\n * @param {string} string\n * @returns {string} A camelized string\n */\nexport const toCamelCase = <T extends string>(string: T) =>\n string.replace(/^([A-Z])|[\\s-_]+(\\w)/g, (match, p1, p2) =>\n p2 ? p2.toUpperCase() : p1.toLowerCase(),\n );\n\n/**\n * Converts string to pascal case\n *\n * @param {string} string\n * @returns {string} A pascalized string\n */\nexport const toPascalCase = <T extends string>(string: T): CamelToPascal<T> => {\n const camelCase = toCamelCase(string);\n\n return (camelCase.charAt(0).toUpperCase() + camelCase.slice(1)) as CamelToPascal<T>;\n};\n\n/**\n * Merges classes into a single string\n *\n * @param {array} classes\n * @returns {string} A string of classes\n */\nexport const mergeClasses = <ClassType = string | undefined | null>(...classes: ClassType[]) =>\n classes\n .filter((className, index, array) => {\n return (\n Boolean(className) &&\n (className as string).trim() !== '' &&\n array.indexOf(className) === index\n );\n })\n .join(' ')\n .trim();\n\n/**\n * Is empty string\n *\n * @param {unknown} value\n * @returns {boolean} Whether the value is an empty string\n */\nexport const isEmptyString = (value: unknown): boolean => value === '';\n\n/**\n * Check if a component has an accessibility prop\n *\n * @param {object} props\n * @returns {boolean} Whether the component has an accessibility prop\n */\nexport const hasA11yProp = (props: Record<string, any>) => {\n for (const prop in props) {\n if (prop.startsWith('aria-') || prop === 'role' || prop === 'title') {\n return true;\n }\n }\n};\n", "export default {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n};\n", "import { createElement, forwardRef } from 'react';\nimport defaultAttributes from './defaultAttributes';\nimport { IconNode, LucideProps } from './types';\nimport { mergeClasses, hasA11yProp } from '@lucide/shared';\n\ninterface IconComponentProps extends LucideProps {\n iconNode: IconNode;\n}\n\n/**\n * Lucide icon component\n *\n * @component Icon\n * @param {object} props\n * @param {string} props.color - The color of the icon\n * @param {number} props.size - The size of the icon\n * @param {number} props.strokeWidth - The stroke width of the icon\n * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width\n * @param {string} props.className - The class name of the icon\n * @param {IconNode} props.children - The children of the icon\n * @param {IconNode} props.iconNode - The icon node of the icon\n *\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst Icon = forwardRef<SVGSVGElement, IconComponentProps>(\n (\n {\n color = 'currentColor',\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = '',\n children,\n iconNode,\n ...rest\n },\n ref,\n ) =>\n createElement(\n 'svg',\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth,\n className: mergeClasses('lucide', className),\n ...(!children && !hasA11yProp(rest) && { 'aria-hidden': 'true' }),\n ...rest,\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...(Array.isArray(children) ? children : [children]),\n ],\n ),\n);\n\nexport default Icon;\n", "import { createElement, forwardRef } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';\nimport { IconNode, LucideProps } from './types';\nimport Icon from './Icon';\n\n/**\n * Create a Lucide icon component\n * @param {string} iconName\n * @param {array} iconNode\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst createLucideIcon = (iconName: string, iconNode: IconNode) => {\n const Component = forwardRef<SVGSVGElement, LucideProps>(({ className, ...props }, ref) =>\n createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className,\n ),\n ...props,\n }),\n );\n\n Component.displayName = toPascalCase(iconName);\n\n return Component;\n};\n\nexport default createLucideIcon;\n", "import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [['path', { d: 'M20 6 9 17l-5-5', key: '1gmf2c' }]];\n\n/**\n * @component @name Check\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cGF0aCBkPSJNMjAgNiA5IDE3bC01LTUiIC8+Cjwvc3ZnPgo=) - https://lucide.dev/icons/check\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Check = createLucideIcon('check', __iconNode);\n\nexport default Check;\n", "import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M12 6v6l4 2', key: 'mmk7yg' }],\n ['circle', { cx: '12', cy: '12', r: '10', key: '1mglay' }],\n];\n\n/**\n * @component @name Clock\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cGF0aCBkPSJNMTIgNnY2bDQgMiIgLz4KICA8Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIgLz4KPC9zdmc+Cg==) - https://lucide.dev/icons/clock\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Clock = createLucideIcon('clock', __iconNode);\n\nexport default Clock;\n", "import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M18 6 6 18', key: '1bl5f8' }],\n ['path', { d: 'm6 6 12 12', key: 'd8bk6v' }],\n];\n\n/**\n * @component @name X\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cGF0aCBkPSJNMTggNiA2IDE4IiAvPgogIDxwYXRoIGQ9Im02IDYgMTIgMTIiIC8+Cjwvc3ZnPgo=) - https://lucide.dev/icons/x\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst X = createLucideIcon('x', __iconNode);\n\nexport default X;\n", "import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\n/**\n * ConditionStatusLine \u2014 inline showWhen diagnostic on EditorCard.\n *\n * Shows a compact one-line status for items with showWhen conditions.\n * Click to expand per-condition detail.\n */\nimport { Check, Clock, X } from 'lucide-react';\nimport { useState } from 'react';\nimport { cn } from '../cn';\nfunction ProgressBar({ current, target }) {\n const pct = Math.min(100, Math.round((current / Math.max(target, 1)) * 100));\n return (_jsx(\"span\", { className: \"se-inline-block se-w-12 se-h-1.5 se-rounded-full se-bg-white/10 se-align-middle se-ml-1\", title: `${current}/${target} (${pct}%)`, children: _jsx(\"span\", { className: cn('se-block se-h-full se-rounded-full se-transition-all', pct >= 100 ? 'se-bg-green-4' : 'se-bg-blue-4'), style: { width: `${pct}%` } }) }));\n}\nfunction ConditionRow({ cs }) {\n return (_jsxs(\"div\", { className: \"se-flex se-items-center se-gap-1 se-pl-3 se-text-[10px] se-text-text-secondary\", children: [cs.passed ? (_jsx(Check, { className: \"se-w-3 se-h-3 se-text-green-4\" })) : (_jsx(X, { className: \"se-w-3 se-h-3 se-text-red-4\" })), _jsxs(\"span\", { children: [cs.type, \":\"] }), _jsx(\"span\", { className: \"se-text-text-tertiary\", children: cs.formatted.label }), cs.formatted.progress && (_jsxs(_Fragment, { children: [_jsx(ProgressBar, { current: cs.formatted.progress.current, target: cs.formatted.progress.target }), _jsxs(\"span\", { className: \"se-text-text-tertiary se-ml-0.5\", children: [cs.formatted.progress.current, \"/\", cs.formatted.progress.target] })] }))] }));\n}\nexport function ConditionStatusLine({ status }) {\n const [expanded, setExpanded] = useState(false);\n if (!status)\n return null;\n const { visible, conditions } = status;\n const passedCount = conditions.filter((c) => c.passed).length;\n const totalCount = conditions.length;\n // Icon: visible = green check, hidden = clock\n const StatusIcon = visible ? Check : Clock;\n const iconColor = visible ? 'se-text-green-4' : 'se-text-yellow-5';\n // Single condition: show inline detail\n // Multi condition: show summary, click to expand\n const isSingle = totalCount === 1;\n if (isSingle) {\n const cs = conditions[0];\n return (_jsxs(\"div\", { className: \"se-text-[10px] se-text-text-secondary se-mt-0.5 se-flex se-items-center se-gap-1\", children: [_jsx(StatusIcon, { className: cn('se-w-3 se-h-3', iconColor) }), _jsxs(\"span\", { children: [cs.type, \":\"] }), _jsx(\"span\", { className: \"se-text-text-tertiary\", children: cs.formatted.label }), cs.formatted.progress && (_jsxs(_Fragment, { children: [_jsx(ProgressBar, { current: cs.formatted.progress.current, target: cs.formatted.progress.target }), _jsxs(\"span\", { className: \"se-text-text-tertiary se-ml-0.5\", children: [cs.formatted.progress.current, \"/\", cs.formatted.progress.target] })] }))] }));\n }\n // Multi-condition: summary line + expandable detail\n return (_jsxs(\"div\", { className: \"se-mt-0.5\", children: [_jsxs(\"button\", { type: \"button\", className: \"se-flex se-items-center se-gap-1 se-text-[10px] se-text-text-secondary se-bg-transparent se-border-none se-cursor-pointer se-p-0 hover:se-text-text-primary\", onClick: (e) => {\n e.stopPropagation();\n setExpanded(!expanded);\n }, children: [_jsx(StatusIcon, { className: cn('se-w-3 se-h-3', iconColor) }), _jsxs(\"span\", { children: [passedCount, \" of \", totalCount, \" conditions met\"] }), _jsx(\"span\", { className: \"se-text-[8px] se-ml-0.5\", children: expanded ? '\\u25b2' : '\\u25bc' })] }), expanded && (_jsx(\"div\", { className: \"se-mt-0.5 se-space-y-0.5\", children: conditions.map((cs, i) => (_jsx(ConditionRow, { cs: cs }, i))) }))] }));\n}\n", "import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { cn } from '../cn';\nexport function DetectionBadge({ found }) {\n return (_jsx(\"span\", { className: cn('se-w-2 se-h-2 se-rounded-full se-shrink-0 se-inline-block', found ? 'se-bg-green-4' : 'se-bg-text-tertiary'), title: found ? 'Found on this page' : 'Not found on this page' }));\n}\n", "import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { useState } from 'react';\nexport function DismissedSection({ count, children }) {\n const [isOpen, setIsOpen] = useState(false);\n return (_jsxs(\"div\", { className: \"se-mt-4 se-cursor-pointer se-select-none\", children: [_jsxs(\"div\", { role: \"button\", tabIndex: 0, className: \"se-text-xs se-font-semibold se-text-text-tertiary se-flex se-items-center se-gap-1.5 se-cursor-pointer\", onClick: () => setIsOpen(!isOpen), onKeyDown: (e) => {\n if (e.key === 'Enter' || e.key === ' ')\n setIsOpen(!isOpen);\n }, children: [_jsx(\"span\", { children: isOpen ? '\\u25be' : '\\u25b8' }), _jsxs(\"span\", { children: [\"Dismissed (\", count, \")\"] })] }), isOpen && _jsx(\"div\", { className: \"se-mt-1.5\", children: children })] }));\n}\n", "import { jsx as _jsx } from \"react/jsx-runtime\";\nexport function EditorBody({ children }) {\n return _jsx(\"div\", { className: \"se-flex-1 se-overflow-auto se-p-6\", children: children });\n}\n", "import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { cn } from '../cn';\nexport function EditorCard({ children, itemKey, onClick, onMouseEnter, onMouseLeave, className, validated, }) {\n return (_jsx(\"div\", { \"data-item-key\": itemKey, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, className: cn('se-py-2 se-px-2.5 se-rounded-lg se-border se-bg-card-bg se-shadow-sm se-mb-1 se-text-sm se-text-text-primary', validated ? 'se-border-green-4/40 se-shadow-glow-green' : 'se-border-border-primary', onClick &&\n 'se-cursor-pointer hover:se-border-border-primary/80 hover:se-bg-sidebar-hover se-transition-colors', className), children: children }));\n}\n", "import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nexport function EditorFooter({ onSave, onPublish }) {\n return (_jsxs(\"div\", { className: \"se-py-3 se-px-4 se-border-t se-border-border-primary se-flex se-gap-2\", children: [_jsx(\"button\", { onClick: onSave, className: \"se-flex-1 se-h-10 se-px-4 se-py-2 se-rounded-md se-bg-btn-neutral se-text-btn-neutral-text se-border se-border-btn-neutral-border hover:se-text-btn-neutral-text-hover se-text-sm se-font-medium se-cursor-pointer se-inline-flex se-items-center se-justify-center focus-visible:se-shadow-focus-primary focus-visible:se-outline-none\", children: \"Save Draft\" }), _jsx(\"button\", { onClick: onPublish, className: \"se-flex-1 se-h-10 se-px-4 se-py-2 se-rounded-md se-border-none se-bg-btn-primary se-text-btn-primary-text hover:se-bg-btn-primary-hover se-text-sm se-font-medium se-cursor-pointer se-inline-flex se-items-center se-justify-center focus-visible:se-shadow-focus-primary focus-visible:se-outline-none\", children: \"Publish\" })] }));\n}\n", "import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nexport function EditorHeader({ title, subtitle }) {\n return (_jsxs(\"div\", { className: \"se-px-4 se-pt-3 se-pb-2\", children: [_jsx(\"h2\", { className: \"se-m-0 se-text-base se-font-semibold se-text-text-primary\", children: title }), subtitle && (_jsx(\"p\", { className: \"se-mt-0.5 se-mb-0 se-text-xs se-text-text-secondary\", children: subtitle }))] }));\n}\n", "import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { cn } from '../cn';\nexport function EditorInput({ label, className, ...props }) {\n return (_jsxs(\"div\", { children: [label && (_jsx(\"label\", { className: \"se-text-sm se-font-medium se-text-input-field-text-label se-mb-1 se-block\", children: label })), _jsx(\"input\", { ...props, className: cn('se-w-full se-py-2 se-px-3 se-rounded-lg se-border se-border-input-field-border se-bg-slate-grey-3 se-text-text-primary se-text-sm se-font-[inherit] se-mb-2 se-box-border', 'placeholder:se-text-input-field-text-placeholder', 'focus:se-border-input-field-border-selected focus:se-outline-none focus:se-shadow-focus-primary', 'disabled:se-bg-input-field-bg-disabled disabled:se-cursor-not-allowed disabled:se-opacity-50', className) })] }));\n}\n", "import { jsx as _jsx } from \"react/jsx-runtime\";\nexport function EditorLayout({ children }) {\n return _jsx(\"div\", { className: \"se-flex se-flex-col se-h-full se-font-sans\", children: children });\n}\n", "import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { useEffect, useRef } from 'react';\nimport { cn } from '../cn';\nexport function EditorTextarea({ label, className, value, ...props }) {\n const ref = useRef(null);\n // Auto-resize to fit content\n useEffect(() => {\n const el = ref.current;\n if (!el)\n return;\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }, [value]);\n return (_jsxs(\"div\", { children: [label && (_jsx(\"label\", { className: \"se-text-sm se-font-medium se-text-input-field-text-label se-mb-1 se-block\", children: label })), _jsx(\"textarea\", { ref: ref, value: value, ...props, className: cn('se-w-full se-py-2 se-px-3 se-rounded-lg se-border se-border-input-field-border se-bg-slate-grey-3 se-text-text-primary se-text-sm se-font-[inherit] se-mb-2 se-resize-y se-min-h-[60px] se-max-h-[50vh] se-overflow-y-auto se-box-border', 'placeholder:se-text-input-field-text-placeholder', 'focus:se-border-input-field-border-selected focus:se-outline-none focus:se-shadow-focus-primary', 'disabled:se-bg-input-field-bg-disabled disabled:se-cursor-not-allowed disabled:se-opacity-50', className) })] }));\n}\n", "import { jsx as _jsx } from \"react/jsx-runtime\";\nexport function EmptyState({ message }) {\n return (_jsx(\"div\", { className: \"se-text-center se-py-8 se-px-4 se-text-text-secondary se-text-sm\", children: message }));\n}\n", "import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\n/**\n * TriggerJourney \u2014 compact horizontal node graph for showWhen conditions.\n *\n * Displays each condition as a small circle node connected by lines.\n * Nodes light up green as conditions are met.\n */\nimport { Check } from 'lucide-react';\nimport { cn } from '../cn';\n/* ------------------------------------------------------------------ */\n/* Internal: small progress bar for event_count nodes */\n/* ------------------------------------------------------------------ */\nfunction ProgressBar({ current, target }) {\n const pct = Math.min(100, Math.round((current / Math.max(target, 1)) * 100));\n return (_jsxs(\"div\", { className: \"se-flex se-items-center se-gap-0.5\", children: [_jsx(\"span\", { className: \"se-inline-block se-w-8 se-h-1 se-rounded-full se-bg-white/10\", title: `${current}/${target} (${pct}%)`, children: _jsx(\"span\", { className: cn('se-block se-h-full se-rounded-full se-transition-all', pct >= 100 ? 'se-bg-green-4' : 'se-bg-blue-4'), style: { width: `${pct}%` } }) }), _jsxs(\"span\", { className: \"se-text-[9px] se-text-text-tertiary\", children: [current, \"/\", target] })] }));\n}\n/* ------------------------------------------------------------------ */\n/* Internal: single journey node with label + optional connection */\n/* ------------------------------------------------------------------ */\nfunction JourneyNode({ cs, isLast }) {\n const hasProgress = !!cs.formatted.progress;\n const inProgress = !cs.passed && hasProgress && cs.formatted.progress.current > 0;\n return (_jsxs(\"div\", { className: \"se-flex se-items-center se-gap-0\", children: [_jsxs(\"div\", { className: \"se-flex se-flex-col se-items-center se-min-w-0\", children: [_jsx(\"div\", { \"data-journey-node\": true, \"data-passed\": cs.passed ? 'true' : 'false', className: cn('se-w-4 se-h-4 se-rounded-full se-border-2 se-flex se-items-center se-justify-center se-shrink-0', cs.passed\n ? 'se-bg-green-4 se-border-green-4'\n : inProgress\n ? 'se-bg-blue-4 se-border-blue-4'\n : 'se-bg-transparent se-border-white/20'), children: cs.passed && _jsx(Check, { className: \"se-w-2.5 se-h-2.5 se-text-white\" }) }), _jsx(\"span\", { className: \"se-text-[9px] se-text-text-tertiary se-truncate se-max-w-[60px] se-text-center se-mt-0.5\", title: cs.formatted.instruction, children: cs.formatted.shortLabel }), hasProgress && (_jsx(ProgressBar, { current: cs.formatted.progress.current, target: cs.formatted.progress.target }))] }), !isLast && (_jsx(\"div\", { \"data-journey-line\": true, className: cn('se-h-0.5 se-w-4 se-self-start se-mt-2 se-shrink-0', cs.passed ? 'se-bg-green-4' : 'se-bg-white/10') }))] }));\n}\n/* ------------------------------------------------------------------ */\n/* Main component */\n/* ------------------------------------------------------------------ */\nexport function TriggerJourney({ status }) {\n if (!status || status.conditions.length === 0) {\n return (_jsx(\"div\", { className: \"se-mt-1 se-text-[10px] se-text-text-tertiary se-italic\", children: \"Always Present\" }));\n }\n const { conditions } = status;\n const allPassed = conditions.every((c) => c.passed);\n const isMulti = conditions.length > 1;\n return (_jsxs(\"div\", { className: \"se-mt-1\", children: [_jsx(\"div\", { className: \"se-flex se-items-start\", children: conditions.map((cs, i) => (_jsx(JourneyNode, { cs: cs, isLast: i === conditions.length - 1 }, i))) }), allPassed && isMulti && (_jsxs(\"div\", { className: \"se-flex se-items-center se-gap-1 se-mt-1 se-text-[10px] se-text-green-4\", children: [_jsx(Check, { className: \"se-w-3 se-h-3\" }), _jsx(\"span\", { children: \"All conditions met\" })] }))] }));\n}\n", "import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nimport { cn } from '../cn';\nexport function GroupHeader({ label, count, className }) {\n return (_jsxs(\"div\", { className: cn('se-text-xs se-font-bold se-text-text-primary se-uppercase se-tracking-wide se-py-1 se-pb-2 se-flex se-items-center se-justify-between', className), children: [_jsx(\"span\", { children: label }), _jsx(\"span\", { className: \"se-text-xs se-text-text-secondary se-bg-badge-slate-bg se-px-1.5 se-py-0.5 se-rounded-lg\", children: count })] }));\n}\n", "/**\n * Format a showWhen condition into a human-readable label.\n * Pure function \u2014 no runtime dependency.\n */\n/**\n * Format match criteria as a parenthetical string.\n * { tagName: 'a' } \u2192 '(tagName: a)'\n */\nfunction formatMatch(match) {\n if (!match || Object.keys(match).length === 0)\n return '';\n const parts = Object.entries(match).map(([k, v]) => `${k}: ${v}`);\n return ` (${parts.join(', ')})`;\n}\n/**\n * Format an operator for display.\n */\nfunction formatOperator(op) {\n switch (op) {\n case 'gte':\n return '\\u2265'; // \u2265\n case 'lte':\n return '\\u2264'; // \u2264\n case 'gt':\n return '>';\n case 'lt':\n return '<';\n case 'eq':\n return '=';\n default:\n return op;\n }\n}\n/**\n * Convert a hyphenated or underscored key into human-readable lowercase text.\n * e.g. \"fine-arts-page-views\" \u2192 \"fine arts page views\"\n */\nfunction humanizeKey(key) {\n return key.replace(/[-_]/g, ' ').toLowerCase();\n}\n/**\n * Strip trailing wildcard segments from a URL path.\n * e.g. \"/fine-arts/**\" \u2192 \"/fine-arts/\"\n */\nfunction cleanUrl(url) {\n return url.replace(/\\/?\\*+$/, '/').replace(/\\/\\/$/, '/');\n}\n// Pre-compiled regexes for event_count classification\nconst PAGE_VIEW_RE = /page.?view/i;\nconst CLICK_RE = /click/i;\n/**\n * Convert a Condition object into a human-readable label.\n * For event_count conditions, also returns progress data.\n */\nexport function formatConditionLabel(condition, accumulatorCount) {\n switch (condition.type) {\n case 'event_count': {\n const key = condition.key;\n const op = condition.operator;\n const target = condition.count;\n const current = accumulatorCount ?? 0;\n const humanized = humanizeKey(key);\n let instruction;\n let shortLabel;\n if (PAGE_VIEW_RE.test(humanized)) {\n // Extract the topic by removing \"page view(s)\" from the humanized key\n const topic = humanized.replace(/\\s*page\\s*views?\\s*/i, '').trim();\n instruction = topic\n ? `View ${topic} pages ${target}+ times`\n : `View pages ${target}+ times`;\n shortLabel = `View ${target}+ times`;\n }\n else if (CLICK_RE.test(humanized)) {\n const topic = humanized.replace(/\\s*clicks?\\s*/i, '').trim();\n instruction = topic\n ? `Click ${topic} ${target}+ times`\n : `Click ${target}+ times`;\n shortLabel = `${target}+ clicks`;\n }\n else {\n // Generic event\n const lastWord = humanized.trim().split(' ').filter(w => w).pop() || 'events';\n instruction = `Reach ${target}+ ${humanized} events`;\n shortLabel = `${target}+ ${lastWord}s`;\n }\n return {\n label: `${key} ${formatOperator(op)} ${target}`,\n instruction,\n shortLabel,\n progress: { current, target, operator: op },\n };\n }\n case 'page_url': {\n const url = condition.url;\n const cleaned = cleanUrl(url);\n const hasWildcard = url !== cleaned;\n const instruction = hasWildcard\n ? `Visit a ${cleaned} page`\n : `Visit ${cleaned}`;\n return {\n label: `${url}`,\n instruction,\n shortLabel: cleaned,\n };\n }\n case 'anchor_visible': {\n const anchorId = condition.anchorId;\n const state = condition.state;\n return {\n label: `${anchorId} (${state})`,\n instruction: `Scroll until ${anchorId} is ${state}`,\n shortLabel: `${anchorId}`,\n };\n }\n case 'event_occurred': {\n const eventName = condition.eventName;\n return {\n label: `${eventName}`,\n instruction: `Trigger a ${eventName} event`,\n shortLabel: `${eventName}`,\n };\n }\n case 'state_equals': {\n const key = condition.key;\n const val = condition.value === undefined ? 'undefined' : JSON.stringify(condition.value);\n return {\n label: `${key} = ${val}`,\n instruction: `${key} equals ${val}`,\n shortLabel: `${key}`,\n };\n }\n case 'viewport': {\n const parts = [];\n if (condition.minWidth !== undefined)\n parts.push(`w ${formatOperator('gte')} ${condition.minWidth}px`);\n if (condition.maxWidth !== undefined)\n parts.push(`w ${formatOperator('lte')} ${condition.maxWidth}px`);\n if (condition.minHeight !== undefined)\n parts.push(`h ${formatOperator('gte')} ${condition.minHeight}px`);\n if (condition.maxHeight !== undefined)\n parts.push(`h ${formatOperator('lte')} ${condition.maxHeight}px`);\n const label = parts.join(', ') || 'any viewport';\n const instruction = parts.length > 0\n ? `Use a viewport ${parts.join(' and ')}`\n : 'Use a viewport of any size';\n const shortLabel = parts.length > 0 ? parts[0] : 'Any size';\n return { label, instruction, shortLabel };\n }\n case 'session_metric': {\n const key = condition.key;\n const op = condition.operator;\n const threshold = condition.threshold;\n return {\n label: `${key} ${formatOperator(op)} ${threshold}`,\n instruction: `${key} reaches ${threshold}+`,\n shortLabel: `${key} ${threshold}+`,\n };\n }\n case 'dismissed': {\n const inverted = condition.inverted;\n const key = condition.key;\n const target = key || 'this';\n return {\n label: inverted ? 'not dismissed' : 'dismissed',\n instruction: inverted\n ? `Do not dismiss ${target}`\n : `Dismiss ${target}`,\n shortLabel: inverted ? 'Not dismissed' : 'Dismissed',\n };\n }\n case 'cooldown_active': {\n const inverted = condition.inverted;\n return {\n label: inverted ? 'cooldown inactive' : 'cooldown active',\n instruction: inverted\n ? 'Wait for cooldown to expire'\n : 'Cooldown is active',\n shortLabel: inverted ? 'Cooldown done' : 'Cooldown active',\n };\n }\n case 'frequency_limit': {\n const inverted = condition.inverted;\n const limit = condition.limit;\n return {\n label: `shown ${formatOperator(inverted ? 'lt' : 'gte')} ${limit} times`,\n instruction: inverted\n ? `Shown fewer than ${limit} times`\n : `Shown ${limit}+ times`,\n shortLabel: inverted ? `< ${limit} views` : `${limit}+ views`,\n };\n }\n case 'route': {\n const routeId = condition.routeId;\n return {\n label: `${routeId}`,\n instruction: `Navigate to ${routeId} route`,\n shortLabel: `${routeId}`,\n };\n }\n default:\n return {\n label: `${condition.type}`,\n instruction: `${condition.type}`,\n shortLabel: `${condition.type}`,\n };\n }\n}\n", "/**\n * useShowWhenStatus \u2014 live showWhen evaluation for editor diagnostics.\n *\n * Subscribes to the runtime's EventAccumulator for reactive updates.\n * Evaluates each item's showWhen strategy locally to get\n * per-condition breakdowns.\n *\n * NOTE: This hook accesses `window.SynOS.handle.runtime` directly\n * because EditorPanelProps doesn't expose runtime. This is safe \u2014\n * the editor only runs after runtime bootstrap.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { formatConditionLabel } from '../formatConditionLabel';\nfunction getRuntime() {\n return window.SynOS?.handle?.runtime ?? null;\n}\n/**\n * Evaluate a single condition against the runtime context.\n */\nfunction evaluateConditionLocally(condition, runtime) {\n const ctx = runtime.context.get();\n const type = condition.type;\n let passed = false;\n let accCount;\n switch (type) {\n case 'event_count': {\n if (!runtime.accumulator)\n break;\n const key = condition.key;\n const withinMs = condition.withinMs;\n const count = runtime.accumulator.getCount(key, withinMs);\n accCount = count;\n const target = condition.count;\n const op = condition.operator;\n switch (op) {\n case 'gte':\n passed = count >= target;\n break;\n case 'lte':\n passed = count <= target;\n break;\n case 'eq':\n passed = count === target;\n break;\n case 'gt':\n passed = count > target;\n break;\n case 'lt':\n passed = count < target;\n break;\n }\n break;\n }\n case 'page_url': {\n const url = condition.url;\n const pattern = url\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '.*')\n .replace(/\\*/g, '[^/]*');\n passed = new RegExp(`^${pattern}$`).test(ctx.page.url);\n break;\n }\n case 'route':\n passed = ctx.page.routeId === condition.routeId;\n break;\n case 'anchor_visible': {\n const anchors = ctx.anchors;\n const anchor = anchors?.find((a) => a.anchorId === condition.anchorId);\n switch (condition.state) {\n case 'visible':\n passed = anchor?.visible === true;\n break;\n case 'present':\n passed = anchor?.present === true;\n break;\n case 'absent':\n passed = !anchor?.present;\n break;\n }\n break;\n }\n case 'event_occurred':\n passed =\n runtime.events?.hasRecentEvent(condition.eventName, condition.withinMs ?? 60000) ?? false;\n break;\n case 'viewport': {\n const { width, height } = ctx.viewport;\n passed = true;\n if (condition.minWidth !== undefined && width < condition.minWidth)\n passed = false;\n if (condition.maxWidth !== undefined && width > condition.maxWidth)\n passed = false;\n if (condition.minHeight !== undefined && height < condition.minHeight)\n passed = false;\n if (condition.maxHeight !== undefined && height > condition.maxHeight)\n passed = false;\n break;\n }\n case 'session_metric': {\n const val = runtime.state?.getSessionMetric(condition.key) ?? 0;\n const threshold = condition.threshold;\n const op = condition.operator;\n switch (op) {\n case 'gte':\n passed = val >= threshold;\n break;\n case 'lte':\n passed = val <= threshold;\n break;\n case 'eq':\n passed = val === threshold;\n break;\n case 'gt':\n passed = val > threshold;\n break;\n case 'lt':\n passed = val < threshold;\n break;\n }\n break;\n }\n case 'dismissed':\n passed = condition.inverted\n ? !(runtime.state?.isDismissed(condition.key) ?? false)\n : (runtime.state?.isDismissed(condition.key) ?? false);\n break;\n case 'cooldown_active':\n passed = condition.inverted\n ? !(runtime.state?.isCooldownActive(condition.key) ?? false)\n : (runtime.state?.isCooldownActive(condition.key) ?? false);\n break;\n case 'frequency_limit': {\n const count = runtime.state?.getFrequencyCount(condition.key) ?? 0;\n const limitReached = count >= condition.limit;\n passed = condition.inverted ? !limitReached : limitReached;\n break;\n }\n }\n const formatted = formatConditionLabel(condition, accCount);\n return {\n passed,\n cs: { type, passed, formatted },\n };\n}\n/**\n * Evaluate all conditions in a showWhen RuleStrategy.\n */\nfunction evaluateShowWhen(showWhen, runtime) {\n if (showWhen.type !== 'rules' || !showWhen.rules?.length) {\n return { visible: !!showWhen.default, isFallback: true, conditions: [] };\n }\n // Evaluate ALL rules' conditions for diagnostic display\n const allConditions = [];\n for (const rule of showWhen.rules) {\n let ruleMatched = true;\n for (const condition of rule.conditions) {\n const { passed, cs } = evaluateConditionLocally(condition, runtime);\n allConditions.push(cs);\n if (!passed)\n ruleMatched = false;\n }\n if (ruleMatched) {\n return { visible: rule.value, isFallback: false, conditions: allConditions };\n }\n }\n // No rules matched \u2014 use default\n return {\n visible: showWhen.default ?? false,\n isFallback: true,\n conditions: allConditions,\n };\n}\n/**\n * Hook: live showWhen evaluation for a list of action items.\n *\n * @param items Array of items with id + optional showWhen\n * @returns Map from item id \u2192 ShowWhenStatus (null for items without showWhen)\n */\nexport function useShowWhenStatus(items) {\n const [statuses, setStatuses] = useState(new Map());\n const itemsRef = useRef(items);\n itemsRef.current = items;\n const evaluate = useCallback(() => {\n const runtime = getRuntime();\n if (!runtime)\n return;\n const map = new Map();\n for (const item of itemsRef.current) {\n if (!item.showWhen) {\n map.set(item.id, null);\n }\n else {\n map.set(item.id, evaluateShowWhen(item.showWhen, runtime));\n }\n }\n setStatuses(map);\n }, []);\n useEffect(() => {\n // Initial evaluation\n evaluate();\n // Subscribe to accumulator changes for reactive event_count updates\n const runtime = getRuntime();\n const unsubs = [];\n if (runtime?.accumulator) {\n unsubs.push(runtime.accumulator.subscribe(evaluate));\n }\n // Poll every 2s for non-accumulator conditions (page_url, viewport, etc.)\n const interval = setInterval(evaluate, 2000);\n return () => {\n unsubs.forEach((u) => u());\n clearInterval(interval);\n };\n }, [evaluate]);\n return statuses;\n}\n", "/**\n * Human-readable summary generation for FAQ items.\n * Pure functions \u2014 no DOM access, just string formatting.\n */\n\nimport type { DecisionStrategy, FAQAnswer, FAQQuestionAction, RuleStrategy } from './types';\n\nconst MAX_Q_LEN = 50;\nconst MAX_A_LEN = 40;\n\nfunction truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return `${text.slice(0, max).trimEnd()}...`;\n}\n\nfunction stripHtml(html: string): string {\n return html.replace(/<[^>]*>/g, '').trim();\n}\n\nfunction getAnswerPreview(answer: FAQAnswer): string {\n if (typeof answer === 'string') return answer;\n if (answer.type === 'rich') return stripHtml(answer.html);\n return answer.content.replace(/[*_#`]/g, '').trim();\n}\n\nfunction isRuleStrategy(s: unknown): s is RuleStrategy<boolean> {\n return (\n typeof s === 'object' &&\n s !== null &&\n (s as Record<string, unknown>).type === 'rules' &&\n Array.isArray((s as Record<string, unknown>).rules)\n );\n}\n\n/**\n * Parse a showWhen strategy into a human-readable trigger description.\n */\nexport function describeTrigger(showWhen?: DecisionStrategy<boolean> | null): string {\n if (!showWhen) return 'All pages';\n if (!isRuleStrategy(showWhen)) return 'All pages';\n\n const pages: string[] = [];\n const anchors: string[] = [];\n\n for (const rule of showWhen.rules) {\n for (const condition of rule.conditions) {\n if (condition.type === 'page_url' && typeof (condition as any).url === 'string') {\n pages.push((condition as any).url);\n }\n if (condition.type === 'anchor_visible' && typeof (condition as any).anchorId === 'string') {\n anchors.push((condition as any).anchorId);\n }\n }\n }\n\n const parts: string[] = [];\n if (pages.length > 0) parts.push(pages[0]);\n if (anchors.length > 0) parts.push(anchors[0]);\n\n return parts.length > 0 ? parts.join(' \\u00b7 ') : 'All pages';\n}\n\n/**\n * Generate a one-liner summary for an FAQ item.\n */\nexport function summarizeFAQItem(item: FAQQuestionAction): string {\n const q = truncate(item.config.question, MAX_Q_LEN);\n const a = truncate(getAnswerPreview(item.config.answer), MAX_A_LEN);\n return `Q: \"${q}\" \\u2014 ${a}`;\n}\n", "/**\n * Adaptive FAQ - Types\n *\n * Type definitions for the FAQ accordion adaptive.\n * Demonstrates compositional action pattern with per-item showWhen.\n */\n\n// ============================================================================\n// Decision Strategy Types (from runtime-sdk)\n// ============================================================================\n\n/**\n * Simplified DecisionStrategy type for this package.\n * Full definition is in @syntrologie/runtime-sdk.\n */\nexport type DecisionStrategy<T = unknown> =\n | RuleStrategy<T>\n | ScoreStrategy<T>\n | ModelStrategy<T>\n | ExternalStrategy<T>;\n\nexport interface RuleStrategy<T = unknown> {\n type: 'rules';\n rules: Array<{\n conditions: Array<Record<string, unknown>>;\n value: T;\n }>;\n default: T;\n}\n\nexport interface ScoreStrategy<T = unknown> {\n type: 'score';\n field: string;\n threshold: number;\n above: T;\n below: T;\n}\n\nexport interface ModelStrategy<T = unknown> {\n type: 'model';\n modelId: string;\n inputs: string[];\n outputMapping: Record<string, T>;\n default: T;\n}\n\nexport interface ExternalStrategy<T = unknown> {\n type: 'external';\n endpoint: string;\n method?: 'GET' | 'POST';\n default: T;\n timeoutMs?: number;\n}\n\n// ============================================================================\n// Event Scope Types\n// ============================================================================\n\n/**\n * Scoped event filtering for event_count conditions.\n * The adaptive registers a predicate built from this scope.\n */\nexport interface EventScope {\n /** Event names to count */\n events: string[];\n /** URL path substring filter */\n urlContains?: string;\n /** Exact prop matching (e.g. { tagName: \"a\" }) */\n props?: Record<string, string | number | boolean>;\n}\n\n// ============================================================================\n// Rich Answer Content Types\n// ============================================================================\n\nexport interface Asset {\n id: string;\n type: 'image' | 'video';\n src: string;\n alt?: string;\n width?: number;\n height?: number;\n}\n\nexport interface RichHTMLAnswer {\n type: 'rich';\n html: string;\n}\n\nexport interface EnhancedMarkdownAnswer {\n type: 'markdown';\n content: string;\n assets?: Asset[];\n}\n\nexport type FAQAnswer = string | RichHTMLAnswer | EnhancedMarkdownAnswer;\n\n// ============================================================================\n// AI Answer Types\n// ============================================================================\n\nexport interface AnswerStrategy {\n endpoint: string;\n context?: string[];\n cache?: 'session' | 'none';\n fallback?: string;\n}\n\n// ============================================================================\n// Feedback Types\n// ============================================================================\n\nexport interface FeedbackConfig {\n style: 'thumbs' | 'rating';\n prompt?: string;\n}\n\nexport type FeedbackValue = 'up' | 'down' | number;\n\n// ============================================================================\n// Ordering Types\n// ============================================================================\n\nexport interface SegmentOrdering {\n type: 'segment';\n segmentWeights: Record<string, string[]>;\n}\n\nexport type OrderingStrategy = 'static' | 'priority' | SegmentOrdering;\n\n// ============================================================================\n// Injection Types\n// ============================================================================\n\nexport interface InjectionRule {\n trigger: DecisionStrategy<boolean>;\n items: FAQQuestionAction[];\n position?: 'prepend' | 'append';\n once?: boolean;\n}\n\n// ============================================================================\n// FAQ Question Action Types\n// ============================================================================\n\nexport interface FAQQuestionAction {\n kind: 'faq:question';\n config: {\n id: string;\n question: string;\n answer: FAQAnswer;\n category?: string;\n priority?: number;\n answerStrategy?: AnswerStrategy;\n };\n showWhen?: DecisionStrategy<boolean> | null;\n /** Toast config \u2014 only fires when showWhen transitions false \u2192 true */\n notify?: {\n title?: string;\n body?: string;\n icon?: string;\n };\n rationale?: {\n why: string;\n confidence?: number;\n };\n}\n\n// ============================================================================\n// FAQ Widget Configuration\n// ============================================================================\n\nexport type ExpandBehavior = 'single' | 'multiple';\n\nexport type FAQTheme = 'light' | 'dark' | 'auto';\n\nexport interface FAQConfig {\n expandBehavior: ExpandBehavior;\n searchable: boolean;\n theme: FAQTheme;\n actions: FAQQuestionAction[];\n feedback?: boolean | FeedbackConfig;\n ordering?: OrderingStrategy;\n injections?: InjectionRule[];\n /** Event scope for registering accumulator predicates */\n scope?: EventScope;\n}\n\n// ============================================================================\n// FAQ Action Types (for executor pattern)\n// ============================================================================\n\nexport interface ScrollToFaqAction {\n kind: 'faq:scroll_to';\n itemId?: string;\n itemQuestion?: string;\n expand?: boolean;\n behavior?: 'smooth' | 'instant' | 'auto';\n}\n\nexport interface ToggleFaqItemAction {\n kind: 'faq:toggle_item';\n itemId?: string;\n itemQuestion?: string;\n state?: 'open' | 'closed' | 'toggle';\n}\n\nexport interface UpdateFaqAction {\n kind: 'faq:update';\n operation: 'add' | 'remove' | 'reorder' | 'replace';\n items?: FAQQuestionAction[];\n itemId?: string;\n order?: string[];\n position?: 'prepend' | 'append' | 'before' | 'after';\n anchorId?: string;\n}\n\n// ============================================================================\n// Widget State Types\n// ============================================================================\n\nexport interface FAQWidgetState {\n expandedItems: Set<string>;\n items: FAQQuestionAction[];\n searchQuery: string;\n collapsedCategories: Set<string>;\n feedbackState: Map<string, FeedbackValue>;\n}\n\n// ============================================================================\n// Executor Types (from shared contracts)\n// ============================================================================\n\nexport type {\n ActionExecutor,\n ExecutorCleanup,\n ExecutorContext,\n ExecutorResult,\n ExecutorUpdate,\n} from '@syntrologie/sdk-contracts';\n\n// ============================================================================\n// Action Namespace\n// ============================================================================\n\nexport const ACTION_NAMESPACE = 'faq';\n\n/**\n * Returns true if the action belongs to this adaptive package.\n * Uses prefix matching so new kinds (e.g. faq:category) are automatically included.\n */\nexport function isOwnAction(action: { kind: string }): boolean {\n return action.kind.startsWith(`${ACTION_NAMESPACE}:`);\n}\n\n// ============================================================================\n// Editor Types\n// ============================================================================\n\nexport interface EditorPanelProps {\n config: Record<string, unknown>;\n onChange: (config: Record<string, unknown>) => void;\n editor: {\n setDirty: (dirty: boolean) => void;\n navigateHome: () => Promise<boolean>;\n save: () => Promise<void>;\n publish: (captureScreenshot?: boolean) => Promise<void>;\n navigateTo: (route: string) => Promise<void>;\n highlightElement: (selector: string) => void;\n clearHighlight: () => void;\n getCurrentRoute: () => string;\n previewConfig: (config: Record<string, unknown>) => void;\n /** Global before/after preview mode set by the panel's toggle. */\n previewMode?: 'before' | 'after';\n /** Flat action index to open in edit mode (from accordion navigation). */\n initialEditKey?: string;\n /** Open the editor in create mode. */\n initialCreate?: boolean;\n /** Clear the initial navigation state (call after consuming). */\n clearInitialState?: () => void;\n /** Get dismissed keys persisted in navigation context. */\n getDismissedKeys?: () => Set<string>;\n /** Sync dismissed keys back to navigation context. */\n setDismissedKeys?: (keys: Set<string>) => void;\n /** Register a back handler shown in the panel header. Pass null to clear. */\n setBackHandler?: (handler: (() => void) | null) => void;\n };\n platformClient?: unknown;\n}\n", "/**\n * Adaptive FAQ - Editor Component\n *\n * Review & tweak editor for AI-generated FAQ question decisions.\n * Displays a scannable list of Q&A cards with trigger, rationale,\n * and inline editing. Includes detection badges and hover-to-highlight.\n */\n\nimport {\n ConditionStatusLine,\n DetectionBadge,\n DismissedSection,\n EditorBody,\n EditorCard,\n EditorFooter,\n EditorHeader,\n EditorInput,\n EditorLayout,\n EditorTextarea,\n EmptyState,\n GroupHeader,\n TriggerJourney,\n useShowWhenStatus,\n} from '@syntrologie/shared-editor-ui';\nimport type React from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { describeTrigger, summarizeFAQItem } from './summarize';\nimport {\n type EditorPanelProps,\n type FAQAnswer,\n type FAQConfig,\n type FAQQuestionAction,\n isOwnAction,\n type RuleStrategy,\n} from './types';\n\n// ============================================================================\n// Targeting Extraction (inlined \u2014 CDN builds can't import from editor-sdk)\n// ============================================================================\n\ninterface TargetingInfo {\n pagePatterns: string[];\n anchorSelectors: string[];\n hasTargeting: boolean;\n}\n\nfunction isRuleStrategy(s: unknown): s is RuleStrategy<boolean> {\n return (\n typeof s === 'object' &&\n s !== null &&\n (s as Record<string, unknown>).type === 'rules' &&\n Array.isArray((s as Record<string, unknown>).rules)\n );\n}\n\nfunction extractTargetingInfo(showWhen?: unknown | null): TargetingInfo {\n if (!showWhen || !isRuleStrategy(showWhen)) {\n return { pagePatterns: [], anchorSelectors: [], hasTargeting: false };\n }\n\n const pagePatterns = new Set<string>();\n const anchorSelectors = new Set<string>();\n\n for (const rule of showWhen.rules) {\n for (const cond of rule.conditions) {\n const c = cond as Record<string, unknown>;\n if (c.type === 'page_url' && typeof c.url === 'string') {\n pagePatterns.add(c.url);\n } else if (c.type === 'anchor_visible' && typeof c.anchorId === 'string') {\n anchorSelectors.add(c.anchorId);\n }\n }\n }\n\n const hasTargeting = pagePatterns.size > 0 || anchorSelectors.size > 0;\n return {\n pagePatterns: [...pagePatterns],\n anchorSelectors: [...anchorSelectors],\n hasTargeting,\n };\n}\n\nfunction extractFirstPage(showWhen?: unknown | null): string | null {\n const info = extractTargetingInfo(showWhen);\n return info.pagePatterns[0] || null;\n}\n\nfunction extractFirstAnchor(showWhen?: unknown | null): string | null {\n const info = extractTargetingInfo(showWhen);\n return info.anchorSelectors[0] || null;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction getAnswerText(answer: FAQAnswer): string {\n if (typeof answer === 'string') return answer;\n if (answer.type === 'rich') return answer.html;\n return answer.content;\n}\n\ninterface FlatItem {\n key: string;\n index: number;\n summary: string;\n trigger: string;\n rationale?: { why: string; confidence?: number };\n firstAnchor: string | null;\n question: FAQQuestionAction;\n}\n\nfunction flattenItems(config: FAQConfig): FlatItem[] {\n const actions = (config.actions || []).filter(isOwnAction);\n return actions.map((q, i) => ({\n key: String(i),\n index: i,\n summary: summarizeFAQItem(q),\n trigger: describeTrigger(q.showWhen),\n rationale: q.rationale,\n firstAnchor: extractFirstAnchor(q.showWhen),\n question: q,\n }));\n}\n\nfunction filterConfig(config: FAQConfig, dismissedKeys: Set<string>): FAQConfig {\n const ownActions = (config.actions || []).filter(isOwnAction);\n return {\n ...config,\n actions: ownActions.filter((_, i) => !dismissedKeys.has(String(i))),\n };\n}\n\n// ============================================================================\n// Detection Hook\n// ============================================================================\n\ninterface DetectionEntry {\n found: boolean;\n element: HTMLElement | null;\n}\n\nfunction useDetection(\n items: FlatItem[],\n getCurrentRoute: () => string\n): Map<string, DetectionEntry> {\n const [detectionMap, setDetectionMap] = useState<Map<string, DetectionEntry>>(new Map());\n const itemsRef = useRef(items);\n itemsRef.current = items;\n\n useEffect(() => {\n const runDetection = () => {\n const map = new Map<string, DetectionEntry>();\n const currentPath = getCurrentRoute();\n\n for (const item of itemsRef.current) {\n const targeting = extractTargetingInfo(item.question.showWhen);\n\n // Check page match\n let pageMatch = true;\n if (targeting.pagePatterns.length > 0) {\n pageMatch = targeting.pagePatterns.some((pattern) => {\n const regex = new RegExp(\n `^${pattern.replace(/\\*\\*/g, '.*').replace(/(?<!\\.)(\\*)/g, '[^/]*')}$`\n );\n return regex.test(currentPath);\n });\n }\n\n // Check anchor presence\n let anchorFound = false;\n let element: HTMLElement | null = null;\n if (item.firstAnchor) {\n try {\n element = document.querySelector(item.firstAnchor) as HTMLElement | null;\n anchorFound = element !== null;\n } catch {\n // Invalid selector\n }\n } else {\n // No anchor to check \u2014 if page matches, consider found\n anchorFound = pageMatch;\n }\n\n map.set(item.key, {\n found: pageMatch && anchorFound,\n element,\n });\n }\n\n setDetectionMap(map);\n };\n\n runDetection();\n\n const interval = setInterval(runDetection, 2000);\n window.addEventListener('popstate', runDetection);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener('popstate', runDetection);\n };\n }, [getCurrentRoute]);\n\n return detectionMap;\n}\n\n// ============================================================================\n// FAQEditor Component\n// ============================================================================\n\nexport function FAQEditor({ config, onChange, editor }: EditorPanelProps) {\n const typedConfig = config as unknown as FAQConfig;\n const [dismissedKeys, setDismissedKeys] = useState<Set<string>>(\n () => editor.getDismissedKeys?.() ?? new Set()\n );\n const [editingKey, setEditingKey] = useState<string | null>(null);\n const [_previewMode, setPreviewMode] = useState<'before' | 'after'>('after');\n const [_hoveredKey, setHoveredKey] = useState<string | null>(null);\n\n // Sync dismissed keys back to navigation context on every change\n useEffect(() => {\n editor.setDismissedKeys?.(dismissedKeys);\n }, [dismissedKeys, editor]);\n\n // React to global before/after toggle from the panel\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally omitted \u2014 adding config/typedConfig/previewConfig would cause infinite re-renders since previewConfig triggers state updates\n useEffect(() => {\n const mode = editor.previewMode;\n if (!mode) return;\n\n if (mode === 'before') {\n // Remove all FAQ items \u2014 push a config with every item filtered out\n const allKeys = new Set(flattenItems(typedConfig).map((item) => item.key));\n const empty = filterConfig(typedConfig, allKeys);\n editor.previewConfig(empty as unknown as Record<string, unknown>);\n } else {\n // Restore the full config\n editor.previewConfig(config);\n }\n }, [editor.previewMode]);\n\n // If navigated here with an editKey, jump directly to that item's edit view\n const initialConsumed = useRef(false);\n useEffect(() => {\n if (!initialConsumed.current) {\n initialConsumed.current = true;\n if (editor.initialEditKey != null) {\n setEditingKey(String(editor.initialEditKey));\n }\n editor.clearInitialState?.();\n }\n }, [editor]);\n\n const allItems = flattenItems(typedConfig);\n const activeItems = allItems.filter((item) => !dismissedKeys.has(item.key));\n const dismissedItems = allItems.filter((item) => dismissedKeys.has(item.key));\n const totalQuestions = activeItems.length;\n\n const detectionMap = useDetection(allItems, editor.getCurrentRoute);\n const foundCount = activeItems.filter((item) => detectionMap.get(item.key)?.found).length;\n\n // Live showWhen status for condition diagnostics\n const showWhenItems = useMemo(\n () =>\n allItems.map((item) => ({\n id: item.key,\n showWhen: item.question.showWhen,\n })),\n [allItems]\n );\n const showWhenStatuses = useShowWhenStatus(showWhenItems);\n\n const handleDismiss = useCallback(\n (key: string) => {\n setDismissedKeys((prev) => {\n const next = new Set(prev);\n next.add(key);\n return next;\n });\n if (editingKey === key) setEditingKey(null);\n },\n [editingKey]\n );\n\n const handleRestore = useCallback((key: string) => {\n setDismissedKeys((prev) => {\n const next = new Set(prev);\n next.delete(key);\n return next;\n });\n }, []);\n\n const handleCardBodyClick = useCallback((item: FlatItem) => {\n setEditingKey(item.key);\n }, []);\n\n const handleTriggerClick = useCallback(\n (item: FlatItem) => {\n const pageUrl = extractFirstPage(item.question.showWhen);\n if (pageUrl) {\n editor.navigateTo(pageUrl);\n }\n if (item.firstAnchor) {\n editor.highlightElement(item.firstAnchor);\n }\n },\n [editor]\n );\n\n const handleBackToList = useCallback(() => {\n setEditingKey(null);\n setPreviewMode('after');\n editor.previewConfig(config);\n editor.clearHighlight();\n }, [editor, config]);\n\n // Register back handler in panel header when editing\n useEffect(() => {\n editor.setBackHandler?.(editingKey !== null ? handleBackToList : null);\n return () => editor.setBackHandler?.(null);\n }, [editingKey, handleBackToList, editor]);\n\n const _handleBeforeAfter = useCallback(\n (mode: 'before' | 'after') => {\n setPreviewMode(mode);\n if (mode === 'before') {\n const filtered = filterConfig(typedConfig, new Set([editingKey!]));\n editor.previewConfig(filtered as unknown as Record<string, unknown>);\n } else {\n editor.previewConfig(config);\n }\n },\n [typedConfig, editingKey, editor, config]\n );\n\n const handleFieldChange = useCallback(\n (index: number, field: string, value: unknown) => {\n const ownActions = (typedConfig.actions || []).filter(isOwnAction).slice();\n const q = { ...ownActions[index], config: { ...ownActions[index].config } };\n (q.config as Record<string, unknown>)[field] = value;\n ownActions[index] = q;\n const otherActions = (typedConfig.actions || []).filter((a) => !isOwnAction(a));\n const updated = { ...typedConfig, actions: [...otherActions, ...ownActions] };\n onChange(updated as unknown as Record<string, unknown>);\n editor.setDirty(true);\n },\n [typedConfig, onChange, editor]\n );\n\n const handlePublish = useCallback(() => {\n if (dismissedKeys.size > 0) {\n const filtered = filterConfig(typedConfig, dismissedKeys);\n onChange(filtered as unknown as Record<string, unknown>);\n }\n editor.publish();\n }, [dismissedKeys, typedConfig, onChange, editor]);\n\n const handleCardHover = useCallback(\n (item: FlatItem) => {\n setHoveredKey(item.key);\n if (item.firstAnchor) {\n editor.highlightElement(item.firstAnchor);\n }\n },\n [editor]\n );\n\n const handleCardLeave = useCallback(() => {\n setHoveredKey(null);\n editor.clearHighlight();\n }, [editor]);\n\n // ---- Edit form renderer ----\n\n const renderEditFields = (index: number) => {\n const actions = (typedConfig.actions || []).filter(isOwnAction);\n const q = actions[index];\n if (!q) return null;\n\n const item = allItems.find((it) => it.key === String(index));\n\n return (\n <div className=\"se-py-1\">\n {/* Trigger line in edit mode */}\n {item && item.trigger !== 'All pages' && (\n <button\n type=\"button\"\n data-trigger\n className=\"se-flex se-items-center se-gap-1 se-text-[11px] se-text-slate-grey-8 se-cursor-pointer se-mb-1 se-border-none se-bg-transparent se-p-0 se-text-left\"\n onClick={() => handleTriggerClick(item)}\n >\n <span>{'\\u{1f4cd}'}</span>\n <span>{item.trigger}</span>\n </button>\n )}\n\n <EditorInput\n label=\"Question\"\n value={q.config.question}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n handleFieldChange(index, 'question', e.target.value)\n }\n />\n\n <EditorTextarea\n label=\"Answer\"\n value={getAnswerText(q.config.answer)}\n onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>\n handleFieldChange(index, 'answer', e.target.value)\n }\n />\n\n <EditorInput\n label=\"Category\"\n value={q.config.category || ''}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n handleFieldChange(index, 'category', e.target.value || undefined)\n }\n placeholder=\"e.g., Billing, Account\"\n />\n\n <div>\n <span className=\"se-text-[11px] se-font-semibold se-text-slate-grey-7 se-mb-1 se-block\">\n AI Rationale\n </span>\n <div className=\"se-p-2 se-rounded se-border se-border-dashed se-border-white/15 se-bg-white/[0.02] se-text-slate-grey-8 se-text-xs se-mb-2\">\n {q.rationale ? q.rationale.why : 'N/A'}\n </div>\n </div>\n\n {/* Full trigger journey \u2014 condition node graph */}\n <TriggerJourney status={showWhenStatuses.get(String(index)) ?? null} />\n </div>\n );\n };\n\n return (\n <EditorLayout>\n {/* Header */}\n <EditorHeader\n title=\"Review Questions\"\n subtitle={`${totalQuestions} question${totalQuestions !== 1 ? 's' : ''}${totalQuestions > 0 ? ` (${foundCount} found on this page)` : ''}`}\n onBack={() => editor.navigateHome()}\n />\n\n {/* Body */}\n <EditorBody>\n {editingKey !== null ? (\n /* ---- Edit mode ---- */\n (() => {\n const editIndex = Number(editingKey);\n const editItem = allItems.find((it) => it.key === editingKey);\n return (\n <>\n <div className=\"se-flex se-items-center se-gap-2 se-mb-3 se-text-[13px] se-font-semibold se-text-slate-grey-10\">\n <span>{'\\u2753'}</span>\n <span>{editItem?.summary}</span>\n </div>\n {renderEditFields(editIndex)}\n </>\n );\n })()\n ) : (\n /* ---- List mode ---- */\n <>\n {allItems.length === 0 && <EmptyState message=\"No FAQ questions configured.\" />}\n\n {activeItems.length > 0 && (\n <>\n <GroupHeader label=\"FAQ\" count={activeItems.length} />\n {activeItems.map((item) => {\n const detection = detectionMap.get(item.key);\n return (\n <EditorCard\n key={item.key}\n itemKey={item.key}\n onClick={() => handleCardBodyClick(item)}\n onMouseEnter={() => handleCardHover(item)}\n onMouseLeave={handleCardLeave}\n >\n {/* Trigger line */}\n {item.trigger !== 'All pages' && (\n <button\n type=\"button\"\n data-trigger\n className=\"se-flex se-items-center se-gap-1 se-text-[11px] se-text-slate-grey-8 se-cursor-pointer se-mb-1 se-border-none se-bg-transparent se-p-0 se-text-left\"\n onClick={(e) => {\n e.stopPropagation();\n handleTriggerClick(item);\n }}\n >\n <span>{'\\u{1f4cd}'}</span>\n <span>{item.trigger}</span>\n </button>\n )}\n {/* Card body: badge + summary + dismiss */}\n {/* biome-ignore lint/a11y/useSemanticElements: cannot use <button> here as it would nest a dismiss <button> inside, which is invalid HTML */}\n <div\n data-card-body\n role=\"button\"\n tabIndex={0}\n className=\"se-flex se-items-center se-gap-2 se-cursor-pointer\"\n onClick={() => handleCardBodyClick(item)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleCardBodyClick(item);\n }}\n >\n <DetectionBadge found={detection?.found ?? false} />\n <span className=\"se-flex-1 se-overflow-hidden se-text-ellipsis se-whitespace-nowrap\">\n {item.summary}\n </span>\n <button\n type=\"button\"\n className=\"se-py-0.5 se-px-1.5 se-rounded se-border-none se-bg-transparent se-text-slate-grey-7 se-text-sm se-cursor-pointer se-shrink-0 se-leading-none\"\n onClick={(e) => {\n e.stopPropagation();\n handleDismiss(item.key);\n }}\n title=\"Dismiss this question\"\n >\n &times;\n </button>\n </div>\n {/* Rationale line */}\n <div className=\"se-text-[10px] se-text-slate-grey-7 se-mt-1\">\n WHY: {item.rationale ? item.rationale.why : 'N/A'}\n </div>\n {/* Condition status line */}\n <ConditionStatusLine status={showWhenStatuses.get(item.key) ?? null} />\n </EditorCard>\n );\n })}\n </>\n )}\n\n {/* Dismissed section */}\n {dismissedItems.length > 0 && (\n <DismissedSection count={dismissedItems.length}>\n {dismissedItems.map((item) => (\n <div\n key={item.key}\n className=\"se-flex se-items-center se-gap-2 se-py-1.5 se-px-2.5 se-rounded-md se-border se-border-white/[0.03] se-bg-transparent se-mb-0.5 se-cursor-pointer se-text-xs se-text-slate-grey-6 se-opacity-60\"\n >\n <span className=\"se-flex-1 se-overflow-hidden se-text-ellipsis se-whitespace-nowrap se-line-through\">\n {item.summary}\n </span>\n <button\n type=\"button\"\n className=\"se-py-0.5 se-px-1.5 se-rounded se-border-none se-bg-transparent se-text-blue-5 se-text-[11px] se-cursor-pointer se-shrink-0 se-leading-none\"\n onClick={(e) => {\n e.stopPropagation();\n handleRestore(item.key);\n }}\n >\n Restore\n </button>\n </div>\n ))}\n </DismissedSection>\n )}\n </>\n )}\n </EditorBody>\n\n {/* Footer */}\n <EditorFooter onSave={() => editor.save()} onPublish={handlePublish} />\n </EditorLayout>\n );\n}\n\n/**\n * Editor panel configuration for the app registry.\n */\nexport const editorPanel = {\n title: 'FAQ',\n icon: '\\u2753',\n description: 'FAQ accordion with per-item visibility',\n};\n\nexport const editor = {\n panel: editorPanel,\n component: FAQEditor,\n};\n\nexport default FAQEditor;\n", "/**\n * Adaptive FAQ - Action Executors\n *\n * Three executors that operate on the FAQStore:\n * - executeScrollToFaq: scroll to a FAQ item and optionally expand it\n * - executeToggleFaqItem: open / close / toggle a FAQ item\n * - executeUpdateFaq: add, remove, reorder, or replace FAQ items\n */\n\nimport type { FAQStore } from './state';\nimport type {\n ExecutorContext,\n ExecutorResult,\n FAQQuestionAction,\n ScrollToFaqAction,\n ToggleFaqItemAction,\n UpdateFaqAction,\n} from './types';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Resolve a FAQ item by direct ID or by fuzzy question text match.\n * Throws if neither yields a result.\n */\nfunction resolveItem(store: FAQStore, itemId?: string, itemQuestion?: string): FAQQuestionAction {\n if (itemId) {\n const found = store.getState().items.find((i) => i.config.id === itemId);\n if (found) return found;\n }\n\n if (itemQuestion) {\n const found = store.findByQuestion(itemQuestion);\n if (found) return found;\n }\n\n throw new Error('FAQ item not found');\n}\n\n// ============================================================================\n// executeScrollToFaq\n// ============================================================================\n\n/**\n * Scroll to a FAQ item in the DOM and optionally expand it.\n *\n * Looks up the item by `itemId` or `itemQuestion`, scrolls the matching\n * `[data-faq-item-id]` element into view, and expands it unless\n * `expand` is explicitly set to `false`.\n */\nexport async function executeScrollToFaq(\n action: ScrollToFaqAction,\n context: ExecutorContext,\n store: FAQStore\n): Promise<ExecutorResult> {\n const item = resolveItem(store, action.itemId, action.itemQuestion);\n const { id } = item.config;\n\n // Expand the item unless explicitly told not to\n if (action.expand !== false) {\n store.expand(id);\n }\n\n // Scroll the DOM element into view (may be absent in test environments)\n const el = document.querySelector(`[data-faq-item-id=\"${id}\"]`);\n if (el) {\n el.scrollIntoView({\n behavior: action.behavior ?? 'smooth',\n });\n }\n\n // Publish analytics event\n context.publishEvent('faq:scroll_to', { itemId: id });\n\n return {\n cleanup: () => {\n // Optionally collapse on revert\n },\n };\n}\n\n// ============================================================================\n// executeToggleFaqItem\n// ============================================================================\n\n/**\n * Open, close, or toggle a FAQ item's expanded state.\n */\nexport async function executeToggleFaqItem(\n action: ToggleFaqItemAction,\n context: ExecutorContext,\n store: FAQStore\n): Promise<ExecutorResult> {\n const item = resolveItem(store, action.itemId, action.itemQuestion);\n const { id } = item.config;\n const desiredState = action.state ?? 'toggle';\n\n let newState: 'open' | 'closed';\n\n switch (desiredState) {\n case 'open':\n store.expand(id);\n newState = 'open';\n break;\n case 'closed':\n store.collapse(id);\n newState = 'closed';\n break;\n default: {\n const wasExpanded = store.getState().expandedItems.has(id);\n store.toggle(id);\n newState = wasExpanded ? 'closed' : 'open';\n break;\n }\n }\n\n context.publishEvent('faq:toggle', { itemId: id, newState });\n\n return {\n cleanup: () => {\n // Revert toggle on cleanup\n },\n };\n}\n\n// ============================================================================\n// executeUpdateFaq\n// ============================================================================\n\n/**\n * Add, remove, reorder, or replace FAQ items in the store.\n */\nexport async function executeUpdateFaq(\n action: UpdateFaqAction,\n context: ExecutorContext,\n store: FAQStore\n): Promise<ExecutorResult> {\n switch (action.operation) {\n case 'add': {\n const items = action.items ?? [];\n const position = action.position === 'prepend' ? 'prepend' : 'append';\n store.addItems(items, position);\n break;\n }\n\n case 'remove': {\n if (!action.itemId) {\n throw new Error('FAQ item not found');\n }\n // Verify the item exists before removing\n const exists = store.getState().items.some((i) => i.config.id === action.itemId);\n if (!exists) {\n throw new Error('FAQ item not found');\n }\n store.removeItem(action.itemId);\n break;\n }\n\n case 'reorder': {\n const order = action.order ?? [];\n store.reorderItems(order);\n break;\n }\n\n case 'replace': {\n const items = action.items ?? [];\n store.replaceItems(items);\n break;\n }\n }\n\n context.publishEvent('faq:update', { operation: action.operation });\n\n return {\n cleanup: () => {\n // Could snapshot previous state for undo\n },\n };\n}\n\n// ============================================================================\n// Executor Definitions for Registration\n// ============================================================================\n\n/**\n * All executors provided by adaptive-faq.\n * These are registered with the runtime's ExecutorRegistry.\n */\nexport const executorDefinitions = [\n { kind: 'faq:scroll_to', executor: executeScrollToFaq },\n { kind: 'faq:toggle_item', executor: executeToggleFaqItem },\n { kind: 'faq:update', executor: executeUpdateFaq },\n] as const;\n", "/**\n * Syntro Design System - Color Tokens\n *\n * This file contains all color tokens from the Figma design system.\n * Colors are organized by scale and semantic meaning.\n *\n * @see https://www.figma.com/design/U0Ol5vM7FQvgPfIgCAgxgb/Design-System\n */\n// ============================================================================\n// BASE COLORS\n// ============================================================================\nexport const base = {\n white: '#ffffff',\n black: '#000000',\n};\n// ============================================================================\n// BRAND COLORS\n// ============================================================================\nexport const brand = {\n 0: '#2c0b0a',\n 1: '#5b1715',\n 2: '#89221f',\n 3: '#b72e2a',\n 4: '#d44844',\n 5: '#dd6d69',\n 6: '#e5918f',\n 7: '#eeb6b4',\n 8: '#f6dada',\n 9: '#faebea',\n};\n// ============================================================================\n// NEUTRAL COLORS\n// ============================================================================\nexport const slateGrey = {\n 0: '#07080a',\n 1: '#0f1318',\n 2: '#0e1114',\n 3: '#1c222a',\n 4: '#2b333f',\n 5: '#394454',\n 6: '#475569',\n 7: '#677384',\n 8: '#87919f',\n 9: '#a8afba',\n 10: '#cbd0d7',\n 11: '#e8eaee',\n 12: '#f6f7f9',\n};\n// ============================================================================\n// SEMANTIC COLOR SCALES\n// ============================================================================\nexport const green = {\n 0: '#07230a',\n 1: '#0e4514',\n 2: '#16681e',\n 3: '#1d8a28',\n 4: '#24ad32',\n 5: '#4fbd5a',\n 6: '#7acd82',\n 7: '#a5deab',\n 8: '#d0eed3',\n 9: '#e5f6e7',\n};\nexport const yellow = {\n 0: '#301f09',\n 1: '#5f3e12',\n 2: '#8f5e1b',\n 3: '#be7d24',\n 4: '#ee9c2d',\n 5: '#f1b057',\n 6: '#f5c481',\n 7: '#f8d7ab',\n 8: '#fcebd5',\n 9: '#fdf5ea',\n};\nexport const red = {\n 0: '#330707',\n 1: '#660f0e',\n 2: '#991616',\n 3: '#cc1e1d',\n 4: '#ff2524',\n 5: '#ff5150',\n 6: '#ff7c7c',\n 7: '#ffa8a7',\n 8: '#ffd3d3',\n 9: '#ffe9e9',\n};\nexport const blue = {\n 0: '#051533',\n 1: '#0a2a66',\n 2: '#0f3f98',\n 3: '#1454cb',\n 4: '#1969fe',\n 5: '#4787fe',\n 6: '#75a5fe',\n 7: '#a3c3ff',\n 8: '#d1e1ff',\n 9: '#e8f0ff',\n};\nexport const orange = {\n 0: '#662500',\n 1: '#993d00',\n 2: '#cc5800',\n 3: '#ff7700',\n 4: '#fea85d',\n 5: '#fec58f',\n 6: '#ffd6ae',\n 7: '#fee6cd',\n 8: '#fff1e1',\n 9: '#fff8f0',\n};\nexport const purple = {\n 0: '#151229',\n 1: '#2a2452',\n 2: '#40357c',\n 3: '#5547a5',\n 4: '#6a59ce',\n 5: '#887ad8',\n 6: '#a69be2',\n 7: '#c3bdeb',\n 8: '#e1def5',\n 9: '#f0eefa',\n};\nexport const pink = {\n 0: '#37091f',\n 1: '#69123c',\n 2: '#9b1c58',\n 3: '#cd2575',\n 4: '#ff2e92',\n 5: '#ff58a8',\n 6: '#ff82be',\n 7: '#ffabd3',\n 8: '#ffd5e9',\n 9: '#ffeaf4',\n};\n// ============================================================================\n// LEGACY COLORS (Being phased out)\n// ============================================================================\nexport const legacy = {\n aqua: {\n 0: '#0c5f8d',\n 1: '#146b99',\n 2: '#1d78a6',\n 3: '#2e89b6',\n 4: '#4a9fc4',\n 5: '#6bb4d1',\n 6: '#93cce0',\n 7: '#bddff0',\n 8: '#dceef8',\n 9: '#f2f8fc',\n },\n violet: {\n 0: '#6927da',\n 1: '#7839ee',\n 2: '#875bf7',\n 3: '#a48afb',\n 4: '#c3b4fd',\n 5: '#ddd6fe',\n 6: '#ece9fe',\n 7: '#f5f3ff',\n 8: '#fbfaff',\n },\n fuchsia: {\n 0: '#9f1ab1',\n 1: '#ba24d5',\n 2: '#d444f1',\n 3: '#e478fa',\n 4: '#eeaafd',\n 5: '#f6d0fe',\n 6: '#fbe8ff',\n 7: '#fdf4ff',\n 8: '#fefaff',\n },\n pink: {\n 0: '#a10f5f',\n 1: '#dd2590',\n 2: '#ee46bc',\n 3: '#f670c7',\n 4: '#faa7e0',\n 5: '#fcceee',\n 6: '#fce7f6',\n 7: '#fdf2fa',\n 8: '#fef6fb',\n },\n};\n// ============================================================================\n// TEXT TOKENS\n// ============================================================================\nexport const text = {\n primary: slateGrey[10],\n secondary: slateGrey[9],\n tertiary: slateGrey[8],\n};\n// ============================================================================\n// BACKGROUND TOKENS\n// ============================================================================\nexport const background = {\n primary: slateGrey[2],\n secondary: slateGrey[0],\n};\n// ============================================================================\n// BORDER TOKENS\n// ============================================================================\nexport const border = {\n primary: slateGrey[4],\n secondary: slateGrey[3],\n};\n// ============================================================================\n// BUTTON TOKENS\n// ============================================================================\nexport const button = {\n primary: {\n text: base.white,\n icon: base.white,\n border: brand[3],\n backgroundDefault: brand[3],\n backgroundHover: brand[2],\n },\n neutral: {\n text: slateGrey[10],\n textHover: base.white,\n icon: slateGrey[10],\n iconHover: base.white,\n border: slateGrey[4],\n background: slateGrey[2],\n },\n link: {\n text: base.white,\n icon: base.white,\n hover: brand[5],\n },\n error: {\n text: red[5],\n hover: red[6],\n },\n success: {\n text: green[5],\n hover: green[6],\n },\n};\n// ============================================================================\n// BADGE TOKENS\n// ============================================================================\nexport const badge = {\n slateGrey: {\n content: slateGrey[10],\n pillOutline: slateGrey[10],\n borderPrimary: slateGrey[5],\n borderSecondary: slateGrey[5],\n background: slateGrey[3],\n },\n brand: {\n content: brand[9],\n pillOutline: brand[9],\n borderPrimary: brand[6],\n borderSecondary: brand[6],\n background: brand[0],\n },\n red: {\n content: red[8],\n pillOutline: red[4],\n borderPrimary: red[2],\n borderSecondary: red[2],\n background: red[0],\n },\n yellow: {\n content: yellow[8],\n pillOutline: yellow[4],\n borderPrimary: yellow[2],\n borderSecondary: yellow[2],\n background: yellow[0],\n },\n green: {\n content: green[8],\n pillOutline: green[4],\n borderPrimary: green[2],\n borderSecondary: green[2],\n background: green[0],\n },\n purple: {\n content: purple[8],\n pillOutline: purple[4],\n borderPrimary: purple[2],\n borderSecondary: purple[2],\n background: purple[0],\n },\n blue: {\n content: blue[8],\n pillOutline: blue[4],\n borderPrimary: blue[2],\n borderSecondary: blue[2],\n background: blue[0],\n },\n orange: {\n content: orange[8],\n pillOutline: orange[4],\n borderPrimary: orange[2],\n borderSecondary: orange[2],\n background: orange[0],\n },\n pink: {\n content: pink[8],\n pillOutline: pink[4],\n borderPrimary: pink[2],\n borderSecondary: pink[2],\n background: pink[0],\n },\n};\n// ============================================================================\n// BADGE BANNER TOKENS\n// ============================================================================\nexport const badgeBanner = {\n green: {\n content: green[8],\n border: green[2],\n background: green[0],\n },\n yellow: {\n content: yellow[8],\n border: yellow[2],\n background: yellow[0],\n },\n red: {\n content: red[8],\n border: red[2],\n background: red[0],\n },\n};\n// ============================================================================\n// ALERT TOKENS\n// ============================================================================\nexport const alert = {\n green: {\n content: green[1],\n background: green[9],\n },\n yellow: {\n content: yellow[1],\n background: yellow[9],\n },\n red: {\n content: red[1],\n background: red[9],\n },\n};\n// ============================================================================\n// TAG TOKENS\n// ============================================================================\nexport const tag = {\n content: slateGrey[10],\n border: slateGrey[4],\n background: '#1c2124',\n};\n// ============================================================================\n// MENU TOKENS\n// ============================================================================\nexport const menu = {\n backgroundDefault: slateGrey[2],\n backgroundHover: slateGrey[1],\n selected: slateGrey[3],\n};\n// ============================================================================\n// INPUT/DROPDOWN TOKENS\n// ============================================================================\nexport const inputDropdown = {\n background: slateGrey[2],\n icon: slateGrey[10],\n borderDefault: slateGrey[4],\n borderSelected: brand[3],\n textLabel: slateGrey[9],\n textPlaceholder: slateGrey[8],\n textHint: slateGrey[8],\n};\nexport const inputField = {\n backgroundDefault: slateGrey[2],\n backgroundDisabled: slateGrey[0],\n textLabel: slateGrey[9],\n textPlaceholder: slateGrey[8],\n textHint: slateGrey[8],\n textError: red[5],\n iconDefault: slateGrey[9],\n iconPlaceholder: slateGrey[10],\n iconError: red[5],\n borderDefault: slateGrey[4],\n borderSelected: brand[3],\n borderError: red[5],\n};\n// ============================================================================\n// TOGGLE TOKENS\n// ============================================================================\nexport const toggle = {\n handleDefault: base.white,\n handleDisabled: slateGrey[10],\n off: {\n backgroundDefault: slateGrey[4],\n backgroundHover: slateGrey[5],\n backgroundDisabled: slateGrey[4],\n },\n on: {\n backgroundDefault: green[3],\n backgroundHover: green[2],\n backgroundDisabled: slateGrey[4],\n },\n};\n// ============================================================================\n// CHECKBOX TOKENS\n// ============================================================================\nexport const checkbox = {\n off: {\n backgroundDefault: '#00000000',\n backgroundHover: slateGrey[5],\n backgroundDisabled: slateGrey[2],\n border: slateGrey[6],\n },\n on: {\n backgroundDefault: green[0],\n backgroundHover: green[1],\n backgroundDisabled: slateGrey[2],\n border: green[3],\n },\n};\n// ============================================================================\n// AVATAR TOKENS\n// ============================================================================\nexport const avatar = {\n content: slateGrey[10],\n background: slateGrey[4],\n};\n// ============================================================================\n// PROGRESS BAR & SLIDER TOKENS\n// ============================================================================\nexport const progressBarSlider = {\n background: slateGrey[4],\n active: green[3],\n};\n// ============================================================================\n// CARD TOKENS\n// ============================================================================\nexport const card = {\n background: slateGrey[1],\n content: slateGrey[9],\n border: slateGrey[4],\n};\n// ============================================================================\n// SIDEBAR TOKENS\n// ============================================================================\nexport const sidebar = {\n backgroundDefault: slateGrey[1],\n backgroundHover: slateGrey[3],\n backgroundActive: slateGrey[4],\n border: slateGrey[4],\n contentPrimary: slateGrey[10],\n contentSecondary: slateGrey[9],\n contentTertiary: slateGrey[8],\n};\n// ============================================================================\n// MODAL TOKENS\n// ============================================================================\nexport const modal = {\n background: slateGrey[1],\n content: slateGrey[9],\n border: slateGrey[4],\n};\n// ============================================================================\n// TAB TOKENS\n// ============================================================================\nexport const tab = {\n activeBackground: slateGrey[3],\n activeContent: brand[5],\n inactiveContent: slateGrey[9],\n border: slateGrey[4],\n};\n// ============================================================================\n// TABLE TOKENS\n// ============================================================================\nexport const table = {\n header: {\n textDefault: slateGrey[9],\n textHover: slateGrey[8],\n backgroundDefault: slateGrey[1],\n },\n border: slateGrey[4],\n cell: {\n textPrimary: slateGrey[10],\n textSecondary: slateGrey[9],\n backgroundDefault: slateGrey[2],\n backgroundHover: slateGrey[1],\n },\n};\n// ============================================================================\n// BREADCRUMBS TOKENS\n// ============================================================================\nexport const breadcrumbs = {\n textPrimaryDefault: slateGrey[10],\n textPrimaryHover: slateGrey[10],\n textSecondaryDefault: slateGrey[8],\n textSecondaryHover: slateGrey[9],\n iconPrimary: slateGrey[10],\n iconSecondary: slateGrey[8],\n};\n// ============================================================================\n// LOADING INDICATOR TOKENS\n// ============================================================================\nexport const loadingIndicator = {\n background: green[1],\n active: green[5],\n};\n// ============================================================================\n// DATE PICKER TOKENS\n// ============================================================================\nexport const datePicker = {\n textDefault: slateGrey[10],\n textSelected: base.white,\n textDisabled: slateGrey[7],\n backgroundDefault: slateGrey[2],\n backgroundMiddle: slateGrey[3],\n backgroundSelected: brand[3],\n border: slateGrey[4],\n};\n// ============================================================================\n// MISC TOKENS\n// ============================================================================\nexport const scroll = slateGrey[9];\n// ============================================================================\n// EXPORTS\n// ============================================================================\nexport const colors = {\n base,\n brand,\n slateGrey,\n green,\n yellow,\n red,\n blue,\n orange,\n purple,\n pink,\n legacy,\n text,\n background,\n border,\n button,\n badge,\n badgeBanner,\n alert,\n tag,\n menu,\n inputDropdown,\n inputField,\n toggle,\n checkbox,\n avatar,\n progressBarSlider,\n card,\n sidebar,\n modal,\n tab,\n table,\n breadcrumbs,\n loadingIndicator,\n datePicker,\n scroll,\n};\nexport default colors;\n", "\n function _RD() {\n return (typeof SynOS !== 'undefined' && SynOS.ReactDOM) || {};\n }\n export default new Proxy({}, { get: function(_, k) { return _RD()[k]; } });\n export function createRoot() { return _RD().createRoot.apply(null, arguments); }\n export function hydrateRoot() { return _RD().hydrateRoot.apply(null, arguments); }\n export function createPortal() { return _RD().createPortal.apply(null, arguments); }\n export function flushSync() { return _RD().flushSync.apply(null, arguments); }\n ", "/**\n * Adaptive FAQ - FAQWidget Component\n *\n * React component that renders a collapsible Q&A accordion with per-item\n * conditional visibility based on showWhen decision strategies.\n *\n * Demonstrates the compositional action pattern where child actions\n * (faq:question) serve as configuration data for the parent widget.\n */\n\nimport { base, purple, slateGrey } from '@syntro/design-system/tokens';\nimport React, { useCallback, useEffect, useMemo, useReducer, useState } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport type {\n DecisionStrategy,\n FAQAnswer,\n FAQConfig,\n FAQQuestionAction,\n FeedbackConfig,\n FeedbackValue,\n} from './types';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Extract plain text from an FAQAnswer for search matching */\nfunction getAnswerText(answer: FAQAnswer): string {\n if (typeof answer === 'string') return answer;\n if (answer.type === 'rich') return answer.html;\n return answer.content;\n}\n\n/** Render an FAQAnswer based on its type */\nfunction renderAnswer(answer: FAQAnswer): React.ReactNode {\n if (typeof answer === 'string') {\n return <p style={{ margin: 0 }}>{answer}</p>;\n }\n if (answer.type === 'rich') {\n // biome-ignore lint/security/noDangerouslySetInnerHtml: content is pre-sanitized by backend \u2014 FAQAnswer.html is CMS/config content, not user-controlled input\n return <div style={{ margin: 0 }} dangerouslySetInnerHTML={{ __html: answer.html }} />;\n }\n // markdown \u2014 render content as text (full markdown rendering is a future enhancement)\n return <p style={{ margin: 0 }}>{answer.content}</p>;\n}\n\n/** Resolve feedback config into a normalized FeedbackConfig or null */\nfunction resolveFeedbackConfig(\n feedback: boolean | FeedbackConfig | undefined\n): FeedbackConfig | null {\n if (!feedback) return null;\n if (feedback === true) {\n return { style: 'thumbs' };\n }\n return feedback;\n}\n\n/** Get the feedback prompt text */\nfunction getFeedbackPrompt(feedbackConfig: FeedbackConfig): string {\n return feedbackConfig.prompt || 'Was this helpful?';\n}\n\n// Widget runtime and props types defined inline (not part of the types.ts spec)\nexport interface FAQWidgetRuntime {\n evaluateSync: <T>(strategy: DecisionStrategy<T>) => { value: T; isFallback: boolean };\n context: { subscribe: (callback: () => void) => () => void };\n events: {\n publish: (name: string, props?: Record<string, unknown>) => void;\n subscribe?: (\n filterOrCallback:\n | { names?: string[]; patterns?: string[]; sources?: string[] }\n | ((event: { name: string; props?: Record<string, unknown>; ts: number }) => void),\n maybeCallback?: (event: { name: string; props?: Record<string, unknown>; ts: number }) => void\n ) => () => void;\n getRecent?: (\n filter?: { names?: string[]; patterns?: string[] },\n limit?: number\n ) => Array<{ name: string; props?: Record<string, unknown>; ts: number }>;\n };\n state?: { get: (key: string) => unknown; set: (key: string, value: unknown) => void };\n /** Event accumulator for reactive showWhen re-evaluation */\n accumulator?: {\n subscribe: (callback: () => void) => () => void;\n register: (key: string, predicate: (event: any) => boolean) => void;\n };\n}\n\ninterface FAQWidgetProps {\n config: FAQConfig;\n runtime: FAQWidgetRuntime;\n instanceId: string;\n}\n\n// ============================================================================\n// Styles\n// ============================================================================\n\nconst baseStyles = {\n container: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n maxWidth: '800px',\n margin: '0 auto',\n },\n searchWrapper: {\n marginBottom: '16px',\n },\n searchInput: {\n width: '100%',\n padding: '12px 16px',\n borderRadius: '8px',\n fontSize: '14px',\n outline: 'none',\n transition: 'border-color 0.15s ease',\n },\n accordion: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '8px',\n },\n item: {\n borderRadius: '8px',\n overflow: 'hidden',\n transition: 'box-shadow 0.15s ease',\n },\n question: {\n width: '100%',\n padding: '16px 20px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n border: 'none',\n cursor: 'pointer',\n fontSize: '15px',\n fontWeight: 500,\n textAlign: 'left' as const,\n transition: 'background-color 0.15s ease',\n },\n chevron: {\n fontSize: '18px',\n transition: 'transform 0.2s ease',\n },\n answer: {\n padding: '0 20px 16px 20px',\n fontSize: '14px',\n lineHeight: 1.6,\n overflow: 'hidden',\n transition: 'max-height 0.2s ease, padding 0.2s ease',\n },\n category: {\n display: 'inline-block',\n fontSize: '11px',\n fontWeight: 600,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n padding: '4px 8px',\n borderRadius: '4px',\n marginBottom: '8px',\n },\n categoryHeader: {\n fontSize: '13px',\n fontWeight: 700,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n padding: '12px 4px 6px 4px',\n marginTop: '8px',\n },\n feedback: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n marginTop: '12px',\n paddingTop: '10px',\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n fontSize: '13px',\n },\n feedbackButton: {\n background: 'none',\n border: '1px solid transparent',\n cursor: 'pointer',\n fontSize: '16px',\n padding: '4px 8px',\n borderRadius: '4px',\n transition: 'background-color 0.15s ease, border-color 0.15s ease',\n },\n feedbackButtonSelected: {\n borderColor: 'rgba(0, 0, 0, 0.2)',\n backgroundColor: 'rgba(0, 0, 0, 0.04)',\n },\n emptyState: {\n textAlign: 'center' as const,\n padding: '48px 24px',\n fontSize: '14px',\n },\n noResults: {\n textAlign: 'center' as const,\n padding: '32px 16px',\n fontSize: '14px',\n },\n} as const;\n\nconst themeStyles = {\n light: {\n container: {\n backgroundColor: base.white,\n color: slateGrey[1],\n },\n searchInput: {\n backgroundColor: slateGrey[12],\n border: `1px solid ${slateGrey[11]}`,\n color: slateGrey[1],\n },\n item: {\n backgroundColor: slateGrey[12],\n border: `1px solid ${slateGrey[11]}`,\n },\n itemExpanded: {\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)',\n },\n question: {\n backgroundColor: 'transparent',\n color: slateGrey[1],\n },\n questionHover: {\n backgroundColor: slateGrey[12],\n },\n answer: {\n color: slateGrey[6],\n },\n category: {\n backgroundColor: purple[8],\n color: purple[2],\n },\n categoryHeader: {\n color: slateGrey[7],\n },\n emptyState: {\n color: slateGrey[8],\n },\n feedbackPrompt: {\n color: slateGrey[7],\n },\n },\n dark: {\n container: {\n backgroundColor: slateGrey[1],\n color: slateGrey[12],\n },\n searchInput: {\n backgroundColor: slateGrey[3],\n border: `1px solid ${slateGrey[5]}`,\n color: slateGrey[12],\n },\n item: {\n backgroundColor: slateGrey[3],\n border: `1px solid ${slateGrey[5]}`,\n },\n itemExpanded: {\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',\n },\n question: {\n backgroundColor: 'transparent',\n color: slateGrey[12],\n },\n questionHover: {\n backgroundColor: slateGrey[5],\n },\n answer: {\n color: slateGrey[8],\n },\n category: {\n backgroundColor: purple[0],\n color: purple[6],\n },\n categoryHeader: {\n color: slateGrey[8],\n },\n emptyState: {\n color: slateGrey[7],\n },\n feedbackPrompt: {\n color: slateGrey[8],\n },\n },\n};\n\n// ============================================================================\n// FAQItem Component\n// ============================================================================\n\ninterface FAQItemProps {\n item: FAQQuestionAction;\n isExpanded: boolean;\n onToggle: () => void;\n theme: 'light' | 'dark';\n feedbackConfig: FeedbackConfig | null;\n feedbackValue: FeedbackValue | undefined;\n onFeedback: (itemId: string, question: string, value: FeedbackValue) => void;\n}\n\nfunction FAQItem({\n item,\n isExpanded,\n onToggle,\n theme,\n feedbackConfig,\n feedbackValue,\n onFeedback,\n}: FAQItemProps) {\n const [isHovered, setIsHovered] = useState(false);\n const colors = themeStyles[theme];\n const { question, answer } = item.config;\n\n const itemStyle: React.CSSProperties = {\n ...baseStyles.item,\n ...colors.item,\n ...(isExpanded ? colors.itemExpanded : {}),\n };\n\n const questionStyle: React.CSSProperties = {\n ...baseStyles.question,\n ...colors.question,\n ...(isHovered ? colors.questionHover : {}),\n };\n\n const chevronStyle: React.CSSProperties = {\n ...baseStyles.chevron,\n transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n };\n\n const answerStyle: React.CSSProperties = {\n ...baseStyles.answer,\n ...colors.answer,\n maxHeight: isExpanded ? '500px' : '0',\n paddingBottom: isExpanded ? '16px' : '0',\n };\n\n const feedbackStyle: React.CSSProperties = {\n ...baseStyles.feedback,\n ...colors.feedbackPrompt,\n };\n\n return (\n <div style={itemStyle} data-faq-item-id={item.config.id}>\n <button\n type=\"button\"\n style={questionStyle}\n onClick={onToggle}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n aria-expanded={isExpanded}\n >\n <span>{question}</span>\n <span style={chevronStyle}>{'\\u25BC'}</span>\n </button>\n <div style={answerStyle} aria-hidden={!isExpanded}>\n {renderAnswer(answer)}\n\n {/* Feedback UI \u2014 only when expanded and feedback is enabled */}\n {isExpanded && feedbackConfig && (\n <div style={feedbackStyle}>\n <span>{getFeedbackPrompt(feedbackConfig)}</span>\n <button\n type=\"button\"\n style={{\n ...baseStyles.feedbackButton,\n ...(feedbackValue === 'up' ? baseStyles.feedbackButtonSelected : {}),\n }}\n aria-label=\"Thumbs up\"\n onClick={() => onFeedback(item.config.id, question, 'up')}\n >\n {'\\uD83D\\uDC4D'}\n </button>\n <button\n type=\"button\"\n style={{\n ...baseStyles.feedbackButton,\n ...(feedbackValue === 'down' ? baseStyles.feedbackButtonSelected : {}),\n }}\n aria-label=\"Thumbs down\"\n onClick={() => onFeedback(item.config.id, question, 'down')}\n >\n {'\\uD83D\\uDC4E'}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// FAQWidget Component\n// ============================================================================\n\n/**\n * FAQWidget - Renders a collapsible Q&A accordion with per-item activation.\n *\n * This component demonstrates the compositional action pattern:\n * - Parent (FAQWidget) receives `config.actions` array\n * - Each action has optional `showWhen` for per-item visibility\n * - Parent evaluates showWhen and filters visible questions\n * - Parent manages expand state and re-rendering on context changes\n */\nexport function FAQWidget({ config, runtime, instanceId }: FAQWidgetProps) {\n // Force re-render when context/accumulator changes.\n // renderTick is used as a useMemo dependency to invalidate cached showWhen evaluations.\n const [renderTick, forceUpdate] = useReducer((x: number) => x + 1, 0);\n\n // Track expanded question IDs\n const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());\n\n // Search query state\n const [searchQuery, setSearchQuery] = useState('');\n\n // Track feedback state per item\n const [feedbackState, setFeedbackState] = useState<Map<string, FeedbackValue>>(new Map());\n\n // Resolve feedback config\n const feedbackConfig = useMemo(() => resolveFeedbackConfig(config.feedback), [config.feedback]);\n\n // Subscribe to context changes for reactive updates\n useEffect(() => {\n const unsubscribe = runtime.context.subscribe(() => {\n forceUpdate();\n });\n return unsubscribe;\n }, [runtime.context]);\n\n // Subscribe to accumulator changes for event_count-based showWhen\n useEffect(() => {\n if (!runtime.accumulator?.subscribe) return;\n return runtime.accumulator.subscribe(() => {\n forceUpdate();\n });\n }, [runtime.accumulator]);\n\n // Register accumulator predicates from scope config\n useEffect(() => {\n if (!config.scope || !runtime.accumulator?.register) return;\n const { events: eventNames, urlContains, props: propFilters } = config.scope;\n\n // Scan showWhen conditions for event_count keys\n const keys = new Set<string>();\n for (const action of config.actions) {\n if (action.showWhen?.type === 'rules') {\n for (const rule of action.showWhen.rules) {\n for (const cond of rule.conditions) {\n if ((cond as any).type === 'event_count' && (cond as any).key) {\n keys.add((cond as any).key);\n }\n }\n }\n }\n }\n\n for (const key of keys) {\n runtime.accumulator.register(key, (event: any) => {\n if (!eventNames.includes(event.name)) return false;\n if (urlContains) {\n const pathname = String(event.props?.pathname ?? '');\n if (!pathname.includes(urlContains)) return false;\n }\n if (propFilters) {\n for (const [k, v] of Object.entries(propFilters)) {\n if (event.props?.[k] !== v) return false;\n }\n }\n return true;\n });\n }\n }, [config.scope, config.actions, runtime.accumulator]);\n\n // Subscribe to faq:open:* events from overlay CTA clicks\n useEffect(() => {\n if (!runtime.events.subscribe) return;\n\n // Check EventBus history for pending faq:open events\n // (may have fired before this widget mounted, e.g. when canvas was closed)\n if (runtime.events.getRecent) {\n const recentEvents = runtime.events.getRecent(\n { patterns: ['^action\\\\.tooltip_cta_clicked$', '^action\\\\.modal_cta_clicked$'] },\n 10\n );\n const pendingEvent = recentEvents\n .filter((e) => {\n const actionId = e.props?.actionId;\n return typeof actionId === 'string' && actionId.startsWith('faq:open:');\n })\n .pop(); // Most recent\n\n if (pendingEvent && Date.now() - pendingEvent.ts < 10000) {\n const questionId = (pendingEvent.props!.actionId as string).replace('faq:open:', '');\n setExpandedIds(new Set([questionId]));\n // Scroll into view after render\n requestAnimationFrame(() => {\n const el = document.querySelector(`[data-faq-item-id=\"${questionId}\"]`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n });\n }\n }\n\n // Subscribe to future CTA events\n const unsubscribe = runtime.events.subscribe(\n { patterns: ['^action\\\\.tooltip_cta_clicked$', '^action\\\\.modal_cta_clicked$'] },\n (event: { name: string; props?: Record<string, unknown>; ts: number }) => {\n const actionId = event.props?.actionId;\n if (typeof actionId !== 'string' || !actionId.startsWith('faq:open:')) return;\n\n const questionId = actionId.replace('faq:open:', '');\n setExpandedIds(new Set([questionId]));\n\n // Scroll the question into view\n requestAnimationFrame(() => {\n const el = document.querySelector(`[data-faq-item-id=\"${questionId}\"]`);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n });\n\n // Request canvas open (for future tile-based FAQ rendering)\n runtime.events.publish('canvas.requestOpen');\n }\n );\n\n return unsubscribe;\n }, [runtime]);\n\n // Filter visible questions based on per-item showWhen\n // biome-ignore lint/correctness/useExhaustiveDependencies: renderTick is intentionally included to force re-evaluation when the runtime's mutable context changes (subscribed above via forceUpdate)\n const visibleQuestions = useMemo(\n () =>\n config.actions.filter((q) => {\n // No showWhen = always visible\n if (!q.showWhen) return true;\n\n // Evaluate the decision strategy\n const result = runtime.evaluateSync<boolean>(q.showWhen);\n return result.value;\n }),\n [config.actions, runtime, renderTick]\n );\n\n // NOTE: faq:question_revealed is now published by useNotifyWatcher in\n // ShadowCanvasOverlay (always mounted), so it fires even with drawer closed.\n\n // Apply priority ordering\n const orderedQuestions = useMemo(() => {\n if (config.ordering === 'priority') {\n return [...visibleQuestions].sort(\n (a, b) => (b.config.priority ?? 0) - (a.config.priority ?? 0)\n );\n }\n // 'static' or undefined \u2014 preserve config order\n return visibleQuestions;\n }, [visibleQuestions, config.ordering]);\n\n // Apply search filter\n const filteredQuestions = useMemo(() => {\n if (!config.searchable || !searchQuery.trim()) {\n return orderedQuestions;\n }\n\n const query = searchQuery.toLowerCase();\n return orderedQuestions.filter(\n (q) =>\n q.config.question.toLowerCase().includes(query) ||\n getAnswerText(q.config.answer).toLowerCase().includes(query) ||\n q.config.category?.toLowerCase().includes(query)\n );\n }, [orderedQuestions, searchQuery, config.searchable]);\n\n // Group by category\n const categoryGroups = useMemo(() => {\n const groups = new Map<string | undefined, FAQQuestionAction[]>();\n for (const q of filteredQuestions) {\n const cat = q.config.category;\n if (!groups.has(cat)) {\n groups.set(cat, []);\n }\n groups.get(cat)!.push(q);\n }\n return groups;\n }, [filteredQuestions]);\n\n // Check if any items have categories\n const hasCategories = useMemo(\n () => filteredQuestions.some((q) => q.config.category),\n [filteredQuestions]\n );\n\n // Resolve theme (auto -> detect system preference)\n const resolvedTheme = useMemo(() => {\n if (config.theme !== 'auto') return config.theme;\n\n // Check system preference (SSR-safe)\n if (typeof window !== 'undefined') {\n return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light';\n }, [config.theme]);\n\n // Handle question toggle\n const handleToggle = useCallback(\n (id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n\n if (config.expandBehavior === 'single') {\n // Single mode: collapse all others\n if (prev.has(id)) {\n return new Set();\n }\n return new Set([id]);\n }\n // Multiple mode: toggle this one\n if (prev.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n\n // Publish toggle event for analytics\n runtime.events.publish('faq:toggled', {\n instanceId,\n questionId: id,\n expanded: !expandedIds.has(id),\n timestamp: Date.now(),\n });\n },\n [config.expandBehavior, runtime.events, instanceId, expandedIds]\n );\n\n // Handle feedback\n const handleFeedback = useCallback(\n (itemId: string, question: string, value: FeedbackValue) => {\n setFeedbackState((prev) => {\n const next = new Map(prev);\n next.set(itemId, value);\n return next;\n });\n\n runtime.events.publish('faq:feedback', {\n itemId,\n question,\n value,\n });\n },\n [runtime.events]\n );\n\n // Compute styles\n const containerStyle: React.CSSProperties = {\n ...baseStyles.container,\n ...themeStyles[resolvedTheme].container,\n };\n\n const searchInputStyle: React.CSSProperties = {\n ...baseStyles.searchInput,\n ...themeStyles[resolvedTheme].searchInput,\n };\n\n const emptyStateStyle: React.CSSProperties = {\n ...baseStyles.emptyState,\n ...themeStyles[resolvedTheme].emptyState,\n };\n\n const categoryHeaderStyle: React.CSSProperties = {\n ...baseStyles.categoryHeader,\n ...themeStyles[resolvedTheme].categoryHeader,\n };\n\n // Render a list of FAQ items\n const renderItems = (items: FAQQuestionAction[]) =>\n items.map((q) => (\n <FAQItem\n key={q.config.id}\n item={q}\n isExpanded={expandedIds.has(q.config.id)}\n onToggle={() => handleToggle(q.config.id)}\n theme={resolvedTheme}\n feedbackConfig={feedbackConfig}\n feedbackValue={feedbackState.get(q.config.id)}\n onFeedback={handleFeedback}\n />\n ));\n\n // Empty state (no visible questions at all)\n if (visibleQuestions.length === 0) {\n return (\n <div style={containerStyle} data-adaptive-id={instanceId} data-adaptive-type=\"adaptive-faq\">\n <div style={emptyStateStyle}>No FAQ questions available.</div>\n </div>\n );\n }\n\n return (\n <div style={containerStyle} data-adaptive-id={instanceId} data-adaptive-type=\"adaptive-faq\">\n {/* Search input */}\n {config.searchable && (\n <div style={baseStyles.searchWrapper}>\n <input\n type=\"text\"\n placeholder=\"Search questions...\"\n value={searchQuery}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSearchQuery(e.target.value)}\n style={searchInputStyle}\n />\n </div>\n )}\n\n {/* Accordion \u2014 grouped by category if categories are present */}\n <div style={baseStyles.accordion}>\n {hasCategories\n ? Array.from(categoryGroups.entries()).map(([category, items]) => (\n <React.Fragment key={category ?? '__ungrouped'}>\n {category && (\n <div style={categoryHeaderStyle} data-category-header={category}>\n {category}\n </div>\n )}\n {renderItems(items)}\n </React.Fragment>\n ))\n : renderItems(filteredQuestions)}\n </div>\n\n {/* No search results */}\n {config.searchable && filteredQuestions.length === 0 && searchQuery && (\n <div style={{ ...baseStyles.noResults, ...themeStyles[resolvedTheme].emptyState }}>\n No questions found matching &quot;{searchQuery}&quot;\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Mountable Widget Interface\n// ============================================================================\n\n/**\n * Mountable widget interface for the runtime's WidgetRegistry.\n */\nexport const FAQMountableWidget = {\n mount(\n container: HTMLElement,\n config?: FAQConfig & { runtime?: FAQWidgetRuntime; instanceId?: string }\n ) {\n const {\n runtime,\n instanceId = 'faq-widget',\n ...faqConfig\n } = config || {\n expandBehavior: 'single' as const,\n searchable: false,\n theme: 'auto' as const,\n actions: [],\n };\n\n // React rendering when runtime + ReactDOM are available\n if (runtime && typeof createRoot === 'function') {\n const root = createRoot(container);\n root.render(\n React.createElement(FAQWidget, {\n config: faqConfig as FAQConfig,\n runtime: runtime as FAQWidgetRuntime,\n instanceId,\n })\n );\n return () => {\n root.unmount();\n };\n }\n\n // HTML fallback when React is not available\n const questions = (faqConfig as FAQConfig).actions || [];\n container.innerHTML = `\n <div style=\"font-family: system-ui; max-width: 800px;\">\n ${questions\n .map(\n (q) => `\n <div style=\"margin-bottom: 8px; padding: 16px; background: ${slateGrey[12]}; border-radius: 8px;\">\n <strong>${q.config.question}</strong>\n <p style=\"margin-top: 8px; color: ${slateGrey[6]};\">${getAnswerText(q.config.answer)}</p>\n </div>\n `\n )\n .join('')}\n </div>\n `;\n\n return () => {\n container.innerHTML = '';\n };\n },\n};\n\nexport default FAQWidget;\n", "/**\n * Adaptive FAQ - Runtime Module\n *\n * Runtime manifest for the FAQ accordion adaptive.\n * Provides action executors and widget registration.\n */\n\nimport { executorDefinitions } from './executors';\nimport { FAQMountableWidget } from './FAQWidget';\n\n// ============================================================================\n// App Runtime Manifest\n// ============================================================================\n\n/**\n * Runtime manifest for adaptive-faq.\n *\n * Provides:\n * - FAQ action executors (scroll_to, toggle_item, update)\n * - Widget-based accordion (compositional faq:question actions)\n */\nexport const runtime = {\n id: 'adaptive-faq',\n version: '2.0.0',\n name: 'FAQ Accordion',\n description:\n 'Collapsible Q&A accordion with actions, rich content, feedback, and personalization',\n\n /**\n * Action executors for programmatic FAQ interaction.\n */\n executors: executorDefinitions,\n\n /**\n * Widget definitions for the runtime's WidgetRegistry.\n */\n widgets: [\n {\n id: 'adaptive-faq:accordion',\n component: FAQMountableWidget,\n metadata: {\n name: 'FAQ Accordion',\n description: 'Collapsible Q&A accordion with search, categories, and feedback',\n icon: '\u2753',\n },\n },\n ],\n};\n\nexport default runtime;\n", "/**\n * CDN Entry Point for Adaptive FAQ\n *\n * This module is bundled for CDN delivery and self-registers with the global\n * SynOS app registry when loaded dynamically via the AppLoader.\n */\n\nimport FAQEditor, { editorPanel } from './editor';\nimport { runtime } from './runtime';\nimport type { FAQQuestionAction } from './types';\n\n/**\n * App manifest for registry registration.\n * Follows the AppManifest interface expected by AppLoader/AppRegistry.\n */\nexport const manifest = {\n id: 'adaptive-faq',\n version: runtime.version,\n name: runtime.name,\n description: runtime.description,\n runtime: {\n actions: runtime.executors,\n widgets: runtime.widgets,\n /**\n * Extract notify watcher entries from tile config props.\n * The runtime evaluates these continuously (even with drawer closed)\n * and publishes faq:question_revealed when showWhen transitions false \u2192 true.\n */\n notifyWatchers(props: Record<string, unknown>) {\n const actions = (props.actions ?? []) as FAQQuestionAction[];\n return actions\n .filter((a) => a.notify && a.showWhen)\n .map((a) => ({\n id: `faq:${a.config.id}`,\n strategy: a.showWhen!,\n eventName: 'faq:question_revealed',\n eventProps: {\n questionId: a.config.id,\n question: a.config.question,\n title: a.notify!.title,\n body: a.notify!.body,\n icon: a.notify!.icon,\n },\n }));\n },\n },\n editor: {\n component: FAQEditor,\n panel: editorPanel,\n getActionLabel(action: Record<string, unknown>) {\n const config = (action.config as Record<string, unknown>) || {};\n return (config.question as string) || (action.kind as string) || 'faq:update';\n },\n },\n metadata: {\n isBuiltIn: false,\n },\n};\n\n/**\n * Self-register with global registry if available.\n * This happens when loaded via script tag (UMD).\n */\nif (typeof window !== 'undefined') {\n const registry = (window as any).SynOS?.appRegistry;\n if (registry && typeof registry.register === 'function') {\n registry.register(manifest);\n }\n}\n\nexport default manifest;\n"],
5
- "mappings": "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",
6
- "names": ["cn", "classes", "_R", "_jsx", "type", "props", "key", "R", "p", "c", "jsx", "jsxs", "Fragment", "_R", "react_default", "_", "k", "useState", "useEffect", "useMemo", "useCallback", "useRef", "useReducer", "_R", "createElement", "_R", "forwardRef", "_R", "_r", "_R", "Fragment", "Suspense", "Children", "Component", "PureComponent", "_RD", "react_dom_default", "_", "k", "CSS_SELECTOR_TYPE", "libraryName", "showWarning", "id", "args", "DEFAULT_OPTIONS", "CSS_SELECTOR_TYPE", "isRegExp", "input", "wildcardToRegExp", "input", "createPatternMatcher", "list", "matchFunctions", "item", "isRegExp", "result", "showWarning", "re", "matchFunction", "INVALID_ID_RE", "INVALID_CLASS_RE", "SELECTOR_PATTERN", "CSS_SELECTOR_TYPE", "attributeBlacklistMatch", "createPatternMatcher", "ESCAPED_COLON", "toKebabCase", "string", "toCamelCase", "match", "p1", "p2", "toPascalCase", "camelCase", "mergeClasses", "classes", "className", "index", "array", "hasA11yProp", "props", "prop", "defaultAttributes", "Icon", "forwardRef", "color", "size", "strokeWidth", "absoluteStrokeWidth", "className", "children", "iconNode", "rest", "ref", "createElement", "defaultAttributes", "mergeClasses", "hasA11yProp", "tag", "attrs", "createLucideIcon", "iconName", "iconNode", "Component", "forwardRef", "className", "props", "ref", "createElement", "Icon", "mergeClasses", "toKebabCase", "toPascalCase", "__iconNode", "Check", "createLucideIcon", "__iconNode", "Clock", "createLucideIcon", "__iconNode", "X", "createLucideIcon", "ProgressBar", "current", "target", "pct", "jsx", "cn", "ConditionRow", "cs", "jsxs", "Check", "X", "Fragment", "ConditionStatusLine", "status", "expanded", "setExpanded", "useState", "visible", "conditions", "passedCount", "c", "totalCount", "StatusIcon", "Clock", "iconColor", "e", "i", "DetectionBadge", "found", "jsx", "cn", "DismissedSection", "count", "children", "isOpen", "setIsOpen", "useState", "jsxs", "e", "jsx", "EditorBody", "children", "jsx", "EditorCard", "children", "itemKey", "onClick", "onMouseEnter", "onMouseLeave", "className", "validated", "jsx", "cn", "EditorFooter", "onSave", "onPublish", "jsxs", "jsx", "EditorHeader", "title", "subtitle", "jsxs", "jsx", "EditorInput", "label", "className", "props", "jsxs", "jsx", "cn", "EditorLayout", "children", "jsx", "EditorTextarea", "label", "className", "value", "props", "ref", "useRef", "useEffect", "el", "jsxs", "jsx", "cn", "EmptyState", "message", "jsx", "ProgressBar", "current", "target", "pct", "jsxs", "jsx", "cn", "JourneyNode", "cs", "isLast", "hasProgress", "inProgress", "Check", "TriggerJourney", "status", "conditions", "allPassed", "c", "isMulti", "i", "GroupHeader", "label", "count", "className", "jsxs", "cn", "jsx", "formatOperator", "op", "humanizeKey", "key", "cleanUrl", "url", "PAGE_VIEW_RE", "CLICK_RE", "formatConditionLabel", "condition", "accumulatorCount", "target", "current", "humanized", "instruction", "shortLabel", "topic", "lastWord", "w", "cleaned", "anchorId", "state", "eventName", "val", "parts", "label", "threshold", "inverted", "limit", "routeId", "getRuntime", "evaluateConditionLocally", "condition", "runtime", "ctx", "type", "passed", "accCount", "key", "withinMs", "count", "target", "pattern", "anchor", "a", "width", "height", "val", "threshold", "limitReached", "formatted", "formatConditionLabel", "evaluateShowWhen", "showWhen", "allConditions", "rule", "ruleMatched", "cs", "useShowWhenStatus", "items", "statuses", "setStatuses", "useState", "itemsRef", "useRef", "evaluate", "useCallback", "map", "item", "useEffect", "unsubs", "interval", "u", "truncate", "text", "max", "stripHtml", "html", "getAnswerPreview", "answer", "isRuleStrategy", "s", "describeTrigger", "showWhen", "pages", "anchors", "rule", "condition", "parts", "summarizeFAQItem", "item", "q", "isOwnAction", "action", "isRuleStrategy", "s", "extractTargetingInfo", "showWhen", "pagePatterns", "anchorSelectors", "rule", "cond", "c", "hasTargeting", "extractFirstPage", "extractFirstAnchor", "getAnswerText", "answer", "flattenItems", "config", "isOwnAction", "q", "i", "summarizeFAQItem", "describeTrigger", "filterConfig", "dismissedKeys", "ownActions", "_", "useDetection", "items", "getCurrentRoute", "detectionMap", "setDetectionMap", "useState", "itemsRef", "useRef", "useEffect", "runDetection", "map", "currentPath", "item", "targeting", "pageMatch", "pattern", "anchorFound", "element", "interval", "FAQEditor", "onChange", "editor", "typedConfig", "setDismissedKeys", "editingKey", "setEditingKey", "_previewMode", "setPreviewMode", "_hoveredKey", "setHoveredKey", "mode", "allKeys", "empty", "initialConsumed", "allItems", "activeItems", "dismissedItems", "totalQuestions", "foundCount", "showWhenItems", "useMemo", "showWhenStatuses", "useShowWhenStatus", "handleDismiss", "useCallback", "key", "prev", "next", "handleRestore", "handleCardBodyClick", "handleTriggerClick", "pageUrl", "handleBackToList", "_handleBeforeAfter", "filtered", "handleFieldChange", "index", "field", "value", "otherActions", "a", "updated", "handlePublish", "handleCardHover", "handleCardLeave", "renderEditFields", "it", "jsxs", "jsx", "EditorInput", "e", "EditorTextarea", "TriggerJourney", "EditorLayout", "EditorHeader", "EditorBody", "editIndex", "editItem", "Fragment", "EmptyState", "GroupHeader", "detection", "EditorCard", "DetectionBadge", "ConditionStatusLine", "DismissedSection", "EditorFooter", "editorPanel", "editor_default", "FAQEditor", "resolveItem", "store", "itemId", "itemQuestion", "found", "i", "executeScrollToFaq", "action", "context", "item", "id", "el", "executeToggleFaqItem", "desiredState", "newState", "wasExpanded", "executeUpdateFaq", "items", "position", "order", "executorDefinitions", "base", "brand", "slateGrey", "green", "yellow", "red", "blue", "orange", "purple", "pink", "text", "slateGrey", "background", "border", "button", "base", "brand", "red", "green", "badge", "yellow", "purple", "blue", "orange", "pink", "badgeBanner", "alert", "tag", "menu", "inputDropdown", "inputField", "toggle", "checkbox", "avatar", "progressBarSlider", "card", "sidebar", "modal", "tab", "table", "breadcrumbs", "loadingIndicator", "datePicker", "scroll", "_RD", "client_default", "_", "k", "createRoot", "getAnswerText", "answer", "renderAnswer", "jsx", "resolveFeedbackConfig", "feedback", "getFeedbackPrompt", "feedbackConfig", "baseStyles", "themeStyles", "base", "slateGrey", "purple", "FAQItem", "item", "isExpanded", "onToggle", "theme", "feedbackValue", "onFeedback", "isHovered", "setIsHovered", "useState", "colors", "question", "itemStyle", "questionStyle", "chevronStyle", "answerStyle", "feedbackStyle", "jsxs", "FAQWidget", "config", "runtime", "instanceId", "renderTick", "forceUpdate", "useReducer", "x", "expandedIds", "setExpandedIds", "searchQuery", "setSearchQuery", "feedbackState", "setFeedbackState", "useMemo", "useEffect", "eventNames", "urlContains", "propFilters", "keys", "action", "rule", "cond", "key", "event", "k", "v", "pendingEvent", "e", "actionId", "questionId", "el", "visibleQuestions", "q", "orderedQuestions", "a", "b", "filteredQuestions", "query", "categoryGroups", "groups", "cat", "hasCategories", "resolvedTheme", "handleToggle", "useCallback", "id", "prev", "next", "handleFeedback", "itemId", "value", "containerStyle", "searchInputStyle", "emptyStateStyle", "categoryHeaderStyle", "renderItems", "items", "category", "react_default", "FAQMountableWidget", "container", "faqConfig", "createRoot", "root", "questions", "runtime", "executorDefinitions", "FAQMountableWidget", "manifest", "runtime", "props", "editor_default", "editorPanel", "action", "registry", "cdn_default"]
7
- }
@@ -1,2 +0,0 @@
1
- function p(){return typeof SynOS<"u"&&SynOS.React||{}}function g(e,n,t){var o=p(),i=n||{},a=i.children;return delete i.children,t!==void 0&&(i.key=t),Array.isArray(a)?o.createElement.apply(null,[e,i].concat(a)):a!==void 0?o.createElement(e,i,a):o.createElement(e,i)}var d=g,m=g,y=p().Fragment;function l({config:e,onChange:n,editor:t}){return m("div",{className:"syntro-gamification-editor",children:[d("p",{children:"Gamification editor coming soon..."}),d("p",{children:"Configure badges, points, rewards, and leaderboards."})]})}var u={panel:{title:"Gamification",icon:"\u{1F3AE}",description:"Badges, rewards, and engagement"},component:l};var x=async(e,n)=>{let{badgeId:t}=e;return n.publishEvent("gamification.badge_awarded",{badgeId:t,awardedAt:Date.now()}),{cleanup:()=>{}}},v=async(e,n)=>{let{points:t,reason:o}=e;return n.publishEvent("gamification.points_added",{points:t,reason:o,timestamp:Date.now()}),{cleanup:()=>{}}},w={names:["page_view","button_click"],handler:(e,n)=>{console.log("[Gamification] Event received for badge trigger check")}},c=[{kind:"gamification:awardBadge",executor:x},{kind:"gamification:addPoints",executor:v}],s=[w],r={id:"adaptive-gamification",version:"1.0.0",name:"Gamification",description:"Badges, rewards, points, and engagement mechanics",executors:c,eventHandlers:s};var f={id:"adaptive-gamification",version:r.version,name:r.name,description:r.description,runtime:{actions:c.map(({kind:e,executor:n})=>({kind:e,executor:n})),events:s},editor:u,metadata:{isBuiltIn:!1}};if(typeof window<"u"){let e=window.SynOS?.appRegistry;e&&typeof e.register=="function"&&e.register(f)}var k=f;export{k as default,f as manifest};
2
- //# sourceMappingURL=index.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["syntro-react:react/jsx-runtime", "../../../../adaptives/adaptive-gamification/src/editor.tsx", "../../../../adaptives/adaptive-gamification/src/runtime.ts", "../../../../adaptives/adaptive-gamification/src/cdn.ts"],
4
- "sourcesContent": ["\n function _R() {\n return (typeof SynOS !== 'undefined' && SynOS.React) || {};\n }\n function _jsx(type, props, key) {\n var R = _R();\n var p = props || {};\n var c = p.children;\n delete p.children;\n if (key !== undefined) p.key = key;\n return Array.isArray(c)\n ? R.createElement.apply(null, [type, p].concat(c))\n : c !== undefined\n ? R.createElement(type, p, c)\n : R.createElement(type, p);\n }\n export var jsx = _jsx;\n export var jsxs = _jsx;\n export var Fragment = _R().Fragment;\n ", "/**\n * Adaptive Gamification - Editor Module\n *\n * Editor panel for configuring gamification features.\n */\n\nimport type { EditorPanelProps } from './types';\n\n/**\n * Gamification editor panel component.\n */\nexport function GamificationEditor({\n config: _config,\n onChange: _onChange,\n editor: _editor,\n}: EditorPanelProps) {\n return (\n <div className=\"syntro-gamification-editor\">\n <p>Gamification editor coming soon...</p>\n <p>Configure badges, points, rewards, and leaderboards.</p>\n </div>\n );\n}\n\n/**\n * Editor module configuration.\n */\nexport const editor = {\n panel: {\n title: 'Gamification',\n icon: '\uD83C\uDFAE',\n description: 'Badges, rewards, and engagement',\n },\n component: GamificationEditor,\n};\n", "/**\n * Adaptive Gamification - Runtime Module\n *\n * Gamification actions: awardBadge, addPoints.\n * Provides gamification features like badges, points, and rewards.\n */\n\nimport type { ActionExecutor, ExecutorResult } from './types';\n\n// ============================================================================\n// Action Types\n// ============================================================================\n\n/**\n * Award badge action\n */\nexport interface AwardBadgeAction {\n kind: 'gamification:awardBadge';\n badgeId: string;\n anchorId?: string;\n label?: string;\n}\n\n/**\n * Add points action\n */\nexport interface AddPointsAction {\n kind: 'gamification:addPoints';\n points: number;\n reason?: string;\n label?: string;\n}\n\n// ============================================================================\n// Executors\n// ============================================================================\n\n/**\n * Execute an awardBadge action\n *\n * Note: This executor uses publishEvent to track badge awards.\n * State management is handled at the app level via AppContext,\n * not at the action executor level.\n */\nexport const executeAwardBadge: ActionExecutor<AwardBadgeAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n const { badgeId } = action;\n\n // Emit telemetry event (state management handled at app level)\n context.publishEvent('gamification.badge_awarded', {\n badgeId,\n awardedAt: Date.now(),\n });\n\n return {\n cleanup: () => {\n // Badge awards are permanent, no cleanup needed\n },\n };\n};\n\n/**\n * Execute an addPoints action\n *\n * Note: This executor uses publishEvent to track points.\n * State management is handled at the app level via AppContext,\n * not at the action executor level.\n */\nexport const executeAddPoints: ActionExecutor<AddPointsAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n const { points, reason } = action;\n\n // Emit telemetry event (state management handled at app level)\n context.publishEvent('gamification.points_added', {\n points,\n reason,\n timestamp: Date.now(),\n });\n\n return {\n cleanup: () => {\n // Points are permanent, no cleanup needed\n },\n };\n};\n\n// ============================================================================\n// Event Handlers\n// ============================================================================\n\n/**\n * Event handler for auto-awarding badges based on triggers.\n */\nexport const badgeTriggerHandler = {\n names: ['page_view', 'button_click'],\n handler: (_event: unknown, _ctx: unknown) => {\n // Auto-award badges based on event triggers\n // This would check badge trigger conditions in the config\n console.log('[Gamification] Event received for badge trigger check');\n },\n};\n\n// ============================================================================\n// Executor Definitions for Registration\n// ============================================================================\n\n/**\n * All executors provided by this app.\n * These are registered with the runtime's ExecutorRegistry.\n */\nexport const executors = [\n { kind: 'gamification:awardBadge', executor: executeAwardBadge },\n { kind: 'gamification:addPoints', executor: executeAddPoints },\n] as const;\n\n/**\n * Event handlers provided by this app.\n */\nexport const eventHandlers = [badgeTriggerHandler];\n\n/**\n * App runtime manifest.\n */\nexport const runtime = {\n id: 'adaptive-gamification',\n version: '1.0.0',\n name: 'Gamification',\n description: 'Badges, rewards, points, and engagement mechanics',\n executors,\n eventHandlers,\n};\n", "/**\n * CDN Entry Point for Adaptive Gamification\n *\n * This module is bundled for CDN delivery and self-registers with the global\n * SynOS app registry when loaded dynamically via the AppLoader.\n */\n\nimport { editor } from './editor';\nimport { eventHandlers, executors, runtime } from './runtime';\n\n/**\n * App manifest for registry registration.\n * Follows the AppManifest interface expected by AppLoader/AppRegistry.\n */\nexport const manifest = {\n id: 'adaptive-gamification',\n version: runtime.version,\n name: runtime.name,\n description: runtime.description,\n runtime: {\n actions: executors.map(({ kind, executor }) => ({\n kind,\n executor,\n })),\n events: eventHandlers,\n },\n editor,\n metadata: {\n isBuiltIn: false,\n },\n};\n\n/**\n * Self-register with global registry if available.\n * This happens when loaded via script tag (UMD).\n */\nif (typeof window !== 'undefined') {\n const registry = (window as any).SynOS?.appRegistry;\n if (registry && typeof registry.register === 'function') {\n registry.register(manifest);\n }\n}\n\nexport default manifest;\n"],
5
- "mappings": "AACY,SAASA,GAAK,CACZ,OAAQ,OAAO,MAAU,KAAe,MAAM,OAAU,CAAC,CAC3D,CACA,SAASC,EAAKC,EAAMC,EAAOC,EAAK,CAC9B,IAAIC,EAAIL,EAAG,EACPM,EAAIH,GAAS,CAAC,EACdI,EAAID,EAAE,SACV,cAAOA,EAAE,SACLF,IAAQ,SAAWE,EAAE,IAAMF,GACxB,MAAM,QAAQG,CAAC,EAClBF,EAAE,cAAc,MAAM,KAAM,CAACH,EAAMI,CAAC,EAAE,OAAOC,CAAC,CAAC,EAC/CA,IAAM,OACJF,EAAE,cAAcH,EAAMI,EAAGC,CAAC,EAC1BF,EAAE,cAAcH,EAAMI,CAAC,CAC/B,CACO,IAAIE,EAAMP,EACNQ,EAAOR,EACPS,EAAWV,EAAG,EAAE,SCPhC,SAASW,EAAmB,CACjC,OAAQC,EACR,SAAUC,EACV,OAAQC,CACV,EAAqB,CACnB,OACEC,EAAC,OAAI,UAAU,6BACb,UAAAC,EAAC,KAAE,8CAAkC,EACrCA,EAAC,KAAE,gEAAoD,GACzD,CAEJ,CAKO,IAAMC,EAAS,CACpB,MAAO,CACL,MAAO,eACP,KAAM,YACN,YAAa,iCACf,EACA,UAAWN,CACb,ECUO,IAAMO,EAAsD,MACjEC,EACAC,IAC4B,CAC5B,GAAM,CAAE,QAAAC,CAAQ,EAAIF,EAGpB,OAAAC,EAAQ,aAAa,6BAA8B,CACjD,QAAAC,EACA,UAAW,KAAK,IAAI,CACtB,CAAC,EAEM,CACL,QAAS,IAAM,CAEf,CACF,CACF,EASaC,EAAoD,MAC/DH,EACAC,IAC4B,CAC5B,GAAM,CAAE,OAAAG,EAAQ,OAAAC,CAAO,EAAIL,EAG3B,OAAAC,EAAQ,aAAa,4BAA6B,CAChD,OAAAG,EACA,OAAAC,EACA,UAAW,KAAK,IAAI,CACtB,CAAC,EAEM,CACL,QAAS,IAAM,CAEf,CACF,CACF,EASaC,EAAsB,CACjC,MAAO,CAAC,YAAa,cAAc,EACnC,QAAS,CAACC,EAAiBC,IAAkB,CAG3C,QAAQ,IAAI,uDAAuD,CACrE,CACF,EAUaC,EAAY,CACvB,CAAE,KAAM,0BAA2B,SAAUV,CAAkB,EAC/D,CAAE,KAAM,yBAA0B,SAAUI,CAAiB,CAC/D,EAKaO,EAAgB,CAACJ,CAAmB,EAKpCK,EAAU,CACrB,GAAI,wBACJ,QAAS,QACT,KAAM,eACN,YAAa,oDACb,UAAAF,EACA,cAAAC,CACF,ECxHO,IAAME,EAAW,CACtB,GAAI,wBACJ,QAASC,EAAQ,QACjB,KAAMA,EAAQ,KACd,YAAaA,EAAQ,YACrB,QAAS,CACP,QAASC,EAAU,IAAI,CAAC,CAAE,KAAAC,EAAM,SAAAC,CAAS,KAAO,CAC9C,KAAAD,EACA,SAAAC,CACF,EAAE,EACF,OAAQC,CACV,EACA,OAAAC,EACA,SAAU,CACR,UAAW,EACb,CACF,EAMA,GAAI,OAAO,OAAW,IAAa,CACjC,IAAMC,EAAY,OAAe,OAAO,YACpCA,GAAY,OAAOA,EAAS,UAAa,YAC3CA,EAAS,SAASP,CAAQ,CAE9B,CAEA,IAAOQ,EAAQR",
6
- "names": ["_R", "_jsx", "type", "props", "key", "R", "p", "c", "jsx", "jsxs", "Fragment", "GamificationEditor", "_config", "_onChange", "_editor", "jsxs", "jsx", "editor", "executeAwardBadge", "action", "context", "badgeId", "executeAddPoints", "points", "reason", "badgeTriggerHandler", "_event", "_ctx", "executors", "eventHandlers", "runtime", "manifest", "runtime", "executors", "kind", "executor", "eventHandlers", "editor", "registry", "cdn_default"]
7
- }