@embedpdf/plugin-ui 1.4.1 → 2.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1313 -655
- package/dist/index.js.map +1 -1
- package/dist/lib/actions.d.ts +110 -74
- package/dist/lib/index.d.ts +8 -7
- package/dist/lib/reducer.d.ts +5 -5
- package/dist/lib/schema.d.ts +257 -0
- package/dist/lib/selectors.d.ts +16 -0
- package/dist/lib/types.d.ts +185 -202
- package/dist/lib/ui-plugin.d.ts +66 -18
- package/dist/lib/utils/consts.d.ts +25 -0
- package/dist/lib/utils/index.d.ts +5 -0
- package/dist/lib/utils/responsive-utils.d.ts +10 -0
- package/dist/lib/utils/schema-merger.d.ts +15 -0
- package/dist/lib/utils/stylesheet-generator.d.ts +40 -0
- package/dist/lib/utils/ui-props.d.ts +14 -0
- package/dist/preact/adapter.d.ts +4 -2
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +450 -49
- package/dist/preact/index.js.map +1 -1
- package/dist/preact/utils.d.ts +1 -0
- package/dist/react/adapter.d.ts +2 -2
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +449 -48
- package/dist/react/index.js.map +1 -1
- package/dist/react/utils.d.ts +1 -0
- package/dist/shared/auto-menu-renderer.d.ts +13 -0
- package/dist/shared/hooks/index.d.ts +4 -0
- package/dist/shared/hooks/use-item-renderer.d.ts +14 -0
- package/dist/shared/hooks/use-register-anchor.d.ts +17 -0
- package/dist/shared/hooks/use-schema-renderer.d.ts +61 -0
- package/dist/shared/hooks/use-selection-menu.d.ts +11 -0
- package/dist/shared/hooks/use-ui.d.ts +13 -5
- package/dist/shared/index.d.ts +4 -1
- package/dist/shared/provider.d.ts +68 -0
- package/dist/shared/registries/anchor-registry.d.ts +16 -0
- package/dist/shared/registries/component-registry.d.ts +20 -0
- package/dist/shared/registries/index.d.ts +3 -0
- package/dist/shared/registries/renderers-registry.d.ts +8 -0
- package/dist/shared/root.d.ts +12 -0
- package/dist/shared/types.d.ts +67 -0
- package/dist/shared-preact/auto-menu-renderer.d.ts +13 -0
- package/dist/shared-preact/hooks/index.d.ts +4 -0
- package/dist/shared-preact/hooks/use-item-renderer.d.ts +14 -0
- package/dist/shared-preact/hooks/use-register-anchor.d.ts +17 -0
- package/dist/shared-preact/hooks/use-schema-renderer.d.ts +61 -0
- package/dist/shared-preact/hooks/use-selection-menu.d.ts +11 -0
- package/dist/shared-preact/hooks/use-ui.d.ts +13 -5
- package/dist/shared-preact/index.d.ts +4 -1
- package/dist/shared-preact/provider.d.ts +68 -0
- package/dist/shared-preact/registries/anchor-registry.d.ts +16 -0
- package/dist/shared-preact/registries/component-registry.d.ts +20 -0
- package/dist/shared-preact/registries/index.d.ts +3 -0
- package/dist/shared-preact/registries/renderers-registry.d.ts +8 -0
- package/dist/shared-preact/root.d.ts +12 -0
- package/dist/shared-preact/types.d.ts +67 -0
- package/dist/shared-react/auto-menu-renderer.d.ts +13 -0
- package/dist/shared-react/hooks/index.d.ts +4 -0
- package/dist/shared-react/hooks/use-item-renderer.d.ts +14 -0
- package/dist/shared-react/hooks/use-register-anchor.d.ts +17 -0
- package/dist/shared-react/hooks/use-schema-renderer.d.ts +61 -0
- package/dist/shared-react/hooks/use-selection-menu.d.ts +11 -0
- package/dist/shared-react/hooks/use-ui.d.ts +13 -5
- package/dist/shared-react/index.d.ts +4 -1
- package/dist/shared-react/provider.d.ts +68 -0
- package/dist/shared-react/registries/anchor-registry.d.ts +16 -0
- package/dist/shared-react/registries/component-registry.d.ts +20 -0
- package/dist/shared-react/registries/index.d.ts +3 -0
- package/dist/shared-react/registries/renderers-registry.d.ts +8 -0
- package/dist/shared-react/root.d.ts +12 -0
- package/dist/shared-react/types.d.ts +67 -0
- package/dist/svelte/auto-menu-renderer.svelte.d.ts +15 -0
- package/dist/svelte/hooks/index.d.ts +5 -0
- package/dist/svelte/hooks/use-item-renderer.svelte.d.ts +24 -0
- package/dist/svelte/hooks/use-register-anchor.svelte.d.ts +18 -0
- package/dist/svelte/hooks/use-schema-renderer.svelte.d.ts +78 -0
- package/dist/svelte/hooks/use-selection-menu.svelte.d.ts +9 -0
- package/dist/svelte/hooks/use-ui.svelte.d.ts +34 -0
- package/dist/svelte/index.cjs +2 -0
- package/dist/svelte/index.cjs.map +1 -0
- package/dist/svelte/index.d.ts +6 -0
- package/dist/svelte/index.js +553 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/svelte/provider.svelte.d.ts +33 -0
- package/dist/svelte/registries/anchor-registry.svelte.d.ts +14 -0
- package/dist/svelte/registries/component-registry.svelte.d.ts +17 -0
- package/dist/svelte/registries/index.d.ts +3 -0
- package/dist/svelte/registries/renderers-registry.svelte.d.ts +3 -0
- package/dist/svelte/root.svelte.d.ts +8 -0
- package/dist/svelte/types.d.ts +67 -0
- package/dist/vue/auto-menu-renderer.vue.d.ts +15 -0
- package/dist/vue/hooks/index.d.ts +5 -0
- package/dist/vue/hooks/use-item-renderer.d.ts +16 -0
- package/dist/vue/hooks/use-register-anchor.d.ts +19 -0
- package/dist/vue/hooks/use-schema-renderer.d.ts +63 -0
- package/dist/vue/hooks/use-selection-menu.d.ts +28 -0
- package/dist/vue/hooks/use-ui.d.ts +940 -0
- package/dist/vue/index.cjs +2 -0
- package/dist/vue/index.cjs.map +1 -0
- package/dist/vue/index.d.ts +6 -0
- package/dist/vue/index.js +544 -0
- package/dist/vue/index.js.map +1 -0
- package/dist/vue/provider.vue.d.ts +43 -0
- package/dist/vue/registries/anchor-registry.d.ts +14 -0
- package/dist/vue/registries/component-registry.d.ts +17 -0
- package/dist/vue/registries/index.d.ts +3 -0
- package/dist/vue/registries/renderers-registry.d.ts +3 -0
- package/dist/vue/root.vue.d.ts +13 -0
- package/dist/vue/types.d.ts +67 -0
- package/package.json +32 -9
- package/dist/lib/menu/menu-manager.d.ts +0 -98
- package/dist/lib/menu/types.d.ts +0 -91
- package/dist/lib/menu/utils.d.ts +0 -6
- package/dist/lib/ui-component.d.ts +0 -30
- package/dist/lib/utils.d.ts +0 -33
- package/dist/shared/components/component-wrapper.d.ts +0 -5
- package/dist/shared/components/index.d.ts +0 -1
- package/dist/shared/components/plugin-ui-provider.d.ts +0 -37
- package/dist/shared-preact/components/component-wrapper.d.ts +0 -5
- package/dist/shared-preact/components/index.d.ts +0 -1
- package/dist/shared-preact/components/plugin-ui-provider.d.ts +0 -37
- package/dist/shared-react/components/component-wrapper.d.ts +0 -5
- package/dist/shared-react/components/index.d.ts +0 -1
- package/dist/shared-react/components/plugin-ui-provider.d.ts +0 -37
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("@embedpdf/core");class e{constructor(t,e){this.children=[],this.updateCallbacks=[],this.hadUpdateBeforeListeners=!1,this.componentConfig=t;const n=t.props||{};if("function"==typeof n){const e=n(t.initialState);this.props={...e,id:t.id}}else this.props={...n,id:t.id};this.type=t.type,this.registry=e}addChild(t,e,n=0,i){this.children.push({id:t,component:e,priority:n,className:i}),this.sortChildren()}sortChildren(){this.children.sort(((t,e)=>t.priority-e.priority))}removeChild(t){this.children=this.children.filter((e=>e.component!==t))}clearChildren(){this.children=[]}get getRenderType(){return this.componentConfig.render||this.type}getRenderer(){return this.registry[this.getRenderType]}getChildren(){return this.children}getChildContext(t){const e=this.componentConfig.getChildContext;return"function"==typeof e?{...t,...e(this.props)}:e&&"object"==typeof e?{...t,...e}:t}update(t){const{id:e,...n}=t;this.props={...this.props,...n},0===this.updateCallbacks.length&&(this.hadUpdateBeforeListeners=!0),this.notifyUpdate()}onUpdate(t){return this.updateCallbacks.push(t),this.hadUpdateBeforeListeners}offUpdate(t){this.updateCallbacks=this.updateCallbacks.filter((e=>e!==t))}notifyUpdate(){this.updateCallbacks.forEach((t=>t()))}}const n="UI_INIT_COMPONENTS",i="UI_SET_HEADER_VISIBLE",o="UI_TOGGLE_PANEL",s="UI_SHOW_COMMAND_MENU",r="UI_HIDE_COMMAND_MENU",a="UI_UPDATE_COMPONENT_STATE",l=t=>({type:r,payload:t}),d={panel:{},header:{},groupedItems:{},divider:{},iconButton:{},tabButton:{},selectButton:{},custom:{},floating:{},commandMenu:{}};function c(){const t=new Map;return{emit(e,n){const i=t.get(e);i&&i.forEach((t=>t(n)))},on(e,n){t.has(e)||t.set(e,new Set);return t.get(e).add(n),()=>this.off(e,n)},off(e,n){const i=t.get(e);i&&(i.delete(n),0===i.size&&t.delete(e))}}}function p(t,e){const n=t=>"function"==typeof t?t(e):t;return"group"===t.type?{...t,label:n(t.label)??""}:{...t,icon:n(t.icon)??"",iconProps:n(t.iconProps)??{},label:n(t.label)??"",visible:n(t.visible)??!0,active:n(t.active)??!1,disabled:n(t.disabled)??!1}}const u=class t{constructor(t={},e){this.registry={},this.shortcutMap={},this.eventController=c(),this.pluginRegistry=e,this.registerItems(t),this.setupKeyboardListeners()}get state(){return this.pluginRegistry.getStore().getState()}registerItem(t){this.registry[t.id]&&console.warn(`Menu item with ID ${t.id} already exists and will be overwritten`),this.registry[t.id]=t,"shortcut"in t&&t.shortcut&&(this.shortcutMap[this.normalizeShortcut(t.shortcut)]=t.id)}registerItems(t){Object.values(t).forEach((t=>{this.registerItem(t)}))}resolve(t){return p(this.registry[t],this.state)}getMenuItem(t){const e=this.resolve(t);if(e)return{item:e,isGroup:"group"===e.type,isMenu:"menu"===e.type,isAction:"action"===e.type}}getAction(t){const e=this.getMenuItem(t);if(e&&e.isAction)return e.item}getMenuOrAction(t){const e=this.getMenuItem(t);if(e)return e.item}getAllItems(){return{...this.registry}}getItemsByIds(t){return t.map((t=>this.resolve(t))).filter((t=>void 0!==t))}getChildItems(t,e={}){var n;const i=this.resolve(t);if(!i||!("children"in i)||!(null==(n=i.children)?void 0:n.length))return[];const o=this.getItemsByIds(i.children);if(!e.flatten)return o;const s=[];for(const r of o)if("group"===r.type)s.push(r);else if("menu"===r.type){const t=this.getChildItems(r.id,{flatten:!0});s.push(...t)}else s.push(r);return s}executeCommand(e,n={}){var i;const o=this.getMenuItem(e);if(!o)return void console.warn(`Menu item '${e}' not found`);if("group"===o.item.type)return void console.warn(`Cannot execute group '${e}'`);const{item:s}=o;s.disabled?console.warn(`Menu item '${e}' is disabled`):o.isAction?(s.action(this.pluginRegistry,this.state),this.eventController.emit(t.EVENTS.COMMAND_EXECUTED,{command:s,source:n.source||"api"})):"children"in s&&(null==(i=s.children)?void 0:i.length)&&this.handleSubmenu(s,n)}executeShortcut(e){const n=this.normalizeShortcut(e),i=this.shortcutMap[n];return!!i&&(this.executeCommand(i,{source:"shortcut"}),this.eventController.emit(t.EVENTS.SHORTCUT_EXECUTED,{shortcut:n,itemId:i}),!0)}on(t,e){return this.eventController.on(t,e)}off(t,e){this.eventController.off(t,e)}handleSubmenu(e,n){this.eventController.emit(t.EVENTS.MENU_REQUESTED,{menuId:e.id,triggerElement:n.triggerElement,position:n.position,flatten:n.flatten||!1})}setupKeyboardListeners(){if("undefined"==typeof window)return;document.addEventListener("keydown",(t=>{const e=t.target;if("INPUT"===e.tagName||"TEXTAREA"===e.tagName||e.isContentEditable)return;const n=this.buildShortcutString(t);n&&this.executeShortcut(n)&&t.preventDefault()}))}buildShortcutString(t){const e=[];t.ctrlKey&&e.push("Ctrl"),t.shiftKey&&e.push("Shift"),t.altKey&&e.push("Alt"),t.metaKey&&e.push("Meta");const n=t.key;if(!["Control","Shift","Alt","Meta"].includes(n)){const t=1===n.length?n.toUpperCase():n;return[...e,t].join("+")}return null}normalizeShortcut(t){return t.split("+").map((t=>t.trim())).join("+")}capabilities(){return{registerItem:this.registerItem.bind(this),registerItems:this.registerItems.bind(this),executeCommand:this.executeCommand.bind(this),getAction:this.getAction.bind(this),getMenuOrAction:this.getMenuOrAction.bind(this),getChildItems:this.getChildItems.bind(this),getItemsByIds:this.getItemsByIds.bind(this),getAllItems:this.getAllItems.bind(this)}}};u.EVENTS={COMMAND_EXECUTED:"menu:command_executed",MENU_REQUESTED:"menu:requested",SHORTCUT_EXECUTED:"menu:shortcut_executed"};let h=u;const m=class extends t.BasePlugin{constructor(t,e,n){super(t,e),this.componentRenderers={},this.components={},this.mapStateCallbacks={},this.globalStoreSubscription=()=>{},this.config=n,this.menuManager=new h(n.menuItems||{},this.registry),this.setupCommandEventHandlers(),this.globalStoreSubscription=this.registry.getStore().subscribe(((t,e)=>{this.onGlobalStoreChange(e)}))}async initialize(){this.buildComponents(),this.linkGroupedItems(),this.setInitialStateUIComponents()}setupCommandEventHandlers(){this.menuManager.on(h.EVENTS.MENU_REQUESTED,(t=>{var e;const{menuId:n,triggerElement:i,position:o,flatten:r}=t;if((null==(e=this.state.commandMenu.commandMenu)?void 0:e.activeCommand)===n)return this.dispatch(l({id:"commandMenu"}));this.dispatch({type:s,payload:{id:"commandMenu",commandId:n,triggerElement:i,position:o,flatten:r}})})),this.menuManager.on(h.EVENTS.COMMAND_EXECUTED,(t=>{this.logger.debug("UIPlugin","CommandExecuted",`Command executed: ${t.command.id}`,{commandId:t.command.id,source:t.source})}))}addComponent(t,n){this.components[t]&&this.logger.warn("UIPlugin","ComponentAlreadyExists",`Component with ID ${t} already exists and will be overwritten`);const i=new e(n,this.componentRenderers);return this.components[t]=i,"function"==typeof n.mapStateToProps&&(this.mapStateCallbacks[t]=n.mapStateToProps),i}buildComponents(){Object.entries(this.config.components).forEach((([t,e])=>{this.addComponent(t,e)}))}linkGroupedItems(){Object.values(this.components).forEach((t=>{var e;if(f(t)){const n=t.componentConfig;null==(e=n.slots)||e.forEach((e=>{const i=this.components[e.componentId];i?t.addChild(e.componentId,i,e.priority,e.className):this.logger.warn("UIPlugin","ChildComponentNotFound",`Child component ${e.componentId} not found for GroupedItems ${n.id}`)}))}}))}setInitialStateUIComponents(){const t=d;Object.entries(this.config.components).forEach((([e,n])=>{n.initialState?t[n.type][e]=n.initialState:t[n.type][e]={}})),this.dispatch({type:n,payload:t})}onGlobalStoreChange(e){for(const[n,i]of Object.entries(this.components)){const o=this.mapStateCallbacks[n];if(!o)continue;const{id:s,...r}=i.props,a=o(e,r),l={...r,...a};t.arePropsEqual(r,l)||i.update(a)}}addSlot(t,e,n,i){const o=this.components[t];if(!o)return void this.logger.error("UIPlugin","ParentComponentNotFound",`Parent component ${t} not found`);if(!f(o))return void this.logger.error("UIPlugin","ParentComponentDoesNotSupportSlots",`Parent component ${t} does not support slots`);const s=this.components[e];if(!s)return void this.logger.error("UIPlugin","ChildComponentNotFound",`Child component ${e} not found`);const r=o.getChildren();let a=n;if(void 0===a){a=(r.length>0?Math.max(...r.map((t=>t.priority))):0)+10}o.addChild(e,s,a,i)}buildCapability(){return{registerComponentRenderer:(t,e)=>{this.componentRenderers[t]=e},getComponent:t=>this.components[t],registerComponent:this.addComponent.bind(this),getCommandMenu:()=>Object.values(this.components).find((t=>function(t){return"commandMenu"===t.type}(t))),hideCommandMenu:()=>this.cooldownDispatch(l({id:"commandMenu"}),100),getFloatingComponents:t=>Object.values(this.components).filter((t=>b(t))).filter((e=>!t||e.props.scrollerPosition===t)),getHeadersByPlacement:t=>Object.values(this.components).filter((t=>C(t))).filter((e=>e.props.placement===t)),getPanelsByLocation:t=>Object.values(this.components).filter((t=>y(t))).filter((e=>e.props.location===t)),addSlot:this.addSlot.bind(this),togglePanel:t=>{this.dispatch((t=>({type:o,payload:t}))(t))},setHeaderVisible:t=>{this.dispatch((t=>({type:i,payload:t}))(t))},updateComponentState:t=>{this.dispatch((t=>({type:a,payload:t}))(t))},...this.menuManager.capabilities()}}async destroy(){this.globalStoreSubscription(),this.components={},this.componentRenderers={},this.mapStateCallbacks={}}};m.id="ui";let g=m;function f(t){return function(t){return"groupedItems"===t.type}(t)||C(t)||y(t)||b(t)||function(t){return"custom"===t.type}(t)}function C(t){return"header"===t.type}function y(t){return"panel"===t.type}function b(t){return"floating"===t.type}const E="ui",I={id:E,name:"UI Plugin",version:"1.0.0",provides:["ui"],requires:[],optional:[],defaultConfig:{enabled:!0,components:{}}};const v={manifest:I,create:(t,e)=>new g(E,t,e),reducer:(t=d,e)=>{switch(e.type){case n:return{...t,...e.payload};case o:{const n=t.panel[e.payload.id]||{},{open:i,visibleChild:o}=e.payload,s=n.visibleChild;let r=n.open,a=n.visibleChild;return o===s?r=void 0!==i?i:!n.open:(a=o,r=!0),{...t,panel:{...t.panel,[e.payload.id]:{...n,open:r,visibleChild:a}}}}case i:return{...t,header:{...t.header,[e.payload.id]:{...t.header[e.payload.id],visible:e.payload.visible,visibleChild:e.payload.visibleChild}}};case s:return{...t,commandMenu:{...t.commandMenu,[e.payload.id]:{activeCommand:e.payload.commandId,triggerElement:e.payload.triggerElement,position:e.payload.position,open:!0,flatten:e.payload.flatten}}};case r:return{...t,commandMenu:{...t.commandMenu,[e.payload.id]:{...t.commandMenu[e.payload.id],open:!1,activeCommand:null,triggerElement:void 0,position:void 0,flatten:!1}}};case a:{const{componentType:n,componentId:i,patch:o}=e.payload;if(!t[n]||!t[n][i])return t;const s=t[n][i],r=Object.fromEntries(Object.entries(o).filter((([t])=>t in s)));return 0===Object.keys(r).length?t:{...t,[n]:{...t[n],[i]:{...s,...r}}}}default:return t}},initialState:d};exports.UIComponent=e,exports.UIPlugin=g,exports.UIPluginPackage=v,exports.UI_PLUGIN_ID=E,exports.createEventController=c,exports.defineComponent=function(){return t=>t},exports.getIconProps=function(t,e){const n=p(t,e);return"group"===n.type?{}:n.iconProps??{}},exports.hasActive=function(t){return"active"in t},exports.isActive=function(t,e){const n=p(t,e);return"group"!==n.type&&!!n.active},exports.isDisabled=function(t,e){const n=p(t,e);return"group"!==n.type&&!!n.disabled},exports.isVisible=function(t,e){const n=p(t,e);return"group"!==n.type&&!!n.visible},exports.manifest=I,exports.resolveMenuItem=p;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t="ui",n={id:t,name:"UI Plugin",version:"1.0.0",provides:["ui"],requires:["commands"],optional:["i18n"],defaultConfig:{enabled:!0,schema:{id:"empty",version:"1.0.0",toolbars:{},menus:{},panels:{},selectionMenus:{}}}},o="UI/INIT_STATE",s="UI/CLEANUP_STATE",i="UI/SET_ACTIVE_TOOLBAR",a="UI/CLOSE_TOOLBAR_SLOT",c="UI/SET_ACTIVE_PANEL",r="UI/CLOSE_PANEL_SLOT",l="UI/SET_PANEL_TAB",d="UI/OPEN_MODAL",u="UI/CLOSE_MODAL",h="UI/OPEN_MENU",m="UI/CLOSE_MENU",p="UI/CLOSE_ALL_MENUS",g="UI/SET_DISABLED_CATEGORIES",I=(e,t)=>({type:o,payload:{documentId:e,schema:t}}),f=e=>({type:s,payload:{documentId:e}}),b=(e,t,n,o)=>({type:i,payload:{documentId:e,placement:t,slot:n,toolbarId:o}}),y=(e,t,n)=>({type:a,payload:{documentId:e,placement:t,slot:n}}),v=(e,t,n,o,s)=>({type:c,payload:{documentId:e,placement:t,slot:n,panelId:o,activeTab:s}}),C=(e,t,n)=>({type:r,payload:{documentId:e,placement:t,slot:n}}),O=(e,t,n)=>({type:l,payload:{documentId:e,panelId:t,tabId:n}}),S=(e,t)=>({type:d,payload:{documentId:e,modalId:t}}),T=e=>({type:u,payload:{documentId:e}}),D=(e,t)=>({type:h,payload:{documentId:e,menuState:t}}),E=(e,t)=>({type:m,payload:{documentId:e,menuId:t}}),$=e=>({type:p,payload:{documentId:e}}),A=e=>({type:g,payload:{categories:e}});function M(e,t){return{...e,...t,toolbars:x(e.toolbars,t.toolbars),menus:L(e.menus,t.menus),panels:P(e.panels,t.panels)}}function x(e,t){if(!t)return e;const n={...e};for(const[o,s]of Object.entries(t))n[o]?n[o]={...n[o],...s,items:s.items??n[o].items,responsive:s.responsive??n[o].responsive}:n[o]=s;return n}function L(e,t){if(!t)return e;const n={...e};for(const[o,s]of Object.entries(t))n[o]?n[o]={...n[o],...s,items:s.items??n[o].items}:n[o]=s;return n}function P(e,t){if(!t)return e;const n={...e};for(const[o,s]of Object.entries(t))n[o]?n[o]={...n[o],...s,content:s.content??n[o].content}:n[o]=s;return n}function _(e,t){var n;if(!(null==(n=e.responsive)?void 0:n.breakpoints))return null;const o=function(e,t,n){if(!n||!(null==t?void 0:t.groups))return e;const o=t.groups.find(e=>e.locales.includes(n));if(!o)return e;const s={};for(const[i,a]of Object.entries(e)){const e=o.breakpoints[i];e?s[i]={minWidth:a.minWidth,maxWidth:a.maxWidth,hide:e.replaceHide?e.replaceHide:[...a.hide||[],...e.hide||[]],show:e.replaceShow?e.replaceShow:[...a.show||[],...e.show||[]]}:s[i]=a}return s}(e.responsive.breakpoints,e.responsive.localeOverrides,t),s=new Map,i=new Map;for(const[r,l]of Object.entries(o))i.set(r,{minWidth:l.minWidth,maxWidth:l.maxWidth});const a=new Set,c=e=>{e.forEach(e=>{a.add(e.id),"group"===e.type&&e.items&&c(e.items),"tab-group"===e.type&&e.tabs&&c(e.tabs),"section"===e.type&&e.items&&c(e.items)})};c(e.items);for(const r of a){const e=[];let t=!0;Array.from(Object.entries(o)).sort((e,t)=>(e[1].minWidth??0)-(t[1].minWidth??0)).forEach(([n,o],s)=>{var i,a;const c=null==(i=o.hide)?void 0:i.includes(r),l=null==(a=o.show)?void 0:a.includes(r);(c||l)&&(e.push({breakpointId:n,minWidth:o.minWidth,maxWidth:o.maxWidth,visible:l||!c,priority:s}),0===s&&(t=l||!c))}),e.length>0&&s.set(r,{itemId:r,shouldRender:!0,visibilityRules:e,defaultVisible:t})}return{items:s,breakpoints:i}}const F={ROOT:"data-epdf",STYLES:"data-epdf-s",ITEM:"data-epdf-i",CATEGORIES:"data-epdf-cat",DISABLED_CATEGORIES:"data-epdf-dis"},U={ROOT:`[${F.ROOT}]`,STYLES:`[${F.STYLES}]`,ITEM:e=>`[${F.ITEM}="${e}"]`,CATEGORIES:e=>`[${F.CATEGORIES}~="${e}"]`,DISABLED_CATEGORY:e=>`[${F.DISABLED_CATEGORIES}~="${e}"]`},w={useContainerQueries:!0};function R(e,t={}){const n={...w,...t.config},o=t.locale,s=W(e,o),i=[];i.push(function(e){const t=e?` (locale: ${e})`:"";return`/* ═══════════════════════════════════════════════════════════════════════════ */\n/* EmbedPDF UI Stylesheet - Auto-generated${t} */\n/* DO NOT EDIT MANUALLY - This file is generated from your UI schema */\n/* ═══════════════════════════════════════════════════════════════════════════ */`}(o));const a=function(e,t){const n=[],o=t.useContainerQueries?"@container":"@media",s=new Set;return e.responsiveItems.forEach((e,t)=>{if(s.has(t))return;s.add(t);const i=function(e,t,n){if(0===t.visibilityRules.length)return null;const o=[],s=U.ITEM(e);t.defaultVisible||o.push(`${s} { display: none; }`);for(const i of t.visibilityRules){const e=[];if(void 0!==i.minWidth&&e.push(`(min-width: ${i.minWidth}px)`),void 0!==i.maxWidth&&e.push(`(max-width: ${i.maxWidth}px)`),e.length>0){const t=i.visible?"flex":"none";o.push(`${n} ${e.join(" and ")} {\n ${s} { display: ${t}; }\n}`)}}return o.length>0?o.join("\n"):null}(t,e,o);i&&n.push(i)}),0===n.length?"":`/* ─── Responsive Visibility Rules ─── */\n/* Items show/hide based on container width */\n\n${n.join("\n\n")}`}(s,n);a&&i.push(a);const c=function(e){if(0===e.categories.size)return"";const t=[],n=Array.from(e.categories).sort();for(const o of n)t.push(`${U.ROOT}[${F.DISABLED_CATEGORIES}~="${o}"] [${F.CATEGORIES}~="${o}"] {\n display: none !important;\n}`);return`/* ─── Category Visibility Rules ─── */\n/* Items hide when ANY of their categories is disabled */\n/* Use: data-disabled-categories="category1 category2" on root element */\n\n${t.join("\n\n")}`}(s);c&&i.push(c);const r=function(e,t){if(0===e.dependencies.length)return"";const n=[],o=t.useContainerQueries?"@container":"@media";for(const s of e.dependencies){const t=J(s,e,o);t.length>0&&n.push(...t)}return 0===n.length?"":`/* ─── Dependency Visibility Rules ─── */\n/* Container elements hide when all their dependencies are hidden */\n\n${n.join("\n\n")}`}(s,n);return r&&i.push(r),i.filter(e=>e.trim()).join("\n\n")}function W(e,t){const n=new Set,o=new Map,s=[],i=new Map,a=new Map;for(const[c,r]of Object.entries(e.menus))j(c,r,n,o,s,i,a,t);for(const[c,r]of Object.entries(e.toolbars))k(c,r,n,o,s,a,t);for(const[c,r]of Object.entries(e.panels))z(c,r,n,o,s);for(const[c,r]of Object.entries(e.selectionMenus||{}))Q(c,r,n,o,s,a,t);return{categories:n,itemCategories:o,dependencies:s,menuBreakpoints:i,responsiveItems:a}}function j(e,t,n,o,s,i,a,c){H(e,t.categories,t.visibilityDependsOn,n,o,s),N(t.items,n,o,s);const r=_(t,c);r&&r.items.forEach((e,t)=>{a.set(t,e)});const l=function(e,t,n){var o;const s=[],i=_(e,n);if((null==(o=e.responsive)?void 0:o.breakpoints)&&i){const e=Array.from(i.breakpoints.entries()).sort((e,t)=>(e[1].minWidth??0)-(t[1].minWidth??0));for(const[n,o]of e){const e=G(i,o),n=new Set;for(const o of e){const e=t.get(o);e&&e.forEach(e=>n.add(e))}s.push({minWidth:o.minWidth,maxWidth:o.maxWidth,visibleCategories:n})}}else{const n=new Set;B(e.items,t,n),s.push({visibleCategories:n})}return s}(t,o,c);i.set(e,l)}function N(e,t,n,o){for(const s of e)H(s.id,s.categories,s.visibilityDependsOn,t,n,o),"section"===s.type&&N(s.items,t,n,o)}function B(e,t,n){for(const o of e){const e=t.get(o.id);e&&e.forEach(e=>n.add(e)),"section"===o.type&&B(o.items,t,n)}}function G(e,t){const n=[];return e.items.forEach((e,o)=>{let s=e.defaultVisible;for(const n of e.visibilityRules){(void 0===n.minWidth||void 0!==t.minWidth&&t.minWidth>=n.minWidth)&&(void 0===n.maxWidth||void 0!==t.maxWidth&&t.maxWidth<=n.maxWidth)&&(s=n.visible)}s&&n.push(o)}),n}function k(e,t,n,o,s,i,a){H(e,t.categories,t.visibilityDependsOn,n,o,s);const c=_(t,a);c&&c.items.forEach((e,t)=>{i.set(t,e)}),V(t.items,n,o,s)}function V(e,t,n,o){for(const s of e)H(s.id,s.categories,s.visibilityDependsOn,t,n,o),"group"===s.type&&s.items&&V(s.items,t,n,o),"tab-group"===s.type&&s.tabs&&Y(s.tabs,t,n,o)}function Y(e,t,n,o){for(const s of e)H(s.id,s.categories,s.visibilityDependsOn,t,n,o)}function z(e,t,n,o,s){if(H(e,t.categories,t.visibilityDependsOn,n,o,s),"tabs"===t.content.type)for(const i of t.content.tabs)H(i.id,i.categories,i.visibilityDependsOn,n,o,s)}function Q(e,t,n,o,s,i,a){if(H(e,t.categories,t.visibilityDependsOn,n,o,s),t.responsive){const e=_(t,a);e&&e.items.forEach((e,t)=>{i.set(t,e)})}q(t.items,n,o,s)}function q(e,t,n,o){for(const s of e)H(s.id,s.categories,s.visibilityDependsOn,t,n,o),"group"===s.type&&s.items&&q(s.items,t,n,o)}function H(e,t,n,o,s,i){var a;(null==t?void 0:t.length)&&(t.forEach(e=>o.add(e)),s.set(e,t)),n&&(n.menuId||(null==(a=n.itemIds)?void 0:a.length))&&i.push({itemId:e,dependsOnMenuId:n.menuId,dependsOnItemIds:n.itemIds})}function J(e,t,n,o){var s;const i=[];if(e.dependsOnMenuId){const o=t.menuBreakpoints.get(e.dependsOnMenuId);if(o&&o.length>0){i.push(`/* "${e.itemId}" depends on menu "${e.dependsOnMenuId}" */`);for(const t of o){if(0===t.visibleCategories.size)continue;const o=Array.from(t.visibleCategories).sort().map(e=>U.DISABLED_CATEGORY(e)).join(""),s=`${U.ROOT}${o} ${U.ITEM(e.itemId)} {\n display: none !important;\n}`,a=[];void 0!==t.minWidth&&a.push(`(min-width: ${t.minWidth}px)`),void 0!==t.maxWidth&&a.push(`(max-width: ${t.maxWidth}px)`),a.length>0?i.push(`${n} ${a.join(" and ")} {\n ${s}\n}`):i.push(s)}}}if(null==(s=e.dependsOnItemIds)?void 0:s.length){const n=new Set;for(const o of e.dependsOnItemIds){const e=t.itemCategories.get(o);e&&e.forEach(e=>n.add(e))}if(n.size>0){const t=Array.from(n).sort().map(e=>U.DISABLED_CATEGORY(e)).join("");i.push(`/* "${e.itemId}" depends on items: ${e.dependsOnItemIds.join(", ")} */\n${U.ROOT}${t} ${U.ITEM(e.itemId)} {\n display: none !important;\n}`)}}return i}const K=class extends e.BasePlugin{constructor(t,n,o){var s,i;super(t,n),this.cachedStylesheet=null,this.cachedLocale=null,this.i18n=null,this.i18nCleanup=null,this.categoryChanged$=e.createBehaviorEmitter(),this.stylesheetInvalidated$=e.createEmitter(),this.toolbarChanged$=e.createScopedEmitter((e,t)=>({documentId:e,...t}),{cache:!1}),this.panelChanged$=e.createScopedEmitter((e,t)=>({documentId:e,...t}),{cache:!1}),this.modalChanged$=e.createScopedEmitter((e,t)=>({documentId:e,...t}),{cache:!1}),this.menuChanged$=e.createScopedEmitter((e,t)=>({documentId:e,...t}),{cache:!1}),this.schema=o.schema,this.stylesheetConfig=o.stylesheetConfig||{},(null==(s=o.disabledCategories)?void 0:s.length)&&this.dispatch(A(o.disabledCategories)),this.i18n=(null==(i=n.getPlugin("i18n"))?void 0:i.provides())??null,this.i18n&&(this.i18nCleanup=this.i18n.onLocaleChange(({currentLocale:e})=>{this.handleLocaleChange(e)}),this.cachedLocale=this.i18n.getLocale())}async initialize(){this.logger.info("UIPlugin","Initialize","UI plugin initialized")}async destroy(){this.i18nCleanup&&(this.i18nCleanup(),this.i18nCleanup=null),this.toolbarChanged$.clear(),this.panelChanged$.clear(),this.modalChanged$.clear(),this.menuChanged$.clear(),this.stylesheetInvalidated$.clear(),super.destroy()}onDocumentLoadingStarted(e){this.dispatch(I(e,this.schema))}onDocumentClosed(e){this.dispatch(f(e)),this.toolbarChanged$.clearScope(e),this.panelChanged$.clearScope(e),this.modalChanged$.clearScope(e),this.menuChanged$.clearScope(e)}handleLocaleChange(e){this.cachedLocale!==e&&(this.logger.debug("UIPlugin","LocaleChange",`Locale changed: ${this.cachedLocale} -> ${e}`),this.cachedLocale=e,this.invalidateStylesheet(),this.stylesheetInvalidated$.emit())}getStylesheet(){var e;const t=(null==(e=this.i18n)?void 0:e.getLocale())??null;return this.cachedStylesheet&&this.cachedLocale===t||(this.cachedStylesheet=R(this.schema,{config:this.stylesheetConfig,locale:t??void 0}),this.cachedLocale=t),this.cachedStylesheet}getLocale(){var e;return(null==(e=this.i18n)?void 0:e.getLocale())??null}invalidateStylesheet(){this.cachedStylesheet=null}onStylesheetInvalidated(e){return this.stylesheetInvalidated$.on(e)}disableCategoryImpl(e){const t=new Set(this.state.disabledCategories);t.has(e)||(t.add(e),this.dispatch(A(Array.from(t))),this.categoryChanged$.emit({disabledCategories:Array.from(t)}))}enableCategoryImpl(e){const t=new Set(this.state.disabledCategories);t.has(e)&&(t.delete(e),this.dispatch(A(Array.from(t))),this.categoryChanged$.emit({disabledCategories:Array.from(t)}))}toggleCategoryImpl(e){this.state.disabledCategories.includes(e)?this.enableCategoryImpl(e):this.disableCategoryImpl(e)}setDisabledCategoriesImpl(e){this.dispatch(A(e)),this.categoryChanged$.emit({disabledCategories:e})}buildCapability(){return{setActiveToolbar:(e,t,n,o)=>this.setToolbarForDocument(e,t,n,o),setActivePanel:(e,t,n,o,s)=>this.setPanelForDocument(e,t,n,o,s),togglePanel:(e,t,n,o,s)=>this.togglePanelForDocument(e,t,n,o,s),openModal:(e,t)=>this.openModalForDocument(e,t),openMenu:(e,t,n,o)=>this.openMenuForDocument(e,t,n,o),toggleMenu:(e,t,n,o)=>this.toggleMenuForDocument(e,t,n,o),forDocument:e=>this.createUIScope(e),getSchema:()=>this.schema,mergeSchema:e=>{this.schema=M(this.schema,e)},disableCategory:e=>this.disableCategoryImpl(e),enableCategory:e=>this.enableCategoryImpl(e),toggleCategory:e=>this.toggleCategoryImpl(e),setDisabledCategories:e=>this.setDisabledCategoriesImpl(e),getDisabledCategories:()=>this.state.disabledCategories,isCategoryDisabled:e=>this.state.disabledCategories.includes(e),onToolbarChanged:this.toolbarChanged$.onGlobal,onPanelChanged:this.panelChanged$.onGlobal,onModalChanged:this.modalChanged$.onGlobal,onMenuChanged:this.menuChanged$.onGlobal,onCategoryChanged:this.categoryChanged$.on}}createUIScope(e){return{setActiveToolbar:(t,n,o)=>this.setToolbarForDocument(t,n,o,e),getActiveToolbar:(t,n)=>this.getToolbarForDocument(t,n,e),closeToolbarSlot:(t,n)=>this.closeToolbarForDocument(t,n,e),isToolbarOpen:(t,n,o)=>this.isToolbarOpenForDocument(t,n,o,e),setActivePanel:(t,n,o,s)=>this.setPanelForDocument(t,n,o,e,s),getActivePanel:(t,n)=>this.getPanelForDocument(t,n,e),closePanelSlot:(t,n)=>this.closePanelForDocument(t,n,e),togglePanel:(t,n,o,s)=>this.togglePanelForDocument(t,n,o,e,s),isPanelOpen:(t,n,o)=>this.isPanelOpenForDocument(t,n,o,e),setPanelTab:(t,n)=>this.setPanelTabForDocument(t,n,e),getPanelTab:t=>this.getPanelTabForDocument(t,e),openModal:t=>this.openModalForDocument(t,e),closeModal:()=>this.closeModalForDocument(e),getActiveModal:()=>this.getActiveModalForDocument(e),openMenu:(t,n,o)=>this.openMenuForDocument(t,n,o,e),closeMenu:t=>this.closeMenuForDocument(t,e),toggleMenu:(t,n,o)=>this.toggleMenuForDocument(t,n,o,e),closeAllMenus:()=>this.closeAllMenusForDocument(e),isMenuOpen:t=>this.isMenuOpenForDocument(t,e),getOpenMenus:()=>this.getOpenMenusForDocument(e),getSchema:()=>this.schema,getState:()=>this.getDocumentStateOrThrow(e),onToolbarChanged:this.toolbarChanged$.forScope(e),onPanelChanged:this.panelChanged$.forScope(e),onModalChanged:this.modalChanged$.forScope(e),onMenuChanged:this.menuChanged$.forScope(e)}}getDocumentState(e){const t=e??this.getActiveDocumentId();return this.state.documents[t]??null}getDocumentStateOrThrow(e){const t=this.getDocumentState(e);if(!t)throw new Error(`UI state not found for document: ${e??"active"}`);return t}setToolbarForDocument(e,t,n,o){const s=o??this.getActiveDocumentId();this.dispatch(b(s,e,t,n)),this.toolbarChanged$.emit(s,{placement:e,slot:t,toolbarId:n})}getToolbarForDocument(e,t,n){const o=`${e}-${t}`,s=this.getDocumentStateOrThrow(n).activeToolbars[o];return(null==s?void 0:s.isOpen)?s.toolbarId:null}closeToolbarForDocument(e,t,n){const o=n??this.getActiveDocumentId();this.dispatch(y(o,e,t)),this.toolbarChanged$.emit(o,{placement:e,slot:t,toolbarId:""})}isToolbarOpenForDocument(e,t,n,o){const s=`${e}-${t}`,i=this.getDocumentStateOrThrow(o).activeToolbars[s];return!(!i||!i.isOpen)&&(!n||i.toolbarId===n)}setPanelForDocument(e,t,n,o,s){const i=o??this.getActiveDocumentId();this.dispatch(v(i,e,t,n,s)),this.panelChanged$.emit(i,{placement:e,slot:t,panelId:n})}getPanelForDocument(e,t,n){const o=`${e}-${t}`,s=this.getDocumentStateOrThrow(n).activePanels[o];return(null==s?void 0:s.isOpen)?s.panelId:null}closePanelForDocument(e,t,n){const o=n??this.getActiveDocumentId();this.dispatch(C(o,e,t)),this.panelChanged$.emit(o,{placement:e,slot:t,panelId:""})}togglePanelForDocument(e,t,n,o,s){const i=o??this.getActiveDocumentId(),a=`${e}-${t}`,c=this.getDocumentStateOrThrow(i).activePanels[a];(null==c?void 0:c.panelId)===n&&(null==c?void 0:c.isOpen)?(this.dispatch(C(i,e,t)),this.panelChanged$.emit(i,{placement:e,slot:t,panelId:""})):(this.dispatch(v(i,e,t,n,s)),this.panelChanged$.emit(i,{placement:e,slot:t,panelId:n}))}isPanelOpenForDocument(e,t,n,o){const s=`${e}-${t}`,i=this.getDocumentStateOrThrow(o).activePanels[s];return!(!i||!i.isOpen)&&(!n||i.panelId===n)}setPanelTabForDocument(e,t,n){const o=n??this.getActiveDocumentId();this.dispatch(O(o,e,t))}getPanelTabForDocument(e,t){return this.getDocumentStateOrThrow(t).panelTabs[e]??null}openModalForDocument(e,t){const n=t??this.getActiveDocumentId();this.dispatch(S(n,e)),this.modalChanged$.emit(n,{modalId:e})}closeModalForDocument(e){const t=e??this.getActiveDocumentId();this.dispatch(T(t)),this.modalChanged$.emit(t,{modalId:null})}getActiveModalForDocument(e){return this.getDocumentStateOrThrow(e).activeModal}openMenuForDocument(e,t,n,o){const s=o??this.getActiveDocumentId();this.dispatch(D(s,{menuId:e,triggeredByCommandId:t,triggeredByItemId:n})),this.menuChanged$.emit(s,{menuId:e,isOpen:!0})}closeMenuForDocument(e,t){const n=t??this.getActiveDocumentId();this.dispatch(E(n,e)),this.menuChanged$.emit(n,{menuId:e,isOpen:!1})}toggleMenuForDocument(e,t,n,o){const s=o??this.getActiveDocumentId();!!this.getDocumentStateOrThrow(s).openMenus[e]?(this.dispatch(E(s,e)),this.menuChanged$.emit(s,{menuId:e,isOpen:!1})):(this.dispatch(D(s,{menuId:e,triggeredByCommandId:t,triggeredByItemId:n})),this.menuChanged$.emit(s,{menuId:e,isOpen:!0}))}closeAllMenusForDocument(e){const t=e??this.getActiveDocumentId();this.dispatch($(t))}isMenuOpenForDocument(e,t){return!!this.getDocumentStateOrThrow(t).openMenus[e]}getOpenMenusForDocument(e){return Object.values(this.getDocumentStateOrThrow(e).openMenus)}};K.id="ui";let X=K;const Z={activeToolbars:{},activePanels:{},activeModal:null,openMenus:{},panelTabs:{}},ee={documents:{},disabledCategories:[]};function te(e){return e.ui??null}function ne(e,t){const n=te(e);return(null==n?void 0:n.documents[t])??null}function oe(e,t){return`${e}-${t}`}function se(e,t,n,o){const s=ne(e,t);return s?s.activeToolbars[oe(n,o)]??null:null}function ie(e,t,n,o){const s=ne(e,t);return s?s.activePanels[oe(n,o)]??null:null}const ae={manifest:n,create:(e,n)=>new X(t,e,n),reducer:(e=ee,t)=>{switch(t.type){case o:{const{documentId:n,schema:o}=t.payload,s={};return Object.values(o.toolbars).forEach(e=>{if(e.permanent&&e.position){const t=`${e.position.placement}-${e.position.slot}`;s[t]={toolbarId:e.id,isOpen:!0}}}),{...e,documents:{...e.documents,[n]:{...Z,activeToolbars:s}}}}case s:{const{documentId:n}=t.payload,{[n]:o,...s}=e.documents;return{...e,documents:s}}case i:{const{documentId:n,placement:o,slot:s,toolbarId:i}=t.payload,a=e.documents[n]||Z,c=`${o}-${s}`;return{...e,documents:{...e.documents,[n]:{...a,activeToolbars:{...a.activeToolbars,[c]:{toolbarId:i,isOpen:!0}}}}}}case c:{const{documentId:n,placement:o,slot:s,panelId:i,activeTab:a}=t.payload,c=e.documents[n]||Z,r=`${o}-${s}`;return{...e,documents:{...e.documents,[n]:{...c,activePanels:{...c.activePanels,[r]:{panelId:i,isOpen:!0}},...a&&{panelTabs:{...c.panelTabs,[i]:a}}}}}}case r:{const{documentId:n,placement:o,slot:s}=t.payload,i=e.documents[n];if(!i)return e;const a=`${o}-${s}`,c=i.activePanels[a];return c?{...e,documents:{...e.documents,[n]:{...i,activePanels:{...i.activePanels,[a]:{...c,isOpen:!1}}}}}:e}case a:{const{documentId:n,placement:o,slot:s}=t.payload,i=e.documents[n];if(!i)return e;const a=`${o}-${s}`,c=i.activeToolbars[a];return c?{...e,documents:{...e.documents,[n]:{...i,activeToolbars:{...i.activeToolbars,[a]:{...c,isOpen:!1}}}}}:e}case l:{const{documentId:n,panelId:o,tabId:s}=t.payload,i=e.documents[n]||Z;return{...e,documents:{...e.documents,[n]:{...i,panelTabs:{...i.panelTabs,[o]:s}}}}}case d:{const{documentId:n,modalId:o}=t.payload,s=e.documents[n]||Z;return{...e,documents:{...e.documents,[n]:{...s,activeModal:o,openMenus:{}}}}}case u:{const{documentId:n}=t.payload,o=e.documents[n];return o?{...e,documents:{...e.documents,[n]:{...o,activeModal:null}}}:e}case h:{const{documentId:n,menuState:o}=t.payload,s=e.documents[n]||Z;return{...e,documents:{...e.documents,[n]:{...s,openMenus:{[o.menuId]:o}}}}}case m:{const{documentId:n,menuId:o}=t.payload,s=e.documents[n];if(!s)return e;const{[o]:i,...a}=s.openMenus;return{...e,documents:{...e.documents,[n]:{...s,openMenus:a}}}}case p:{const{documentId:n}=t.payload,o=e.documents[n];return o?{...e,documents:{...e.documents,[n]:{...o,openMenus:{}}}}:e}case g:return{...e,disabledCategories:t.payload.categories};default:return e}},initialState:ee};exports.CLEANUP_UI_STATE=s,exports.CLOSE_ALL_MENUS=p,exports.CLOSE_MENU=m,exports.CLOSE_MODAL=u,exports.CLOSE_PANEL_SLOT=r,exports.CLOSE_TOOLBAR_SLOT=a,exports.INIT_UI_STATE=o,exports.OPEN_MENU=h,exports.OPEN_MODAL=d,exports.SET_ACTIVE_PANEL=c,exports.SET_ACTIVE_TOOLBAR=i,exports.SET_DISABLED_CATEGORIES=g,exports.SET_PANEL_TAB=l,exports.UIPlugin=X,exports.UIPluginPackage=ae,exports.UI_ATTRIBUTES=F,exports.UI_PLUGIN_ID=t,exports.UI_SELECTORS=U,exports.cleanupUIState=f,exports.closeAllMenus=$,exports.closeMenu=E,exports.closeModal=T,exports.closePanelSlot=C,exports.closeToolbarSlot=y,exports.extractCategories=function(e){const t=W(e);return Array.from(t.categories).sort()},exports.generateUIStylesheet=R,exports.getItemResponsiveMetadata=function(e,t,n){const o=_(t,n);return(null==o?void 0:o.items.get(e))??null},exports.getStylesheetConfig=function(e={}){return{...w,...e}},exports.getUIItemProps=function(e,t){var n;return{[F.ITEM]:e.id,[F.CATEGORIES]:(null==(n=e.categories)?void 0:n.join(" "))||void 0,...t}},exports.initUIState=I,exports.isPanelOpen=function(e,t,n,o,s){const i=ie(e,t,n,o);return!(!i||!i.isOpen)&&(!s||i.panelId===s)},exports.isToolbarOpen=function(e,t,n,o,s){const i=se(e,t,n,o);return!(!i||!i.isOpen)&&(!s||i.toolbarId===s)},exports.manifest=n,exports.mergeUISchema=M,exports.openMenu=D,exports.openModal=S,exports.removeFromSchema=function(e,t){const n={...e};return t.toolbars&&(n.toolbars={...n.toolbars},t.toolbars.forEach(e=>delete n.toolbars[e])),t.menus&&(n.menus={...n.menus},t.menus.forEach(e=>delete n.menus[e])),t.panels&&(n.panels={...n.panels},t.panels.forEach(e=>delete n.panels[e])),t.commands&&(n.toolbars=function(e,t){const n={};for(const[o,s]of Object.entries(e))n[o]={...s,items:s.items.filter(e=>"command-button"===e.type?!t.includes(e.commandId):"group"===e.type?e.items.some(e=>"command-button"!==e.type||!t.includes(e.commandId)):"tab-group"!==e.type||e.tabs.some(e=>!t.includes(e.commandId)))};return n}(n.toolbars,t.commands),n.menus=function(e,t){const n={};for(const[o,s]of Object.entries(e))n[o]={...s,items:s.items.filter(e=>"command"===e.type?!t.includes(e.commandId):"section"!==e.type||e.items.some(e=>"command"!==e.type||!t.includes(e.commandId)))};return n}(n.menus,t.commands)),n},exports.resolveResponsiveMetadata=_,exports.selectPanelSlot=ie,exports.selectToolbarSlot=se,exports.selectUIDocumentState=ne,exports.selectUIState=te,exports.setActivePanel=v,exports.setActiveToolbar=b,exports.setDisabledCategories=A,exports.setPanelTab=O;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/lib/ui-component.ts","../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/utils.ts","../src/lib/menu/utils.ts","../src/lib/menu/menu-manager.ts","../src/lib/ui-plugin.ts","../src/lib/manifest.ts","../src/lib/index.ts","../src/lib/menu/types.ts"],"sourcesContent":["import { BaseUIComponent, childrenFunctionOptions } from './types';\n\nexport class UIComponent<T extends BaseUIComponent<any, any, any>> {\n public componentConfig: T;\n public props: T['id'] extends string\n ? T extends BaseUIComponent<infer P, any, any>\n ? P & { id: string }\n : any\n : any;\n public type: string;\n private children: Array<{\n id: string;\n component: UIComponent<any>;\n priority: number;\n className?: string;\n }> = [];\n private registry: Record<\n string,\n (\n props: any,\n children: (options?: childrenFunctionOptions) => any[],\n context?: Record<string, any>,\n ) => any\n >;\n private updateCallbacks: (() => void)[] = [];\n private hadUpdateBeforeListeners = false;\n\n constructor(\n componentConfig: T,\n registry: Record<\n string,\n (\n props: any,\n children: (options?: childrenFunctionOptions) => any[],\n context?: Record<string, any>,\n ) => any\n >,\n ) {\n this.componentConfig = componentConfig;\n\n const props = componentConfig.props || {};\n\n if (typeof props === 'function') {\n const initialProps = props(componentConfig.initialState);\n this.props = { ...initialProps, id: componentConfig.id };\n } else {\n this.props = { ...props, id: componentConfig.id };\n }\n\n this.type = componentConfig.type;\n this.registry = registry;\n }\n\n addChild(id: string, child: UIComponent<any>, priority: number = 0, className?: string) {\n this.children.push({ id, component: child, priority, className });\n // Sort children by priority\n this.sortChildren();\n }\n\n // Helper to sort children by priority\n private sortChildren() {\n this.children.sort((a, b) => a.priority - b.priority);\n }\n\n removeChild(child: UIComponent<any>) {\n this.children = this.children.filter((c) => c.component !== child);\n }\n\n clearChildren() {\n this.children = [];\n }\n\n get getRenderType() {\n return this.componentConfig.render || this.type;\n }\n\n public getRenderer() {\n return this.registry[this.getRenderType];\n }\n\n public getChildren() {\n return this.children;\n }\n\n // Optionally, a component can provide a function to extend the context for its children.\n // For instance, a header could supply a \"direction\" based on its position.\n public getChildContext(context: Record<string, any>): Record<string, any> {\n const childContextProp = this.componentConfig.getChildContext;\n if (typeof childContextProp === 'function') {\n // Handle function case (existing behavior)\n return { ...context, ...childContextProp(this.props) };\n } else if (childContextProp && typeof childContextProp === 'object') {\n // Handle object case\n return { ...context, ...childContextProp };\n }\n return context;\n }\n\n update(newProps: Partial<T extends BaseUIComponent<infer P, any, any> ? P : any>) {\n const { id, ...otherProps } = newProps;\n this.props = { ...this.props, ...otherProps };\n if (this.updateCallbacks.length === 0) {\n this.hadUpdateBeforeListeners = true;\n }\n this.notifyUpdate();\n }\n\n onUpdate(callback: () => void) {\n this.updateCallbacks.push(callback);\n return this.hadUpdateBeforeListeners;\n }\n\n offUpdate(callback: () => void) {\n this.updateCallbacks = this.updateCallbacks.filter((cb) => cb !== callback);\n }\n\n protected notifyUpdate() {\n this.updateCallbacks.forEach((cb) => cb());\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { UIPluginState } from './types';\n\nexport const UI_INIT_COMPONENTS = 'UI_INIT_COMPONENTS';\nexport const UI_INIT_FLYOUT = 'UI_INIT_FLYOUT';\nexport const UI_TOGGLE_FLYOUT = 'UI_TOGGLE_FLYOUT';\nexport const UI_SET_HEADER_VISIBLE = 'UI_SET_HEADER_VISIBLE';\nexport const UI_TOGGLE_PANEL = 'UI_TOGGLE_PANEL';\nexport const UI_SHOW_COMMAND_MENU = 'UI_SHOW_COMMAND_MENU';\nexport const UI_HIDE_COMMAND_MENU = 'UI_HIDE_COMMAND_MENU';\nexport const UI_UPDATE_COMMAND_MENU = 'UI_UPDATE_COMMAND_MENU';\nexport const UI_UPDATE_COMPONENT_STATE = 'UI_UPDATE_COMPONENT_STATE';\n\nexport interface InitFlyoutPayload {\n id: string;\n triggerElement: HTMLElement;\n}\n\nexport interface ToggleFlyoutPayload {\n id: string;\n open?: boolean;\n}\n\nexport interface SetHeaderVisiblePayload {\n id: string;\n visible: boolean;\n visibleChild?: string;\n}\n\nexport interface TogglePanelPayload {\n id: string;\n open?: boolean;\n visibleChild: string;\n}\n\nexport interface ShowCommandMenuPayload {\n id: string;\n commandId: string;\n triggerElement?: HTMLElement;\n position?: 'top' | 'bottom' | 'left' | 'right';\n flatten?: boolean;\n}\n\nexport interface UpdateComponentStatePayload<T = any> {\n /** one of the top-level keys inside UIPluginState, e.g. \"panel\" | \"custom\" … */\n componentType: keyof UIPluginState;\n /** same id you used when registering the component */\n componentId: string;\n /** partial patch – only keys existing in the current state will be applied */\n patch: Partial<T>;\n}\n\nexport interface HideCommandMenuPayload {\n id: string;\n}\n\nexport interface UiInitComponentsAction extends Action {\n type: typeof UI_INIT_COMPONENTS;\n payload: UIPluginState;\n}\n\nexport interface UiInitFlyoutAction extends Action {\n type: typeof UI_INIT_FLYOUT;\n payload: InitFlyoutPayload;\n}\n\nexport interface UiToggleFlyoutAction extends Action {\n type: typeof UI_TOGGLE_FLYOUT;\n payload: ToggleFlyoutPayload;\n}\n\nexport interface UiSetHeaderVisibleAction extends Action {\n type: typeof UI_SET_HEADER_VISIBLE;\n payload: SetHeaderVisiblePayload;\n}\n\nexport interface UiTogglePanelAction extends Action {\n type: typeof UI_TOGGLE_PANEL;\n payload: TogglePanelPayload;\n}\n\nexport interface UiShowCommandMenuAction extends Action {\n type: typeof UI_SHOW_COMMAND_MENU;\n payload: ShowCommandMenuPayload;\n}\n\nexport interface UiHideCommandMenuAction extends Action {\n type: typeof UI_HIDE_COMMAND_MENU;\n payload: HideCommandMenuPayload;\n}\n\nexport interface UiUpdateComponentStateAction extends Action {\n type: typeof UI_UPDATE_COMPONENT_STATE;\n payload: UpdateComponentStatePayload;\n}\n\nexport type UIPluginAction =\n | UiInitComponentsAction\n | UiInitFlyoutAction\n | UiToggleFlyoutAction\n | UiSetHeaderVisibleAction\n | UiTogglePanelAction\n | UiShowCommandMenuAction\n | UiHideCommandMenuAction\n | UiUpdateComponentStateAction;\n\nexport const uiInitComponents = (state: UIPluginState): UiInitComponentsAction => ({\n type: UI_INIT_COMPONENTS,\n payload: state,\n});\n\nexport const uiInitFlyout = (payload: InitFlyoutPayload): UiInitFlyoutAction => ({\n type: UI_INIT_FLYOUT,\n payload,\n});\n\nexport const uiToggleFlyout = (payload: ToggleFlyoutPayload): UiToggleFlyoutAction => ({\n type: UI_TOGGLE_FLYOUT,\n payload,\n});\n\nexport const uiTogglePanel = (payload: TogglePanelPayload): UiTogglePanelAction => ({\n type: UI_TOGGLE_PANEL,\n payload,\n});\n\nexport const uiSetHeaderVisible = (payload: SetHeaderVisiblePayload): UiSetHeaderVisibleAction => ({\n type: UI_SET_HEADER_VISIBLE,\n payload,\n});\n\nexport const uiShowCommandMenu = (payload: ShowCommandMenuPayload): UiShowCommandMenuAction => ({\n type: UI_SHOW_COMMAND_MENU,\n payload,\n});\n\nexport const uiHideCommandMenu = (payload: HideCommandMenuPayload): UiHideCommandMenuAction => ({\n type: UI_HIDE_COMMAND_MENU,\n payload,\n});\n\nexport const uiUpdateComponentState = <T>(\n payload: UpdateComponentStatePayload<T>,\n): UiUpdateComponentStateAction => ({\n type: UI_UPDATE_COMPONENT_STATE,\n payload,\n});\n","import { Reducer } from '@embedpdf/core';\nimport { UIPluginState } from './types';\nimport {\n UI_HIDE_COMMAND_MENU,\n UI_INIT_COMPONENTS,\n UI_SET_HEADER_VISIBLE,\n UI_SHOW_COMMAND_MENU,\n UI_TOGGLE_PANEL,\n UI_UPDATE_COMPONENT_STATE,\n UIPluginAction,\n} from './actions';\n\nexport const initialState: UIPluginState = {\n panel: {},\n header: {},\n groupedItems: {},\n divider: {},\n iconButton: {},\n tabButton: {},\n selectButton: {},\n custom: {},\n floating: {},\n commandMenu: {},\n};\n\nexport const uiReducer: Reducer<UIPluginState, UIPluginAction> = (state = initialState, action) => {\n switch (action.type) {\n case UI_INIT_COMPONENTS:\n return {\n ...state,\n ...action.payload,\n };\n case UI_TOGGLE_PANEL: {\n const prevPanel = state.panel[action.payload.id] || {};\n const { open: nextOpen, visibleChild: nextVisibleChild } = action.payload;\n const prevVisibleChild = prevPanel.visibleChild;\n\n let open = prevPanel.open;\n let visibleChild = prevPanel.visibleChild;\n\n if (nextVisibleChild === prevVisibleChild) {\n // Toggle open if visibleChild is the same\n open = nextOpen !== undefined ? nextOpen : !prevPanel.open;\n } else {\n // Only change visibleChild, keep open as is\n visibleChild = nextVisibleChild;\n open = true;\n }\n\n return {\n ...state,\n panel: {\n ...state.panel,\n [action.payload.id]: {\n ...prevPanel,\n open,\n visibleChild,\n },\n },\n };\n }\n case UI_SET_HEADER_VISIBLE:\n return {\n ...state,\n header: {\n ...state.header,\n [action.payload.id]: {\n ...state.header[action.payload.id],\n visible: action.payload.visible,\n visibleChild: action.payload.visibleChild,\n },\n },\n };\n case UI_SHOW_COMMAND_MENU:\n return {\n ...state,\n commandMenu: {\n ...state.commandMenu,\n [action.payload.id]: {\n activeCommand: action.payload.commandId,\n triggerElement: action.payload.triggerElement,\n position: action.payload.position,\n open: true,\n flatten: action.payload.flatten,\n },\n },\n };\n case UI_HIDE_COMMAND_MENU:\n return {\n ...state,\n commandMenu: {\n ...state.commandMenu,\n [action.payload.id]: {\n ...state.commandMenu[action.payload.id],\n open: false,\n activeCommand: null,\n triggerElement: undefined,\n position: undefined,\n flatten: false,\n },\n },\n };\n case UI_UPDATE_COMPONENT_STATE: {\n const { componentType, componentId, patch } = action.payload;\n\n // if the slice or the component is unknown → ignore\n if (!state[componentType] || !state[componentType][componentId]) return state;\n\n const current = state[componentType][componentId] as Record<string, any>;\n\n // keep only keys that already exist\n const filteredPatch = Object.fromEntries(Object.entries(patch).filter(([k]) => k in current));\n\n // no allowed keys? -> no-op\n if (Object.keys(filteredPatch).length === 0) return state;\n\n return {\n ...state,\n [componentType]: {\n ...state[componentType],\n [componentId]: {\n ...current,\n ...filteredPatch,\n },\n },\n };\n }\n default:\n return state;\n }\n};\n","import type { CustomComponent } from './types';\n\nexport function defineComponent<TInit, TProps, TStore = any>() {\n return <\n C extends CustomComponent<TStore> & {\n initialState: TInit;\n props: (init: TInit) => TProps;\n mapStateToProps: (storeState: TStore, ownProps: TProps) => TProps;\n },\n >(\n c: C,\n ) => c;\n}\n\n/**\n * Type definition for event callbacks\n */\nexport type EventCallback = (data: any) => void;\n\n/**\n * Interface for the event controller\n */\nexport interface EventController {\n /**\n * Emit an event of the specified type with the given data\n */\n emit(eventType: string, data: any): void;\n\n /**\n * Subscribe to events of the specified type\n * Returns a function that can be called to unsubscribe\n */\n on(eventType: string, callback: EventCallback): () => void;\n\n /**\n * Unsubscribe a specific callback from events of the specified type\n */\n off(eventType: string, callback: EventCallback): void;\n}\n\n/**\n * Creates an event controller that manages event subscriptions and dispatching\n * This is a lightweight pub/sub implementation for typed events\n */\nexport function createEventController(): EventController {\n // Map of event types to sets of callbacks\n const eventMap = new Map<string, Set<EventCallback>>();\n\n return {\n emit(eventType: string, data: any): void {\n const callbacks = eventMap.get(eventType);\n if (callbacks) {\n // Call each callback with the event data\n callbacks.forEach((callback) => callback(data));\n }\n },\n\n on(eventType: string, callback: EventCallback): () => void {\n // Create a set for this event type if it doesn't exist\n if (!eventMap.has(eventType)) {\n eventMap.set(eventType, new Set());\n }\n\n // Add the callback to the set\n const callbacks = eventMap.get(eventType)!;\n callbacks.add(callback);\n\n // Return a function that removes this specific callback\n return () => this.off(eventType, callback);\n },\n\n off(eventType: string, callback: EventCallback): void {\n const callbacks = eventMap.get(eventType);\n if (callbacks) {\n // Remove the callback from the set\n callbacks.delete(callback);\n\n // Clean up empty sets\n if (callbacks.size === 0) {\n eventMap.delete(eventType);\n }\n }\n },\n };\n}\n","import { MenuItem, Dynamic, ResolvedMenuItem } from './types';\n\nexport function resolveMenuItem<TStore>(\n item: MenuItem<TStore>,\n state: TStore,\n): ResolvedMenuItem<TStore> {\n const dyn = <T>(v: Dynamic<TStore, T> | undefined): T | undefined =>\n typeof v === 'function' ? (v as any)(state) : v;\n\n if (item.type === 'group') {\n return {\n ...item,\n label: dyn(item.label) ?? '',\n };\n }\n\n // spread keeps unknown keys (e.g. children) intact\n return {\n ...item,\n icon: dyn(item.icon) ?? '',\n iconProps: dyn(item.iconProps) ?? {},\n label: dyn(item.label) ?? '',\n visible: dyn(item.visible) ?? true,\n active: dyn(item.active) ?? false,\n disabled: dyn(item.disabled) ?? false,\n };\n}\n\nexport function isActive<TStore>(item: MenuItem<TStore>, state: TStore): boolean {\n const resolved = resolveMenuItem(item, state);\n\n if (resolved.type === 'group') {\n return false;\n }\n\n return resolved.active ? true : false;\n}\n\nexport function isVisible<TStore>(item: MenuItem<TStore>, state: TStore): boolean {\n const resolved = resolveMenuItem(item, state);\n\n if (resolved.type === 'group') {\n return false;\n }\n\n return resolved.visible ? true : false;\n}\n\nexport function isDisabled<TStore>(item: MenuItem<TStore>, state: TStore): boolean {\n const resolved = resolveMenuItem(item, state);\n\n if (resolved.type === 'group') {\n return false;\n }\n\n return resolved.disabled ? true : false;\n}\n\nexport function getIconProps<TStore>(item: MenuItem<TStore>, state: TStore): any {\n const resolved = resolveMenuItem(item, state);\n if (resolved.type === 'group') {\n return {};\n }\n return resolved.iconProps ?? {};\n}\n","import { PluginRegistry } from '@embedpdf/core';\nimport {\n MenuItem,\n Action,\n ExecuteOptions,\n ResolvedMenuItem,\n MenuRegistry,\n Menu,\n MenuManagerCapabilities,\n ResolvedMenuItemResult,\n ResolvedMenu,\n ResolvedAction,\n} from './types';\nimport { EventCallback, createEventController } from '../utils';\nimport { resolveMenuItem } from './utils';\n\n/**\n * MenuManager manages a registry of menu items and handles their execution.\n * It also manages keyboard shortcuts and implements responsive behavior.\n */\nexport class MenuManager {\n private registry: MenuRegistry = {};\n private shortcutMap: Record<string, string> = {}; // maps shortcut to menu item id\n private eventController = createEventController();\n private pluginRegistry: PluginRegistry;\n\n // Event types\n static readonly EVENTS = {\n COMMAND_EXECUTED: 'menu:command_executed',\n MENU_REQUESTED: 'menu:requested',\n SHORTCUT_EXECUTED: 'menu:shortcut_executed',\n };\n\n constructor(items: MenuRegistry = {}, pluginRegistry: PluginRegistry) {\n this.pluginRegistry = pluginRegistry;\n this.registerItems(items);\n this.setupKeyboardListeners();\n }\n\n /**\n * Get the current state of the plugin registry\n */\n private get state() {\n return this.pluginRegistry.getStore().getState();\n }\n\n /**\n * Register a single menu item\n */\n registerItem(item: MenuItem): void {\n if (this.registry[item.id]) {\n console.warn(`Menu item with ID ${item.id} already exists and will be overwritten`);\n }\n\n this.registry[item.id] = item;\n\n if ('shortcut' in item && item.shortcut) {\n this.shortcutMap[this.normalizeShortcut(item.shortcut)] = item.id;\n }\n }\n\n /**\n * Register multiple menu items at once\n */\n registerItems(items: MenuRegistry): void {\n Object.values(items).forEach((item) => {\n this.registerItem(item);\n });\n }\n\n /**\n * Resolve a menu item by ID\n */\n public resolve(id: string): ResolvedMenuItem {\n const raw = this.registry[id];\n return resolveMenuItem(raw, this.state);\n }\n\n /**\n * Get a menu item by ID with type information\n */\n getMenuItem(id: string): ResolvedMenuItemResult | undefined {\n const item = this.resolve(id);\n if (!item) return undefined;\n\n return {\n item,\n isGroup: item.type === 'group',\n isMenu: item.type === 'menu',\n isAction: item.type === 'action',\n };\n }\n\n /**\n * Get a action by ID (only returns Action type items)\n */\n getAction(id: string): ResolvedAction | undefined {\n const resolved = this.getMenuItem(id);\n if (!resolved || !resolved.isAction) return undefined;\n return resolved.item as ResolvedAction;\n }\n\n /**\n * Get menu or action by ID\n */\n getMenuOrAction(id: string): ResolvedMenu | ResolvedAction | undefined {\n const resolved = this.getMenuItem(id);\n if (!resolved) return undefined;\n return resolved.item as ResolvedMenu | ResolvedAction;\n }\n\n /**\n * Get all registered menu items\n */\n getAllItems(): MenuRegistry {\n return { ...this.registry };\n }\n\n /**\n * Get menu items by their IDs\n */\n getItemsByIds(ids: string[]): ResolvedMenuItem[] {\n return ids.map((id) => this.resolve(id)).filter((item) => item !== undefined);\n }\n\n /**\n * Get child items for a given menu ID\n * If flatten is true, it will recursively include submenu children but not groups\n */\n getChildItems(menuId: string, options: { flatten?: boolean } = {}): ResolvedMenuItem[] {\n const item = this.resolve(menuId);\n if (!item || !('children' in item) || !item.children?.length) {\n return [];\n }\n\n // Get all immediate children\n const children = this.getItemsByIds(item.children);\n\n // If flatten is false or not specified, return immediate children\n if (!options.flatten) {\n return children;\n }\n\n // If flatten is true, recursively include menu children\n const flattened: ResolvedMenuItem[] = [];\n\n for (const child of children) {\n if (child.type === 'group') {\n // For groups, add the group itself but don't flatten its children\n flattened.push(child);\n } else if (child.type === 'menu') {\n // For menus, recursively flatten their children\n const menuChildren = this.getChildItems(child.id, { flatten: true });\n flattened.push(...menuChildren);\n } else {\n // For commands, add them directly\n flattened.push(child);\n }\n }\n\n return flattened;\n }\n\n /**\n * Execute a command by ID\n */\n executeCommand(id: string, options: ExecuteOptions = {}): void {\n const resolved = this.getMenuItem(id);\n if (!resolved) {\n console.warn(`Menu item '${id}' not found`);\n return;\n }\n if (resolved.item.type === 'group') {\n console.warn(`Cannot execute group '${id}'`);\n return;\n }\n\n const { item } = resolved;\n\n if (item.disabled) {\n console.warn(`Menu item '${id}' is disabled`);\n return;\n }\n\n if (resolved.isAction) {\n // Execute the command's action\n (item as Action).action(this.pluginRegistry, this.state);\n this.eventController.emit(MenuManager.EVENTS.COMMAND_EXECUTED, {\n command: item,\n source: options.source || 'api',\n });\n } else if ('children' in item && item.children?.length) {\n // Handle submenu\n this.handleSubmenu(item, options);\n }\n }\n\n /**\n * Execute a command from a keyboard shortcut\n */\n executeShortcut(shortcut: string): boolean {\n const normalizedShortcut = this.normalizeShortcut(shortcut);\n const itemId = this.shortcutMap[normalizedShortcut];\n\n if (itemId) {\n this.executeCommand(itemId, { source: 'shortcut' });\n this.eventController.emit(MenuManager.EVENTS.SHORTCUT_EXECUTED, {\n shortcut: normalizedShortcut,\n itemId,\n });\n return true;\n }\n return false;\n }\n\n /**\n * Subscribe to menu events\n */\n on(eventType: string, callback: EventCallback): () => void {\n return this.eventController.on(eventType, callback);\n }\n\n /**\n * Remove an event subscription\n */\n off(eventType: string, callback: EventCallback): void {\n this.eventController.off(eventType, callback);\n }\n\n /**\n * Handle a menu item that has children (showing a submenu)\n */\n private handleSubmenu(menuItem: MenuItem, options: ExecuteOptions): void {\n this.eventController.emit(MenuManager.EVENTS.MENU_REQUESTED, {\n menuId: menuItem.id,\n triggerElement: options.triggerElement,\n position: options.position,\n flatten: options.flatten || false,\n });\n }\n\n /**\n * Set up keyboard listeners for shortcuts\n */\n private setupKeyboardListeners(): void {\n if (typeof window === 'undefined') return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // Don't handle shortcuts if the event target is an input, textarea, or has contentEditable\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n\n const shortcut = this.buildShortcutString(event);\n if (shortcut && this.executeShortcut(shortcut)) {\n event.preventDefault();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n }\n\n /**\n * Convert a KeyboardEvent to a shortcut string\n */\n private buildShortcutString(event: KeyboardEvent): string | null {\n const modifiers: string[] = [];\n if (event.ctrlKey) modifiers.push('Ctrl');\n if (event.shiftKey) modifiers.push('Shift');\n if (event.altKey) modifiers.push('Alt');\n if (event.metaKey) modifiers.push('Meta');\n\n // Only add non-modifier keys\n const key = event.key;\n const isModifier = ['Control', 'Shift', 'Alt', 'Meta'].includes(key);\n if (!isModifier) {\n // Handle special case for uppercase letters\n const displayKey = key.length === 1 ? key.toUpperCase() : key;\n return [...modifiers, displayKey].join('+');\n }\n\n return null;\n }\n\n /**\n * Normalize a shortcut string for consistent comparison\n */\n private normalizeShortcut(shortcut: string): string {\n return shortcut\n .split('+')\n .map((part) => part.trim())\n .join('+');\n }\n\n /**\n * Get capabilities for the MenuManager\n */\n capabilities(): MenuManagerCapabilities {\n return {\n registerItem: this.registerItem.bind(this),\n registerItems: this.registerItems.bind(this),\n executeCommand: this.executeCommand.bind(this),\n getAction: this.getAction.bind(this),\n getMenuOrAction: this.getMenuOrAction.bind(this),\n getChildItems: this.getChildItems.bind(this),\n getItemsByIds: this.getItemsByIds.bind(this),\n getAllItems: this.getAllItems.bind(this),\n };\n }\n}\n","import { BasePlugin, CoreState, PluginRegistry, StoreState, arePropsEqual } from '@embedpdf/core';\nimport {\n childrenFunctionOptions,\n CommandMenuComponent,\n CustomComponent,\n FloatingComponent,\n GroupedItemsComponent,\n HeaderComponent,\n PanelComponent,\n UICapability,\n UIComponentType,\n UIPluginConfig,\n UIPluginState,\n} from './types';\nimport { UIComponent } from './ui-component';\nimport { initialState } from './reducer';\nimport {\n uiInitComponents,\n UIPluginAction,\n uiSetHeaderVisible,\n uiShowCommandMenu,\n uiTogglePanel,\n uiHideCommandMenu,\n TogglePanelPayload,\n SetHeaderVisiblePayload,\n uiUpdateComponentState,\n UpdateComponentStatePayload,\n} from './actions';\nimport { MenuManager } from './menu/menu-manager';\n\nexport class UIPlugin extends BasePlugin<\n UIPluginConfig,\n UICapability,\n UIPluginState,\n UIPluginAction\n> {\n static readonly id = 'ui' as const;\n private componentRenderers: Record<\n string,\n (\n props: any,\n children: (options?: childrenFunctionOptions) => any[],\n context?: Record<string, any>,\n ) => any\n > = {};\n private components: Record<string, UIComponent<UIComponentType<any>>> = {};\n private config: UIPluginConfig;\n private mapStateCallbacks: {\n [componentId: string]: (storeState: any, ownProps: any) => any;\n } = {};\n private globalStoreSubscription: () => void = () => {};\n private menuManager: MenuManager; // Add this\n\n constructor(id: string, registry: PluginRegistry, config: UIPluginConfig) {\n super(id, registry);\n this.config = config;\n\n // Initialize command center\n this.menuManager = new MenuManager(config.menuItems || {}, this.registry);\n\n // Subscribe to command events\n this.setupCommandEventHandlers();\n\n // Subscribe exactly once to the global store\n this.globalStoreSubscription = this.registry.getStore().subscribe((_action, newState) => {\n this.onGlobalStoreChange(newState);\n });\n }\n\n async initialize(): Promise<void> {\n // Step 1: Build all individual components\n this.buildComponents();\n\n // Step 2: Link children for grouped items\n this.linkGroupedItems();\n\n // Step 3: Set initial state for UI components\n this.setInitialStateUIComponents();\n }\n\n // Set up handlers for command events\n private setupCommandEventHandlers(): void {\n // Handle command menu requests\n this.menuManager.on(MenuManager.EVENTS.MENU_REQUESTED, (data) => {\n const { menuId, triggerElement, position, flatten } = data;\n\n const isOpen = this.state.commandMenu.commandMenu?.activeCommand === menuId;\n if (isOpen) {\n return this.dispatch(uiHideCommandMenu({ id: 'commandMenu' }));\n }\n\n this.dispatch(\n uiShowCommandMenu({\n id: 'commandMenu',\n commandId: menuId,\n triggerElement,\n position,\n flatten,\n }),\n );\n });\n\n // Optional: Track command execution for analytics or other purposes\n this.menuManager.on(MenuManager.EVENTS.COMMAND_EXECUTED, (data) => {\n this.logger.debug('UIPlugin', 'CommandExecuted', `Command executed: ${data.command.id}`, {\n commandId: data.command.id,\n source: data.source,\n });\n });\n }\n\n private addComponent(id: string, componentConfig: UIComponentType<any>) {\n if (this.components[id]) {\n this.logger.warn(\n 'UIPlugin',\n 'ComponentAlreadyExists',\n `Component with ID ${id} already exists and will be overwritten`,\n );\n }\n // Step 1: Build the UIComponent\n const component = new UIComponent(componentConfig, this.componentRenderers);\n this.components[id] = component;\n\n // Step 2: Store mapStateToProps if present\n if (typeof componentConfig.mapStateToProps === 'function') {\n this.mapStateCallbacks[id] = componentConfig.mapStateToProps;\n }\n\n return component;\n }\n\n private buildComponents() {\n Object.entries(this.config.components).forEach(([id, componentConfig]) => {\n this.addComponent(id, componentConfig);\n });\n }\n\n private linkGroupedItems() {\n Object.values(this.components).forEach((component) => {\n if (isItemWithSlots(component)) {\n const props = component.componentConfig;\n props.slots?.forEach((slot) => {\n const child = this.components[slot.componentId];\n if (child) {\n component.addChild(slot.componentId, child, slot.priority, slot.className);\n } else {\n this.logger.warn(\n 'UIPlugin',\n 'ChildComponentNotFound',\n `Child component ${slot.componentId} not found for GroupedItems ${props.id}`,\n );\n }\n });\n }\n });\n }\n\n private setInitialStateUIComponents() {\n const defaultState: UIPluginState = initialState;\n\n Object.entries(this.config.components).forEach(([componentId, definition]) => {\n if (definition.initialState) {\n // store the initialState object, e.g. { open: false } or { active: true }\n defaultState[definition.type][componentId] = definition.initialState;\n } else {\n defaultState[definition.type][componentId] = {};\n }\n });\n\n this.dispatch(uiInitComponents(defaultState));\n }\n\n private onGlobalStoreChange(state: StoreState<CoreState>) {\n for (const [id, uiComponent] of Object.entries(this.components)) {\n const mapFn = this.mapStateCallbacks[id];\n if (!mapFn) continue; // no mapping\n\n // ownProps is the UIComponent's current props\n const { id: _id, ...ownProps } = uiComponent.props;\n\n const partial = mapFn(state, ownProps);\n // If partial is non-empty or changes from old, do update\n const merged = { ...ownProps, ...partial };\n\n if (!arePropsEqual(ownProps, merged)) {\n uiComponent.update(partial);\n }\n }\n }\n\n private addSlot(parentId: string, slotId: string, priority?: number, className?: string) {\n // 1. Get the parent component\n const parentComponent = this.components[parentId];\n\n if (!parentComponent) {\n this.logger.error(\n 'UIPlugin',\n 'ParentComponentNotFound',\n `Parent component ${parentId} not found`,\n );\n return;\n }\n\n // 2. Check if parent has slots (is a container type)\n if (!isItemWithSlots(parentComponent)) {\n this.logger.error(\n 'UIPlugin',\n 'ParentComponentDoesNotSupportSlots',\n `Parent component ${parentId} does not support slots`,\n );\n return;\n }\n\n // 3. Get the component to add to the slot\n const childComponent = this.components[slotId];\n\n if (!childComponent) {\n this.logger.error(\n 'UIPlugin',\n 'ChildComponentNotFound',\n `Child component ${slotId} not found`,\n );\n return;\n }\n\n const parentChildren = parentComponent.getChildren();\n\n // 4. Determine priority for the new slot\n let slotPriority = priority;\n\n if (slotPriority === undefined) {\n // If no priority is specified, add it at the end with a reasonable gap\n const maxPriority =\n parentChildren.length > 0 ? Math.max(...parentChildren.map((child) => child.priority)) : 0;\n slotPriority = maxPriority + 10; // Add a gap of 10\n }\n\n // 6. Add the child to the parent component with the appropriate priority\n // The UIComponent will handle sorting and avoid duplicates\n parentComponent.addChild(slotId, childComponent, slotPriority, className);\n }\n\n protected buildCapability(): UICapability {\n return {\n registerComponentRenderer: (\n type: string,\n renderer: (\n props: any,\n children: (options?: childrenFunctionOptions) => any[],\n context?: Record<string, any>,\n ) => any,\n ) => {\n this.componentRenderers[type] = renderer;\n },\n getComponent: <T>(id: string): T | undefined => {\n return this.components[id] as T | undefined;\n },\n registerComponent: this.addComponent.bind(this),\n getCommandMenu: () =>\n Object.values(this.components).find((component) => isCommandMenuComponent(component)),\n hideCommandMenu: () => this.cooldownDispatch(uiHideCommandMenu({ id: 'commandMenu' }), 100),\n getFloatingComponents: (scrollerPosition?: 'inside' | 'outside') =>\n Object.values(this.components)\n .filter((component) => isFloatingComponent(component))\n .filter(\n (component) =>\n !scrollerPosition || component.props.scrollerPosition === scrollerPosition,\n ),\n getHeadersByPlacement: (placement: 'top' | 'bottom' | 'left' | 'right') =>\n Object.values(this.components)\n .filter((component) => isHeaderComponent(component))\n .filter((component) => component.props.placement === placement),\n getPanelsByLocation: (location: 'left' | 'right') =>\n Object.values(this.components)\n .filter((component) => isPanelComponent(component))\n .filter((component) => component.props.location === location),\n addSlot: this.addSlot.bind(this),\n togglePanel: (payload: TogglePanelPayload) => {\n this.dispatch(uiTogglePanel(payload));\n },\n setHeaderVisible: (payload: SetHeaderVisiblePayload) => {\n this.dispatch(uiSetHeaderVisible(payload));\n },\n updateComponentState: (payload: UpdateComponentStatePayload) => {\n this.dispatch(uiUpdateComponentState(payload));\n },\n ...this.menuManager.capabilities(),\n };\n }\n\n async destroy(): Promise<void> {\n this.globalStoreSubscription();\n this.components = {};\n this.componentRenderers = {};\n this.mapStateCallbacks = {};\n }\n}\n\nfunction isItemWithSlots(\n component: UIComponent<UIComponentType<any>>,\n): component is\n | UIComponent<GroupedItemsComponent>\n | UIComponent<HeaderComponent>\n | UIComponent<PanelComponent>\n | UIComponent<FloatingComponent>\n | UIComponent<CustomComponent> {\n return (\n isGroupedItemsComponent(component) ||\n isHeaderComponent(component) ||\n isPanelComponent(component) ||\n isFloatingComponent(component) ||\n isCustomComponent(component)\n );\n}\n\n// Type guard function\nfunction isGroupedItemsComponent(\n component: UIComponent<UIComponentType>,\n): component is UIComponent<GroupedItemsComponent> {\n return component.type === 'groupedItems';\n}\n\nfunction isHeaderComponent(\n component: UIComponent<UIComponentType>,\n): component is UIComponent<HeaderComponent> {\n return component.type === 'header';\n}\n\nfunction isPanelComponent(\n component: UIComponent<UIComponentType>,\n): component is UIComponent<PanelComponent> {\n return component.type === 'panel';\n}\n\nfunction isFloatingComponent(\n component: UIComponent<UIComponentType>,\n): component is UIComponent<FloatingComponent> {\n return component.type === 'floating';\n}\n\nfunction isCommandMenuComponent(\n component: UIComponent<UIComponentType>,\n): component is UIComponent<CommandMenuComponent> {\n return component.type === 'commandMenu';\n}\n\nfunction isCustomComponent(\n component: UIComponent<UIComponentType>,\n): component is UIComponent<CustomComponent> {\n return component.type === 'custom';\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { UIPluginConfig } from './types';\n\nexport const UI_PLUGIN_ID = 'ui';\n\nexport const manifest: PluginManifest<UIPluginConfig> = {\n id: UI_PLUGIN_ID,\n name: 'UI Plugin',\n version: '1.0.0',\n provides: ['ui'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n components: {},\n },\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { UIPlugin } from './ui-plugin';\nimport { manifest, UI_PLUGIN_ID } from './manifest';\nimport { UIPluginConfig, UIPluginState } from './types';\nimport { uiReducer, initialState } from './reducer';\nimport { UIPluginAction } from './actions';\n\nexport const UIPluginPackage: PluginPackage<\n UIPlugin,\n UIPluginConfig,\n UIPluginState,\n UIPluginAction\n> = {\n manifest,\n create: (registry, config) => new UIPlugin(UI_PLUGIN_ID, registry, config),\n reducer: uiReducer,\n initialState,\n};\n\nexport * from './manifest';\nexport * from './ui-plugin';\nexport * from './types';\nexport * from './ui-component';\nexport * from './utils';\nexport * from './menu/types';\nexport * from './menu/utils';\n","import { PluginRegistry } from '@embedpdf/core';\n\nexport type Dynamic<TStore, T> = T | ((state: TStore) => T);\n\nexport type IconProps = {\n primaryColor?: string;\n secondaryColor?: string;\n className?: string;\n title?: string;\n};\n\nexport interface MenuItemBase<TStore = any> {\n icon?: Dynamic<TStore, string>;\n iconProps?: Dynamic<TStore, IconProps>;\n label: Dynamic<TStore, string>;\n active?: Dynamic<TStore, boolean>; // whether command is currently active\n disabled?: Dynamic<TStore, boolean>; // whether command is currently disabled\n shortcut?: string; // \"Ctrl+Plus\"\n shortcutLabel?: string; // \"Ctrl+Plus\"\n visible?: Dynamic<TStore, boolean>; // whether command should be visible\n dividerBefore?: boolean; // whether to add a divider before the command\n}\n\nexport interface Action<TStore = any> extends MenuItemBase<TStore> {\n id: string; // \"zoomIn\"\n type: 'action'; // i18n key or literal\n action: (registry: PluginRegistry, state: TStore) => void; // executed onClick // whether to add a divider before the command\n}\n\nexport interface Group<TStore = any> {\n id: string;\n type: 'group';\n label: Dynamic<TStore, string>;\n children: string[];\n}\n\nexport interface Menu<TStore = any> extends MenuItemBase<TStore> {\n id: string;\n type: 'menu';\n children: string[];\n}\n\nexport type MenuItem<TStore = any> = Action<TStore> | Group | Menu<TStore>;\n\nexport type MenuRegistry = Record<string, MenuItem>;\n\n// Options for executing an action\nexport interface ExecuteOptions {\n source?: 'click' | 'shortcut' | 'api';\n triggerElement?: HTMLElement;\n flatten?: boolean;\n position?: 'top' | 'bottom' | 'left' | 'right';\n}\n\nexport function hasActive<TStore>(command: MenuItem<TStore>): command is Action<TStore> {\n return 'active' in command;\n}\n\nexport interface MenuManagerCapabilities {\n registerItem: (commandItem: MenuItem) => void;\n registerItems: (commands: MenuRegistry) => void;\n executeCommand: (id: string, options?: ExecuteOptions) => void;\n getAction: (id: string) => ResolvedAction | undefined;\n getMenuOrAction: (id: string) => ResolvedMenu | ResolvedAction | undefined;\n getChildItems: (commandId: string, options?: { flatten?: boolean }) => ResolvedMenuItem[];\n getItemsByIds: (ids: string[]) => ResolvedMenuItem[];\n getAllItems: () => MenuRegistry;\n}\n\n// Add these new resolved types after the existing interfaces\nexport type Resolved<TStore, T> = T extends Dynamic<TStore, infer U> ? U : T;\n\nexport interface ResolvedMenuItemBase<TStore = any> {\n icon?: string;\n iconProps?: IconProps;\n label: string;\n active?: boolean;\n disabled?: boolean;\n shortcut?: string;\n shortcutLabel?: string;\n visible?: boolean;\n dividerBefore?: boolean;\n}\n\nexport interface ResolvedAction<TStore = any> extends ResolvedMenuItemBase<TStore> {\n id: string;\n type: 'action';\n action: (registry: PluginRegistry, state: TStore) => void;\n}\n\nexport interface ResolvedGroup<TStore = any> {\n id: string;\n type: 'group';\n label: string;\n children: string[];\n}\n\nexport interface ResolvedMenu<TStore = any> extends ResolvedMenuItemBase<TStore> {\n id: string;\n type: 'menu';\n children: string[];\n}\n\nexport type ResolvedMenuItem<TStore = any> =\n | ResolvedAction<TStore>\n | ResolvedGroup<TStore>\n | ResolvedMenu<TStore>;\n\n// Result of menu item resolution\nexport interface ResolvedMenuItemResult<TStore = any> {\n item: ResolvedMenuItem<TStore>;\n isGroup: boolean;\n isMenu: boolean;\n isAction: boolean;\n}\n"],"names":["UIComponent","constructor","componentConfig","registry","this","children","updateCallbacks","hadUpdateBeforeListeners","props","initialProps","initialState","id","type","addChild","child","priority","className","push","component","sortChildren","sort","a","b","removeChild","filter","c","clearChildren","getRenderType","render","getRenderer","getChildren","getChildContext","context","childContextProp","update","newProps","otherProps","length","notifyUpdate","onUpdate","callback","offUpdate","cb","forEach","UI_INIT_COMPONENTS","UI_SET_HEADER_VISIBLE","UI_TOGGLE_PANEL","UI_SHOW_COMMAND_MENU","UI_HIDE_COMMAND_MENU","UI_UPDATE_COMPONENT_STATE","uiHideCommandMenu","payload","panel","header","groupedItems","divider","iconButton","tabButton","selectButton","custom","floating","commandMenu","createEventController","eventMap","Map","emit","eventType","data","callbacks","get","on","has","set","Set","add","off","delete","size","resolveMenuItem","item","state","dyn","v","label","icon","iconProps","visible","active","disabled","_MenuManager","items","pluginRegistry","shortcutMap","eventController","registerItems","setupKeyboardListeners","getStore","getState","registerItem","console","warn","shortcut","normalizeShortcut","Object","values","resolve","getMenuItem","isGroup","isMenu","isAction","getAction","resolved","getMenuOrAction","getAllItems","getItemsByIds","ids","map","getChildItems","menuId","options","_a","flatten","flattened","menuChildren","executeCommand","action","EVENTS","COMMAND_EXECUTED","command","source","handleSubmenu","executeShortcut","normalizedShortcut","itemId","SHORTCUT_EXECUTED","menuItem","MENU_REQUESTED","triggerElement","position","window","document","addEventListener","event","target","tagName","isContentEditable","buildShortcutString","preventDefault","modifiers","ctrlKey","shiftKey","altKey","metaKey","key","includes","displayKey","toUpperCase","join","split","part","trim","capabilities","bind","MenuManager","_UIPlugin","BasePlugin","config","super","componentRenderers","components","mapStateCallbacks","globalStoreSubscription","menuManager","menuItems","setupCommandEventHandlers","subscribe","_action","newState","onGlobalStoreChange","initialize","buildComponents","linkGroupedItems","setInitialStateUIComponents","activeCommand","dispatch","commandId","logger","debug","addComponent","mapStateToProps","entries","isItemWithSlots","slots","slot","componentId","defaultState","definition","uiComponent","mapFn","_id","ownProps","partial","merged","arePropsEqual","addSlot","parentId","slotId","parentComponent","error","childComponent","parentChildren","slotPriority","Math","max","buildCapability","registerComponentRenderer","renderer","getComponent","registerComponent","getCommandMenu","find","isCommandMenuComponent","hideCommandMenu","cooldownDispatch","getFloatingComponents","scrollerPosition","isFloatingComponent","getHeadersByPlacement","placement","isHeaderComponent","getPanelsByLocation","location","isPanelComponent","togglePanel","uiTogglePanel","setHeaderVisible","uiSetHeaderVisible","updateComponentState","uiUpdateComponentState","destroy","UIPlugin","isGroupedItemsComponent","isCustomComponent","UI_PLUGIN_ID","manifest","name","version","provides","requires","optional","defaultConfig","enabled","UIPluginPackage","create","reducer","prevPanel","open","nextOpen","visibleChild","nextVisibleChild","prevVisibleChild","componentType","patch","current","filteredPatch","fromEntries","k","keys"],"mappings":"kHAEO,MAAMA,EAyBX,WAAAC,CACEC,EACAC,GAnBFC,KAAQC,SAKH,GASLD,KAAQE,gBAAkC,GAC1CF,KAAQG,0BAA2B,EAajCH,KAAKF,gBAAkBA,EAEjB,MAAAM,EAAQN,EAAgBM,OAAS,CAAC,EAEpC,GAAiB,mBAAVA,EAAsB,CACzB,MAAAC,EAAeD,EAAMN,EAAgBQ,cAC3CN,KAAKI,MAAQ,IAAKC,EAAcE,GAAIT,EAAgBS,GAAG,MAEvDP,KAAKI,MAAQ,IAAKA,EAAOG,GAAIT,EAAgBS,IAG/CP,KAAKQ,KAAOV,EAAgBU,KAC5BR,KAAKD,SAAWA,CAAA,CAGlB,QAAAU,CAASF,EAAYG,EAAyBC,EAAmB,EAAGC,GAC7DZ,KAAAC,SAASY,KAAK,CAAEN,KAAIO,UAAWJ,EAAOC,WAAUC,cAErDZ,KAAKe,cAAa,CAIZ,YAAAA,GACDf,KAAAC,SAASe,MAAK,CAACC,EAAGC,IAAMD,EAAEN,SAAWO,EAAEP,UAAQ,CAGtD,WAAAQ,CAAYT,GACLV,KAAAC,SAAWD,KAAKC,SAASmB,QAAQC,GAAMA,EAAEP,YAAcJ,GAAK,CAGnE,aAAAY,GACEtB,KAAKC,SAAW,EAAC,CAGnB,iBAAIsB,GACK,OAAAvB,KAAKF,gBAAgB0B,QAAUxB,KAAKQ,IAAA,CAGtC,WAAAiB,GACE,OAAAzB,KAAKD,SAASC,KAAKuB,cAAa,CAGlC,WAAAG,GACL,OAAO1B,KAAKC,QAAA,CAKP,eAAA0B,CAAgBC,GACf,MAAAC,EAAmB7B,KAAKF,gBAAgB6B,gBAC1C,MAA4B,mBAArBE,EAEF,IAAKD,KAAYC,EAAiB7B,KAAKI,QACrCyB,GAAgD,iBAArBA,EAE7B,IAAKD,KAAYC,GAEnBD,CAAA,CAGT,MAAAE,CAAOC,GACL,MAAMxB,GAAEA,KAAOyB,GAAeD,EAC9B/B,KAAKI,MAAQ,IAAKJ,KAAKI,SAAU4B,GACG,IAAhChC,KAAKE,gBAAgB+B,SACvBjC,KAAKG,0BAA2B,GAElCH,KAAKkC,cAAa,CAGpB,QAAAC,CAASC,GAEP,OADKpC,KAAAE,gBAAgBW,KAAKuB,GACnBpC,KAAKG,wBAAA,CAGd,SAAAkC,CAAUD,GACRpC,KAAKE,gBAAkBF,KAAKE,gBAAgBkB,QAAQkB,GAAOA,IAAOF,GAAQ,CAGlE,YAAAF,GACRlC,KAAKE,gBAAgBqC,SAASD,GAAOA,KAAI,EClHtC,MAAME,EAAqB,qBAGrBC,EAAwB,wBACxBC,EAAkB,kBAClBC,EAAuB,uBACvBC,EAAuB,uBAEvBC,EAA4B,4BA6H5BC,EAAqBC,IAA8D,CAC9FvC,KAAMoC,EACNG,YC9HWzC,EAA8B,CACzC0C,MAAO,CAAC,EACRC,OAAQ,CAAC,EACTC,aAAc,CAAC,EACfC,QAAS,CAAC,EACVC,WAAY,CAAC,EACbC,UAAW,CAAC,EACZC,aAAc,CAAC,EACfC,OAAQ,CAAC,EACTC,SAAU,CAAC,EACXC,YAAa,CAAA,GCsBR,SAASC,IAER,MAAAC,MAAeC,IAEd,MAAA,CACL,IAAAC,CAAKC,EAAmBC,GAChB,MAAAC,EAAYL,EAASM,IAAIH,GAC3BE,GAEFA,EAAUzB,SAASH,GAAaA,EAAS2B,IAE7C,EAEA,EAAAG,CAAGJ,EAAmB1B,GAEfuB,EAASQ,IAAIL,IAChBH,EAASS,IAAIN,EAAe,IAAAO,KAQ9B,OAJkBV,EAASM,IAAIH,GACrBQ,IAAIlC,GAGP,IAAMpC,KAAKuE,IAAIT,EAAW1B,EACnC,EAEA,GAAAmC,CAAIT,EAAmB1B,GACf,MAAA4B,EAAYL,EAASM,IAAIH,GAC3BE,IAEFA,EAAUQ,OAAOpC,GAGM,IAAnB4B,EAAUS,MACZd,EAASa,OAAOV,GAEpB,EAGN,CClFgB,SAAAY,EACdC,EACAC,GAEM,MAAAC,EAAUC,GACD,mBAANA,EAAoBA,EAAUF,GAASE,EAE5C,MAAc,UAAdH,EAAKnE,KACA,IACFmE,EACHI,MAAOF,EAAIF,EAAKI,QAAU,IAKvB,IACFJ,EACHK,KAAMH,EAAIF,EAAKK,OAAS,GACxBC,UAAWJ,EAAIF,EAAKM,YAAc,CAAC,EACnCF,MAAOF,EAAIF,EAAKI,QAAU,GAC1BG,QAASL,EAAIF,EAAKO,WAAY,EAC9BC,OAAQN,EAAIF,EAAKQ,UAAW,EAC5BC,SAAUP,EAAIF,EAAKS,YAAa,EAEpC,CCNO,MAAMC,EAAN,MAAMA,EAaX,WAAAxF,CAAYyF,EAAsB,CAAC,EAAGC,GAZtCvF,KAAQD,SAAyB,CAAC,EAClCC,KAAQwF,YAAsC,CAAC,EAC/CxF,KAAQyF,gBAAkB/B,IAWxB1D,KAAKuF,eAAiBA,EACtBvF,KAAK0F,cAAcJ,GACnBtF,KAAK2F,wBAAuB,CAM9B,SAAYf,GACV,OAAO5E,KAAKuF,eAAeK,WAAWC,UAAS,CAMjD,YAAAC,CAAanB,GACP3E,KAAKD,SAAS4E,EAAKpE,KACrBwF,QAAQC,KAAK,qBAAqBrB,EAAKpE,6CAGpCP,KAAAD,SAAS4E,EAAKpE,IAAMoE,EAErB,aAAcA,GAAQA,EAAKsB,WAC7BjG,KAAKwF,YAAYxF,KAAKkG,kBAAkBvB,EAAKsB,WAAatB,EAAKpE,GACjE,CAMF,aAAAmF,CAAcJ,GACZa,OAAOC,OAAOd,GAAO/C,SAASoC,IAC5B3E,KAAK8F,aAAanB,EAAI,GACvB,CAMI,OAAA0B,CAAQ9F,GAEN,OAAAmE,EADK1E,KAAKD,SAASQ,GACEP,KAAK4E,MAAK,CAMxC,WAAA0B,CAAY/F,GACJ,MAAAoE,EAAO3E,KAAKqG,QAAQ9F,GACtB,GAACoE,EAEE,MAAA,CACLA,OACA4B,QAAuB,UAAd5B,EAAKnE,KACdgG,OAAsB,SAAd7B,EAAKnE,KACbiG,SAAwB,WAAd9B,EAAKnE,KACjB,CAMF,SAAAkG,CAAUnG,GACF,MAAAoG,EAAW3G,KAAKsG,YAAY/F,GAClC,GAAKoG,GAAaA,EAASF,SAC3B,OAAOE,EAAShC,IAAA,CAMlB,eAAAiC,CAAgBrG,GACR,MAAAoG,EAAW3G,KAAKsG,YAAY/F,GAC9B,GAACoG,EACL,OAAOA,EAAShC,IAAA,CAMlB,WAAAkC,GACS,MAAA,IAAK7G,KAAKD,SAAS,CAM5B,aAAA+G,CAAcC,GACZ,OAAOA,EAAIC,KAAKzG,GAAOP,KAAKqG,QAAQ9F,KAAKa,QAAQuD,QAAkB,IAATA,GAAkB,CAO9E,aAAAsC,CAAcC,EAAgBC,EAAiC,UACvD,MAAAxC,EAAO3E,KAAKqG,QAAQa,GACtB,IAACvC,KAAU,aAAcA,MAAU,OAAAyC,EAAAzC,EAAK1E,eAAL,EAAAmH,EAAenF,QACpD,MAAO,GAIT,MAAMhC,EAAWD,KAAK8G,cAAcnC,EAAK1E,UAGrC,IAACkH,EAAQE,QACJ,OAAApH,EAIT,MAAMqH,EAAgC,GAEtC,IAAA,MAAW5G,KAAST,EACd,GAAe,UAAfS,EAAMF,KAER8G,EAAUzG,KAAKH,QAAK,GACI,SAAfA,EAAMF,KAAiB,CAE1B,MAAA+G,EAAevH,KAAKiH,cAAcvG,EAAMH,GAAI,CAAE8G,SAAS,IACnDC,EAAAzG,QAAQ0G,EAAY,MAG9BD,EAAUzG,KAAKH,GAIZ,OAAA4G,CAAA,CAMT,cAAAE,CAAejH,EAAY4G,EAA0B,UAC7C,MAAAR,EAAW3G,KAAKsG,YAAY/F,GAClC,IAAKoG,EAEH,YADQZ,QAAAC,KAAK,cAAczF,gBAGzB,GAAuB,UAAvBoG,EAAShC,KAAKnE,KAEhB,YADQuF,QAAAC,KAAK,yBAAyBzF,MAIlC,MAAAoE,KAAEA,GAASgC,EAEbhC,EAAKS,SACCW,QAAAC,KAAK,cAAczF,kBAIzBoG,EAASF,UAEV9B,EAAgB8C,OAAOzH,KAAKuF,eAAgBvF,KAAK4E,OAClD5E,KAAKyF,gBAAgB5B,KAAKwB,EAAYqC,OAAOC,iBAAkB,CAC7DC,QAASjD,EACTkD,OAAQV,EAAQU,QAAU,SAEnB,aAAclD,IAAQ,OAAAyC,EAAKzC,EAAA1E,mBAAUgC,SAEzCjC,KAAA8H,cAAcnD,EAAMwC,EAC3B,CAMF,eAAAY,CAAgB9B,GACR,MAAA+B,EAAqBhI,KAAKkG,kBAAkBD,GAC5CgC,EAASjI,KAAKwF,YAAYwC,GAEhC,QAAIC,IACFjI,KAAKwH,eAAeS,EAAQ,CAAEJ,OAAQ,aACtC7H,KAAKyF,gBAAgB5B,KAAKwB,EAAYqC,OAAOQ,kBAAmB,CAC9DjC,SAAU+B,EACVC,YAEK,EAEF,CAMT,EAAA/D,CAAGJ,EAAmB1B,GACpB,OAAOpC,KAAKyF,gBAAgBvB,GAAGJ,EAAW1B,EAAQ,CAMpD,GAAAmC,CAAIT,EAAmB1B,GAChBpC,KAAAyF,gBAAgBlB,IAAIT,EAAW1B,EAAQ,CAMtC,aAAA0F,CAAcK,EAAoBhB,GACxCnH,KAAKyF,gBAAgB5B,KAAKwB,EAAYqC,OAAOU,eAAgB,CAC3DlB,OAAQiB,EAAS5H,GACjB8H,eAAgBlB,EAAQkB,eACxBC,SAAUnB,EAAQmB,SAClBjB,QAASF,EAAQE,UAAW,GAC7B,CAMK,sBAAA1B,GACF,GAAkB,oBAAX4C,OAAwB,OAe1BC,SAAAC,iBAAiB,WAbHC,IAErB,MAAMC,EAASD,EAAMC,OACrB,GAAuB,UAAnBA,EAAOC,SAA0C,aAAnBD,EAAOC,SAA0BD,EAAOE,kBACxE,OAGI,MAAA5C,EAAWjG,KAAK8I,oBAAoBJ,GACtCzC,GAAYjG,KAAK+H,gBAAgB9B,IACnCyC,EAAMK,gBAAe,GAIyB,CAM5C,mBAAAD,CAAoBJ,GAC1B,MAAMM,EAAsB,GACxBN,EAAMO,SAAmBD,EAAAnI,KAAK,QAC9B6H,EAAMQ,UAAoBF,EAAAnI,KAAK,SAC/B6H,EAAMS,QAAkBH,EAAAnI,KAAK,OAC7B6H,EAAMU,SAAmBJ,EAAAnI,KAAK,QAGlC,MAAMwI,EAAMX,EAAMW,IAElB,IADmB,CAAC,UAAW,QAAS,MAAO,QAAQC,SAASD,GAC/C,CAEf,MAAME,EAA4B,IAAfF,EAAIpH,OAAeoH,EAAIG,cAAgBH,EAC1D,MAAO,IAAIL,EAAWO,GAAYE,KAAK,IAAG,CAGrC,OAAA,IAAA,CAMD,iBAAAvD,CAAkBD,GACxB,OAAOA,EACJyD,MAAM,KACN1C,KAAK2C,GAASA,EAAKC,SACnBH,KAAK,IAAG,CAMb,YAAAI,GACS,MAAA,CACL/D,aAAc9F,KAAK8F,aAAagE,KAAK9J,MACrC0F,cAAe1F,KAAK0F,cAAcoE,KAAK9J,MACvCwH,eAAgBxH,KAAKwH,eAAesC,KAAK9J,MACzC0G,UAAW1G,KAAK0G,UAAUoD,KAAK9J,MAC/B4G,gBAAiB5G,KAAK4G,gBAAgBkD,KAAK9J,MAC3CiH,cAAejH,KAAKiH,cAAc6C,KAAK9J,MACvC8G,cAAe9G,KAAK8G,cAAcgD,KAAK9J,MACvC6G,YAAa7G,KAAK6G,YAAYiD,KAAK9J,MACrC,GAzRFqF,EAAgBqC,OAAS,CACvBC,iBAAkB,wBAClBS,eAAgB,iBAChBF,kBAAmB,0BAVhB,IAAM6B,EAAN1E,ECUA,MAAM2E,EAAN,cAAuBC,EAAAA,WAuB5B,WAAApK,CAAYU,EAAYR,EAA0BmK,GAChDC,MAAM5J,EAAIR,GAjBZC,KAAQoK,mBAOJ,CAAC,EACLpK,KAAQqK,WAAgE,CAAC,EAEzErK,KAAQsK,kBAEJ,CAAC,EACLtK,KAAQuK,wBAAsC,OAK5CvK,KAAKkK,OAASA,EAGTlK,KAAAwK,YAAc,IAAIT,EAAYG,EAAOO,WAAa,CAAC,EAAGzK,KAAKD,UAGhEC,KAAK0K,4BAGA1K,KAAAuK,wBAA0BvK,KAAKD,SAAS6F,WAAW+E,WAAU,CAACC,EAASC,KAC1E7K,KAAK8K,oBAAoBD,EAAQ,GAClC,CAGH,gBAAME,GAEJ/K,KAAKgL,kBAGLhL,KAAKiL,mBAGLjL,KAAKkL,6BAA4B,CAI3B,yBAAAR,GAEN1K,KAAKwK,YAAYtG,GAAG6F,EAAYrC,OAAOU,gBAAiBrE,UACtD,MAAMmD,OAAEA,EAAAmB,eAAQA,EAAgBC,SAAAA,EAAAjB,QAAUA,GAAYtD,EAGtD,IADe,OAAAqD,EAAKpH,KAAA4E,MAAMnB,YAAYA,sBAAa0H,iBAAkBjE,EAEnE,OAAOlH,KAAKoL,SAAStI,EAAkB,CAAEvC,GAAI,iBAG1CP,KAAAoL,SLwCqF,CAC9F5K,KAAMmC,EACNI,QKzCwB,CAChBxC,GAAI,cACJ8K,UAAWnE,EACXmB,iBACAC,WACAjB,YAEJ,IAIFrH,KAAKwK,YAAYtG,GAAG6F,EAAYrC,OAAOC,kBAAmB5D,IACnD/D,KAAAsL,OAAOC,MAAM,WAAY,kBAAmB,qBAAqBxH,EAAK6D,QAAQrH,KAAM,CACvF8K,UAAWtH,EAAK6D,QAAQrH,GACxBsH,OAAQ9D,EAAK8D,QACd,GACF,CAGK,YAAA2D,CAAajL,EAAYT,GAC3BE,KAAKqK,WAAW9J,IAClBP,KAAKsL,OAAOtF,KACV,WACA,yBACA,qBAAqBzF,4CAIzB,MAAMO,EAAY,IAAIlB,EAAYE,EAAiBE,KAAKoK,oBAQjD,OAPFpK,KAAAqK,WAAW9J,GAAMO,EAGyB,mBAApChB,EAAgB2L,kBACpBzL,KAAAsK,kBAAkB/J,GAAMT,EAAgB2L,iBAGxC3K,CAAA,CAGD,eAAAkK,GACC7E,OAAAuF,QAAQ1L,KAAKkK,OAAOG,YAAY9H,SAAQ,EAAEhC,EAAIT,MAC9CE,KAAAwL,aAAajL,EAAIT,EAAe,GACtC,CAGK,gBAAAmL,GACN9E,OAAOC,OAAOpG,KAAKqK,YAAY9H,SAASzB,UAClC,GAAA6K,EAAgB7K,GAAY,CAC9B,MAAMV,EAAQU,EAAUhB,gBAClB,OAAAsH,EAAAhH,EAAAwL,QAAAxE,EAAO7E,SAASsJ,IACpB,MAAMnL,EAAQV,KAAKqK,WAAWwB,EAAKC,aAC/BpL,EACFI,EAAUL,SAASoL,EAAKC,YAAapL,EAAOmL,EAAKlL,SAAUkL,EAAKjL,WAEhEZ,KAAKsL,OAAOtF,KACV,WACA,yBACA,mBAAmB6F,EAAKC,0CAA0C1L,EAAMG,KAC1E,GAEH,IAEJ,CAGK,2BAAA2K,GACN,MAAMa,EAA8BzL,EAE7B6F,OAAAuF,QAAQ1L,KAAKkK,OAAOG,YAAY9H,SAAQ,EAAEuJ,EAAaE,MACxDA,EAAW1L,aAEbyL,EAAaC,EAAWxL,MAAMsL,GAAeE,EAAW1L,aAExDyL,EAAaC,EAAWxL,MAAMsL,GAAe,CAAC,CAAA,IAI7C9L,KAAAoL,SL/D0E,CACjF5K,KAAMgC,EACNO,QK6DiCgJ,GAAa,CAGtC,mBAAAjB,CAAoBlG,GACf,IAAA,MAACrE,EAAI0L,KAAgB9F,OAAOuF,QAAQ1L,KAAKqK,YAAa,CACzD,MAAA6B,EAAQlM,KAAKsK,kBAAkB/J,GACrC,IAAK2L,EAAO,SAGZ,MAAQ3L,GAAI4L,KAAQC,GAAaH,EAAY7L,MAEvCiM,EAAUH,EAAMtH,EAAOwH,GAEvBE,EAAS,IAAKF,KAAaC,GAE5BE,EAAAA,cAAcH,EAAUE,IAC3BL,EAAYnK,OAAOuK,EACrB,CACF,CAGM,OAAAG,CAAQC,EAAkBC,EAAgB/L,EAAmBC,GAE7D,MAAA+L,EAAkB3M,KAAKqK,WAAWoC,GAExC,IAAKE,EAMH,YALA3M,KAAKsL,OAAOsB,MACV,WACA,0BACA,oBAAoBH,eAMpB,IAACd,EAAgBgB,GAMnB,YALA3M,KAAKsL,OAAOsB,MACV,WACA,qCACA,oBAAoBH,4BAMlB,MAAAI,EAAiB7M,KAAKqK,WAAWqC,GAEvC,IAAKG,EAMH,YALA7M,KAAKsL,OAAOsB,MACV,WACA,yBACA,mBAAmBF,eAKjB,MAAAI,EAAiBH,EAAgBjL,cAGvC,IAAIqL,EAAepM,EAEnB,QAAqB,IAAjBoM,EAA4B,CAI9BA,GADED,EAAe7K,OAAS,EAAI+K,KAAKC,OAAOH,EAAe9F,KAAKtG,GAAUA,EAAMC,YAAa,GAC9D,EAAA,CAK/BgM,EAAgBlM,SAASiM,EAAQG,EAAgBE,EAAcnM,EAAS,CAGhE,eAAAsM,GACD,MAAA,CACLC,0BAA2B,CACzB3M,EACA4M,KAMKpN,KAAAoK,mBAAmB5J,GAAQ4M,CAAA,EAElCC,aAAkB9M,GACTP,KAAKqK,WAAW9J,GAEzB+M,kBAAmBtN,KAAKwL,aAAa1B,KAAK9J,MAC1CuN,eAAgB,IACdpH,OAAOC,OAAOpG,KAAKqK,YAAYmD,MAAM1M,GAiF7C,SACEA,GAEA,MAA0B,gBAAnBA,EAAUN,IACnB,CArF2DiN,CAAuB3M,KAC5E4M,gBAAiB,IAAM1N,KAAK2N,iBAAiB7K,EAAkB,CAAEvC,GAAI,gBAAkB,KACvFqN,sBAAwBC,GACtB1H,OAAOC,OAAOpG,KAAKqK,YAChBjJ,QAAQN,GAAcgN,EAAoBhN,KAC1CM,QACEN,IACE+M,GAAoB/M,EAAUV,MAAMyN,mBAAqBA,IAElEE,sBAAwBC,GACtB7H,OAAOC,OAAOpG,KAAKqK,YAChBjJ,QAAQN,GAAcmN,EAAkBnN,KACxCM,QAAQN,GAAcA,EAAUV,MAAM4N,YAAcA,IACzDE,oBAAsBC,GACpBhI,OAAOC,OAAOpG,KAAKqK,YAChBjJ,QAAQN,GAAcsN,EAAiBtN,KACvCM,QAAQN,GAAcA,EAAUV,MAAM+N,WAAaA,IACxD3B,QAASxM,KAAKwM,QAAQ1C,KAAK9J,MAC3BqO,YAActL,IACP/C,KAAAoL,SL7JgB,CAACrI,IAAsD,CAClFvC,KAAMkC,EACNK,YK2JoBuL,CAAcvL,GAAQ,EAEtCwL,iBAAmBxL,IACZ/C,KAAAoL,SL3JqB,CAACrI,IAAgE,CACjGvC,KAAMiC,EACNM,YKyJoByL,CAAmBzL,GAAQ,EAE3C0L,qBAAuB1L,IAChB/C,KAAAoL,SL/IyB,CACpCrI,IACkC,CAClCvC,KAAMqC,EACNE,YK2IoB2L,CAAuB3L,GAAQ,KAE5C/C,KAAKwK,YAAYX,eACtB,CAGF,aAAM8E,GACJ3O,KAAKuK,0BACLvK,KAAKqK,WAAa,CAAC,EACnBrK,KAAKoK,mBAAqB,CAAC,EAC3BpK,KAAKsK,kBAAoB,CAAC,CAAA,GAlQ5BN,EAAgBzJ,GAAK,KANhB,IAAMqO,EAAN5E,EA4QP,SAAS2B,EACP7K,GAOA,OAUF,SACEA,GAEA,MAA0B,iBAAnBA,EAAUN,IACnB,CAbIqO,CAAwB/N,IACxBmN,EAAkBnN,IAClBsN,EAAiBtN,IACjBgN,EAAoBhN,IAoCxB,SACEA,GAEA,MAA0B,WAAnBA,EAAUN,IACnB,CAvCIsO,CAAkBhO,EAEtB,CASA,SAASmN,EACPnN,GAEA,MAA0B,WAAnBA,EAAUN,IACnB,CAEA,SAAS4N,EACPtN,GAEA,MAA0B,UAAnBA,EAAUN,IACnB,CAEA,SAASsN,EACPhN,GAEA,MAA0B,aAAnBA,EAAUN,IACnB,CC/UO,MAAMuO,EAAe,KAEfC,EAA2C,CACtDzO,GAAIwO,EACJE,KAAM,YACNC,QAAS,QACTC,SAAU,CAAC,MACXC,SAAU,GACVC,SAAU,GACVC,cAAe,CACbC,SAAS,EACTlF,WAAY,CAAA,ICPT,MAAMmF,EAKT,CACFR,WACAS,OAAQ,CAAC1P,EAAUmK,IAAW,IAAI0E,EAASG,EAAchP,EAAUmK,GACnEwF,QNU+D,CAAC9K,EAAQtE,EAAcmH,KACtF,OAAQA,EAAOjH,MACb,KAAKgC,EACI,MAAA,IACFoC,KACA6C,EAAO1E,SAEd,KAAKL,EAAiB,CACpB,MAAMiN,EAAY/K,EAAM5B,MAAMyE,EAAO1E,QAAQxC,KAAO,CAAC,GAC7CqP,KAAMC,EAAUC,aAAcC,GAAqBtI,EAAO1E,QAC5DiN,EAAmBL,EAAUG,aAEnC,IAAIF,EAAOD,EAAUC,KACjBE,EAAeH,EAAUG,aAWtB,OATHC,IAAqBC,EAEvBJ,OAAoB,IAAbC,EAAyBA,GAAYF,EAAUC,MAGvCE,EAAAC,EACRH,GAAA,GAGF,IACFhL,EACH5B,MAAO,IACF4B,EAAM5B,MACT,CAACyE,EAAO1E,QAAQxC,IAAK,IAChBoP,EACHC,OACAE,iBAGN,CAEF,KAAKrN,EACI,MAAA,IACFmC,EACH3B,OAAQ,IACH2B,EAAM3B,OACT,CAACwE,EAAO1E,QAAQxC,IAAK,IAChBqE,EAAM3B,OAAOwE,EAAO1E,QAAQxC,IAC/B2E,QAASuC,EAAO1E,QAAQmC,QACxB4K,aAAcrI,EAAO1E,QAAQ+M,gBAIrC,KAAKnN,EACI,MAAA,IACFiC,EACHnB,YAAa,IACRmB,EAAMnB,YACT,CAACgE,EAAO1E,QAAQxC,IAAK,CACnB4K,cAAe1D,EAAO1E,QAAQsI,UAC9BhD,eAAgBZ,EAAO1E,QAAQsF,eAC/BC,SAAUb,EAAO1E,QAAQuF,SACzBsH,MAAM,EACNvI,QAASI,EAAO1E,QAAQsE,WAIhC,KAAKzE,EACI,MAAA,IACFgC,EACHnB,YAAa,IACRmB,EAAMnB,YACT,CAACgE,EAAO1E,QAAQxC,IAAK,IAChBqE,EAAMnB,YAAYgE,EAAO1E,QAAQxC,IACpCqP,MAAM,EACNzE,cAAe,KACf9C,oBAAgB,EAChBC,cAAU,EACVjB,SAAS,KAIjB,KAAKxE,EAA2B,CAC9B,MAAMoN,cAAEA,EAAAnE,YAAeA,EAAaoE,MAAAA,GAAUzI,EAAO1E,QAGjD,IAAC6B,EAAMqL,KAAmBrL,EAAMqL,GAAenE,GAAqB,OAAAlH,EAExE,MAAMuL,EAAUvL,EAAMqL,GAAenE,GAG/BsE,EAAgBjK,OAAOkK,YAAYlK,OAAOuF,QAAQwE,GAAO9O,QAAO,EAAEkP,KAAOA,KAAKH,KAGpF,OAA0C,IAAtChK,OAAOoK,KAAKH,GAAenO,OAAqB2C,EAE7C,IACFA,EACHqL,CAACA,GAAgB,IACZrL,EAAMqL,GACTnE,CAACA,GAAc,IACVqE,KACAC,IAGT,CAEF,QACS,OAAAxL,EAAA,EMhHXtE,kKLdK,WACL,OAOEe,GACGA,CACP,uBC8CgB,SAAqBsD,EAAwBC,GACrD,MAAA+B,EAAWjC,EAAgBC,EAAMC,GACnC,MAAkB,UAAlB+B,EAASnG,KACJ,CAAC,EAEHmG,EAAS1B,WAAa,CAAC,CAChC,oBKVO,SAA2B2C,GAChC,MAAO,WAAYA,CACrB,mBL5BgB,SAAiBjD,EAAwBC,GACjD,MAAA+B,EAAWjC,EAAgBC,EAAMC,GAEnC,MAAkB,UAAlB+B,EAASnG,QAINmG,EAASxB,MAClB,qBAYgB,SAAmBR,EAAwBC,GACnD,MAAA+B,EAAWjC,EAAgBC,EAAMC,GAEnC,MAAkB,UAAlB+B,EAASnG,QAINmG,EAASvB,QAClB,oBAlBgB,SAAkBT,EAAwBC,GAClD,MAAA+B,EAAWjC,EAAgBC,EAAMC,GAEnC,MAAkB,UAAlB+B,EAASnG,QAINmG,EAASzB,OAClB"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/lib/manifest.ts","../src/lib/actions.ts","../src/lib/utils/schema-merger.ts","../src/lib/utils/responsive-utils.ts","../src/lib/utils/consts.ts","../src/lib/utils/stylesheet-generator.ts","../src/lib/ui-plugin.ts","../src/lib/reducer.ts","../src/lib/selectors.ts","../src/lib/index.ts","../src/lib/utils/ui-props.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { UIPluginConfig } from './types';\n\nexport const UI_PLUGIN_ID = 'ui';\n\nexport const manifest: PluginManifest<UIPluginConfig> = {\n id: UI_PLUGIN_ID,\n name: 'UI Plugin',\n version: '1.0.0',\n provides: ['ui'],\n requires: ['commands'], // Depends on commands\n optional: ['i18n'],\n defaultConfig: {\n enabled: true,\n schema: {\n id: 'empty',\n version: '1.0.0',\n toolbars: {},\n menus: {},\n panels: {},\n selectionMenus: {},\n },\n },\n};\n","import { Action } from '@embedpdf/core';\nimport { OpenMenuState, UISchema } from './types';\n\nexport const INIT_UI_STATE = 'UI/INIT_STATE';\nexport const CLEANUP_UI_STATE = 'UI/CLEANUP_STATE';\nexport const SET_ACTIVE_TOOLBAR = 'UI/SET_ACTIVE_TOOLBAR';\nexport const CLOSE_TOOLBAR_SLOT = 'UI/CLOSE_TOOLBAR_SLOT';\nexport const SET_ACTIVE_PANEL = 'UI/SET_ACTIVE_PANEL';\nexport const CLOSE_PANEL_SLOT = 'UI/CLOSE_PANEL_SLOT';\nexport const SET_PANEL_TAB = 'UI/SET_PANEL_TAB';\nexport const OPEN_MODAL = 'UI/OPEN_MODAL';\nexport const CLOSE_MODAL = 'UI/CLOSE_MODAL';\nexport const OPEN_MENU = 'UI/OPEN_MENU';\nexport const CLOSE_MENU = 'UI/CLOSE_MENU';\nexport const CLOSE_ALL_MENUS = 'UI/CLOSE_ALL_MENUS';\nexport const SET_DISABLED_CATEGORIES = 'UI/SET_DISABLED_CATEGORIES';\n\nexport interface InitUIStateAction extends Action {\n type: typeof INIT_UI_STATE;\n payload: { documentId: string; schema: UISchema };\n}\n\nexport interface CleanupUIStateAction extends Action {\n type: typeof CLEANUP_UI_STATE;\n payload: { documentId: string };\n}\n\nexport interface SetActiveToolbarAction extends Action {\n type: typeof SET_ACTIVE_TOOLBAR;\n payload: { documentId: string; placement: string; slot: string; toolbarId: string };\n}\n\nexport interface CloseToolbarSlotAction extends Action {\n type: typeof CLOSE_TOOLBAR_SLOT;\n payload: { documentId: string; placement: string; slot: string };\n}\n\nexport interface SetActivePanelAction extends Action {\n type: typeof SET_ACTIVE_PANEL;\n payload: {\n documentId: string;\n placement: string;\n slot: string;\n panelId: string;\n activeTab?: string;\n };\n}\n\nexport interface ClosePanelSlotAction extends Action {\n type: typeof CLOSE_PANEL_SLOT;\n payload: { documentId: string; placement: string; slot: string };\n}\n\nexport interface SetPanelTabAction extends Action {\n type: typeof SET_PANEL_TAB;\n payload: { documentId: string; panelId: string; tabId: string };\n}\n\nexport interface OpenModalAction extends Action {\n type: typeof OPEN_MODAL;\n payload: { documentId: string; modalId: string };\n}\n\nexport interface CloseModalAction extends Action {\n type: typeof CLOSE_MODAL;\n payload: { documentId: string };\n}\n\nexport interface OpenMenuAction extends Action {\n type: typeof OPEN_MENU;\n payload: { documentId: string; menuState: OpenMenuState };\n}\n\nexport interface CloseMenuAction extends Action {\n type: typeof CLOSE_MENU;\n payload: { documentId: string; menuId: string };\n}\n\nexport interface CloseAllMenusAction extends Action {\n type: typeof CLOSE_ALL_MENUS;\n payload: { documentId: string };\n}\n\nexport interface SetDisabledCategoriesAction extends Action {\n type: typeof SET_DISABLED_CATEGORIES;\n payload: { categories: string[] };\n}\n\nexport type UIAction =\n | InitUIStateAction\n | CleanupUIStateAction\n | SetActiveToolbarAction\n | CloseToolbarSlotAction\n | SetActivePanelAction\n | ClosePanelSlotAction\n | SetPanelTabAction\n | OpenModalAction\n | CloseModalAction\n | OpenMenuAction\n | CloseMenuAction\n | CloseAllMenusAction\n | SetDisabledCategoriesAction;\n\n// Action creators\nexport const initUIState = (documentId: string, schema: UISchema): InitUIStateAction => ({\n type: INIT_UI_STATE,\n payload: { documentId, schema },\n});\n\nexport const cleanupUIState = (documentId: string): CleanupUIStateAction => ({\n type: CLEANUP_UI_STATE,\n payload: { documentId },\n});\n\nexport const setActiveToolbar = (\n documentId: string,\n placement: string,\n slot: string,\n toolbarId: string,\n): SetActiveToolbarAction => ({\n type: SET_ACTIVE_TOOLBAR,\n payload: { documentId, placement, slot, toolbarId },\n});\n\nexport const closeToolbarSlot = (\n documentId: string,\n placement: string,\n slot: string,\n): CloseToolbarSlotAction => ({\n type: CLOSE_TOOLBAR_SLOT,\n payload: { documentId, placement, slot },\n});\n\nexport const setActivePanel = (\n documentId: string,\n placement: string,\n slot: string,\n panelId: string,\n activeTab?: string,\n): SetActivePanelAction => ({\n type: SET_ACTIVE_PANEL,\n payload: { documentId, placement, slot, panelId, activeTab },\n});\n\nexport const closePanelSlot = (\n documentId: string,\n placement: string,\n slot: string,\n): ClosePanelSlotAction => ({\n type: CLOSE_PANEL_SLOT,\n payload: { documentId, placement, slot },\n});\n\nexport const setPanelTab = (\n documentId: string,\n panelId: string,\n tabId: string,\n): SetPanelTabAction => ({\n type: SET_PANEL_TAB,\n payload: { documentId, panelId, tabId },\n});\n\nexport const openModal = (documentId: string, modalId: string): OpenModalAction => ({\n type: OPEN_MODAL,\n payload: { documentId, modalId },\n});\n\nexport const closeModal = (documentId: string): CloseModalAction => ({\n type: CLOSE_MODAL,\n payload: { documentId },\n});\n\nexport const openMenu = (documentId: string, menuState: OpenMenuState): OpenMenuAction => ({\n type: OPEN_MENU,\n payload: { documentId, menuState },\n});\n\nexport const closeMenu = (documentId: string, menuId: string): CloseMenuAction => ({\n type: CLOSE_MENU,\n payload: { documentId, menuId },\n});\n\nexport const closeAllMenus = (documentId: string): CloseAllMenusAction => ({\n type: CLOSE_ALL_MENUS,\n payload: { documentId },\n});\n\nexport const setDisabledCategories = (categories: string[]): SetDisabledCategoriesAction => ({\n type: SET_DISABLED_CATEGORIES,\n payload: { categories },\n});\n","import { UISchema, ToolbarSchema, MenuSchema, PanelSchema } from '../types';\n\n/**\n * Deep merge UI schemas\n * Allows users to override/extend default schema\n */\nexport function mergeUISchema(base: UISchema, override: Partial<UISchema>): UISchema {\n return {\n ...base,\n ...override,\n toolbars: mergeToolbars(base.toolbars, override.toolbars),\n menus: mergeMenus(base.menus, override.menus),\n panels: mergePanels(base.panels, override.panels),\n };\n}\n\nfunction mergeToolbars(\n base: Record<string, ToolbarSchema>,\n override?: Record<string, ToolbarSchema>,\n): Record<string, ToolbarSchema> {\n if (!override) return base;\n\n const result = { ...base };\n\n for (const [id, toolbar] of Object.entries(override)) {\n if (result[id]) {\n // Merge existing toolbar\n result[id] = {\n ...result[id],\n ...toolbar,\n items: toolbar.items ?? result[id].items,\n responsive: toolbar.responsive ?? result[id].responsive,\n };\n } else {\n // Add new toolbar\n result[id] = toolbar;\n }\n }\n\n return result;\n}\n\nfunction mergeMenus(\n base: Record<string, MenuSchema>,\n override?: Record<string, MenuSchema>,\n): Record<string, MenuSchema> {\n if (!override) return base;\n\n const result = { ...base };\n\n for (const [id, menu] of Object.entries(override)) {\n if (result[id]) {\n // Merge existing menu\n result[id] = {\n ...result[id],\n ...menu,\n items: menu.items ?? result[id].items,\n };\n } else {\n // Add new menu\n result[id] = menu;\n }\n }\n\n return result;\n}\n\nfunction mergePanels(\n base: Record<string, PanelSchema>,\n override?: Record<string, PanelSchema>,\n): Record<string, PanelSchema> {\n if (!override) return base;\n\n const result = { ...base };\n\n for (const [id, panel] of Object.entries(override)) {\n if (result[id]) {\n // Merge existing panel\n result[id] = {\n ...result[id],\n ...panel,\n content: panel.content ?? result[id].content,\n };\n } else {\n // Add new panel\n result[id] = panel;\n }\n }\n\n return result;\n}\n\n/**\n * Helper to remove items from schema\n */\nexport function removeFromSchema(\n schema: UISchema,\n options: {\n toolbars?: string[];\n menus?: string[];\n panels?: string[];\n commands?: string[]; // Remove commands from all menus/toolbars\n },\n): UISchema {\n const result = { ...schema };\n\n // Remove toolbars\n if (options.toolbars) {\n result.toolbars = { ...result.toolbars };\n options.toolbars.forEach((id) => delete result.toolbars[id]);\n }\n\n // Remove menus\n if (options.menus) {\n result.menus = { ...result.menus };\n options.menus.forEach((id) => delete result.menus[id]);\n }\n\n // Remove panels\n if (options.panels) {\n result.panels = { ...result.panels };\n options.panels.forEach((id) => delete result.panels[id]);\n }\n\n // Remove commands from all toolbars/menus\n if (options.commands) {\n result.toolbars = removeCommandsFromToolbars(result.toolbars, options.commands);\n result.menus = removeCommandsFromMenus(result.menus, options.commands);\n }\n\n return result;\n}\n\nfunction removeCommandsFromToolbars(\n toolbars: Record<string, ToolbarSchema>,\n commandIds: string[],\n): Record<string, ToolbarSchema> {\n const result: Record<string, ToolbarSchema> = {};\n\n for (const [id, toolbar] of Object.entries(toolbars)) {\n result[id] = {\n ...toolbar,\n items: toolbar.items.filter((item) => {\n if (item.type === 'command-button') {\n return !commandIds.includes(item.commandId);\n }\n if (item.type === 'group') {\n return item.items.some((child) =>\n child.type === 'command-button' ? !commandIds.includes(child.commandId) : true,\n );\n }\n if (item.type === 'tab-group') {\n return item.tabs.some((tab) => !commandIds.includes(tab.commandId));\n }\n return true;\n }),\n };\n }\n\n return result;\n}\n\nfunction removeCommandsFromMenus(\n menus: Record<string, MenuSchema>,\n commandIds: string[],\n): Record<string, MenuSchema> {\n const result: Record<string, MenuSchema> = {};\n\n for (const [id, menu] of Object.entries(menus)) {\n result[id] = {\n ...menu,\n items: menu.items.filter((item) => {\n if (item.type === 'command') {\n return !commandIds.includes(item.commandId);\n }\n if (item.type === 'section') {\n return item.items.some((child) =>\n child.type === 'command' ? !commandIds.includes(child.commandId) : true,\n );\n }\n return true;\n }),\n };\n }\n\n return result;\n}\n","import {\n ToolbarSchema,\n MenuSchema,\n ResponsiveMetadata,\n ResponsiveItemMetadata,\n ResponsiveVisibilityRule,\n BreakpointRule,\n LocaleOverrides,\n SelectionMenuSchema,\n} from '../types';\n\n/**\n * Processes responsive configuration and returns metadata for all items\n * This is framework-agnostic and lives in plugin-ui\n */\nexport function resolveResponsiveMetadata(\n schema: ToolbarSchema | MenuSchema | SelectionMenuSchema,\n currentLocale?: string,\n): ResponsiveMetadata | null {\n if (!schema.responsive?.breakpoints) {\n return null;\n }\n\n // Apply locale overrides to get effective breakpoints\n const effectiveBreakpoints = applyLocaleOverrides(\n schema.responsive.breakpoints,\n schema.responsive.localeOverrides,\n currentLocale,\n );\n\n const items = new Map<string, ResponsiveItemMetadata>();\n const breakpoints = new Map<string, { minWidth?: number; maxWidth?: number }>();\n\n // Extract breakpoint definitions (widths never change!)\n for (const [breakpointId, config] of Object.entries(effectiveBreakpoints)) {\n breakpoints.set(breakpointId, {\n minWidth: config.minWidth,\n maxWidth: config.maxWidth,\n });\n }\n\n // Collect all item IDs from schema\n const allItemIds = new Set<string>();\n const collectItemIds = (items: any[]) => {\n items.forEach((item) => {\n allItemIds.add(item.id);\n if (item.type === 'group' && item.items) {\n collectItemIds(item.items);\n }\n if (item.type === 'tab-group' && item.tabs) {\n collectItemIds(item.tabs);\n }\n if (item.type === 'section' && item.items) {\n collectItemIds(item.items);\n }\n });\n };\n collectItemIds(schema.items);\n\n // Process each item\n for (const itemId of allItemIds) {\n const rules: ResponsiveVisibilityRule[] = [];\n let defaultVisible = true; // Assume visible by default\n\n // Sort breakpoints by width for proper cascade\n const sortedBreakpoints = Array.from(Object.entries(effectiveBreakpoints)).sort((a, b) => {\n const aMin = a[1].minWidth ?? 0;\n const bMin = b[1].minWidth ?? 0;\n return aMin - bMin;\n });\n\n sortedBreakpoints.forEach(([breakpointId, config], index) => {\n const isHidden = config.hide?.includes(itemId);\n const isShown = config.show?.includes(itemId);\n\n // If neither hide nor show mentions this item, skip\n if (!isHidden && !isShown) {\n return;\n }\n\n rules.push({\n breakpointId,\n minWidth: config.minWidth,\n maxWidth: config.maxWidth,\n visible: isShown || !isHidden,\n priority: index,\n });\n\n // The first (smallest) breakpoint determines default visibility\n if (index === 0) {\n defaultVisible = isShown || !isHidden;\n }\n });\n\n // Only add items that have responsive rules\n if (rules.length > 0) {\n items.set(itemId, {\n itemId,\n shouldRender: true, // Always render for SSR\n visibilityRules: rules,\n defaultVisible,\n });\n }\n }\n\n return { items, breakpoints };\n}\n\n/**\n * Apply locale-specific overrides to breakpoints\n * Merges locale-specific show/hide rules with base breakpoints\n */\nfunction applyLocaleOverrides(\n baseBreakpoints: Record<string, BreakpointRule>,\n localeOverrides: LocaleOverrides | undefined,\n currentLocale: string | undefined,\n): Record<string, BreakpointRule> {\n // No locale or no overrides - return base breakpoints\n if (!currentLocale || !localeOverrides?.groups) {\n return baseBreakpoints;\n }\n\n // Find matching locale group\n const matchingGroup = localeOverrides.groups.find((group) =>\n group.locales.includes(currentLocale),\n );\n\n // No matching group - return base breakpoints\n if (!matchingGroup) {\n return baseBreakpoints;\n }\n\n // Clone and merge show/hide rules\n const effective: Record<string, BreakpointRule> = {};\n\n for (const [breakpointId, baseRule] of Object.entries(baseBreakpoints)) {\n const override = matchingGroup.breakpoints[breakpointId];\n\n if (!override) {\n // No override for this breakpoint - use base as-is\n effective[breakpointId] = baseRule;\n continue;\n }\n\n // Merge the rules\n effective[breakpointId] = {\n // Width constraints never change!\n minWidth: baseRule.minWidth,\n maxWidth: baseRule.maxWidth,\n\n // Merge hide lists (base + additional) or use replacement\n hide: override.replaceHide\n ? override.replaceHide\n : [...(baseRule.hide || []), ...(override.hide || [])],\n\n // Merge show lists (base + additional) or use replacement\n show: override.replaceShow\n ? override.replaceShow\n : [...(baseRule.show || []), ...(override.show || [])],\n };\n }\n\n return effective;\n}\n\n/**\n * Get responsive metadata for a specific item\n */\nexport function getItemResponsiveMetadata(\n itemId: string,\n schema: ToolbarSchema | MenuSchema,\n currentLocale?: string,\n): ResponsiveItemMetadata | null {\n const metadata = resolveResponsiveMetadata(schema, currentLocale);\n return metadata?.items.get(itemId) ?? null;\n}\n","/**\n * Using 'embedpdf' prefix to avoid conflicts with other libraries.\n */\nexport const UI_ATTRIBUTES = {\n /** Root element marker */\n ROOT: 'data-epdf',\n /** Style element marker for deduplication */\n STYLES: 'data-epdf-s',\n /** Item ID for responsive and dependency rules */\n ITEM: 'data-epdf-i',\n /** Item categories for category-based hiding */\n CATEGORIES: 'data-epdf-cat',\n /** Disabled categories list on root element */\n DISABLED_CATEGORIES: 'data-epdf-dis',\n} as const;\n\n/**\n * CSS selectors derived from attributes\n */\nexport const UI_SELECTORS = {\n ROOT: `[${UI_ATTRIBUTES.ROOT}]`,\n STYLES: `[${UI_ATTRIBUTES.STYLES}]`,\n ITEM: (id: string) => `[${UI_ATTRIBUTES.ITEM}=\"${id}\"]`,\n CATEGORIES: (category: string) => `[${UI_ATTRIBUTES.CATEGORIES}~=\"${category}\"]`,\n DISABLED_CATEGORY: (category: string) => `[${UI_ATTRIBUTES.DISABLED_CATEGORIES}~=\"${category}\"]`,\n} as const;\n","import {\n UISchema,\n ToolbarSchema,\n ToolbarItem,\n TabItem,\n MenuSchema,\n MenuItem,\n PanelSchema,\n SelectionMenuSchema,\n SelectionMenuItem,\n BreakpointRule,\n VisibilityDependency,\n ResponsiveItemMetadata,\n} from '../types';\nimport { resolveResponsiveMetadata } from './responsive-utils';\nimport { UI_ATTRIBUTES, UI_SELECTORS } from './consts';\n\n// ─────────────────────────────────────────────────────────\n// Configuration\n// ─────────────────────────────────────────────────────────\n\nexport interface StylesheetConfig {\n /** Use container queries (@container) instead of media queries (@media). Default: true */\n useContainerQueries?: boolean;\n}\n\nexport interface StylesheetGenerationOptions {\n config?: StylesheetConfig;\n /** Current locale for locale-aware responsive rules */\n locale?: string;\n}\n\nconst DEFAULT_CONFIG: Required<StylesheetConfig> = {\n useContainerQueries: true,\n};\n\n// ─────────────────────────────────────────────────────────\n// Analysis Types\n// ─────────────────────────────────────────────────────────\n\ninterface SchemaAnalysis {\n /** All unique categories found in schema */\n categories: Set<string>;\n /** Map of item ID -> categories array */\n itemCategories: Map<string, string[]>;\n /** All dependency rules collected from schema */\n dependencies: DependencyRule[];\n /** Breakpoint visibility info per menu (for dependency calculations) */\n menuBreakpoints: Map<string, BreakpointVisibility[]>;\n /** All responsive item metadata */\n responsiveItems: Map<string, ResponsiveItemMetadata>;\n}\n\ninterface DependencyRule {\n itemId: string;\n dependsOnMenuId?: string;\n dependsOnItemIds?: string[];\n}\n\ninterface BreakpointVisibility {\n minWidth?: number;\n maxWidth?: number;\n /** Categories that are responsive-visible at this breakpoint */\n visibleCategories: Set<string>;\n}\n\n// ─────────────────────────────────────────────────────────\n// Public API\n// ─────────────────────────────────────────────────────────\n\n/**\n * Generates complete CSS stylesheet for UI visibility.\n *\n * Includes:\n * 1. Responsive visibility rules (container queries or media queries)\n * 2. Category visibility rules\n * 3. Breakpoint-aware dependency rules\n *\n * This is pure logic - no DOM manipulation.\n *\n * @param schema - The UI schema to generate CSS for\n * @param options - Generation options including config and locale\n * @returns Generated CSS string\n */\nexport function generateUIStylesheet(\n schema: UISchema,\n options: StylesheetGenerationOptions = {},\n): string {\n const cfg = { ...DEFAULT_CONFIG, ...options.config };\n const locale = options.locale;\n const analysis = analyzeSchema(schema, locale);\n const sections: string[] = [];\n\n // Header\n sections.push(generateHeader(locale));\n\n // 1. Responsive visibility rules\n const responsiveCSS = generateResponsiveRules(analysis, cfg);\n if (responsiveCSS) sections.push(responsiveCSS);\n\n // 2. Category visibility rules\n const categoryCSS = generateCategoryRules(analysis, cfg);\n if (categoryCSS) sections.push(categoryCSS);\n\n // 3. Dependency rules (breakpoint-aware)\n const dependencyCSS = generateDependencyRules(analysis, cfg);\n if (dependencyCSS) sections.push(dependencyCSS);\n\n return sections.filter((s) => s.trim()).join('\\n\\n');\n}\n\n/**\n * Extract all unique categories from the schema.\n * Useful for building UI to toggle categories.\n *\n * @param schema - The UI schema to extract categories from\n * @returns Sorted array of unique category names\n */\nexport function extractCategories(schema: UISchema): string[] {\n const analysis = analyzeSchema(schema);\n return Array.from(analysis.categories).sort();\n}\n\n/**\n * Get the stylesheet configuration with defaults applied.\n *\n * @param config - Optional partial configuration\n * @returns Complete configuration with defaults\n */\nexport function getStylesheetConfig(config: StylesheetConfig = {}): Required<StylesheetConfig> {\n return { ...DEFAULT_CONFIG, ...config };\n}\n\n// ─────────────────────────────────────────────────────────\n// Schema Analysis\n// ─────────────────────────────────────────────────────────\n\nfunction analyzeSchema(schema: UISchema, locale?: string): SchemaAnalysis {\n const categories = new Set<string>();\n const itemCategories = new Map<string, string[]>();\n const dependencies: DependencyRule[] = [];\n const menuBreakpoints = new Map<string, BreakpointVisibility[]>();\n const responsiveItems = new Map<string, ResponsiveItemMetadata>();\n\n // Analyze menus first (needed for dependency calculations)\n for (const [menuId, menu] of Object.entries(schema.menus)) {\n analyzeMenu(\n menuId,\n menu,\n categories,\n itemCategories,\n dependencies,\n menuBreakpoints,\n responsiveItems,\n locale,\n );\n }\n\n // Analyze toolbars\n for (const [toolbarId, toolbar] of Object.entries(schema.toolbars)) {\n analyzeToolbar(\n toolbarId,\n toolbar,\n categories,\n itemCategories,\n dependencies,\n responsiveItems,\n locale,\n );\n }\n\n // Analyze panels\n for (const [panelId, panel] of Object.entries(schema.panels)) {\n analyzePanel(panelId, panel, categories, itemCategories, dependencies);\n }\n\n // Analyze selection menus\n for (const [selMenuId, selMenu] of Object.entries(schema.selectionMenus || {})) {\n analyzeSelectionMenu(\n selMenuId,\n selMenu,\n categories,\n itemCategories,\n dependencies,\n responsiveItems,\n locale,\n );\n }\n\n return { categories, itemCategories, dependencies, menuBreakpoints, responsiveItems };\n}\n\n// ─────────────────────────────────────────────────────────\n// Menu Analysis\n// ─────────────────────────────────────────────────────────\n\nfunction analyzeMenu(\n menuId: string,\n menu: MenuSchema,\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n menuBreakpoints: Map<string, BreakpointVisibility[]>,\n responsiveItems: Map<string, ResponsiveItemMetadata>,\n locale?: string,\n): void {\n // Menu-level categories and dependencies\n collectCategoriesAndDependency(\n menuId,\n menu.categories,\n menu.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n\n // Collect from menu items\n analyzeMenuItems(menu.items, categories, itemCategories, dependencies);\n\n // Get responsive metadata with locale\n const metadata = resolveResponsiveMetadata(menu, locale);\n if (metadata) {\n metadata.items.forEach((itemMeta, itemId) => {\n responsiveItems.set(itemId, itemMeta);\n });\n }\n\n // Compute visibility per breakpoint for dependency calculations\n const breakpointVisibilities = computeMenuBreakpointVisibilities(menu, itemCategories, locale);\n menuBreakpoints.set(menuId, breakpointVisibilities);\n}\n\nfunction analyzeMenuItems(\n items: MenuItem[],\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n): void {\n for (const item of items) {\n collectCategoriesAndDependency(\n item.id,\n item.categories,\n item.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n\n // Recurse into sections\n if (item.type === 'section') {\n analyzeMenuItems(item.items, categories, itemCategories, dependencies);\n }\n }\n}\n\nfunction computeMenuBreakpointVisibilities(\n menu: MenuSchema,\n itemCategories: Map<string, string[]>,\n locale?: string,\n): BreakpointVisibility[] {\n const breakpointVisibilities: BreakpointVisibility[] = [];\n\n // Get effective breakpoints (with locale overrides applied)\n const metadata = resolveResponsiveMetadata(menu, locale);\n\n if (menu.responsive?.breakpoints && metadata) {\n const sortedBreakpoints = Array.from(metadata.breakpoints.entries()).sort(\n (a, b) => (a[1].minWidth ?? 0) - (b[1].minWidth ?? 0),\n );\n\n for (const [_bpId, bp] of sortedBreakpoints) {\n const visibleItems = computeVisibleItemsAtBreakpoint(metadata, bp);\n const visibleCats = new Set<string>();\n\n for (const itemId of visibleItems) {\n const cats = itemCategories.get(itemId);\n if (cats) cats.forEach((c) => visibleCats.add(c));\n }\n\n breakpointVisibilities.push({\n minWidth: bp.minWidth,\n maxWidth: bp.maxWidth,\n visibleCategories: visibleCats,\n });\n }\n } else {\n // No responsive rules - collect all item categories\n const allCats = new Set<string>();\n collectAllMenuItemCategories(menu.items, itemCategories, allCats);\n breakpointVisibilities.push({ visibleCategories: allCats });\n }\n\n return breakpointVisibilities;\n}\n\nfunction collectAllMenuItemCategories(\n items: MenuItem[],\n itemCategories: Map<string, string[]>,\n result: Set<string>,\n): void {\n for (const item of items) {\n const cats = itemCategories.get(item.id);\n if (cats) cats.forEach((c) => result.add(c));\n\n if (item.type === 'section') {\n collectAllMenuItemCategories(item.items, itemCategories, result);\n }\n }\n}\n\nfunction computeVisibleItemsAtBreakpoint(\n metadata: {\n items: Map<string, ResponsiveItemMetadata>;\n breakpoints: Map<string, { minWidth?: number; maxWidth?: number }>;\n },\n targetBp: { minWidth?: number; maxWidth?: number },\n): string[] {\n const visible: string[] = [];\n\n metadata.items.forEach((itemMeta, itemId) => {\n // Check if item is visible at this breakpoint\n let isVisible = itemMeta.defaultVisible;\n\n for (const rule of itemMeta.visibilityRules) {\n // Check if this rule applies to our target breakpoint\n const ruleApplies =\n (rule.minWidth === undefined ||\n (targetBp.minWidth !== undefined && targetBp.minWidth >= rule.minWidth)) &&\n (rule.maxWidth === undefined ||\n (targetBp.maxWidth !== undefined && targetBp.maxWidth <= rule.maxWidth));\n\n if (ruleApplies) {\n isVisible = rule.visible;\n }\n }\n\n if (isVisible) {\n visible.push(itemId);\n }\n });\n\n return visible;\n}\n\n// ─────────────────────────────────────────────────────────\n// Toolbar Analysis\n// ─────────────────────────────────────────────────────────\n\nfunction analyzeToolbar(\n toolbarId: string,\n toolbar: ToolbarSchema,\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n responsiveItems: Map<string, ResponsiveItemMetadata>,\n locale?: string,\n): void {\n // Toolbar-level categories and dependencies\n collectCategoriesAndDependency(\n toolbarId,\n toolbar.categories,\n toolbar.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n\n // Get responsive metadata with locale\n const metadata = resolveResponsiveMetadata(toolbar, locale);\n if (metadata) {\n metadata.items.forEach((itemMeta, itemId) => {\n responsiveItems.set(itemId, itemMeta);\n });\n }\n\n // Analyze items\n analyzeToolbarItems(toolbar.items, categories, itemCategories, dependencies);\n}\n\nfunction analyzeToolbarItems(\n items: ToolbarItem[],\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n): void {\n for (const item of items) {\n collectCategoriesAndDependency(\n item.id,\n item.categories,\n item.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n\n // Recurse into groups\n if (item.type === 'group' && item.items) {\n analyzeToolbarItems(item.items, categories, itemCategories, dependencies);\n }\n\n // Recurse into tab groups\n if (item.type === 'tab-group' && item.tabs) {\n analyzeTabItems(item.tabs, categories, itemCategories, dependencies);\n }\n }\n}\n\nfunction analyzeTabItems(\n tabs: TabItem[],\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n): void {\n for (const tab of tabs) {\n collectCategoriesAndDependency(\n tab.id,\n tab.categories,\n tab.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n }\n}\n\n// ─────────────────────────────────────────────────────────\n// Panel Analysis\n// ─────────────────────────────────────────────────────────\n\nfunction analyzePanel(\n panelId: string,\n panel: PanelSchema,\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n): void {\n // Panel-level categories and dependencies\n collectCategoriesAndDependency(\n panelId,\n panel.categories,\n panel.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n\n // Analyze panel tabs if present\n if (panel.content.type === 'tabs') {\n for (const tab of panel.content.tabs) {\n collectCategoriesAndDependency(\n tab.id,\n tab.categories,\n tab.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n }\n }\n}\n\n// ─────────────────────────────────────────────────────────\n// Selection Menu Analysis\n// ─────────────────────────────────────────────────────────\n\nfunction analyzeSelectionMenu(\n selMenuId: string,\n selMenu: SelectionMenuSchema,\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n responsiveItems: Map<string, ResponsiveItemMetadata>,\n locale?: string,\n): void {\n // Selection menu level\n collectCategoriesAndDependency(\n selMenuId,\n selMenu.categories,\n selMenu.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n\n // Get responsive metadata if present\n if (selMenu.responsive) {\n const metadata = resolveResponsiveMetadata(selMenu, locale);\n if (metadata) {\n metadata.items.forEach((itemMeta, itemId) => {\n responsiveItems.set(itemId, itemMeta);\n });\n }\n }\n\n // Analyze items\n analyzeSelectionMenuItems(selMenu.items, categories, itemCategories, dependencies);\n}\n\nfunction analyzeSelectionMenuItems(\n items: SelectionMenuItem[],\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n): void {\n for (const item of items) {\n collectCategoriesAndDependency(\n item.id,\n item.categories,\n item.visibilityDependsOn,\n categories,\n itemCategories,\n dependencies,\n );\n\n // Recurse into groups\n if (item.type === 'group' && item.items) {\n analyzeSelectionMenuItems(item.items, categories, itemCategories, dependencies);\n }\n }\n}\n\n// ─────────────────────────────────────────────────────────\n// Shared Analysis Helpers\n// ─────────────────────────────────────────────────────────\n\nfunction collectCategoriesAndDependency(\n itemId: string,\n itemCats: string[] | undefined,\n visibilityDep: VisibilityDependency | undefined,\n categories: Set<string>,\n itemCategories: Map<string, string[]>,\n dependencies: DependencyRule[],\n): void {\n // Collect categories\n if (itemCats?.length) {\n itemCats.forEach((c) => categories.add(c));\n itemCategories.set(itemId, itemCats);\n }\n\n // Collect dependencies\n if (visibilityDep && (visibilityDep.menuId || visibilityDep.itemIds?.length)) {\n dependencies.push({\n itemId,\n dependsOnMenuId: visibilityDep.menuId,\n dependsOnItemIds: visibilityDep.itemIds,\n });\n }\n}\n\n// ─────────────────────────────────────────────────────────\n// CSS Generation - Header\n// ─────────────────────────────────────────────────────────\n\nfunction generateHeader(locale?: string): string {\n const localeInfo = locale ? ` (locale: ${locale})` : '';\n return `/* ═══════════════════════════════════════════════════════════════════════════ */\n/* EmbedPDF UI Stylesheet - Auto-generated${localeInfo} */\n/* DO NOT EDIT MANUALLY - This file is generated from your UI schema */\n/* ═══════════════════════════════════════════════════════════════════════════ */`;\n}\n\n// ─────────────────────────────────────────────────────────\n// CSS Generation - Responsive Rules\n// ─────────────────────────────────────────────────────────\n\nfunction generateResponsiveRules(\n analysis: SchemaAnalysis,\n cfg: Required<StylesheetConfig>,\n): string {\n const rules: string[] = [];\n const queryType = cfg.useContainerQueries ? '@container' : '@media';\n const processedItems = new Set<string>();\n\n // Process all responsive items\n analysis.responsiveItems.forEach((itemMeta, itemId) => {\n if (processedItems.has(itemId)) return;\n processedItems.add(itemId);\n\n const itemRules = generateItemResponsiveRules(itemId, itemMeta, queryType, cfg);\n if (itemRules) rules.push(itemRules);\n });\n\n if (rules.length === 0) return '';\n\n return `/* ─── Responsive Visibility Rules ─── */\n/* Items show/hide based on container width */\n\n${rules.join('\\n\\n')}`;\n}\n\nfunction generateItemResponsiveRules(\n itemId: string,\n metadata: ResponsiveItemMetadata,\n queryType: string,\n cfg: Required<StylesheetConfig>,\n): string | null {\n if (metadata.visibilityRules.length === 0) return null;\n\n const rules: string[] = [];\n const selector = UI_SELECTORS.ITEM(itemId);\n\n // Base visibility (for mobile-first approach)\n if (!metadata.defaultVisible) {\n rules.push(`${selector} { display: none; }`);\n }\n\n // Breakpoint-specific rules\n for (const rule of metadata.visibilityRules) {\n const conditions: string[] = [];\n\n if (rule.minWidth !== undefined) {\n conditions.push(`(min-width: ${rule.minWidth}px)`);\n }\n if (rule.maxWidth !== undefined) {\n conditions.push(`(max-width: ${rule.maxWidth}px)`);\n }\n\n if (conditions.length > 0) {\n const display = rule.visible ? 'flex' : 'none';\n rules.push(`${queryType} ${conditions.join(' and ')} {\n ${selector} { display: ${display}; }\n}`);\n }\n }\n\n return rules.length > 0 ? rules.join('\\n') : null;\n}\n\n// ─────────────────────────────────────────────────────────\n// CSS Generation - Category Rules\n// ─────────────────────────────────────────────────────────\n\nfunction generateCategoryRules(analysis: SchemaAnalysis, cfg: Required<StylesheetConfig>): string {\n if (analysis.categories.size === 0) return '';\n\n const rules: string[] = [];\n\n // Sort categories for consistent output\n const sortedCategories = Array.from(analysis.categories).sort();\n\n for (const category of sortedCategories) {\n // Using ~= selector matches when category is in space-separated list\n // This works correctly for items with multiple categories\n rules.push(\n `${UI_SELECTORS.ROOT}[${UI_ATTRIBUTES.DISABLED_CATEGORIES}~=\"${category}\"] [${UI_ATTRIBUTES.CATEGORIES}~=\"${category}\"] {\n display: none !important;\n}`,\n );\n }\n\n return `/* ─── Category Visibility Rules ─── */\n/* Items hide when ANY of their categories is disabled */\n/* Use: data-disabled-categories=\"category1 category2\" on root element */\n\n${rules.join('\\n\\n')}`;\n}\n\n// ─────────────────────────────────────────────────────────\n// CSS Generation - Dependency Rules\n// ─────────────────────────────────────────────────────────\n\nfunction generateDependencyRules(\n analysis: SchemaAnalysis,\n cfg: Required<StylesheetConfig>,\n): string {\n if (analysis.dependencies.length === 0) return '';\n\n const rules: string[] = [];\n const queryType = cfg.useContainerQueries ? '@container' : '@media';\n\n for (const dep of analysis.dependencies) {\n const depRules = generateSingleDependencyRules(dep, analysis, queryType, cfg);\n if (depRules.length > 0) {\n rules.push(...depRules);\n }\n }\n\n if (rules.length === 0) return '';\n\n return `/* ─── Dependency Visibility Rules ─── */\n/* Container elements hide when all their dependencies are hidden */\n\n${rules.join('\\n\\n')}`;\n}\n\nfunction generateSingleDependencyRules(\n dep: DependencyRule,\n analysis: SchemaAnalysis,\n queryType: string,\n cfg: Required<StylesheetConfig>,\n): string[] {\n const rules: string[] = [];\n\n // Handle menu-based dependencies\n if (dep.dependsOnMenuId) {\n const breakpoints = analysis.menuBreakpoints.get(dep.dependsOnMenuId);\n if (breakpoints && breakpoints.length > 0) {\n rules.push(`/* \"${dep.itemId}\" depends on menu \"${dep.dependsOnMenuId}\" */`);\n\n for (const bp of breakpoints) {\n if (bp.visibleCategories.size === 0) continue;\n\n // Generate selector: hide when ALL visible categories are disabled\n const categorySelectors = Array.from(bp.visibleCategories)\n .sort()\n .map((cat) => UI_SELECTORS.DISABLED_CATEGORY(cat))\n .join('');\n\n const cssRule = `${UI_SELECTORS.ROOT}${categorySelectors} ${UI_SELECTORS.ITEM(dep.itemId)} {\n display: none !important;\n}`;\n\n // Wrap in media/container query if breakpoint has width constraints\n const conditions: string[] = [];\n if (bp.minWidth !== undefined) conditions.push(`(min-width: ${bp.minWidth}px)`);\n if (bp.maxWidth !== undefined) conditions.push(`(max-width: ${bp.maxWidth}px)`);\n\n if (conditions.length > 0) {\n rules.push(`${queryType} ${conditions.join(' and ')} {\n ${cssRule}\n}`);\n } else {\n rules.push(cssRule);\n }\n }\n }\n }\n\n // Handle direct item dependencies\n if (dep.dependsOnItemIds?.length) {\n const relevantCategories = new Set<string>();\n for (const itemId of dep.dependsOnItemIds) {\n const cats = analysis.itemCategories.get(itemId);\n if (cats) cats.forEach((c) => relevantCategories.add(c));\n }\n\n if (relevantCategories.size > 0) {\n const categorySelectors = Array.from(relevantCategories)\n .sort()\n .map((cat) => UI_SELECTORS.DISABLED_CATEGORY(cat))\n .join('');\n\n rules.push(`/* \"${dep.itemId}\" depends on items: ${dep.dependsOnItemIds.join(', ')} */\n${UI_SELECTORS.ROOT}${categorySelectors} ${UI_SELECTORS.ITEM(dep.itemId)} {\n display: none !important;\n}`);\n }\n }\n\n return rules;\n}\n","import {\n BasePlugin,\n Listener,\n PluginRegistry,\n Unsubscribe,\n createBehaviorEmitter,\n createEmitter,\n createScopedEmitter,\n} from '@embedpdf/core';\nimport { I18nCapability, I18nPlugin } from '@embedpdf/plugin-i18n';\nimport {\n UICapability,\n UIPluginConfig,\n UIState,\n UIScope,\n UISchema,\n UIDocumentState,\n ToolbarChangedData,\n ToolbarChangedEvent,\n PanelChangedData,\n PanelChangedEvent,\n ModalChangedData,\n ModalChangedEvent,\n MenuChangedData,\n MenuChangedEvent,\n} from './types';\nimport {\n UIAction,\n initUIState,\n cleanupUIState,\n setActiveToolbar,\n closeToolbarSlot,\n setActivePanel,\n closePanelSlot,\n setPanelTab,\n openModal,\n closeModal,\n openMenu,\n closeMenu,\n closeAllMenus,\n setDisabledCategories,\n} from './actions';\nimport { mergeUISchema } from './utils/schema-merger';\nimport { generateUIStylesheet, StylesheetConfig } from './utils';\n\nexport class UIPlugin extends BasePlugin<UIPluginConfig, UICapability, UIState, UIAction> {\n static readonly id = 'ui' as const;\n\n private schema: UISchema;\n private stylesheetConfig: StylesheetConfig;\n\n // Stylesheet caching with locale awareness\n private cachedStylesheet: string | null = null;\n private cachedLocale: string | null = null;\n\n // Optional i18n integration\n private i18n: I18nCapability | null = null;\n private i18nCleanup: (() => void) | null = null;\n\n // Events\n private readonly categoryChanged$ = createBehaviorEmitter<{ disabledCategories: string[] }>();\n private readonly stylesheetInvalidated$ = createEmitter<void>();\n\n private readonly toolbarChanged$ = createScopedEmitter<\n ToolbarChangedData,\n ToolbarChangedEvent,\n string\n >((documentId, data) => ({ documentId, ...data }), { cache: false });\n\n private readonly panelChanged$ = createScopedEmitter<PanelChangedData, PanelChangedEvent, string>(\n (documentId, data) => ({ documentId, ...data }),\n { cache: false },\n );\n\n private readonly modalChanged$ = createScopedEmitter<ModalChangedData, ModalChangedEvent, string>(\n (documentId, data) => ({ documentId, ...data }),\n { cache: false },\n );\n\n private readonly menuChanged$ = createScopedEmitter<MenuChangedData, MenuChangedEvent, string>(\n (documentId, data) => ({ documentId, ...data }),\n { cache: false },\n );\n\n constructor(id: string, registry: PluginRegistry, config: UIPluginConfig) {\n super(id, registry);\n this.schema = config.schema;\n this.stylesheetConfig = config.stylesheetConfig || {};\n\n // Initialize disabled categories from config\n if (config.disabledCategories?.length) {\n this.dispatch(setDisabledCategories(config.disabledCategories));\n }\n\n this.i18n = registry.getPlugin<I18nPlugin>('i18n')?.provides() ?? null;\n\n if (this.i18n) {\n this.i18nCleanup = this.i18n.onLocaleChange(({ currentLocale }) => {\n this.handleLocaleChange(currentLocale);\n });\n\n // Initialize cached locale\n this.cachedLocale = this.i18n.getLocale();\n }\n }\n\n async initialize(): Promise<void> {\n this.logger.info('UIPlugin', 'Initialize', 'UI plugin initialized');\n }\n\n async destroy(): Promise<void> {\n if (this.i18nCleanup) {\n this.i18nCleanup();\n this.i18nCleanup = null;\n }\n\n this.toolbarChanged$.clear();\n this.panelChanged$.clear();\n this.modalChanged$.clear();\n this.menuChanged$.clear();\n this.stylesheetInvalidated$.clear();\n super.destroy();\n }\n\n protected override onDocumentLoadingStarted(documentId: string): void {\n this.dispatch(initUIState(documentId, this.schema));\n }\n\n protected override onDocumentClosed(documentId: string): void {\n this.dispatch(cleanupUIState(documentId));\n\n // Clear scoped emitters\n this.toolbarChanged$.clearScope(documentId);\n this.panelChanged$.clearScope(documentId);\n this.modalChanged$.clearScope(documentId);\n this.menuChanged$.clearScope(documentId);\n }\n\n /**\n * Handle locale changes from i18n plugin.\n * Invalidates stylesheet and emits change event.\n */\n private handleLocaleChange(newLocale: string): void {\n if (this.cachedLocale === newLocale) return;\n\n this.logger.debug(\n 'UIPlugin',\n 'LocaleChange',\n `Locale changed: ${this.cachedLocale} -> ${newLocale}`,\n );\n\n this.cachedLocale = newLocale;\n this.invalidateStylesheet();\n this.stylesheetInvalidated$.emit();\n }\n\n /**\n * Get the generated CSS stylesheet.\n * Automatically regenerates if locale has changed.\n * This is pure logic - DOM injection is handled by framework layer.\n */\n public getStylesheet(): string {\n const currentLocale = this.i18n?.getLocale() ?? null;\n\n // Check if we need to regenerate\n if (this.cachedStylesheet && this.cachedLocale === currentLocale) {\n return this.cachedStylesheet;\n }\n\n // Generate new stylesheet\n this.cachedStylesheet = generateUIStylesheet(this.schema, {\n config: this.stylesheetConfig,\n locale: currentLocale ?? undefined,\n });\n this.cachedLocale = currentLocale;\n\n return this.cachedStylesheet;\n }\n\n /**\n * Get the current locale (if i18n is available)\n */\n public getLocale(): string | null {\n return this.i18n?.getLocale() ?? null;\n }\n\n /**\n * Regenerate stylesheet (call after schema changes)\n */\n public invalidateStylesheet(): void {\n this.cachedStylesheet = null;\n }\n\n public onStylesheetInvalidated(listener: Listener<void>): Unsubscribe {\n return this.stylesheetInvalidated$.on(listener);\n }\n\n // ─────────────────────────────────────────────────────────\n // Category Management\n // ─────────────────────────────────────────────────────────\n\n private disableCategoryImpl(category: string): void {\n const current = new Set(this.state.disabledCategories);\n if (!current.has(category)) {\n current.add(category);\n this.dispatch(setDisabledCategories(Array.from(current)));\n this.categoryChanged$.emit({ disabledCategories: Array.from(current) });\n }\n }\n\n private enableCategoryImpl(category: string): void {\n const current = new Set(this.state.disabledCategories);\n if (current.has(category)) {\n current.delete(category);\n this.dispatch(setDisabledCategories(Array.from(current)));\n this.categoryChanged$.emit({ disabledCategories: Array.from(current) });\n }\n }\n\n private toggleCategoryImpl(category: string): void {\n if (this.state.disabledCategories.includes(category)) {\n this.enableCategoryImpl(category);\n } else {\n this.disableCategoryImpl(category);\n }\n }\n\n private setDisabledCategoriesImpl(categories: string[]): void {\n this.dispatch(setDisabledCategories(categories));\n this.categoryChanged$.emit({ disabledCategories: categories });\n }\n\n // ─────────────────────────────────────────────────────────\n // Capability\n // ─────────────────────────────────────────────────────────\n\n protected buildCapability(): UICapability {\n return {\n // Active document operations\n setActiveToolbar: (placement, slot, toolbarId, documentId) =>\n this.setToolbarForDocument(placement, slot, toolbarId, documentId),\n setActivePanel: (placement, slot, panelId, documentId, activeTab) =>\n this.setPanelForDocument(placement, slot, panelId, documentId, activeTab),\n togglePanel: (placement, slot, panelId, documentId, activeTab) =>\n this.togglePanelForDocument(placement, slot, panelId, documentId, activeTab),\n openModal: (modalId, documentId) => this.openModalForDocument(modalId, documentId),\n openMenu: (menuId, triggeredByCommandId, triggeredByItemId, documentId) =>\n this.openMenuForDocument(menuId, triggeredByCommandId, triggeredByItemId, documentId),\n toggleMenu: (menuId, triggeredByCommandId, triggeredByItemId, documentId) =>\n this.toggleMenuForDocument(menuId, triggeredByCommandId, triggeredByItemId, documentId),\n\n // Document-scoped operations\n forDocument: (documentId) => this.createUIScope(documentId),\n\n // Schema\n getSchema: () => this.schema,\n mergeSchema: (partial) => {\n this.schema = mergeUISchema(this.schema, partial);\n },\n\n // Category management\n disableCategory: (category) => this.disableCategoryImpl(category),\n enableCategory: (category) => this.enableCategoryImpl(category),\n toggleCategory: (category) => this.toggleCategoryImpl(category),\n setDisabledCategories: (categories) => this.setDisabledCategoriesImpl(categories),\n getDisabledCategories: () => this.state.disabledCategories,\n isCategoryDisabled: (category) => this.state.disabledCategories.includes(category),\n\n // Events\n onToolbarChanged: this.toolbarChanged$.onGlobal,\n onPanelChanged: this.panelChanged$.onGlobal,\n onModalChanged: this.modalChanged$.onGlobal,\n onMenuChanged: this.menuChanged$.onGlobal,\n onCategoryChanged: this.categoryChanged$.on,\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Scoping\n // ─────────────────────────────────────────────────────────\n\n private createUIScope(documentId: string): UIScope {\n return {\n // ───── Toolbars ─────\n setActiveToolbar: (placement, slot, toolbarId) =>\n this.setToolbarForDocument(placement, slot, toolbarId, documentId),\n getActiveToolbar: (placement, slot) =>\n this.getToolbarForDocument(placement, slot, documentId),\n closeToolbarSlot: (placement, slot) =>\n this.closeToolbarForDocument(placement, slot, documentId),\n isToolbarOpen: (placement, slot, toolbarId) =>\n this.isToolbarOpenForDocument(placement, slot, toolbarId, documentId),\n\n // ───── Panels ─────\n setActivePanel: (placement, slot, panelId, activeTab) =>\n this.setPanelForDocument(placement, slot, panelId, documentId, activeTab),\n getActivePanel: (placement, slot) => this.getPanelForDocument(placement, slot, documentId),\n closePanelSlot: (placement, slot) => this.closePanelForDocument(placement, slot, documentId),\n togglePanel: (placement, slot, panelId, activeTab) =>\n this.togglePanelForDocument(placement, slot, panelId, documentId, activeTab),\n isPanelOpen: (placement, slot, panelId) =>\n this.isPanelOpenForDocument(placement, slot, panelId, documentId),\n\n // ───── Panel tabs ─────\n setPanelTab: (panelId, tabId) => this.setPanelTabForDocument(panelId, tabId, documentId),\n getPanelTab: (panelId) => this.getPanelTabForDocument(panelId, documentId),\n\n // ───── Modals ─────\n openModal: (modalId) => this.openModalForDocument(modalId, documentId),\n closeModal: () => this.closeModalForDocument(documentId),\n getActiveModal: () => this.getActiveModalForDocument(documentId),\n\n // ───── Menus ─────\n openMenu: (menuId, triggeredByCommandId, triggeredByItemId) =>\n this.openMenuForDocument(menuId, triggeredByCommandId, triggeredByItemId, documentId),\n closeMenu: (menuId) => this.closeMenuForDocument(menuId, documentId),\n toggleMenu: (menuId, triggeredByCommandId, triggeredByItemId) =>\n this.toggleMenuForDocument(menuId, triggeredByCommandId, triggeredByItemId, documentId),\n closeAllMenus: () => this.closeAllMenusForDocument(documentId),\n isMenuOpen: (menuId) => this.isMenuOpenForDocument(menuId, documentId),\n getOpenMenus: () => this.getOpenMenusForDocument(documentId),\n\n // ───── Schema & state ─────\n getSchema: () => this.schema,\n getState: () => this.getDocumentStateOrThrow(documentId),\n\n // ───── Scoped events ─────\n onToolbarChanged: this.toolbarChanged$.forScope(documentId),\n onPanelChanged: this.panelChanged$.forScope(documentId),\n onModalChanged: this.modalChanged$.forScope(documentId),\n onMenuChanged: this.menuChanged$.forScope(documentId),\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // State Helpers\n // ─────────────────────────────────────────────────────────\n\n private getDocumentState(documentId?: string): UIDocumentState | null {\n const id = documentId ?? this.getActiveDocumentId();\n return this.state.documents[id] ?? null;\n }\n\n private getDocumentStateOrThrow(documentId?: string): UIDocumentState {\n const state = this.getDocumentState(documentId);\n if (!state) {\n throw new Error(`UI state not found for document: ${documentId ?? 'active'}`);\n }\n return state;\n }\n\n // ─────────────────────────────────────────────────────────\n // Core Operations - Toolbars\n // ─────────────────────────────────────────────────────────\n\n private setToolbarForDocument(\n placement: string,\n slot: string,\n toolbarId: string,\n documentId?: string,\n ): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(setActiveToolbar(id, placement, slot, toolbarId));\n this.toolbarChanged$.emit(id, { placement, slot, toolbarId });\n }\n\n private getToolbarForDocument(\n placement: string,\n slot: string,\n documentId?: string,\n ): string | null {\n const slotKey = `${placement}-${slot}`;\n const toolbarSlot = this.getDocumentStateOrThrow(documentId).activeToolbars[slotKey];\n return toolbarSlot?.isOpen ? toolbarSlot.toolbarId : null;\n }\n\n private closeToolbarForDocument(placement: string, slot: string, documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(closeToolbarSlot(id, placement, slot));\n this.toolbarChanged$.emit(id, { placement, slot, toolbarId: '' });\n }\n\n private isToolbarOpenForDocument(\n placement: string,\n slot: string,\n toolbarId?: string,\n documentId?: string,\n ): boolean {\n const slotKey = `${placement}-${slot}`;\n const toolbarSlot = this.getDocumentStateOrThrow(documentId).activeToolbars[slotKey];\n if (!toolbarSlot || !toolbarSlot.isOpen) return false;\n return toolbarId ? toolbarSlot.toolbarId === toolbarId : true;\n }\n\n // ─────────────────────────────────────────────────────────\n // Core Operations - Panels\n // ─────────────────────────────────────────────────────────\n\n private setPanelForDocument(\n placement: string,\n slot: string,\n panelId: string,\n documentId?: string,\n activeTab?: string,\n ): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(setActivePanel(id, placement, slot, panelId, activeTab));\n this.panelChanged$.emit(id, { placement, slot, panelId });\n }\n\n private getPanelForDocument(placement: string, slot: string, documentId?: string): string | null {\n const slotKey = `${placement}-${slot}`;\n const panelSlot = this.getDocumentStateOrThrow(documentId).activePanels[slotKey];\n return panelSlot?.isOpen ? panelSlot.panelId : null;\n }\n\n private closePanelForDocument(placement: string, slot: string, documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(closePanelSlot(id, placement, slot));\n this.panelChanged$.emit(id, { placement, slot, panelId: '' });\n }\n\n private togglePanelForDocument(\n placement: string,\n slot: string,\n panelId: string,\n documentId?: string,\n activeTab?: string,\n ): void {\n const id = documentId ?? this.getActiveDocumentId();\n const slotKey = `${placement}-${slot}`;\n const panelSlot = this.getDocumentStateOrThrow(id).activePanels[slotKey];\n\n if (panelSlot?.panelId === panelId && panelSlot?.isOpen) {\n this.dispatch(closePanelSlot(id, placement, slot));\n this.panelChanged$.emit(id, { placement, slot, panelId: '' });\n } else {\n this.dispatch(setActivePanel(id, placement, slot, panelId, activeTab));\n this.panelChanged$.emit(id, { placement, slot, panelId });\n }\n }\n\n private isPanelOpenForDocument(\n placement: string,\n slot: string,\n panelId?: string,\n documentId?: string,\n ): boolean {\n const slotKey = `${placement}-${slot}`;\n const panelSlot = this.getDocumentStateOrThrow(documentId).activePanels[slotKey];\n if (!panelSlot || !panelSlot.isOpen) return false;\n return panelId ? panelSlot.panelId === panelId : true;\n }\n\n // ─────────────────────────────────────────────────────────\n // Core Operations - Panel Tabs\n // ─────────────────────────────────────────────────────────\n\n private setPanelTabForDocument(panelId: string, tabId: string, documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(setPanelTab(id, panelId, tabId));\n }\n\n private getPanelTabForDocument(panelId: string, documentId?: string): string | null {\n return this.getDocumentStateOrThrow(documentId).panelTabs[panelId] ?? null;\n }\n\n // ─────────────────────────────────────────────────────────\n // Core Operations - Modals\n // ─────────────────────────────────────────────────────────\n\n private openModalForDocument(modalId: string, documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(openModal(id, modalId));\n this.modalChanged$.emit(id, { modalId });\n }\n\n private closeModalForDocument(documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(closeModal(id));\n this.modalChanged$.emit(id, { modalId: null });\n }\n\n private getActiveModalForDocument(documentId?: string): string | null {\n return this.getDocumentStateOrThrow(documentId).activeModal;\n }\n\n // ─────────────────────────────────────────────────────────\n // Core Operations - Menus\n // ─────────────────────────────────────────────────────────\n\n private openMenuForDocument(\n menuId: string,\n triggeredByCommandId?: string,\n triggeredByItemId?: string,\n documentId?: string,\n ): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(openMenu(id, { menuId, triggeredByCommandId, triggeredByItemId }));\n this.menuChanged$.emit(id, { menuId, isOpen: true });\n }\n\n private closeMenuForDocument(menuId: string, documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(closeMenu(id, menuId));\n this.menuChanged$.emit(id, { menuId, isOpen: false });\n }\n\n private toggleMenuForDocument(\n menuId: string,\n triggeredByCommandId?: string,\n triggeredByItemId?: string,\n documentId?: string,\n ): void {\n const id = documentId ?? this.getActiveDocumentId();\n const isOpen = !!this.getDocumentStateOrThrow(id).openMenus[menuId];\n\n if (isOpen) {\n this.dispatch(closeMenu(id, menuId));\n this.menuChanged$.emit(id, { menuId, isOpen: false });\n } else {\n this.dispatch(openMenu(id, { menuId, triggeredByCommandId, triggeredByItemId }));\n this.menuChanged$.emit(id, { menuId, isOpen: true });\n }\n }\n\n private closeAllMenusForDocument(documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n this.dispatch(closeAllMenus(id));\n }\n\n private isMenuOpenForDocument(menuId: string, documentId?: string): boolean {\n return !!this.getDocumentStateOrThrow(documentId).openMenus[menuId];\n }\n\n private getOpenMenusForDocument(documentId?: string): Array<{\n menuId: string;\n triggeredByCommandId?: string;\n triggeredByItemId?: string;\n }> {\n return Object.values(this.getDocumentStateOrThrow(documentId).openMenus);\n }\n}\n","import { UIState, UIDocumentState } from './types';\nimport {\n UIAction,\n INIT_UI_STATE,\n CLEANUP_UI_STATE,\n SET_ACTIVE_TOOLBAR,\n SET_ACTIVE_PANEL,\n CLOSE_PANEL_SLOT,\n CLOSE_TOOLBAR_SLOT,\n SET_PANEL_TAB,\n OPEN_MODAL,\n CLOSE_MODAL,\n OPEN_MENU,\n CLOSE_MENU,\n CLOSE_ALL_MENUS,\n SET_DISABLED_CATEGORIES,\n} from './actions';\n\nexport const initialDocumentState: UIDocumentState = {\n activeToolbars: {},\n activePanels: {},\n activeModal: null,\n openMenus: {},\n panelTabs: {},\n};\n\nexport const initialState: UIState = {\n documents: {},\n disabledCategories: [],\n};\n\nexport const uiReducer = (state = initialState, action: UIAction): UIState => {\n switch (action.type) {\n case INIT_UI_STATE: {\n const { documentId, schema } = action.payload;\n\n // Initialize permanent toolbars from schema\n const activeToolbars: Record<string, { toolbarId: string; isOpen: boolean }> = {};\n\n Object.values(schema.toolbars).forEach((toolbar) => {\n if (toolbar.permanent && toolbar.position) {\n const slotKey = `${toolbar.position.placement}-${toolbar.position.slot}`;\n activeToolbars[slotKey] = {\n toolbarId: toolbar.id,\n isOpen: true, // Permanent toolbars are always open\n };\n }\n });\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...initialDocumentState,\n activeToolbars, // Initialize with permanent toolbars\n },\n },\n };\n }\n\n case CLEANUP_UI_STATE: {\n const { documentId } = action.payload;\n const { [documentId]: removed, ...remaining } = state.documents;\n return {\n ...state,\n documents: remaining,\n };\n }\n\n case SET_ACTIVE_TOOLBAR: {\n const { documentId, placement, slot, toolbarId } = action.payload;\n const docState = state.documents[documentId] || initialDocumentState;\n const slotKey = `${placement}-${slot}`;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n activeToolbars: {\n ...docState.activeToolbars,\n [slotKey]: {\n toolbarId,\n isOpen: true,\n },\n },\n },\n },\n };\n }\n\n case SET_ACTIVE_PANEL: {\n const { documentId, placement, slot, panelId, activeTab } = action.payload;\n const docState = state.documents[documentId] || initialDocumentState;\n const slotKey = `${placement}-${slot}`;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n activePanels: {\n ...docState.activePanels,\n [slotKey]: {\n panelId,\n isOpen: true,\n },\n },\n ...(activeTab && {\n panelTabs: {\n ...docState.panelTabs,\n [panelId]: activeTab,\n },\n }),\n },\n },\n };\n }\n\n case CLOSE_PANEL_SLOT: {\n const { documentId, placement, slot } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n const slotKey = `${placement}-${slot}`;\n const panelSlot = docState.activePanels[slotKey];\n\n // If no panel in this slot, nothing to close\n if (!panelSlot) return state;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n activePanels: {\n ...docState.activePanels,\n [slotKey]: {\n ...panelSlot,\n isOpen: false, // Keep panel, just close it\n },\n },\n },\n },\n };\n }\n\n case CLOSE_TOOLBAR_SLOT: {\n const { documentId, placement, slot } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n const slotKey = `${placement}-${slot}`;\n const toolbarSlot = docState.activeToolbars[slotKey];\n\n // If no toolbar in this slot, nothing to close\n if (!toolbarSlot) return state;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n activeToolbars: {\n ...docState.activeToolbars,\n [slotKey]: {\n ...toolbarSlot,\n isOpen: false, // Keep toolbar, just close it\n },\n },\n },\n },\n };\n }\n\n case SET_PANEL_TAB: {\n const { documentId, panelId, tabId } = action.payload;\n const docState = state.documents[documentId] || initialDocumentState;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n panelTabs: {\n ...docState.panelTabs,\n [panelId]: tabId,\n },\n },\n },\n };\n }\n\n case OPEN_MODAL: {\n const { documentId, modalId } = action.payload;\n const docState = state.documents[documentId] || initialDocumentState;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n activeModal: modalId,\n openMenus: {}, // Close all menus when opening modal\n },\n },\n };\n }\n\n case CLOSE_MODAL: {\n const { documentId } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n activeModal: null,\n },\n },\n };\n }\n\n case OPEN_MENU: {\n const { documentId, menuState } = action.payload;\n const docState = state.documents[documentId] || initialDocumentState;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n openMenus: {\n // Close other menus, open this one\n [menuState.menuId]: menuState,\n },\n },\n },\n };\n }\n\n case CLOSE_MENU: {\n const { documentId, menuId } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n const { [menuId]: removed, ...remainingMenus } = docState.openMenus;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n openMenus: remainingMenus,\n },\n },\n };\n }\n\n case CLOSE_ALL_MENUS: {\n const { documentId } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n openMenus: {},\n },\n },\n };\n }\n\n case SET_DISABLED_CATEGORIES: {\n return {\n ...state,\n disabledCategories: action.payload.categories,\n };\n }\n\n default:\n return state;\n }\n};\n","import { UIState, UIDocumentState, ToolbarSlotState, PanelSlotState } from './types';\n\n// Shape of state.plugins passed into command active()\nexport type PluginsSlice = Record<string, any>;\n\nexport function selectUIState(plugins: PluginsSlice): UIState | null {\n return (plugins['ui'] as UIState | undefined) ?? null;\n}\n\nexport function selectUIDocumentState(\n plugins: PluginsSlice,\n documentId: string,\n): UIDocumentState | null {\n const ui = selectUIState(plugins);\n return ui?.documents[documentId] ?? null;\n}\n\nfunction makeSlotKey(placement: string, slot: string): string {\n return `${placement}-${slot}`;\n}\n\n// ─────────────────────────────────────────────────────────\n// Toolbars\n// ─────────────────────────────────────────────────────────\n\nexport function selectToolbarSlot(\n plugins: PluginsSlice,\n documentId: string,\n placement: string,\n slot: string,\n): ToolbarSlotState | null {\n const doc = selectUIDocumentState(plugins, documentId);\n if (!doc) return null;\n return doc.activeToolbars[makeSlotKey(placement, slot)] ?? null;\n}\n\n/**\n * Is a toolbar open in this slot?\n * If toolbarId is provided, also matches that specific toolbar.\n */\nexport function isToolbarOpen(\n plugins: PluginsSlice,\n documentId: string,\n placement: string,\n slot: string,\n toolbarId?: string,\n): boolean {\n const slotState = selectToolbarSlot(plugins, documentId, placement, slot);\n if (!slotState || !slotState.isOpen) return false;\n return toolbarId ? slotState.toolbarId === toolbarId : true;\n}\n\n// ─────────────────────────────────────────────────────────\n// Panels\n// ─────────────────────────────────────────────────────────\n\nexport function selectPanelSlot(\n plugins: PluginsSlice,\n documentId: string,\n placement: string,\n slot: string,\n): PanelSlotState | null {\n const doc = selectUIDocumentState(plugins, documentId);\n if (!doc) return null;\n return doc.activePanels[makeSlotKey(placement, slot)] ?? null;\n}\n\n/**\n * Is a panel open in this slot?\n * If panelId is provided, also matches that specific panel.\n */\nexport function isPanelOpen(\n plugins: PluginsSlice,\n documentId: string,\n placement: string,\n slot: string,\n panelId?: string,\n): boolean {\n const slotState = selectPanelSlot(plugins, documentId, placement, slot);\n if (!slotState || !slotState.isOpen) return false;\n return panelId ? slotState.panelId === panelId : true;\n}\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, UI_PLUGIN_ID } from './manifest';\nimport { UIPluginConfig, UIState } from './types';\nimport { UIPlugin } from './ui-plugin';\nimport { UIAction } from './actions';\nimport { uiReducer, initialState } from './reducer';\n\nexport const UIPluginPackage: PluginPackage<UIPlugin, UIPluginConfig, UIState, UIAction> = {\n manifest,\n create: (registry, config) => new UIPlugin(UI_PLUGIN_ID, registry, config),\n reducer: uiReducer,\n initialState,\n};\n\nexport * from './ui-plugin';\nexport * from './types';\nexport * from './schema';\nexport * from './manifest';\nexport * from './utils';\nexport * from './selectors';\nexport * from './actions';\n\n// Explicit exports for stylesheet generation (useful for SSR/build-time generation)\nexport {\n generateUIStylesheet,\n extractCategories,\n getStylesheetConfig,\n type StylesheetConfig,\n} from './utils/stylesheet-generator';\n","import { UI_ATTRIBUTES } from './consts';\n\nexport interface UIItemLike {\n id: string;\n categories?: string[];\n}\n\nexport interface UIItemProps {\n [UI_ATTRIBUTES.ITEM]: string;\n [UI_ATTRIBUTES.CATEGORIES]?: string;\n}\n\n/**\n * Get data attribute props for a UI item.\n * Spread these onto the wrapper element for CSS-based visibility control.\n */\nexport function getUIItemProps<\n T extends Record<string, string | undefined> = Record<string, never>,\n>(item: UIItemLike, extra?: T): UIItemProps & T {\n const props = {\n [UI_ATTRIBUTES.ITEM]: item.id,\n [UI_ATTRIBUTES.CATEGORIES]: item.categories?.join(' ') || undefined,\n ...extra,\n } as UIItemProps & T;\n\n return props;\n}\n"],"names":["UI_PLUGIN_ID","manifest","id","name","version","provides","requires","optional","defaultConfig","enabled","schema","toolbars","menus","panels","selectionMenus","INIT_UI_STATE","CLEANUP_UI_STATE","SET_ACTIVE_TOOLBAR","CLOSE_TOOLBAR_SLOT","SET_ACTIVE_PANEL","CLOSE_PANEL_SLOT","SET_PANEL_TAB","OPEN_MODAL","CLOSE_MODAL","OPEN_MENU","CLOSE_MENU","CLOSE_ALL_MENUS","SET_DISABLED_CATEGORIES","initUIState","documentId","type","payload","cleanupUIState","setActiveToolbar","placement","slot","toolbarId","closeToolbarSlot","setActivePanel","panelId","activeTab","closePanelSlot","setPanelTab","tabId","openModal","modalId","closeModal","openMenu","menuState","closeMenu","menuId","closeAllMenus","setDisabledCategories","categories","mergeUISchema","base","override","mergeToolbars","mergeMenus","mergePanels","result","toolbar","Object","entries","items","responsive","menu","panel","content","resolveResponsiveMetadata","currentLocale","_a","breakpoints","effectiveBreakpoints","baseBreakpoints","localeOverrides","groups","matchingGroup","find","group","locales","includes","effective","breakpointId","baseRule","minWidth","maxWidth","hide","replaceHide","show","replaceShow","applyLocaleOverrides","Map","config","set","allItemIds","Set","collectItemIds","forEach","item","add","tabs","itemId","rules","defaultVisible","Array","from","sort","a","b","index","isHidden","isShown","_b","push","visible","priority","length","shouldRender","visibilityRules","UI_ATTRIBUTES","ROOT","STYLES","ITEM","CATEGORIES","DISABLED_CATEGORIES","UI_SELECTORS","category","DISABLED_CATEGORY","DEFAULT_CONFIG","useContainerQueries","generateUIStylesheet","options","cfg","locale","analysis","analyzeSchema","sections","localeInfo","generateHeader","responsiveCSS","queryType","processedItems","responsiveItems","itemMeta","has","itemRules","metadata","selector","rule","conditions","display","join","generateItemResponsiveRules","generateResponsiveRules","categoryCSS","size","sortedCategories","generateCategoryRules","dependencyCSS","dependencies","dep","depRules","generateSingleDependencyRules","generateDependencyRules","filter","s","trim","itemCategories","menuBreakpoints","analyzeMenu","analyzeToolbar","analyzePanel","selMenuId","selMenu","analyzeSelectionMenu","collectCategoriesAndDependency","visibilityDependsOn","analyzeMenuItems","breakpointVisibilities","sortedBreakpoints","_bpId","bp","visibleItems","computeVisibleItemsAtBreakpoint","visibleCats","cats","get","c","visibleCategories","allCats","collectAllMenuItemCategories","computeMenuBreakpointVisibilities","targetBp","isVisible","analyzeToolbarItems","analyzeTabItems","tab","analyzeSelectionMenuItems","itemCats","visibilityDep","itemIds","dependsOnMenuId","dependsOnItemIds","categorySelectors","map","cat","cssRule","relevantCategories","_UIPlugin","BasePlugin","constructor","registry","super","this","cachedStylesheet","cachedLocale","i18n","i18nCleanup","categoryChanged$","createBehaviorEmitter","stylesheetInvalidated$","createEmitter","toolbarChanged$","createScopedEmitter","data","cache","panelChanged$","modalChanged$","menuChanged$","stylesheetConfig","disabledCategories","dispatch","getPlugin","onLocaleChange","handleLocaleChange","getLocale","initialize","logger","info","destroy","clear","onDocumentLoadingStarted","onDocumentClosed","clearScope","newLocale","debug","invalidateStylesheet","emit","getStylesheet","onStylesheetInvalidated","listener","on","disableCategoryImpl","current","state","enableCategoryImpl","delete","toggleCategoryImpl","setDisabledCategoriesImpl","buildCapability","setToolbarForDocument","setPanelForDocument","togglePanel","togglePanelForDocument","openModalForDocument","triggeredByCommandId","triggeredByItemId","openMenuForDocument","toggleMenu","toggleMenuForDocument","forDocument","createUIScope","getSchema","mergeSchema","partial","disableCategory","enableCategory","toggleCategory","getDisabledCategories","isCategoryDisabled","onToolbarChanged","onGlobal","onPanelChanged","onModalChanged","onMenuChanged","onCategoryChanged","getActiveToolbar","getToolbarForDocument","closeToolbarForDocument","isToolbarOpen","isToolbarOpenForDocument","getActivePanel","getPanelForDocument","closePanelForDocument","isPanelOpen","isPanelOpenForDocument","setPanelTabForDocument","getPanelTab","getPanelTabForDocument","closeModalForDocument","getActiveModal","getActiveModalForDocument","closeMenuForDocument","closeAllMenusForDocument","isMenuOpen","isMenuOpenForDocument","getOpenMenus","getOpenMenusForDocument","getState","getDocumentStateOrThrow","forScope","getDocumentState","getActiveDocumentId","documents","Error","slotKey","toolbarSlot","activeToolbars","isOpen","panelSlot","activePanels","panelTabs","activeModal","openMenus","values","UIPlugin","initialDocumentState","initialState","selectUIState","plugins","selectUIDocumentState","ui","makeSlotKey","selectToolbarSlot","doc","selectPanelSlot","UIPluginPackage","create","reducer","action","permanent","position","removed","remaining","docState","remainingMenus","extra","slotState","commands","commandIds","commandId","some","child","removeCommandsFromToolbars","removeCommandsFromMenus"],"mappings":"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"}
|