@hazem3500/komo 0.9.0 → 0.9.1
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/README.md +52 -0
- package/dist/adapters/class-theme.d.ts +22 -0
- package/dist/adapters/class-theme.js +1 -0
- package/dist/adapters/tailwind.d.ts +62 -0
- package/dist/adapters/tailwind.js +1 -0
- package/dist/chunk-5LHGJFWQ.js +1 -0
- package/dist/chunk-JC6FXUNO.js +1 -0
- package/dist/design-comment-RTVUFVDE.js +1 -0
- package/dist/design-comment.d.ts +8 -0
- package/dist/design-mode-styles.d.ts +1 -1
- package/dist/design-mode.d.ts +2 -0
- package/dist/design-mode.js +1 -1
- package/dist/design-system.d.ts +150 -0
- package/dist/design-tokens.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/inline-text-editor-SWPVB35B.js +1 -0
- package/dist/inline-text-editor.d.ts +3 -0
- package/dist/node.mjs +1 -1
- package/dist/react-inspector.d.ts +9 -1
- package/dist/react-props-panel-XQ4T3RLV.js +1 -0
- package/dist/react-props-panel.d.ts +3 -1
- package/dist/react.js +1 -1
- package/dist/review-layout.d.ts +3 -1
- package/dist/setup.js +1 -1
- package/dist/tag-editor-ZA7NLPOJ.js +1 -0
- package/dist/{toolbar-runtime-2SIUE6SQ.js → toolbar-runtime-2JO6YXD5.js} +1 -1
- package/dist/types.d.ts +7 -0
- package/package.json +11 -2
- package/server/iap.ts +133 -0
- package/server/setup-client.txt +116 -72
- package/src/types.ts +8 -0
- package/dist/chunk-JQVBZ2BB.js +0 -1
- package/dist/chunk-Z2ABBESO.js +0 -1
- package/dist/design-comment-QPTW66JO.js +0 -1
- package/dist/inline-text-editor-F7B6FQQ3.js +0 -1
- package/dist/react-props-panel-XSMDR2CY.js +0 -1
- package/dist/tag-editor-VDPZ6CO3.js +0 -1
|
@@ -39,5 +39,13 @@ export declare function isEditablePropValue(prop: InspectableProp, value: unknow
|
|
|
39
39
|
export declare function registerInspectableRoot(element: HTMLElement, definition: InspectableComponent, props: Record<string, unknown>, onChange: (next: Record<string, InspectableScalar>) => void): () => void;
|
|
40
40
|
/** Refresh a registered root's latest state and callback without replacing its identity. */
|
|
41
41
|
export declare function updateInspectableRoot(element: HTMLElement | null, definition: InspectableComponent, props: Record<string, unknown>, onChange: (next: Record<string, InspectableScalar>) => void): void;
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* The registered React component whose root is exactly this element. Descendants
|
|
44
|
+
* don't inherit the root's props, like layers inside a Figma instance.
|
|
45
|
+
*/
|
|
43
46
|
export declare function inspectableFor(target: Element | null): RegisteredInspectableComponent | null;
|
|
47
|
+
/** The nearest registered component root strictly above `target`, if any. */
|
|
48
|
+
export declare function inspectableAncestor(target: Element | null): {
|
|
49
|
+
root: HTMLElement;
|
|
50
|
+
component: RegisteredInspectableComponent;
|
|
51
|
+
} | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,d as t,e as n,g as i,h as o,i as a,j as r,k as s,l as d,m as l,n as p,o as c,p as u,q as g,r as f,s as m,t as h,u as b,v as k,w as x,x as v}from"./chunk-JC6FXUNO.js";import"./chunk-I7AUKTXE.js";var y=new Map,w=new WeakMap,E=new WeakSet,C=new WeakMap;function $(e){return void 0===e?"unset":JSON.stringify(e)??"unset"}var S=new Map;function P(e){if(e)for(let[e,n]of y){let i=t(e);i&&(S.set(e,i.props),i.setProps({...i.props,...Object.fromEntries(n)}))}else for(let[e,n]of S)t(e)?.setProps(n);e||S.clear(),s(e)}function N(e){return!!y.get(e)?.size}function A(e){let n=t(e),i=n?.definition.textProp,o=n?.definition.props.find(e=>e.name===i);if(!n||!i||"string"!==o?.kind)return null;let a=n.props[i];if("string"!=typeof a||a.length>500)return null;let r=y.get(e);return r||y.set(e,r=new Map),r.has(i)||r.set(i,a),{propName:i,before:a}}function z(n,i,o){let a=t(n),r=a?.definition.props.find(e=>e.name===i);return!(!a||a.definition.textProp!==i||"string"!==r?.kind||o.length>500||!e(r,o))&&(a.setProps({...a.props,[i]:o}),!0)}function M(e,t,n,i){if(n===i){let i=y.get(e);return void(i?.get(t)===n&&!(w.get(e)??[]).some(e=>e.propName===t)&&(i.delete(t),i.size||y.delete(e)))}let o=w.get(e);o||w.set(e,o=[]),o.push({propName:t,before:n,after:i})}function L(e,t,n){z(e,t,n);let i=y.get(e);i?.get(t)===n&&!(w.get(e)??[]).some(e=>e.propName===t)&&(i.delete(t),i.size||y.delete(e))}function T(e){return!!e&&!!w.get(e)?.length}function R(e){let n=y.get(e),o=t(e);if(!n?.size||!o)return;let a=i(e),r=[...n].map(([e,t])=>{let n=o.definition.props.find(t=>t.name===e)?.styleProperty,i=o.props[e],r=n&&"string"==typeof i?a?.tokens.find(e=>e.properties.includes(n)&&i===`var(${e.cssVariable})`):void 0;return`- ${e}: ${$(t)} → ${$(i)}${r?` [${r.path}]`:" [custom value]"}`});return["Proposed React prop changes (preview only)",`Component: ${o.definition.name}`,`Source: ${o.definition.source}:${o.definition.line}`,...r,"Preview values use the app's React state callback; Komo does not write source files."].join("\n")}function q(e){return[R(e),v(e)].filter(e=>!!e).join("\n\n")||void 0}function D(e,n,i){C.get(e)?.abort();let o=new AbortController;C.set(e,o),e.addEventListener("click",e=>{let o=n();if(!o)return;let a=v(o);!t(o)&&!a||(e.stopImmediatePropagation(),i(o,q(o)))},{capture:!0,signal:o.signal})}function j(e){return b(e)}function O(e){return h(e)}function V(e){k(e)}function B(e){x(e)}function H(e){if(!e||E.has(e))return;let t=document.createElement("style");t.textContent=".design-react-source{display:block;padding:0 0 8px;color:#77736f;font-size:10px;overflow-wrap:anywhere}.design-react-inside{padding:10px 12px}.design-react-inside button{padding:0;border:0;background:none;color:#bda6ef;font:inherit;cursor:pointer}.design-react-inside button:hover{text-decoration:underline}.design-react-field.design-field{display:grid;grid-template-columns:76px minmax(0,1fr);gap:0 8px;height:auto;min-height:28px;margin-top:4px;background:none;box-shadow:none;color:#898680;font-size:11px}.design-react-field>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.design-react-field.design-field>:is(input,select){box-sizing:border-box;width:100%;min-width:0;height:28px;padding:0 8px;border:0;border-radius:6px;background:#ffffff0a;color:#f1efeb;font:inherit;font-size:11px}.design-react-field.design-field>:is(input,select):focus-visible{outline:1px solid #bda6ef;outline-offset:-1px}.design-react-field input[type=checkbox]{justify-self:end;width:14px;height:14px;accent-color:#bda6ef}.design-react-field input:disabled{opacity:.55;cursor:not-allowed}.design-react-type{display:none}.design-react-field .design-token-binding{grid-column:2;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:6px;margin-top:4px;color:#77736f;font-size:10px}.design-react-field .design-token-binding select{min-width:0;height:24px;border:0;border-radius:6px;background:#ffffff0a;color:#e9e6e1;padding:0 6px;font:inherit;font-size:10px}.design-react-field .design-token-binding[data-mode=token] select{background:#bda6ef24;color:#e6dcfb}.design-token-binding__state{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.design-field>.design-token-binding{display:contents}.design-field:has(>.design-token-binding)>input[data-property]{padding-right:28px}.design-token-icon,.design-token-detach,.design-field>.design-token-binding select{position:absolute;top:4px;right:4px;width:20px;height:20px;box-sizing:border-box;border-radius:5px}.design-token-icon{display:grid;place-items:center;color:#77736f;opacity:0;pointer-events:none;transition:opacity .12s}.design-token-icon::before{content:'';width:6px;height:6px;border:1.2px solid currentColor;border-radius:1.5px;rotate:45deg}.design-field:is(:hover,:focus-within) .design-token-icon{opacity:1}.design-field>.design-token-binding select{margin:0;padding:0;border:0;opacity:0;cursor:pointer;appearance:none}.design-field>.design-token-binding select:hover+.design-token-icon,.design-field:has(.design-token-binding select:hover) .design-token-icon{background:#ffffff14;color:#e9e6e1}.design-field:has(.design-token-binding select:focus-visible) :is(.design-token-icon,.design-token-chip){outline:2px solid #bda6ef;outline-offset:1px;opacity:1}.design-field[data-token-mode=override] .design-token-icon{opacity:1;color:#e7c27d}.design-token-chip,.design-token-detach{display:none}.design-field:is([data-token-mode=token],[data-token-mode=connected])>input[data-property]{visibility:hidden}.design-field:is([data-token-mode=token],[data-token-mode=connected]) .design-token-chip{position:absolute;inset:4px 28px 4px var(--lead,4px);display:flex;align-items:center;gap:5px;padding:0 6px;border-radius:4px;background:#bda6ef1f;color:#e6dcfb;font-size:11px;white-space:nowrap;overflow:hidden;pointer-events:none}.design-token-chip::before{content:'';flex:none;width:5px;height:5px;border:1.2px solid #c8b5f4;border-radius:1px;rotate:45deg}.design-field:is([data-token-mode=token],[data-token-mode=connected]) .design-token-binding select{left:var(--lead,4px);right:28px;width:auto}.design-field:is([data-token-mode=token],[data-token-mode=connected]) .design-token-icon{display:none}.design-field:is([data-token-mode=token],[data-token-mode=connected]) .design-token-detach{display:grid;place-items:center;color:#898680}.design-token-detach:hover{background:#ffffff14;color:#f1efeb}.design-token-detach svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.2;stroke-linecap:round}.design-theme-group .design-react-source{padding:0 0 6px}.design-theme-heading{display:block;padding:8px 0 2px;color:#77736f;font-size:10px;text-transform:capitalize}.design-theme-token{position:relative;display:grid;grid-template-columns:96px minmax(0,1fr) 20px;align-items:center;gap:6px;margin-top:4px}.design-theme-token>span{overflow:hidden;color:#898680;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.design-theme-token[data-changed]>span{color:#e6dcfb}.design-theme-token[data-changed]::before{content:'';position:absolute;top:calc(50% - 2px);left:-8px;width:4px;height:4px;border-radius:50%;background:#bda6ef}.design-theme-reset{display:grid;place-items:center;width:20px;height:20px;padding:0;border:0;border-radius:5px;background:none;color:#77736f;cursor:pointer}.design-theme-reset:disabled{visibility:hidden}.design-theme-reset:hover{background:#ffffff14;color:#f1efeb}.design-theme-reset svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}",e.append(t),E.add(e)}function F(e,t,n,a){let r=i(e);if(!r)return null;let s=m(r,t);if(!s.length)return null;H(a);let d=document.createElement("span");d.className="design-token-binding",d.setAttribute("data-mode","custom");let c=document.createElement("span");c.className="design-token-icon",c.setAttribute("aria-hidden","true");let h=document.createElement("span");h.className="design-token-chip",h.setAttribute("aria-hidden","true");let b=document.createElement("button");b.type="button",b.className="design-token-detach",b.title="Detach token",b.setAttribute("aria-label",`Detach token from ${t}`),b.innerHTML='<svg viewBox="0 0 12 12"><path d="M5 3.5 6.5 2a2.1 2.1 0 0 1 3 3L8 6.5M7 8.5 5.5 10a2.1 2.1 0 0 1-3-3L4 5.5M2 2l8 8"/></svg>';let k=document.createElement("select");k.setAttribute("aria-label",`Style token for ${t}`);let x=document.createElement("small");x.className="design-token-binding__state",x.setAttribute("aria-live","polite");let v=`komo-token-${t}-${Math.random().toString(36).slice(2,8)}`;x.id=v,k.setAttribute("aria-describedby",v);let y=document.createElement("option");y.value="custom",y.textContent="Custom value",k.append(y);for(let e of s){let t=document.createElement("option"),n=o(r,e);t.value=e.path,t.textContent=n?`${e.path} · ${n}`:e.path,k.append(t)}let w=()=>{let n=u(r,e,t),i=n?null:g(r,e,t),o="token"===n?.mode?s.find(e=>e.path===n.tokenPath):void 0,a=o??i?.token;k.value=a?.path??"custom",h.textContent=a?.path??"";let l=n?.declaredPath,p=o?"token":i?"connected":l?"override":"custom";d.dataset.mode=p,d.parentElement?.setAttribute("data-token-mode",p),x.textContent="token"===p?l&&l!==o?.path?`Rebound from ${l} · preview`:`Linked to ${o?.path} · preview`:"connected"===p?"Connected "+("inline"===i?.origin?"inline":"from stylesheet"):"override"===p?`Custom override · was ${l}`:"",k.title=x.textContent||"Choose a token"},E=new MutationObserver(w);E.observe(e,{attributes:!0,attributeFilter:["style"]});let C=new MutationObserver(()=>{d.isConnected||(E.disconnect(),C.disconnect())});return C.observe(d.ownerDocument,{childList:!0,subtree:!0}),k.addEventListener("change",()=>{let i=e.style.getPropertyValue(t),o=s.find(e=>e.path===k.value),a=u(r,e,t);if(o&&a&&o.path===a.declaredPath)f(r,e,t),n(i,e.style.getPropertyValue(t),o.path);else if(o)(o.path!==g(r,e,t)?.token.path||a)&&l(r,e,o,t,{recordHistory:!1})&&n(i,e.style.getPropertyValue(t),o.path);else{let o=d.parentElement?.querySelector("[data-property]")?.value??getComputedStyle(e).getPropertyValue(t).trim(),a=/^-?[\d.]+$/.test(o.trim())&&!/weight|line/.test(t)?`${o.trim()}px`:o;p(r,e,t,a),e.style.setProperty(t,a),n(i,a)}w()}),b.addEventListener("click",()=>{let e=s.find(e=>e.path===k.value),t=d.parentElement?.querySelector("input[data-property]"),n=e&&o(r,e);t&&n&&(t.value="number"===t.type?String(parseFloat(n)):n),k.value="custom",k.dispatchEvent(new Event("change")),d.parentElement?.querySelector("[data-property]")?.focus()}),d.append(h,k,c,b,x),queueMicrotask(w),w(),d}function I(e){let t=i(e);return new Set(t?.elementBindings.get(e)?.keys()??[])}function U(e,t,n,i,o,a,r){for(let s of t){let t=[...n.querySelectorAll("[data-field-property]")].find(e=>e.dataset.fieldProperty===s.property);if(!t||t.querySelector(".design-token-binding"))continue;let d=t.querySelector("[data-property]");if(!d)continue;let l=F(e,s.property,n=>{i(s,d,n),a&&(d.value=a(s,e));let o=t.querySelector('input[type="range"],input[type="color"]');o&&(o.value="color"===s.kind&&r?r(d.value):d.value)},o);l&&t.append(l)}}var W=!1;function _(e,t,n,o){let a=i(e);if(!a||!a.tokens.length)return null;H(o);let r=document.createElement("details");r.className="design-group design-theme-group",r.open=W,r.addEventListener("toggle",()=>{r.isConnected&&(W=r.open)});let s=document.createElement("summary");s.textContent="Shared theme";let d=document.createElement("small");d.className="design-react-source",d.textContent="Changes every element using these tokens",r.append(s,d);let l=new Map;for(let e of a.tokens){let t=e.path.split(".")[0];l.set(t,[...l.get(t)??[],e])}let p=a.tokens.length>6&&l.size>1;for(let[e,i]of p?l:new Map([["",a.tokens]])){if(e){let t=document.createElement("small");t.className="design-theme-heading",t.textContent=e,r.append(t)}for(let o of i)r.append(K(a,o,t,n,e))}return r}function K(e,t,n,i,s){let l=document.createElement("div");l.className="design-theme-token";let p=document.createElement("span");p.textContent=s&&t.path.slice(s.length+1)||t.path,p.title=`${t.path} · ${a(e,t)} matching · ${t.impactSelector}`;let c=n.fields.find(e=>t.properties.includes(e.property)),u={property:t.cssVariable,label:`Shared theme value for ${t.path}`,kind:"dimension"===t.type?"size":c?.kind??"text",glyph:"color"===t.type?void 0:c?.glyph,values:c?.values},g=!1,f=n.fieldControl(u,{element:e.root,begin:()=>{g=!1},apply:(n,o,a)=>{let s=null!==a&&r(e,t,a.trim(),g);n.setAttribute("aria-invalid",String(!s)),s&&(g=!0,k(),i())},commit:(e,t,n)=>{!1!==n&&(g=!1,"true"===e.getAttribute("aria-invalid")&&b())}}),m=f.querySelector("[data-property]"),h=f.querySelector('input[type="color"]'),b=()=>{let i=o(e,t);m.value=i,h&&(h.value=n.toHex(i)),m.removeAttribute("aria-invalid"),k()},k=()=>{x.disabled=!l.toggleAttribute("data-changed",e.themeEdits.has(t.path)),"fontFamily"===t.type&&(m.title=m.value)},x=document.createElement("button");return x.type="button",x.className="design-theme-reset",x.title="Reset to page value",x.setAttribute("aria-label",`Reset ${t.path}`),x.innerHTML='<svg viewBox="0 0 16 16"><path d="M2.5 2.5v3h3M3 5.5a5.5 5.5 0 1 1-.5 2.5"/></svg>',x.addEventListener("click",()=>{d(e,t),b(),i()}),b(),l.append(p,f,x),l}function J(e,t,n){let o=i(e);o&&p(o,e,t,n)}function X(e,t){let n=i(e);n&&c(n,e,t)}function G(e){let n=w.get(e)?.pop(),i=t(e);if(!n||!i)return;i.setProps({...i.props,[n.propName]:n.before});let o=y.get(e);if(o){let t=o.get(n.propName);Object.is(t,n.before)&&o.delete(n.propName),o.size||y.delete(e)}}function Q(e){let n=y.get(e),i=t(e);!n?.size||!i||(i.setProps({...i.props,...Object.fromEntries(n)}),y.delete(e),w.delete(e))}function Y(t,n,i,o,a,r){let s=n.definition.props.find(e=>e.name===i);if(!s||!e(s,o))return a.setAttribute("aria-invalid","true"),!1;a.removeAttribute("aria-invalid");let d=n.props[i];if(Object.is(d,o))return!0;let l=y.get(t);l||y.set(t,l=new Map);let p=l.has(i)?l.get(i):d;Object.is(p,o)?l.delete(i):l.set(i,p),l.size||y.delete(t);let c=w.get(t);return c||w.set(t,c=[]),c.push({propName:i,before:d,after:o}),n.setProps({...n.props,[i]:o}),r(),!0}function Z(e,o,a,r){let s=t(e);if(!s)return function(e,t,i){let o=n(e);if(!o)return null;H(i);let a=document.createElement("small");if(a.className="design-react-source design-react-group design-react-inside",a.append(`Inside ${o.component.definition.name}`),t){let e=document.createElement("button");e.type="button",e.textContent="Select component",e.addEventListener("click",()=>t(o.root)),a.append(" · ",e)}return a}(e,r,a);H(a);let d=document.createElement("details");d.className="design-group design-react-group",d.open=!0;let l=document.createElement("summary");l.textContent="Properties",d.append(l);let p=document.createElement("small");p.className="design-react-source",p.textContent=`${s.definition.name} · ${s.definition.source}:${s.definition.line}`,d.append(p);for(let t of s.definition.props){let n=t.styleProperty,a=document.createElement("label");a.className="design-field design-react-field";let r=document.createElement("span");r.textContent=t.name;let l,p=s.props[t.name];if("enum"===t.kind){let e=document.createElement("select");for(let n of t.values??[]){let t=document.createElement("option");t.value=String(n),t.textContent=String(n),e.append(t)}if(void 0===p&&!t.required){let t=document.createElement("option");t.value="",t.textContent="unset",e.prepend(t)}e.value=void 0===p?"":String(p),l=e}else{let e=document.createElement("input");"boolean"===t.kind?(e.type="checkbox",e.checked=!0===p):"number"===t.kind?(e.type="number",e.step="any",e.value="number"==typeof p?String(p):""):(e.type="text",e.maxLength=500,e.autocomplete="off",e.value="string"==typeof p?p:""),l=e}if(l.setAttribute("aria-label",`${s.definition.name} ${t.name}`),"unsupported"===t.kind)l=document.createElement("input"),l.disabled=!0,l.value=`Read only · ${t.typeLabel}`,l.setAttribute("aria-label",`${s.definition.name} ${t.name}, read only`),a.title=`Komo does not edit ${t.typeLabel} props.`;else{let n=()=>{let n=l instanceof HTMLInputElement&&"checkbox"===l.type?l.checked:l.value,i=n;if("number"===t.kind)i=""===String(n).trim()?void 0:Number(n);else if("enum"===t.kind){let e=(t.values??[]).find(e=>String(e)===n);i=""!==n||t.required?e:void 0}else"boolean"===t.kind&&(i=!0===n);Y(e,s,t.name,i,l,o)};l.addEventListener("change",n)}a.append(r,l);let c=document.createElement("small");if(c.className="design-react-type",c.textContent=`${t.typeLabel}${t.required?" · required":" · optional"}`,a.append(c),a.title||=c.textContent,"string"===t.kind&&n){let r=i(e),d=r?m(r,n):[];if(d.length){let i=document.createElement("span");i.className="design-token-binding";let r=document.createElement("span");r.textContent="Style token";let p=document.createElement("select");p.setAttribute("aria-label",`Style token for ${t.name}`);let c=document.createElement("option");c.value="custom",c.textContent="Custom value",p.append(c);for(let e of d){let t=document.createElement("option");t.value=e.path,t.textContent=e.path,p.append(t)}let u=()=>{let e=d.find(e=>s.props[t.name]===`var(${e.cssVariable})`);p.value=e?.path??"custom",i.dataset.mode=e?"token":"custom"};p.addEventListener("change",()=>{let i=d.find(e=>e.path===p.value),a=i?`var(${i.cssVariable})`:"string"==typeof s.props[t.name]&&String(s.props[t.name]).startsWith("var(")?e.ownerDocument.defaultView?.getComputedStyle(e).getPropertyValue(n).trim()??"":"string"==typeof s.props[t.name]?s.props[t.name]:"";Y(e,s,t.name,a,l,o)&&u()}),i.append(r,p),a.append(i),u()}}d.append(a)}return d}export{U as attachStyleTokenControls,A as beginReactTextEdit,j as canUndoDesignTokenEdit,T as canUndoReactProp,L as cancelReactTextEdit,_ as createDesignThemePanel,F as createElementTokenControl,Z as createReactPropsPanel,M as finishReactTextEdit,O as hasDesignTokenEdit,N as hasReactPropChanges,D as installCommentCapture,J as noteDesignTokenOverride,z as previewReactTextEdit,q as proposedDesignChanges,R as proposedReactChanges,B as resetDesignTokenEdits,Q as resetReactProps,P as showDesignBefore,X as syncDesignTokenBinding,I as tokenBoundProperties,V as undoDesignTokenEdit,G as undoReactProp};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Before/After for React prop previews and shared theme values. */
|
|
2
|
+
export declare function showDesignBefore(on: boolean): void;
|
|
1
3
|
export declare function hasReactPropChanges(element: HTMLElement): boolean;
|
|
2
4
|
export interface ReactTextEditStart {
|
|
3
5
|
propName: string;
|
|
@@ -35,5 +37,5 @@ export declare function noteDesignTokenOverride(element: HTMLElement, property:
|
|
|
35
37
|
export declare function syncDesignTokenBinding(element: HTMLElement, property: string): void;
|
|
36
38
|
export declare function undoReactProp(element: HTMLElement): void;
|
|
37
39
|
export declare function resetReactProps(element: HTMLElement): void;
|
|
38
|
-
export declare function createReactPropsPanel(element: HTMLElement, onEdit: () => void, styleRoot?: ShadowRoot): HTMLElement | null;
|
|
40
|
+
export declare function createReactPropsPanel(element: HTMLElement, onEdit: () => void, styleRoot?: ShadowRoot, select?: (root: HTMLElement) => void): HTMLElement | null;
|
|
39
41
|
export {};
|
package/dist/react.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{b as e,c as n,
|
|
1
|
+
"use client";import{b as e,c as n,f as t}from"./chunk-JC6FXUNO.js";import{b as r}from"./chunk-5LHGJFWQ.js";import"./chunk-Q7WSWLMV.js";import"./chunk-Y2GRLW4Q.js";import"./chunk-7YUXYVQA.js";import"./chunk-YZP3KX4Y.js";import"./chunk-I7AUKTXE.js";import{useEffect as o,useRef as s}from"react";function c(e){let n=s(null);o(()=>{if(n.current&&function(e,n){return[...new Set([...Object.keys(e),...Object.keys(n)])].every(t=>{if("shortcuts"===t||"features"===t){let r=e[t]??{},o=n[t]??{};return Object.keys({...r,...o}).every(e=>Object.is(r[e],o[e]))}if("design"===t){let t=e.design,r=n.design;if(!t||!r)return t===r;let o=t.themes??[],s=r.themes??[];return t.tokens===r.tokens&&t.components===r.components&&o.length===s.length&&o.every((e,n)=>e===s[n])}if("onboarding"!==t)return Object.is(e[t],n[t]);let r=e.onboarding,o=n.onboarding;return r&&o?Object.keys({...r,...o}).every(e=>"sites"===e?r.sites?.length===o.sites?.length&&(r.sites??[]).every((e,n)=>e===o.sites?.[n]):Object.is(r[e],o[e])):r===o})}(n.current.config,e)||(n.current?.controller.destroy(),n.current=null,!1===e.enabled))return;let t={...e,...e.onboarding?{onboarding:{...e.onboarding,...e.onboarding.sites?{sites:[...e.onboarding.sites]}:{}}}:{}};n.current={config:t,controller:r(t)}}),o(()=>()=>{n.current?.controller.destroy(),n.current=null},[])}function u(t){let r=s(null),c=s(null);return c.current||(c.current=e=>{r.current=e}),o(()=>{if(!0===t.enabled&&r.current)return e(r.current,t.component,t.props,t.onChange)},[t.enabled,t.component]),o(()=>{!0===t.enabled&&n(r.current,t.component,t.props,t.onChange)},[t.enabled,t.component,t.props,t.onChange]),{ref:c.current,"data-komo-inspectable":t.component.id}}function i(e){o(()=>{if(!0!==e.enabled)return;let n=e.root??document.documentElement;return t(n,e.tokens)},[e.root,e.tokens,e.enabled])}export{c as useKomo,i as useKomoDesignTokens,u as useKomoInspectable};
|
package/dist/review-layout.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const REVIEW_BREAKPOINT = 760;
|
|
2
2
|
export declare const isCompactReview: (width: number, height: number) => boolean;
|
|
3
|
-
export declare function reviewLayout(width: number, height: number, expanded: boolean, pageHeight?: number, account?: boolean
|
|
3
|
+
export declare function reviewLayout(width: number, height: number, expanded: boolean, pageHeight?: number, account?: boolean,
|
|
4
|
+
/** Fit the page's full width beside the sidebar instead of letting it run under the left edge. */
|
|
5
|
+
fit?: boolean): {
|
|
4
6
|
desktop: boolean;
|
|
5
7
|
mobile: boolean;
|
|
6
8
|
framed: boolean;
|
package/dist/setup.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as o,c as n}from"./chunk-
|
|
1
|
+
import{a as o,c as n}from"./chunk-5LHGJFWQ.js";import"./chunk-Q7WSWLMV.js";import"./chunk-Y2GRLW4Q.js";import"./chunk-7YUXYVQA.js";import"./chunk-YZP3KX4Y.js";import"./chunk-I7AUKTXE.js";function r(r){return(s={})=>n(o({...r,...s}))}export{r as defineKomo};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./chunk-I7AUKTXE.js";var t=12,e=/^[\p{L}\p{N}][\p{L}\p{N} ._-]{0,31}$/u;function n(t){let n=t.trim().replace(/^#/,"").toLocaleLowerCase("en-US");return e.test(n)?n:null}function a(t,e){let a=[...e.tags],o=!1,i=!1,r=(...e)=>{i=!0,t.replaceChildren(...e),i=!1},l=`komo-tags-${Math.random().toString(36).slice(2)}`,d=null,p=0,s=()=>{cancelAnimationFrame(p),d?.remove(),d=null};!function c(g=!1){s();let u=document.createElement("style");u.textContent='\n.tag-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-width: 0; min-height: 24px; font-size: 12px; }\n.tag-row .tag-chip {\n display: inline-flex; align-items: center; gap: 2px; max-width: 160px; height: 22px; padding: 0 2px 0 7px;\n border-radius: 6px; font-weight: 500; line-height: 1; color: var(--accent, #bda6ef);\n background: color-mix(in srgb, var(--accent, #bda6ef) 14%, transparent);\n}\n.tag-row .tag-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.tag-row .tag-chip button, .tag-row .tag-add {\n display: inline-flex; align-items: center; border: 0; padding: 0; color: inherit; background: none; cursor: pointer; font-family: inherit;\n}\n.tag-row .tag-chip button { justify-content: center; width: 18px; height: 18px; border-radius: 4px; opacity: .6; }\n.tag-row .tag-chip button:hover, .tag-row .tag-chip button:focus-visible { opacity: 1; background: color-mix(in srgb, currentColor 16%, transparent); }\n.tag-row .tag-add {\n gap: 4px; height: 22px; padding: 0 6px; border-radius: 6px; font-size: 12px; color: #858585;\n transition: color var(--duration-quick, 150ms), background var(--duration-quick, 150ms);\n}\n.tag-row .tag-add:hover, .tag-row .tag-add:focus-visible { color: #eee; background: #ffffff0d; }\n.tag-row .tag-input {\n width: 96px; height: 24px; padding: 0 8px; border: 0; border-radius: 6px; outline: none;\n font-family: inherit; font-size: 12px; color: #eee; background: #ffffff07; box-shadow: inset 0 0 0 1px #ffffff05;\n}\n.tag-row .tag-input::placeholder { color: #858585; }\n.tag-row .tag-input:focus { box-shadow: inset 0 0 0 1px #ffffff20; }\n.tag-row .tag-input[aria-invalid="true"] { box-shadow: inset 0 0 0 1px #f28b8299; }\n/* A floating menu attached to komo\'s root, so no container can clip it. */\n.tag-options {\n position: fixed; z-index: 40; display: grid; gap: 1px; width: 220px; max-height: 220px; overflow: auto;\n padding: 4px; border-radius: 10px; background: #2a2a2a; box-shadow: 0 0 0 1px #ffffff14, 0 12px 32px #0007;\n font-size: 12px;\n}\n.tag-options:empty { display: none; }\n.tag-option {\n display: flex; align-items: center; gap: 6px; min-height: 28px; padding: 0 8px; border-radius: 6px;\n color: #ddd; cursor: pointer; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;\n}\n.tag-option[aria-selected="true"] { background: #ffffff14; color: #fff; }\n.tag-option-hint, .tag-option-empty { color: #858585; }\n.tag-option-empty { padding: 6px 8px; }\n/* The tag row grows when the picker opens, instead of spilling over the text above it. */\n.new-comment-composer .draft-body:has(.tag-slot) { grid-template-rows: minmax(28px, auto) minmax(28px, auto); }\n.new-comment-composer .draft-body .tag-slot { grid-row: 2; grid-column: 2; align-self: start; min-width: 0; padding-top: 2px; }\n.new-comment-composer .draft-body:has(.tag-slot) .send { align-self: start; }\n.new-comment-composer .draft-body:not(:has(.avatar)) .tag-slot { grid-column: 1; }\n/* Line up with message text: 16px gutter plus the 24px avatar and 8px gap. */\n.thread-tags { padding: 8px 16px 12px 48px; }\n';let f=document.createElement("div");f.className="tag-row",f.setAttribute("role","group"),f.setAttribute("aria-label","Tags");for(let t of a){let n=document.createElement("span");n.className="tag-chip";let o=document.createElement("span");o.textContent=`#${t}`;let i=document.createElement("button");i.type="button",i.textContent="×",i.setAttribute("aria-label",`Remove tag ${t}`),i.addEventListener("click",()=>{a=a.filter(e=>e!==t),e.onRemove(t),c()}),n.append(o,i),f.append(n)}if(o){let m=document.createElement("input");m.className="tag-input",m.placeholder="Add tag…",m.maxLength=33,m.autocomplete="off",m.setAttribute("role","combobox"),m.setAttribute("aria-label","Add tag"),m.setAttribute("aria-autocomplete","list"),m.setAttribute("aria-controls",l);let x=document.createElement("div");x.className="tag-options",x.id=l,x.setAttribute("role","listbox"),x.setAttribute("aria-label","Tags");let h=[],b=-1,w=t=>{!a.includes(t)&&a.length<12&&(a=[...a,t].sort(),e.onAdd(t)),o=a.length<12,c(o)},v=t=>{b=t,x.querySelectorAll("[role=option]").forEach((e,n)=>{e.setAttribute("aria-selected",String(n===t)),n===t&&e.scrollIntoView?.({block:"nearest"})}),t>=0?m.setAttribute("aria-activedescendant",`${l}-${t}`):m.removeAttribute("aria-activedescendant")},y=()=>{let t=m.value.trim().replace(/^#/,"").toLocaleLowerCase("en-US"),o=n(m.value),i=e.suggestions.filter(t=>!a.includes(t));h=(t?[...i.filter(e=>e.startsWith(t)),...i.filter(e=>!e.startsWith(t)&&e.includes(t))]:i).map(t=>({tag:t,create:!1})),o&&!a.includes(o)&&!i.includes(o)&&h.push({tag:o,create:!0}),x.replaceChildren(...h.map(({tag:t,create:e},n)=>{let a=document.createElement("div");return a.id=`${l}-${n}`,a.className="tag-option",a.setAttribute("role","option"),e&&a.append(Object.assign(document.createElement("span"),{className:"tag-option-hint",textContent:"Create"})),a.append(Object.assign(document.createElement("span"),{textContent:`#${t}`})),a.addEventListener("pointerdown",t=>t.preventDefault()),a.addEventListener("click",()=>w(t)),a.addEventListener("pointermove",()=>v(n)),a})),h.length||x.append(Object.assign(document.createElement("div"),{className:"tag-option-empty",textContent:t?a.includes(o??"")?"Already added":"Use letters, numbers, spaces, . _ or -":"Type to create a tag"})),m.setAttribute("aria-expanded",String(h.length>0)),v(t&&h.length?0:-1)};m.addEventListener("input",y),m.addEventListener("keydown",t=>{if(t.stopPropagation(),!t.isComposing)if("ArrowDown"===t.key||"ArrowUp"===t.key){if(t.preventDefault(),!h.length)return;let e=h.length-1;v("ArrowDown"===t.key?b>=e?0:b+1:b<=0?e:b-1)}else if("Enter"===t.key||","===t.key)if(t.preventDefault(),b>=0&&h[b])w(h[b].tag);else if(m.value.trim()){let t=n(m.value);t?w(t):m.setAttribute("aria-invalid","true")}else o=!1,c();else if("Escape"===t.key)t.preventDefault(),o=!1,c();else if("Backspace"===t.key&&!m.value&&a.length){let t=a.at(-1);a=a.slice(0,-1),e.onRemove(t),c(!0)}}),m.addEventListener("input",()=>m.removeAttribute("aria-invalid")),m.addEventListener("blur",()=>{i||!m.isConnected||!o||(o=!1,c())}),f.append(m),r(u,f);let A=t.getRootNode();(A instanceof ShadowRoot?A:document.body).append(x),d=x;let k=()=>{if(!m.isConnected)return s();let t=m.getBoundingClientRect(),e=x.offsetHeight,n=window.innerHeight-t.bottom-8,a=e+4<=n||t.top-8<n?t.bottom+4:t.top-4-e;x.style.top=`${Math.max(8,a)}px`,x.style.left=`${Math.max(8,Math.min(t.left,window.innerWidth-x.offsetWidth-8))}px`,p=requestAnimationFrame(k)};return y(),k(),void((g||o)&&m.focus({preventScroll:!0}))}if(a.length<12){let t=document.createElement("button");t.type="button",t.className="tag-add",t.textContent=a.length?"+":"+ Add tag",t.setAttribute("aria-label","Add tag"),t.addEventListener("click",()=>{o=!0,c(!0)}),f.append(t)}r(u,f)}()}export{t as MAX_TAGS,n as normalizeTag,a as tagEditor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as t,A as e,B as n,C as r,D as i,E as o,F as s,G as a,H as l,I as u,J as c,K as d,L as h,M as m,N as p,O as f,P as g,Q as v,R as y,S as w,T as x,U as E,V as P,W as S,X as b,Y as C,Z as M,_ as k,a as T,aa as A,b as L,ba as D,c as I,ca as j,da as V,ea as _,fa as O,ga as R,ha as W,ia as N,j as B,ja as F,k as H,ka as U,l as G,m as Y,n as $,o as X,p as z,q,r as K,s as Z,t as J,u as Q,v as tt,w as et,x as nt,y as rt,z as it}from"./chunk-7YUXYVQA.js";import{c as ot,g as st,k as at}from"./chunk-YZP3KX4Y.js";import{a as lt}from"./chunk-I7AUKTXE.js";import{createRoot as ut}from"react-dom/client";import{flushSync as ct}from"react-dom";import{createElement as dt}from"react";import*as ht from"react";var mt=({size:t=24,color:e="currentColor",...n})=>ht.createElement("svg",{viewBox:"0 0 24 24",width:t,height:t,stroke:e,strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...n},ht.createElement("path",{d:"m7 15 5 5 5-5M7 9l5-5 5 5"}));mt.displayName="ChevronSelectorVertical";import*as pt from"react";var ft=({size:t=24,color:e="currentColor",...n})=>pt.createElement("svg",{viewBox:"0 0 24 24",width:t,height:t,stroke:e,strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...n},pt.createElement("path",{d:"M18 6 6 18M6 6l12 12"}));ft.displayName="XClose";import*as gt from"react";var vt=({size:t=24,color:e="currentColor",...n})=>gt.createElement("svg",{viewBox:"0 0 24 24",width:t,height:t,stroke:e,strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...n},gt.createElement("path",{d:"M19 12H5m0 0 7 7m-7-7 7-7"}));vt.displayName="ArrowLeft";import*as yt from"react";var wt=({size:t=24,color:e="currentColor",...n})=>yt.createElement("svg",{viewBox:"0 0 24 24",width:t,height:t,stroke:e,strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...n},yt.createElement("path",{d:"m9 18 6-6-6-6"}));wt.displayName="ChevronRight";import{useEffect as xt,useId as Et,useLayoutEffect as Pt,useRef as St,useState as bt}from"react";import{createContext as Ct}from"react";var Mt=Ct({});import{useRef as kt}from"react";import{useLayoutEffect as Tt,useEffect as At}from"react";var Lt=typeof window<"u"?Tt:At;import{createContext as Dt}from"react";var It=Dt(null);import{createContext as jt}from"react";var Vt=jt({transformPagePoint:t=>t,isStatic:!1,reducedMotion:"never"});import{useContext as _t,useId as Ot,useEffect as Rt,useCallback as Wt}from"react";import{createContext as Nt}from"react";var Bt=Nt({strict:!1}),Ft={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]},Ht=!1;function Ut(){return function(){if(Ht)return;let t={};for(let e in Ft)t[e]={isEnabled:t=>Ft[e].some(e=>!!t[e])};v(t),Ht=!0}(),y()}var Gt=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","propagate","ignoreStrict","viewport"]);function Yt(t){return t.startsWith("while")||t.startsWith("drag")&&"draggable"!==t||t.startsWith("layout")||t.startsWith("onTap")||t.startsWith("onPan")||t.startsWith("onLayout")||Gt.has(t)}var $t,Xt=t=>!Yt(t);try{"function"==typeof($t=lt("@emotion/is-prop-valid").default)&&(Xt=t=>t.startsWith("on")?!Yt(t):$t(t))}catch{}import{jsxs as zt,jsx as qt}from"react/jsx-runtime";import{forwardRef as Kt,useContext as Zt}from"react";import{createContext as Jt}from"react";var Qt=Jt({});import{useContext as te,useMemo as ee}from"react";function ne(t){let{initial:e,animate:n}=function(t,e){if(h(t)){let{initial:e,animate:n}=t;return{initial:!1===e||d(e)?e:void 0,animate:d(n)?n:void 0}}return!1!==t.inherit?e:{}}(t,te(Qt));return ee(()=>({initial:e,animate:n}),[re(e),re(n)])}function re(t){return Array.isArray(t)?t.join(" "):t}import{Fragment as ie,useMemo as oe,createElement as se}from"react";import{useMemo as ae}from"react";var le=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function ue(t,e,n){for(let r in e)!rt(e[r])&&!b(r,n)&&(t[r]=e[r])}function ce(t,e){let n={};return ue(n,t.style||{},t),Object.assign(n,function({transformTemplate:t},e){return ae(()=>{let n={style:{},transform:{},transformOrigin:{},vars:{}};return S(n,e,t),Object.assign({},n.vars,n.style)},[e])}(t,e)),n}function de(t,e){let n={},r=ce(t,e);return t.drag&&!1!==t.dragListener&&(n.draggable=!1,r.userSelect=r.WebkitUserSelect=r.WebkitTouchCallout="none",r.touchAction=!0===t.drag?"none":"pan-"+("x"===t.drag?"y":"x")),void 0===t.tabIndex&&(t.onTap||t.onTapStart||t.whileTap)&&(n.tabIndex=0),n.style=r,n}import{useMemo as he}from"react";var me=()=>({style:{},transform:{},transformOrigin:{},vars:{},attrs:{}});function pe(e,n,r,i){let o=he(()=>{let r={style:{},transform:{},transformOrigin:{},vars:{},attrs:{}};return k(r,n,t(i),e.transformTemplate,e.style),{...r.attrs,style:{...r.style}}},[n]);if(e.style){let t={};ue(t,e.style,e),o.style={...t,...o.style}}return o}var fe=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function ge(t){return"string"==typeof t&&!t.includes("-")&&!!(fe.indexOf(t)>-1||/[A-Z]/u.test(t))}function ve(t,e,n,{latestValues:r},i,o=!1,s){let a=(s??ge(t)?pe:de)(e,r,i,t),l=function(t,e,n){let r={};for(let i in t)"values"===i&&"object"==typeof t.values||rt(t[i])||(Xt(i)||!0===n&&Yt(i)||!e&&!Yt(i)||t.draggable&&i.startsWith("onDrag"))&&(r[i]=t[i]);return r}(e,"string"==typeof t,o),u=t!==ie?{...l,...a,ref:n}:{},{children:c}=e,d=oe(()=>rt(c)?c.get():c,[c]);return se(t,{...u,children:d})}import{useContext as ye}from"react";function we(t,e,n,r){let i={},o=r(t,{});for(let t in o)i[t]=R(o[t]);let{initial:s,animate:a}=t,l=h(t),u=m(t);e&&u&&!l&&!1!==t.inherit&&(void 0===s&&(s=e.initial),void 0===a&&(a=e.animate));let d=!!n&&!1===n.initial;d=d||!1===s;let p=d?a:s;if(p&&"boolean"!=typeof p&&!c(p)){let e=Array.isArray(p)?p:[p];for(let n=0;n<e.length;n++){let r=et(t,e[n]);if(r){let{transitionEnd:t,transition:e,...n}=r;for(let t in n){let e=n[t];if(Array.isArray(e)){e=e[d?e.length-1:0]}null!==e&&(i[t]=e)}for(let e in t)i[e]=t[e]}}}return i}var xe=t=>(e,n)=>{let r=ye(Qt),i=ye(It),o=()=>function({scrapeMotionValuesFromProps:t,createRenderState:e},n,r,i){return{latestValues:we(n,r,i,t),renderState:e()}}(t,e,r,i);return n?o():function(t){let e=kt(null);return null===e.current&&(e.current=t()),e.current}(o)},Ee=xe({scrapeMotionValuesFromProps:C,createRenderState:le}),Pe=xe({scrapeMotionValuesFromProps:A,createRenderState:me}),Se=Symbol.for("motionComponentSymbol");import{useRef as be,useInsertionEffect as Ce,useCallback as Me}from"react";function ke(t,e,n){let r=be(n);Ce(()=>{r.current=n});let i=be(null);return Me(n=>{n&&t.onMount?.(n),e&&(n?e.mount(n):e.unmount());let o=r.current;if("function"==typeof o)if(n){let t=o(n);"function"==typeof t&&(i.current=t)}else i.current?(i.current(),i.current=null):o(n);else o&&(o.current=n)},[e])}import{useContext as Te,useRef as Ae,useInsertionEffect as Le,useEffect as De}from"react";import{createContext as Ie}from"react";var je=Ie({});function Ve(t){return t&&"object"==typeof t&&Object.prototype.hasOwnProperty.call(t,"current")}function _e(t,n,r,i,o,s){let{visualElement:a}=Te(Qt),l=Te(Bt),u=Te(It),c=Te(Vt),d=c.reducedMotion,h=c.skipAnimations,m=Ae(null),p=Ae(!1);i=i||l.renderer,!m.current&&i&&(m.current=i(t,{visualState:n,parent:a,props:r,presenceContext:u,blockInitialAnimation:!!u&&!1===u.initial,reducedMotionConfig:d,skipAnimations:h,isSVG:s}),p.current&&m.current&&(m.current.manuallyAnimateOnMount=!0));let f=m.current,g=Te(je);f&&!f.projection&&o&&("html"===f.type||"svg"===f.type)&&function(t,e,n,r){let{layoutId:i,layout:o,drag:s,dragConstraints:a,layoutScroll:l,layoutRoot:u,layoutAnchor:c,layoutCrossfade:d}=e;t.projection=new n(t.latestValues,e["data-framer-portal-id"]?void 0:Oe(t.parent)),t.projection.setOptions({layoutId:i,layout:o,alwaysMeasureLayout:!!s||a&&Ve(a),visualElement:t,animationType:"string"==typeof o?o:"both",initialPromotionConfig:r,crossfade:d,layoutScroll:l,layoutRoot:u,layoutAnchor:c})}(m.current,r,o,g);let v=Ae(!1);Le(()=>{f&&v.current&&f.update(r,u)});let y=r[e],w=Ae(!!y&&typeof window<"u"&&!window.MotionHandoffIsComplete?.(y)&&window.MotionHasOptimisedAnimation?.(y));return Lt(()=>{p.current=!0,f&&(v.current=!0,window.MotionIsMounted=!0,f.updateFeatures(),f.scheduleRenderMicrotask(),w.current&&f.animationState&&f.animationState.animateChanges())}),De(()=>{f&&(!w.current&&f.animationState&&f.animationState.animateChanges(),w.current&&(queueMicrotask(()=>{window.MotionHandoffMarkAsComplete?.(y)}),w.current=!1),f.enteringChildren=void 0)}),f}function Oe(t){if(t)return!1!==t.options.allowProjection?t.projection:Oe(t.parent)}function Re(t,{forwardMotionProps:e=!1,type:n}={},r,i){r&&function(t){let e=Ut();for(let n in t)e[n]={...e[n],...t[n]};v(e)}(r);let o=n?"svg"===n:ge(t),s=o?Pe:Ee;function a(n,r){let a,l={...Zt(Vt),...n,layoutId:We(n)},{isStatic:u}=l,c=ne(n),d=s(n,u);if(!u&&typeof window<"u"){Zt(Bt).strict;let e=function(t){let e=Ut(),{drag:n,layout:r}=e;if(!n&&!r)return{};let i={...n,...r};return{MeasureLayout:n?.isEnabled(t)||r?.isEnabled(t)?i.MeasureLayout:void 0,ProjectionNode:i.ProjectionNode}}(l);a=e.MeasureLayout,c.visualElement=_e(t,d,l,i,e.ProjectionNode,o)}return zt(Qt.Provider,{value:c,children:[a&&c.visualElement?qt(a,{visualElement:c.visualElement,...l}):null,ve(t,n,ke(d,c.visualElement,r),d,u,e,o)]})}a.displayName=`motion.${"string"==typeof t?t:`create(${t.displayName??t.name??""})`}`;let l=Kt(a);return l[Se]=t,l}function We({layoutId:t}){let e=Zt(Mt).id;return e&&void 0!==t?e+"-"+t:t}import{Fragment as Ne}from"react";var Be=0,Fe={animation:{Feature:class extends w{constructor(t){super(t),t.animationState||(t.animationState=j(t))}updateAnimationControlsSubscription(){let{animate:t}=this.node.getProps();c(t)&&(this.unmountControls=t.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){let{animate:t}=this.node.getProps(),{animate:e}=this.node.prevProps||{};t!==e&&this.updateAnimationControlsSubscription()}unmount(){this.node.animationState.reset(),this.unmountControls?.()}}},exit:{Feature:class extends w{constructor(){super(...arguments),this.id=Be++,this.isExitComplete=!1}update(){if(!this.node.presenceContext)return;let{isPresent:t,onExitComplete:e}=this.node.presenceContext,{isPresent:n}=this.node.prevPresenceContext||{};if(!this.node.animationState||t===n)return;if(t&&!1===n){if(this.isExitComplete){let{initial:t,custom:e}=this.node.getProps();if("string"==typeof t||"object"==typeof t&&null!==t&&!Array.isArray(t)){let n=nt(this.node,t,e);if(n){let{transition:t,transitionEnd:e,...r}=n;for(let t in r)this.node.getValue(t)?.jump(r[t])}}this.node.animationState.reset(),this.node.animationState.animateChanges()}else this.node.animationState.setActive("exit",!1);return void(this.isExitComplete=!1)}let r=this.node.animationState.setActive("exit",!t);e&&!t&&r.then(()=>{this.isExitComplete=!0,e(this.id)})}mount(){let{register:t,onExitComplete:e}=this.node.presenceContext||{};e&&e(this.id),t&&(this.unmount=t(this.id))}unmount(){}}}};function He(t){return{point:{x:t.pageX,y:t.pageY}}}function Ue(t,e,n,r){return O(t,e,(t=>e=>o(e)&&t(e,He(e)))(n),r)}var Ge=({current:t})=>t?t.ownerDocument.defaultView:null,Ye=new Set(["auto","scroll"]),$e=class{constructor(t,e,{transformPagePoint:n,contextWindow:r=window,dragSnapToOrigin:i=!1,distanceThreshold:s=3,element:a}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.lastRawMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.scrollPositions=new Map,this.removeScrollListeners=null,this.onElementScroll=t=>{this.handleScroll(t.target)},this.onWindowScroll=()=>{this.handleScroll(window)},this.updatePoint=()=>{if(!this.lastMoveEvent||!this.lastMoveEventInfo)return;this.lastRawMoveEventInfo&&(this.lastMoveEventInfo=Xe(this.lastRawMoveEventInfo,this.transformPagePoint));let t=qe(this.lastMoveEventInfo,this.history),e=null!==this.startEvent,n=U(t.offset,{x:0,y:0})>=this.distanceThreshold;if(!e&&!n)return;let{point:r}=t,{timestamp:i}=Z;this.history.push({...r,timestamp:i});let{onStart:o,onMove:s}=this.handlers;e||(o&&o(this.lastMoveEvent,t),this.startEvent=this.lastMoveEvent),s&&s(this.lastMoveEvent,t)},this.handlePointerMove=(t,e)=>{this.lastMoveEvent=t,this.lastRawMoveEventInfo=e,this.lastMoveEventInfo=Xe(e,this.transformPagePoint),q.update(this.updatePoint,!0)},this.handlePointerUp=(t,e)=>{this.end();let{onEnd:n,onSessionEnd:r,resumeAnimation:i}=this.handlers;if((this.dragSnapToOrigin||!this.startEvent)&&i&&i(),!this.lastMoveEvent||!this.lastMoveEventInfo)return;let o=qe("pointercancel"===t.type?this.lastMoveEventInfo:Xe(e,this.transformPagePoint),this.history);this.startEvent&&n&&n(t,o),r&&r(t,o)},!o(t))return;this.dragSnapToOrigin=i,this.handlers=e,this.transformPagePoint=n,this.distanceThreshold=s,this.contextWindow=r||window;let l=Xe(He(t),this.transformPagePoint),{point:u}=l,{timestamp:c}=Z;this.history=[{...u,timestamp:c}];let{onSessionStart:d}=e;d&&d(t,qe(l,this.history));let h={passive:!0,capture:!0};this.removeListeners=Y(Ue(this.contextWindow,"pointermove",this.handlePointerMove,h),Ue(this.contextWindow,"pointerup",this.handlePointerUp,h),Ue(this.contextWindow,"pointercancel",this.handlePointerUp,h)),a&&this.startScrollTracking(a)}startScrollTracking(t){let e=t.parentElement;for(;e;){let t=getComputedStyle(e);(Ye.has(t.overflowX)||Ye.has(t.overflowY))&&this.scrollPositions.set(e,{x:e.scrollLeft,y:e.scrollTop}),e=e.parentElement}this.scrollPositions.set(window,{x:window.scrollX,y:window.scrollY}),window.addEventListener("scroll",this.onElementScroll,{capture:!0}),window.addEventListener("scroll",this.onWindowScroll),this.removeScrollListeners=()=>{window.removeEventListener("scroll",this.onElementScroll,{capture:!0}),window.removeEventListener("scroll",this.onWindowScroll)}}handleScroll(t){let e=this.scrollPositions.get(t);if(!e)return;let n=t===window,r=n?{x:window.scrollX,y:window.scrollY}:{x:t.scrollLeft,y:t.scrollTop},i=r.x-e.x,o=r.y-e.y;0===i&&0===o||(n?this.lastMoveEventInfo&&(this.lastMoveEventInfo.point.x+=i,this.lastMoveEventInfo.point.y+=o):this.history.length>0&&(this.history[0].x-=i,this.history[0].y-=o),this.scrollPositions.set(t,r),q.update(this.updatePoint,!0))}updateHandlers(t){this.handlers=t}end(){this.removeListeners&&this.removeListeners(),this.removeScrollListeners&&this.removeScrollListeners(),this.scrollPositions.clear(),K(this.updatePoint)}};function Xe(t,e){return e?{point:e(t.point)}:t}function ze(t,e){return{x:t.x-e.x,y:t.y-e.y}}function qe({point:t},e){return{point:t,delta:ze(t,Ze(e)),offset:ze(t,Ke(e)),velocity:Je(e,.1)}}function Ke(t){return t[0]}function Ze(t){return t[t.length-1]}function Je(t,e){if(t.length<2)return{x:0,y:0};let n=t.length-1,r=null,i=Ze(t);for(;n>=0&&(r=t[n],!(i.timestamp-r.timestamp>X(e)));)n--;if(!r)return{x:0,y:0};r===t[0]&&t.length>2&&i.timestamp-r.timestamp>2*X(e)&&(r=t[1]);let o=z(i.timestamp-r.timestamp);if(0===o)return{x:0,y:0};let s={x:(i.x-r.x)/o,y:(i.y-r.y)/o};return s.x===1/0&&(s.x=0),s.y===1/0&&(s.y=0),s}function Qe(t,e,n){return{min:void 0!==e?t.min+e:void 0,max:void 0!==n?t.max+n-(t.max-t.min):void 0}}function tn(t,e){let n=e.min-t.min,r=e.max-t.max;return e.max-e.min<t.max-t.min&&([n,r]=[r,n]),{min:n,max:r}}var en=.35;function nn(t,e,n){return{min:rn(t,e),max:rn(t,n)}}function rn(t,e){return"number"==typeof t?t:t[e]||0}var on=new WeakMap,sn=class{constructor(t){this.openDragLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=u(),this.latestPointerEvent=null,this.latestPanInfo=null,this.visualElement=t}start(t,{snapToCursor:e=!1,distanceThreshold:n}={}){let{presenceContext:i}=this.visualElement;if(i&&!1===i.isPresent)return;let{dragSnapToOrigin:o}=this.getProps();this.panSession=new $e(t,{onSessionStart:t=>{e&&this.snapToCursor(He(t).point),this.stopAnimation()},onStart:(t,e)=>{let{drag:n,dragPropagation:i,onDragStart:o}=this.getProps();if(n&&!i&&(this.openDragLock&&this.openDragLock(),this.openDragLock=r(n),!this.openDragLock))return;this.latestPointerEvent=t,this.latestPanInfo=e,this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),_(t=>{let e=this.getAxisMotionValue(t).get()||0;if(J.test(e)){let{projection:n}=this.visualElement;if(n&&n.layout){let r=n.layout.layoutBox[t];r&&(e=V(r)*(parseFloat(e)/100))}}this.originPoint[t]=e}),o&&q.update(()=>o(t,e),!1,!0),it(this.visualElement,"transform");let{animationState:s}=this.visualElement;s&&s.setActive("whileDrag",!0)},onMove:(t,e)=>{this.latestPointerEvent=t,this.latestPanInfo=e;let{dragPropagation:n,dragDirectionLock:r,onDirectionLock:i,onDrag:o}=this.getProps();if(!n&&!this.openDragLock)return;let{offset:s}=e;if(r&&null===this.currentDirection)return this.currentDirection=function(t,e=10){let n=null;return Math.abs(t.y)>e?n="y":Math.abs(t.x)>e&&(n="x"),n}(s),void(null!==this.currentDirection&&i&&i(this.currentDirection));this.updateAxis("x",e.point,s),this.updateAxis("y",e.point,s),this.visualElement.render(),o&&q.update(()=>o(t,e),!1,!0)},onSessionEnd:(t,e)=>{this.latestPointerEvent=t,this.latestPanInfo=e,this.stop(t,e),this.latestPointerEvent=null,this.latestPanInfo=null},resumeAnimation:()=>{let{dragSnapToOrigin:t}=this.getProps();(t||this.constraints)&&this.startAnimation({x:0,y:0})}},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:o,distanceThreshold:n,contextWindow:Ge(this.visualElement),element:this.visualElement.current})}stop(t,e){let n=t||this.latestPointerEvent,r=e||this.latestPanInfo,i=this.isDragging;if(this.cancel(),!i||!r||!n)return;let{velocity:o}=r;this.startAnimation(o);let{onDragEnd:s}=this.getProps();s&&q.postRender(()=>s(n,r))}cancel(){this.isDragging=!1;let{projection:t,animationState:e}=this.visualElement;t&&(t.isAnimationBlocked=!1),this.endPanSession();let{dragPropagation:n}=this.getProps();!n&&this.openDragLock&&(this.openDragLock(),this.openDragLock=null),e&&e.setActive("whileDrag",!1)}endPanSession(){this.panSession&&this.panSession.end(),this.panSession=void 0}updateAxis(t,e,n){let{drag:r}=this.getProps();if(!n||!ln(t,r,this.currentDirection))return;let i=this.getAxisMotionValue(t),o=this.originPoint[t]+n[t];this.constraints&&this.constraints[t]&&(o=function(t,{min:e,max:n},r){return void 0!==e&&t<e?t=r?Q(e,t,r.min):Math.max(t,e):void 0!==n&&t>n&&(t=r?Q(n,t,r.max):Math.min(t,n)),t}(o,this.constraints[t],this.elastic[t])),i.set(o)}resolveConstraints(){let{dragConstraints:t,dragElastic:e}=this.getProps(),n=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):this.visualElement.projection?.layout,r=this.constraints;t&&Ve(t)?this.constraints||(this.constraints=this.resolveRefConstraints()):this.constraints=!(!t||!n)&&function(t,{top:e,left:n,bottom:r,right:i}){return{x:Qe(t.x,n,i),y:Qe(t.y,e,r)}}(n.layoutBox,t),this.elastic=function(t=en){return!1===t?t=0:!0===t&&(t=en),{x:nn(t,"left","right"),y:nn(t,"top","bottom")}}(e),r!==this.constraints&&!Ve(t)&&n&&this.constraints&&!this.hasMutatedConstraints&&_(t=>{!1!==this.constraints&&this.getAxisMotionValue(t)&&(this.constraints[t]=function(t,e){let n={};return void 0!==e.min&&(n.min=e.min-t.min),void 0!==e.max&&(n.max=e.max-t.min),n}(n.layoutBox[t],this.constraints[t]))})}resolveRefConstraints(){let{dragConstraints:t,onMeasureDragConstraints:e}=this.getProps();if(!t||!Ve(t))return!1;let n=t.current;H(null!==n,"If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.","drag-constraints-ref");let{projection:r}=this.visualElement;if(!r||!r.layout)return!1;r.root&&(r.root.scroll=void 0,r.root.updateScroll());let i=P(n,r.root,this.visualElement.getTransformPagePoint()),o=function(t,e){return{x:tn(t.x,e.x),y:tn(t.y,e.y)}}(r.layout.layoutBox,i);if(e){let t=e(E(o));this.hasMutatedConstraints=!!t,t&&(o=x(t))}return o}startAnimation(t){let{drag:e,dragMomentum:n,dragElastic:r,dragTransition:i,dragSnapToOrigin:o,onDragTransitionEnd:s}=this.getProps(),a=this.constraints||{},l=_(s=>{if(!ln(s,e,this.currentDirection))return;let l=a&&a[s]||{};(!0===o||o===s)&&(l={min:0,max:0});let u=r?200:1e6,c=r?40:1e7,d={type:"inertia",velocity:n?t[s]:0,bounceStiffness:u,bounceDamping:c,timeConstant:750,restDelta:1,restSpeed:10,...i,...l};return this.startAxisValueAnimation(s,d)});return Promise.all(l).then(s)}startAxisValueAnimation(t,e){let n=this.getAxisMotionValue(t);return it(this.visualElement,t),n.start(tt(t,n,0,e,this.visualElement,!1))}stopAnimation(){_(t=>this.getAxisMotionValue(t).stop())}getAxisMotionValue(t){let e=`_drag${t.toUpperCase()}`;return this.visualElement.getProps()[e]||this.visualElement.getValue(t,this.visualElement.latestValues[t]??0)}snapToCursor(t){_(e=>{let{drag:n}=this.getProps();if(!ln(e,n,this.currentDirection))return;let{projection:r}=this.visualElement,i=this.getAxisMotionValue(e);if(r&&r.layout){let{min:n,max:o}=r.layout.layoutBox[e],s=i.get()||0;i.set(t[e]-Q(n,o,.5)+s)}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;let{drag:t,dragConstraints:e}=this.getProps(),{projection:n}=this.visualElement;if(!Ve(e)||!n||!this.constraints)return;this.stopAnimation();let r={x:0,y:0};_(t=>{let e=this.getAxisMotionValue(t);if(e&&!1!==this.constraints){let n=e.get();r[t]=function(t,e){let n=.5,r=V(t),i=V(e);return i>r?n=$(e.min,e.max-r,t.min):r>i&&(n=$(t.min,t.max-i,e.min)),B(0,1,n)}({min:n,max:n},this.constraints[t])}});let{transformTemplate:i}=this.visualElement.getProps();this.visualElement.current.style.transform=i?i({},""):"none",n.root&&n.root.updateScroll(),n.updateLayout(),this.constraints=!1,this.resolveConstraints(),_(e=>{if(!ln(e,t,null))return;let n=this.getAxisMotionValue(e),{min:i,max:o}=this.constraints[e];n.set(Q(i,o,r[e]))}),this.visualElement.render()}addListeners(){if(!this.visualElement.current)return;on.set(this.visualElement,this);let t,e=this.visualElement.current,n=Ue(e,"pointerdown",t=>{let{drag:n,dragListener:r=!0}=this.getProps(),i=t.target,o=i!==e&&s(i);n&&r&&!o&&this.start(t)}),r=()=>{let{dragConstraints:n}=this.getProps();Ve(n)&&n.current&&(this.constraints=this.resolveRefConstraints(),t||(t=function(t,e,n){let r=l(t,an(n)),i=l(e,an(n));return()=>{r(),i()}}(e,n.current,()=>this.scalePositionWithinConstraints())))},{projection:i}=this.visualElement,o=i.addEventListener("measure",r);i&&!i.layout&&(i.root&&i.root.updateScroll(),i.updateLayout()),q.read(r);let a=O(window,"resize",()=>this.scalePositionWithinConstraints()),u=i.addEventListener("didUpdate",({delta:t,hasLayoutChanged:e})=>{this.isDragging&&e&&(_(e=>{let n=this.getAxisMotionValue(e);n&&(this.originPoint[e]+=t[e].translate,n.set(n.get()+t[e].translate))}),this.visualElement.render())});return()=>{a(),n(),o(),u&&u(),t&&t()}}getProps(){let t=this.visualElement.getProps(),{drag:e=!1,dragDirectionLock:n=!1,dragPropagation:r=!1,dragConstraints:i=!1,dragElastic:o=en,dragMomentum:s=!0}=t;return{...t,drag:e,dragDirectionLock:n,dragPropagation:r,dragConstraints:i,dragElastic:o,dragMomentum:s}}};function an(t){let e=!0;return()=>{e?e=!1:t()}}function ln(t,e,n){return!(!0!==e&&e!==t||null!==n&&n!==t)}var un=t=>(e,n)=>{t&&q.update(()=>t(e,n),!1,!0)};import{jsx as cn}from"react/jsx-runtime";import{useContext as dn,Component as hn}from"react";var mn=!1,pn=class extends hn{componentDidMount(){let{visualElement:t,layoutGroup:e,switchLayoutGroup:n,layoutId:r}=this.props,{projection:i}=t;i&&(e.group&&e.group.add(i),n&&n.register&&r&&n.register(i),mn&&i.root.didUpdate(),i.addEventListener("animationComplete",()=>{this.safeToRemove()}),i.setOptions({...i.options,layoutDependency:this.props.layoutDependency,onExitComplete:()=>this.safeToRemove()})),W.hasEverUpdated=!0}getSnapshotBeforeUpdate(t){let{layoutDependency:e,visualElement:n,drag:r,isPresent:i}=this.props,{projection:o}=n;return o&&(o.isPresent=i,t.layoutDependency!==e&&o.setOptions({...o.options,layoutDependency:e}),mn=!0,r||t.layoutDependency!==e||void 0===e||t.isPresent!==i?o.willUpdate():this.safeToRemove(),t.isPresent!==i&&(i?o.promote():o.relegate()||q.postRender(()=>{let t=o.getStack();(!t||!t.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){let{visualElement:t,layoutAnchor:e}=this.props,{projection:r}=t;r&&(r.options.layoutAnchor=e,r.root.didUpdate(),n.postRender(()=>{!r.currentAnimation&&r.isLead()&&this.safeToRemove()}))}componentWillUnmount(){let{visualElement:t,layoutGroup:e,switchLayoutGroup:n}=this.props,{projection:r}=t;mn=!0,r&&(r.scheduleCheckAfterUnmount(),e&&e.group&&e.group.remove(r),n&&n.deregister&&n.deregister(r))}safeToRemove(){let{safeToRemove:t}=this.props;t&&t()}render(){return null}};function fn(t){let[e,n]=function(t=!0){let e=_t(It);if(null===e)return[!0,null];let{isPresent:n,onExitComplete:r,register:i}=e,o=Ot();Rt(()=>{if(t)return i(o)},[t]);let s=Wt(()=>t&&r&&r(o),[o,r,t]);return!n&&r?[!1,s]:[!0]}(),r=dn(Mt);return cn(pn,{...t,layoutGroup:r,switchLayoutGroup:dn(je),isPresent:e,safeToRemove:n})}var gn={pan:{Feature:class extends w{constructor(){super(...arguments),this.removePointerDownListener=G}onPointerDown(t){this.session=new $e(t,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:Ge(this.node)})}createPanHandlers(){let{onPanSessionStart:t,onPanStart:e,onPan:n,onPanEnd:r}=this.node.getProps();return{onSessionStart:un(t),onStart:un(e),onMove:un(n),onEnd:(t,e)=>{delete this.session,r&&q.postRender(()=>r(t,e))}}}mount(){this.removePointerDownListener=Ue(this.node.current,"pointerdown",t=>this.onPointerDown(t))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}},drag:{Feature:class extends w{constructor(t){super(t),this.removeGroupControls=G,this.removeListeners=G,this.controls=new sn(t)}mount(){let{dragControls:t}=this.node.getProps();t&&(this.removeGroupControls=t.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||G}update(){let{dragControls:t}=this.node.getProps(),{dragControls:e}=this.node.prevProps||{};t!==e&&(this.removeGroupControls(),t&&(this.removeGroupControls=t.subscribe(this.controls)))}unmount(){this.removeGroupControls(),this.removeListeners(),this.controls.isDragging||this.controls.endPanSession()}},ProjectionNode:N,MeasureLayout:fn}};function vn(t,e,n){let{props:r}=t;t.animationState&&r.whileHover&&t.animationState.setActive("whileHover","Start"===n);let i=r["onHover"+n];i&&q.postRender(()=>i(e,He(e)))}function yn(t,e,n){let{props:r}=t;if(t.current instanceof HTMLButtonElement&&t.current.disabled)return;t.animationState&&r.whileTap&&t.animationState.setActive("whileTap","Start"===n);let i=r["onTap"+("End"===n?"":n)];i&&q.postRender(()=>i(e,He(e)))}var wn=new WeakMap,xn=new WeakMap,En=t=>{let e=wn.get(t.target);e&&e(t)},Pn=t=>{t.forEach(En)};function Sn(t,e,n){let r=function({root:t,...e}){let n=t||document;xn.has(n)||xn.set(n,{});let r=xn.get(n),i=JSON.stringify(e);return r[i]||(r[i]=new IntersectionObserver(Pn,{root:t,...e})),r[i]}(e);return wn.set(t,n),r.observe(t),()=>{wn.delete(t),r.unobserve(t)}}var bn={some:0,all:1};var Cn={inView:{Feature:class extends w{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){this.stopObserver?.();let{viewport:t={}}=this.node.getProps(),{root:e,margin:n,amount:r="some",once:i}=t,o={root:e?e.current:void 0,rootMargin:n,threshold:"number"==typeof r?r:bn[r]};this.stopObserver=Sn(this.node.current,o,t=>{let{isIntersecting:e}=t;if(this.isInView===e||(this.isInView=e,i&&!e&&this.hasEnteredView))return;e&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",e);let{onViewportEnter:n,onViewportLeave:r}=this.node.getProps(),o=e?n:r;o&&o(t)})}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;let{props:t,prevProps:e}=this.node;["amount","margin","root"].some(function({viewport:t={}},{viewport:e={}}={}){return n=>t[n]!==e[n]}(t,e))&&this.startObserver()}unmount(){this.stopObserver?.(),this.hasEnteredView=!1,this.isInView=!1}}},tap:{Feature:class extends w{mount(){let{current:t}=this.node;if(!t)return;let{globalTapTarget:e,propagate:n}=this.node.props;this.unmount=a(t,(t,e)=>(yn(this.node,e,"Start"),(t,{success:e})=>yn(this.node,t,e?"End":"Cancel")),{useGlobalTarget:e,stopPropagation:!1===n?.tap})}unmount(){}}},focus:{Feature:class extends w{constructor(){super(...arguments),this.isActive=!1}onFocus(){let t=!1;try{t=this.node.current.matches(":focus-visible")}catch{t=!0}!t||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=Y(O(this.node.current,"focus",()=>this.onFocus()),O(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}},hover:{Feature:class extends w{mount(){let{current:t}=this.node;t&&(this.unmount=i(t,(t,e)=>(vn(this.node,e,"Start"),t=>vn(this.node,t,"End"))))}unmount(){}}}},Mn=function(t,e){if(typeof Proxy>"u")return Re;let n=new Map,r=(n,r)=>Re(n,r,t,e);return new Proxy((t,e)=>r(t,e),{get:(i,o)=>"create"===o?r:(n.has(o)||n.set(o,Re(o,void 0,t,e)),n.get(o))})}({...Fe,...Cn,...gn,...{layout:{ProjectionNode:N,MeasureLayout:fn}}},(t,e)=>e.isSVG??ge(t)?new D(e):new M(e,{allowProjection:t!==Ne}));import{useState as kn}from"react";var Tn=Mn;import{Fragment as An,jsx as Ln,jsxs as Dn}from"react/jsx-runtime";function In({items:t,defaultActiveId:e,activeId:n,edge:r="bottom",alignEnd:i=!1,onActiveChange:o,label:s="App navigation",moreLabel:a="More",backLabel:l="Back",className:u="",style:c}){let d=Et(),[h,m]=bt({kind:"collapsed"}),[v,y]=bt(e??t[0]?.id),[w,x]=bt(null),E=St(null),P=St(null),S=St(r),b="left"===r||"right"===r;Pt(()=>{let t=P.current;if(!t||!w)return;let e=t.getBoundingClientRect(),n=Math.max(8-e.left,Math.min(0,window.innerWidth-8-e.right)),r=Math.max(8-e.top,Math.min(0,window.innerHeight-8-e.bottom));t.style.left=`${w.x+n}px`,t.style.top=`${w.y+r}px`},[w]);let C=St(null),M=St(null),k=St(h),A=St("more"),D=St(!1),j=St(!1),V=St(!1),_=St(null),O=St(void 0),R=St(void 0),W=St(!1),N=St(!1),B=function(){!f.current&&g();let[t]=kn(p.current);return t}(),H=n??v,U="collapsed"!==h.kind,G=t.filter(t=>!1!==t.showInBar),Y=G.find(t=>"dismiss"===t.id),$=G.filter(t=>"dismiss"!==t.id),X=t.filter(t=>t.children?.length);function z(){clearTimeout(O.current),x(null)}function q(){z(),clearTimeout(R.current),W.current=!1}function K(t,e,n=!1){clearTimeout(O.current);let i=E.current,o=M.current;if(!i||!o||U||j.current||V.current&&!n)return;let s=i.getBoundingClientRect(),a=t.getBoundingClientRect(),l={label:e,x:"left"===r?s.width+8:"right"===r?-8:a.left-s.left+a.width/2,y:"top"===r?s.height+8:"bottom"===r?-8:a.top-s.top+a.height/2};clearTimeout(R.current);let u=()=>{W.current=!0,x(l)};n||W.current?u():O.current=setTimeout(u,400)}function Z(t,e,n){q(),U||(A.current=e,D.current=n),_.current="first",m(t)}function J(t=!0,e=A.current){q(),V.current=!0,_.current=t&&D.current?e:null,m({kind:"collapsed"})}function Q(){"group"===h.kind&&(_.current=h.id,m({kind:"main"}))}function tt(t,e){let n=!!t.children?.length,r=H===t.id||!!t.children?.some(t=>t.id===H),i=!e&&t.keepOpenOnSelect,s=(e,n=!1)=>Ln(Vn,{label:t.label,icon:n,reduced:!!B,children:e}),a=r&&t.activeIcon?t.activeIcon:t.icon,l=Dn(An,{children:[Ln("span",{className:"morphing-menu__icon","aria-hidden":"true",style:i?{display:"grid"}:void 0,children:i?s(a,!0):a}),!e&&Ln("span",{className:"morphing-menu__label",style:i?{display:"grid"}:void 0,children:i?s(t.label):t.label}),!e&&n&&Ln(jn,{})]}),u={className:e?"morphing-menu__shortcut":"morphing-menu__row","data-menu-item":t.id,"aria-label":t.label,"aria-current":r?n?"true":"page":void 0,"aria-expanded":n?"group"===h.kind&&h.id===t.id:void 0,"aria-controls":n?`${d}-group-${t.id}`:void 0,onClick:e=>n?Z({kind:"group",id:t.id},t.id,0===e.detail):function(t){y(t.id),o?.(t.id),U&&!t.keepOpenOnSelect?J(!0,"group"===h.kind?h.id:t.id):q(),t.onSelect?.()}(t),onPointerEnter:n=>{e&&"mouse"===n.pointerType&&K(n.currentTarget,t.label)},onPointerLeave:z,onPointerDown:q,onFocus:n=>{e&&n.currentTarget.matches(":focus-visible")&&K(n.currentTarget,t.label,!0)},onBlur:z};return t.href&&!n?Ln("a",{href:t.href,...u,children:l},t.id):Ln(Tn.button,{layout:!!e&&"position",transition:B?{duration:0}:T,type:"button",...u,children:l},t.id)}Pt(()=>{let t=E.current,e=C.current,n=M.current;if(!t||!e||!n)return;let i=S.current!==r;S.current=r;let o=k.current;k.current=h;let s=[...t.querySelectorAll(".morphing-menu__panel")],a=s.find(t=>"false"===t.getAttribute("aria-hidden")),l=[],u=!1,c=t=>(l.push(t),t),d=()=>({width:a?.offsetWidth??n.offsetWidth,height:a?.offsetHeight??n.offsetHeight}),p=i||o.kind!==h.kind||"group"===o.kind&&"group"===h.kind&&o.id!==h.id,f="collapsed"===o.kind!=("collapsed"===h.kind),g=B||!p;if(g)(()=>{let t=d();e.style.width=`${t.width}px`,e.style.height=`${t.height}px`})();else if(f&&!U)c(F(e,d(),I));else if(f){let t=Math.min(n.offsetWidth,n.offsetWidth>250?280:200);c(F(e,{width:t,height:n.offsetHeight>52?32:28},L)).finished.then(()=>{u||c(F(e,d(),{...T,bounce:U?.24:.15}))}).catch(()=>{})}else c(F(e,d(),{...T,duration:.25,bounce:.1}));c(F(n,{opacity:U?0:1,scale:U&&!B?.8:1,filter:U&&!B?"blur(8px)":"blur(0px)"},{duration:g?0:U?.15:.22,delay:g||U?0:.08,...U?{}:{ease:"easeOut"}}));for(let t of s){let e=t===a;for(let[n,r]of[...t.querySelectorAll(".morphing-menu__row")].entries())e&&f&&!g&&Object.assign(r.style,{opacity:"0",transform:"translateY(48px)",filter:"blur(4px)"}),c(F(r,{opacity:e?1:0,y:e||B?0:16,filter:e||B?"blur(0px)":"blur(2px)"},{...T,duration:g?0:e?f?.4:.25:.12,bounce:f?.3:0,delay:!g&&e?(f?.2:0)+.02*n:0}))}let v=[...(U?a:n)?.querySelectorAll("[data-menu-item]")??[]],y=_.current;_.current=null,y&&(j.current=!0,(("first"===y?v[0]:v.find(t=>t.dataset.menuItem===y))??(U?void 0:v.find(t=>"more"===t.dataset.menuItem)))?.focus({preventScroll:!0}),j.current=!1);let w=()=>m(t=>({...t}));return window.addEventListener("resize",w),()=>{u=!0,l.forEach(t=>t.stop()),window.removeEventListener("resize",w)}},[h,B,r,t.length,G.length]),xt(()=>{if(!U)return;let t=new AbortController;return st(E.current,"pointerdown",t=>{t.target instanceof Node&&!t.composedPath().includes(E.current)&&J(!1)},{signal:t.signal}),()=>t.abort()},[U]),xt(()=>()=>{clearTimeout(O.current),clearTimeout(R.current)},[]);let et=Dn("button",{type:"button",className:"morphing-menu__row","data-menu-item":"close",onClick:()=>J(!0,"more"),children:[Ln(ft,{"aria-hidden":"true"}),Ln("span",{className:"morphing-menu__label",children:"Close drawer"})]});return Dn("nav",{ref:E,"aria-label":s,className:["morphing-menu",u].filter(Boolean).join(" "),"data-view":h.kind,"data-edge":r,"data-vertical":b,"data-align-end":i,style:{"--mm-count":G.length+1,...c},onPointerMove:t=>{if(!V.current||"mouse"!==t.pointerType||!t.movementX&&!t.movementY)return;V.current=!1;let e=t.target instanceof Element?t.target.closest(".morphing-menu__shortcut"):null;e&&K(e,e.getAttribute("aria-label")??"")},onKeyDown:t=>{"Escape"===t.key&&(V.current=!0,q(),U&&(t.preventDefault(),t.stopPropagation(),"group"===h.kind?Q():J()))},onBlur:t=>{t.relatedTarget instanceof Node&&t.currentTarget.contains(t.relatedTarget)||(U?t.relatedTarget instanceof Node&&J(!1):N.current||q())},children:[Dn("div",{ref:C,className:"morphing-menu__shell",children:[Dn("div",{ref:M,className:"morphing-menu__bar","aria-hidden":U,inert:U,onPointerEnter:t=>{"mouse"===t.pointerType&&(N.current=!0,clearTimeout(R.current))},onPointerLeave:t=>{"mouse"===t.pointerType&&(N.current=!1,z(),clearTimeout(R.current),R.current=setTimeout(()=>{W.current=!1},300))},children:[$.map(t=>tt(t,!0)),Ln(Tn.button,{layout:"position",transition:B?{duration:0}:T,type:"button",className:"morphing-menu__shortcut","data-menu-item":"more","aria-label":a,"aria-expanded":U,"aria-controls":`${d}-main`,onClick:t=>Z({kind:"main"},"more",0===t.detail),onPointerEnter:t=>{"mouse"===t.pointerType&&K(t.currentTarget,a)},onPointerLeave:z,onPointerDown:q,onBlur:z,onFocus:t=>{t.currentTarget.matches(":focus-visible")&&K(t.currentTarget,a,!0)},children:Ln(mt,{"aria-hidden":"true"})}),Y&&tt(Y,!0)]}),Dn("div",{id:`${d}-main`,className:"morphing-menu__panel","aria-hidden":"main"!==h.kind,inert:"main"!==h.kind,children:[[...t].sort((t,e)=>(t.expandedOrder??0)-(e.expandedOrder??0)).map(t=>tt(t,!1)),et]}),X.map(t=>{let e="group"===h.kind&&h.id===t.id;return Dn("div",{id:`${d}-group-${t.id}`,className:"morphing-menu__panel","aria-label":t.label,"aria-hidden":!e,inert:!e,children:[Dn("button",{type:"button",className:"morphing-menu__row","data-menu-item":"back",onClick:Q,children:[Ln(vt,{"aria-hidden":"true"}),Ln("span",{children:l})]}),t.children.map(t=>tt(t,!1)),et]},t.id)})]}),w&&!U&&Ln("div",{ref:P,className:"morphing-menu__tooltip","aria-hidden":"true",style:{left:w.x,top:w.y},children:w.label})]})}function jn(){return Ln(wt,{className:"morphing-menu__chevron","aria-hidden":"true"})}function Vn({label:t,icon:e,reduced:n,children:r}){let i=St(null),o=St(null);return Pt(()=>{let r=i.current,s=o.current;if(o.current={label:t,node:r.cloneNode(!0)},!s||s.label===t||n)return;let a=s.node;a.setAttribute("aria-hidden","true"),r.parentElement.append(a);let l={duration:200,easing:"cubic-bezier(.22,1,.36,1)"},u=r.animate([{opacity:0,transform:e?"scale(.7)":"translateY(4px)",filter:"blur(2px)"},{opacity:1,transform:"none",filter:"blur(0px)"}],l),c=a.animate([{opacity:1,transform:"none",filter:"blur(0px)"},{opacity:0,transform:e?"scale(.7)":"translateY(-4px)",filter:"blur(2px)"}],l);return c.finished.then(()=>a.remove()).catch(()=>{}),()=>{u.cancel(),c.cancel(),a.remove()}},[t,e,n]),Ln("span",{ref:i,style:{gridArea:"1 / 1",display:"flex",alignItems:"center"},children:r})}function _n(t){return"glyph"in t?dt("span",{style:{display:"contents"},dangerouslySetInnerHTML:{__html:ot[t.glyph]}}):dt("span",{className:"review-avatar"},t.user?.avatarUrl?dt("img",{src:t.user.avatarUrl,alt:"",referrerPolicy:"no-referrer"}):t.user?at(t.user.name):_n({glyph:"person"}))}var On=t=>dt(In,{...t,items:t.items.map(t=>({...t,icon:_n(t.icon)}))});function Rn(t,e){t.replaceChildren();let n=ut(t);return ct(()=>n.render(On(e))),{render:t=>n.render(On(t)),unmount:()=>n.unmount()}}export{Rn as mountToolbar};
|
|
1
|
+
import{$ as t,A as e,B as n,C as r,D as i,E as o,F as s,G as a,H as l,I as u,J as c,K as d,L as h,M as m,N as p,O as f,P as g,Q as v,R as y,S as x,T as w,U as E,V as P,W as S,X as b,Y as C,Z as M,_ as k,a as T,aa as A,b as L,ba as D,c as I,ca as j,da as V,ea as R,fa as _,ga as O,ha as W,ia as N,j as B,ja as F,k as H,ka as U,l as $,m as G,n as Y,o as X,p as z,q,r as K,s as Z,t as J,u as Q,v as tt,w as et,x as nt,y as rt,z as it}from"./chunk-7YUXYVQA.js";import{c as ot,g as st,k as at}from"./chunk-YZP3KX4Y.js";import{a as lt}from"./chunk-I7AUKTXE.js";import{createRoot as ut}from"react-dom/client";import{flushSync as ct}from"react-dom";import{createElement as dt}from"react";import*as ht from"react";var mt=({size:t=24,color:e="currentColor",...n})=>ht.createElement("svg",{viewBox:"0 0 24 24",width:t,height:t,stroke:e,strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...n},ht.createElement("path",{d:"m7 15 5 5 5-5M7 9l5-5 5 5"}));mt.displayName="ChevronSelectorVertical";import*as pt from"react";var ft=({size:t=24,color:e="currentColor",...n})=>pt.createElement("svg",{viewBox:"0 0 24 24",width:t,height:t,stroke:e,strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...n},pt.createElement("path",{d:"M18 6 6 18M6 6l12 12"}));ft.displayName="XClose";import*as gt from"react";var vt=({size:t=24,color:e="currentColor",...n})=>gt.createElement("svg",{viewBox:"0 0 24 24",width:t,height:t,stroke:e,strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...n},gt.createElement("path",{d:"M19 12H5m0 0 7 7m-7-7 7-7"}));vt.displayName="ArrowLeft";import*as yt from"react";var xt=({size:t=24,color:e="currentColor",...n})=>yt.createElement("svg",{viewBox:"0 0 24 24",width:t,height:t,stroke:e,strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...n},yt.createElement("path",{d:"m9 18 6-6-6-6"}));xt.displayName="ChevronRight";import{useEffect as wt,useId as Et,useLayoutEffect as Pt,useRef as St,useState as bt}from"react";import{createContext as Ct}from"react";var Mt=Ct({});import{useRef as kt}from"react";import{useLayoutEffect as Tt,useEffect as At}from"react";var Lt=typeof window<"u"?Tt:At;import{createContext as Dt}from"react";var It=Dt(null);import{createContext as jt}from"react";var Vt=jt({transformPagePoint:t=>t,isStatic:!1,reducedMotion:"never"});import{useContext as Rt,useId as _t,useEffect as Ot,useCallback as Wt}from"react";import{createContext as Nt}from"react";var Bt=Nt({strict:!1}),Ft={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]},Ht=!1;function Ut(){return function(){if(Ht)return;let t={};for(let e in Ft)t[e]={isEnabled:t=>Ft[e].some(e=>!!t[e])};v(t),Ht=!0}(),y()}var $t=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","propagate","ignoreStrict","viewport"]);function Gt(t){return t.startsWith("while")||t.startsWith("drag")&&"draggable"!==t||t.startsWith("layout")||t.startsWith("onTap")||t.startsWith("onPan")||t.startsWith("onLayout")||$t.has(t)}var Yt,Xt=t=>!Gt(t);try{"function"==typeof(Yt=lt("@emotion/is-prop-valid").default)&&(Xt=t=>t.startsWith("on")?!Gt(t):Yt(t))}catch{}import{jsxs as zt,jsx as qt}from"react/jsx-runtime";import{forwardRef as Kt,useContext as Zt}from"react";import{createContext as Jt}from"react";var Qt=Jt({});import{useContext as te,useMemo as ee}from"react";function ne(t){let{initial:e,animate:n}=function(t,e){if(h(t)){let{initial:e,animate:n}=t;return{initial:!1===e||d(e)?e:void 0,animate:d(n)?n:void 0}}return!1!==t.inherit?e:{}}(t,te(Qt));return ee(()=>({initial:e,animate:n}),[re(e),re(n)])}function re(t){return Array.isArray(t)?t.join(" "):t}import{Fragment as ie,useMemo as oe,createElement as se}from"react";import{useMemo as ae}from"react";var le=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function ue(t,e,n){for(let r in e)!rt(e[r])&&!b(r,n)&&(t[r]=e[r])}function ce(t,e){let n={};return ue(n,t.style||{},t),Object.assign(n,function({transformTemplate:t},e){return ae(()=>{let n={style:{},transform:{},transformOrigin:{},vars:{}};return S(n,e,t),Object.assign({},n.vars,n.style)},[e])}(t,e)),n}function de(t,e){let n={},r=ce(t,e);return t.drag&&!1!==t.dragListener&&(n.draggable=!1,r.userSelect=r.WebkitUserSelect=r.WebkitTouchCallout="none",r.touchAction=!0===t.drag?"none":"pan-"+("x"===t.drag?"y":"x")),void 0===t.tabIndex&&(t.onTap||t.onTapStart||t.whileTap)&&(n.tabIndex=0),n.style=r,n}import{useMemo as he}from"react";var me=()=>({style:{},transform:{},transformOrigin:{},vars:{},attrs:{}});function pe(e,n,r,i){let o=he(()=>{let r={style:{},transform:{},transformOrigin:{},vars:{},attrs:{}};return k(r,n,t(i),e.transformTemplate,e.style),{...r.attrs,style:{...r.style}}},[n]);if(e.style){let t={};ue(t,e.style,e),o.style={...t,...o.style}}return o}var fe=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function ge(t){return"string"==typeof t&&!t.includes("-")&&!!(fe.indexOf(t)>-1||/[A-Z]/u.test(t))}function ve(t,e,n,{latestValues:r},i,o=!1,s){let a=(s??ge(t)?pe:de)(e,r,i,t),l=function(t,e,n){let r={};for(let i in t)"values"===i&&"object"==typeof t.values||rt(t[i])||(Xt(i)||!0===n&&Gt(i)||!e&&!Gt(i)||t.draggable&&i.startsWith("onDrag"))&&(r[i]=t[i]);return r}(e,"string"==typeof t,o),u=t!==ie?{...l,...a,ref:n}:{},{children:c}=e,d=oe(()=>rt(c)?c.get():c,[c]);return se(t,{...u,children:d})}import{useContext as ye}from"react";function xe(t,e,n,r){let i={},o=r(t,{});for(let t in o)i[t]=O(o[t]);let{initial:s,animate:a}=t,l=h(t),u=m(t);e&&u&&!l&&!1!==t.inherit&&(void 0===s&&(s=e.initial),void 0===a&&(a=e.animate));let d=!!n&&!1===n.initial;d=d||!1===s;let p=d?a:s;if(p&&"boolean"!=typeof p&&!c(p)){let e=Array.isArray(p)?p:[p];for(let n=0;n<e.length;n++){let r=et(t,e[n]);if(r){let{transitionEnd:t,transition:e,...n}=r;for(let t in n){let e=n[t];if(Array.isArray(e)){e=e[d?e.length-1:0]}null!==e&&(i[t]=e)}for(let e in t)i[e]=t[e]}}}return i}var we=t=>(e,n)=>{let r=ye(Qt),i=ye(It),o=()=>function({scrapeMotionValuesFromProps:t,createRenderState:e},n,r,i){return{latestValues:xe(n,r,i,t),renderState:e()}}(t,e,r,i);return n?o():function(t){let e=kt(null);return null===e.current&&(e.current=t()),e.current}(o)},Ee=we({scrapeMotionValuesFromProps:C,createRenderState:le}),Pe=we({scrapeMotionValuesFromProps:A,createRenderState:me}),Se=Symbol.for("motionComponentSymbol");import{useRef as be,useInsertionEffect as Ce,useCallback as Me}from"react";function ke(t,e,n){let r=be(n);Ce(()=>{r.current=n});let i=be(null);return Me(n=>{n&&t.onMount?.(n),e&&(n?e.mount(n):e.unmount());let o=r.current;if("function"==typeof o)if(n){let t=o(n);"function"==typeof t&&(i.current=t)}else i.current?(i.current(),i.current=null):o(n);else o&&(o.current=n)},[e])}import{useContext as Te,useRef as Ae,useInsertionEffect as Le,useEffect as De}from"react";import{createContext as Ie}from"react";var je=Ie({});function Ve(t){return t&&"object"==typeof t&&Object.prototype.hasOwnProperty.call(t,"current")}function Re(t,n,r,i,o,s){let{visualElement:a}=Te(Qt),l=Te(Bt),u=Te(It),c=Te(Vt),d=c.reducedMotion,h=c.skipAnimations,m=Ae(null),p=Ae(!1);i=i||l.renderer,!m.current&&i&&(m.current=i(t,{visualState:n,parent:a,props:r,presenceContext:u,blockInitialAnimation:!!u&&!1===u.initial,reducedMotionConfig:d,skipAnimations:h,isSVG:s}),p.current&&m.current&&(m.current.manuallyAnimateOnMount=!0));let f=m.current,g=Te(je);f&&!f.projection&&o&&("html"===f.type||"svg"===f.type)&&function(t,e,n,r){let{layoutId:i,layout:o,drag:s,dragConstraints:a,layoutScroll:l,layoutRoot:u,layoutAnchor:c,layoutCrossfade:d}=e;t.projection=new n(t.latestValues,e["data-framer-portal-id"]?void 0:_e(t.parent)),t.projection.setOptions({layoutId:i,layout:o,alwaysMeasureLayout:!!s||a&&Ve(a),visualElement:t,animationType:"string"==typeof o?o:"both",initialPromotionConfig:r,crossfade:d,layoutScroll:l,layoutRoot:u,layoutAnchor:c})}(m.current,r,o,g);let v=Ae(!1);Le(()=>{f&&v.current&&f.update(r,u)});let y=r[e],x=Ae(!!y&&typeof window<"u"&&!window.MotionHandoffIsComplete?.(y)&&window.MotionHasOptimisedAnimation?.(y));return Lt(()=>{p.current=!0,f&&(v.current=!0,window.MotionIsMounted=!0,f.updateFeatures(),f.scheduleRenderMicrotask(),x.current&&f.animationState&&f.animationState.animateChanges())}),De(()=>{f&&(!x.current&&f.animationState&&f.animationState.animateChanges(),x.current&&(queueMicrotask(()=>{window.MotionHandoffMarkAsComplete?.(y)}),x.current=!1),f.enteringChildren=void 0)}),f}function _e(t){if(t)return!1!==t.options.allowProjection?t.projection:_e(t.parent)}function Oe(t,{forwardMotionProps:e=!1,type:n}={},r,i){r&&function(t){let e=Ut();for(let n in t)e[n]={...e[n],...t[n]};v(e)}(r);let o=n?"svg"===n:ge(t),s=o?Pe:Ee;function a(n,r){let a,l={...Zt(Vt),...n,layoutId:We(n)},{isStatic:u}=l,c=ne(n),d=s(n,u);if(!u&&typeof window<"u"){Zt(Bt).strict;let e=function(t){let e=Ut(),{drag:n,layout:r}=e;if(!n&&!r)return{};let i={...n,...r};return{MeasureLayout:n?.isEnabled(t)||r?.isEnabled(t)?i.MeasureLayout:void 0,ProjectionNode:i.ProjectionNode}}(l);a=e.MeasureLayout,c.visualElement=Re(t,d,l,i,e.ProjectionNode,o)}return zt(Qt.Provider,{value:c,children:[a&&c.visualElement?qt(a,{visualElement:c.visualElement,...l}):null,ve(t,n,ke(d,c.visualElement,r),d,u,e,o)]})}a.displayName=`motion.${"string"==typeof t?t:`create(${t.displayName??t.name??""})`}`;let l=Kt(a);return l[Se]=t,l}function We({layoutId:t}){let e=Zt(Mt).id;return e&&void 0!==t?e+"-"+t:t}import{Fragment as Ne}from"react";var Be=0,Fe={animation:{Feature:class extends x{constructor(t){super(t),t.animationState||(t.animationState=j(t))}updateAnimationControlsSubscription(){let{animate:t}=this.node.getProps();c(t)&&(this.unmountControls=t.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){let{animate:t}=this.node.getProps(),{animate:e}=this.node.prevProps||{};t!==e&&this.updateAnimationControlsSubscription()}unmount(){this.node.animationState.reset(),this.unmountControls?.()}}},exit:{Feature:class extends x{constructor(){super(...arguments),this.id=Be++,this.isExitComplete=!1}update(){if(!this.node.presenceContext)return;let{isPresent:t,onExitComplete:e}=this.node.presenceContext,{isPresent:n}=this.node.prevPresenceContext||{};if(!this.node.animationState||t===n)return;if(t&&!1===n){if(this.isExitComplete){let{initial:t,custom:e}=this.node.getProps();if("string"==typeof t||"object"==typeof t&&null!==t&&!Array.isArray(t)){let n=nt(this.node,t,e);if(n){let{transition:t,transitionEnd:e,...r}=n;for(let t in r)this.node.getValue(t)?.jump(r[t])}}this.node.animationState.reset(),this.node.animationState.animateChanges()}else this.node.animationState.setActive("exit",!1);return void(this.isExitComplete=!1)}let r=this.node.animationState.setActive("exit",!t);e&&!t&&r.then(()=>{this.isExitComplete=!0,e(this.id)})}mount(){let{register:t,onExitComplete:e}=this.node.presenceContext||{};e&&e(this.id),t&&(this.unmount=t(this.id))}unmount(){}}}};function He(t){return{point:{x:t.pageX,y:t.pageY}}}function Ue(t,e,n,r){return _(t,e,(t=>e=>o(e)&&t(e,He(e)))(n),r)}var $e=({current:t})=>t?t.ownerDocument.defaultView:null,Ge=new Set(["auto","scroll"]),Ye=class{constructor(t,e,{transformPagePoint:n,contextWindow:r=window,dragSnapToOrigin:i=!1,distanceThreshold:s=3,element:a}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.lastRawMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.scrollPositions=new Map,this.removeScrollListeners=null,this.onElementScroll=t=>{this.handleScroll(t.target)},this.onWindowScroll=()=>{this.handleScroll(window)},this.updatePoint=()=>{if(!this.lastMoveEvent||!this.lastMoveEventInfo)return;this.lastRawMoveEventInfo&&(this.lastMoveEventInfo=Xe(this.lastRawMoveEventInfo,this.transformPagePoint));let t=qe(this.lastMoveEventInfo,this.history),e=null!==this.startEvent,n=U(t.offset,{x:0,y:0})>=this.distanceThreshold;if(!e&&!n)return;let{point:r}=t,{timestamp:i}=Z;this.history.push({...r,timestamp:i});let{onStart:o,onMove:s}=this.handlers;e||(o&&o(this.lastMoveEvent,t),this.startEvent=this.lastMoveEvent),s&&s(this.lastMoveEvent,t)},this.handlePointerMove=(t,e)=>{this.lastMoveEvent=t,this.lastRawMoveEventInfo=e,this.lastMoveEventInfo=Xe(e,this.transformPagePoint),q.update(this.updatePoint,!0)},this.handlePointerUp=(t,e)=>{this.end();let{onEnd:n,onSessionEnd:r,resumeAnimation:i}=this.handlers;if((this.dragSnapToOrigin||!this.startEvent)&&i&&i(),!this.lastMoveEvent||!this.lastMoveEventInfo)return;let o=qe("pointercancel"===t.type?this.lastMoveEventInfo:Xe(e,this.transformPagePoint),this.history);this.startEvent&&n&&n(t,o),r&&r(t,o)},!o(t))return;this.dragSnapToOrigin=i,this.handlers=e,this.transformPagePoint=n,this.distanceThreshold=s,this.contextWindow=r||window;let l=Xe(He(t),this.transformPagePoint),{point:u}=l,{timestamp:c}=Z;this.history=[{...u,timestamp:c}];let{onSessionStart:d}=e;d&&d(t,qe(l,this.history));let h={passive:!0,capture:!0};this.removeListeners=G(Ue(this.contextWindow,"pointermove",this.handlePointerMove,h),Ue(this.contextWindow,"pointerup",this.handlePointerUp,h),Ue(this.contextWindow,"pointercancel",this.handlePointerUp,h)),a&&this.startScrollTracking(a)}startScrollTracking(t){let e=t.parentElement;for(;e;){let t=getComputedStyle(e);(Ge.has(t.overflowX)||Ge.has(t.overflowY))&&this.scrollPositions.set(e,{x:e.scrollLeft,y:e.scrollTop}),e=e.parentElement}this.scrollPositions.set(window,{x:window.scrollX,y:window.scrollY}),window.addEventListener("scroll",this.onElementScroll,{capture:!0}),window.addEventListener("scroll",this.onWindowScroll),this.removeScrollListeners=()=>{window.removeEventListener("scroll",this.onElementScroll,{capture:!0}),window.removeEventListener("scroll",this.onWindowScroll)}}handleScroll(t){let e=this.scrollPositions.get(t);if(!e)return;let n=t===window,r=n?{x:window.scrollX,y:window.scrollY}:{x:t.scrollLeft,y:t.scrollTop},i=r.x-e.x,o=r.y-e.y;0===i&&0===o||(n?this.lastMoveEventInfo&&(this.lastMoveEventInfo.point.x+=i,this.lastMoveEventInfo.point.y+=o):this.history.length>0&&(this.history[0].x-=i,this.history[0].y-=o),this.scrollPositions.set(t,r),q.update(this.updatePoint,!0))}updateHandlers(t){this.handlers=t}end(){this.removeListeners&&this.removeListeners(),this.removeScrollListeners&&this.removeScrollListeners(),this.scrollPositions.clear(),K(this.updatePoint)}};function Xe(t,e){return e?{point:e(t.point)}:t}function ze(t,e){return{x:t.x-e.x,y:t.y-e.y}}function qe({point:t},e){return{point:t,delta:ze(t,Ze(e)),offset:ze(t,Ke(e)),velocity:Je(e,.1)}}function Ke(t){return t[0]}function Ze(t){return t[t.length-1]}function Je(t,e){if(t.length<2)return{x:0,y:0};let n=t.length-1,r=null,i=Ze(t);for(;n>=0&&(r=t[n],!(i.timestamp-r.timestamp>X(e)));)n--;if(!r)return{x:0,y:0};r===t[0]&&t.length>2&&i.timestamp-r.timestamp>2*X(e)&&(r=t[1]);let o=z(i.timestamp-r.timestamp);if(0===o)return{x:0,y:0};let s={x:(i.x-r.x)/o,y:(i.y-r.y)/o};return s.x===1/0&&(s.x=0),s.y===1/0&&(s.y=0),s}function Qe(t,e,n){return{min:void 0!==e?t.min+e:void 0,max:void 0!==n?t.max+n-(t.max-t.min):void 0}}function tn(t,e){let n=e.min-t.min,r=e.max-t.max;return e.max-e.min<t.max-t.min&&([n,r]=[r,n]),{min:n,max:r}}var en=.35;function nn(t,e,n){return{min:rn(t,e),max:rn(t,n)}}function rn(t,e){return"number"==typeof t?t:t[e]||0}var on=new WeakMap,sn=class{constructor(t){this.openDragLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=u(),this.latestPointerEvent=null,this.latestPanInfo=null,this.visualElement=t}start(t,{snapToCursor:e=!1,distanceThreshold:n}={}){let{presenceContext:i}=this.visualElement;if(i&&!1===i.isPresent)return;let{dragSnapToOrigin:o}=this.getProps();this.panSession=new Ye(t,{onSessionStart:t=>{e&&this.snapToCursor(He(t).point),this.stopAnimation()},onStart:(t,e)=>{let{drag:n,dragPropagation:i,onDragStart:o}=this.getProps();if(n&&!i&&(this.openDragLock&&this.openDragLock(),this.openDragLock=r(n),!this.openDragLock))return;this.latestPointerEvent=t,this.latestPanInfo=e,this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),R(t=>{let e=this.getAxisMotionValue(t).get()||0;if(J.test(e)){let{projection:n}=this.visualElement;if(n&&n.layout){let r=n.layout.layoutBox[t];r&&(e=V(r)*(parseFloat(e)/100))}}this.originPoint[t]=e}),o&&q.update(()=>o(t,e),!1,!0),it(this.visualElement,"transform");let{animationState:s}=this.visualElement;s&&s.setActive("whileDrag",!0)},onMove:(t,e)=>{this.latestPointerEvent=t,this.latestPanInfo=e;let{dragPropagation:n,dragDirectionLock:r,onDirectionLock:i,onDrag:o}=this.getProps();if(!n&&!this.openDragLock)return;let{offset:s}=e;if(r&&null===this.currentDirection)return this.currentDirection=function(t,e=10){let n=null;return Math.abs(t.y)>e?n="y":Math.abs(t.x)>e&&(n="x"),n}(s),void(null!==this.currentDirection&&i&&i(this.currentDirection));this.updateAxis("x",e.point,s),this.updateAxis("y",e.point,s),this.visualElement.render(),o&&q.update(()=>o(t,e),!1,!0)},onSessionEnd:(t,e)=>{this.latestPointerEvent=t,this.latestPanInfo=e,this.stop(t,e),this.latestPointerEvent=null,this.latestPanInfo=null},resumeAnimation:()=>{let{dragSnapToOrigin:t}=this.getProps();(t||this.constraints)&&this.startAnimation({x:0,y:0})}},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:o,distanceThreshold:n,contextWindow:$e(this.visualElement),element:this.visualElement.current})}stop(t,e){let n=t||this.latestPointerEvent,r=e||this.latestPanInfo,i=this.isDragging;if(this.cancel(),!i||!r||!n)return;let{velocity:o}=r;this.startAnimation(o);let{onDragEnd:s}=this.getProps();s&&q.postRender(()=>s(n,r))}cancel(){this.isDragging=!1;let{projection:t,animationState:e}=this.visualElement;t&&(t.isAnimationBlocked=!1),this.endPanSession();let{dragPropagation:n}=this.getProps();!n&&this.openDragLock&&(this.openDragLock(),this.openDragLock=null),e&&e.setActive("whileDrag",!1)}endPanSession(){this.panSession&&this.panSession.end(),this.panSession=void 0}updateAxis(t,e,n){let{drag:r}=this.getProps();if(!n||!ln(t,r,this.currentDirection))return;let i=this.getAxisMotionValue(t),o=this.originPoint[t]+n[t];this.constraints&&this.constraints[t]&&(o=function(t,{min:e,max:n},r){return void 0!==e&&t<e?t=r?Q(e,t,r.min):Math.max(t,e):void 0!==n&&t>n&&(t=r?Q(n,t,r.max):Math.min(t,n)),t}(o,this.constraints[t],this.elastic[t])),i.set(o)}resolveConstraints(){let{dragConstraints:t,dragElastic:e}=this.getProps(),n=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):this.visualElement.projection?.layout,r=this.constraints;t&&Ve(t)?this.constraints||(this.constraints=this.resolveRefConstraints()):this.constraints=!(!t||!n)&&function(t,{top:e,left:n,bottom:r,right:i}){return{x:Qe(t.x,n,i),y:Qe(t.y,e,r)}}(n.layoutBox,t),this.elastic=function(t=en){return!1===t?t=0:!0===t&&(t=en),{x:nn(t,"left","right"),y:nn(t,"top","bottom")}}(e),r!==this.constraints&&!Ve(t)&&n&&this.constraints&&!this.hasMutatedConstraints&&R(t=>{!1!==this.constraints&&this.getAxisMotionValue(t)&&(this.constraints[t]=function(t,e){let n={};return void 0!==e.min&&(n.min=e.min-t.min),void 0!==e.max&&(n.max=e.max-t.min),n}(n.layoutBox[t],this.constraints[t]))})}resolveRefConstraints(){let{dragConstraints:t,onMeasureDragConstraints:e}=this.getProps();if(!t||!Ve(t))return!1;let n=t.current;H(null!==n,"If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.","drag-constraints-ref");let{projection:r}=this.visualElement;if(!r||!r.layout)return!1;r.root&&(r.root.scroll=void 0,r.root.updateScroll());let i=P(n,r.root,this.visualElement.getTransformPagePoint()),o=function(t,e){return{x:tn(t.x,e.x),y:tn(t.y,e.y)}}(r.layout.layoutBox,i);if(e){let t=e(E(o));this.hasMutatedConstraints=!!t,t&&(o=w(t))}return o}startAnimation(t){let{drag:e,dragMomentum:n,dragElastic:r,dragTransition:i,dragSnapToOrigin:o,onDragTransitionEnd:s}=this.getProps(),a=this.constraints||{},l=R(s=>{if(!ln(s,e,this.currentDirection))return;let l=a&&a[s]||{};(!0===o||o===s)&&(l={min:0,max:0});let u=r?200:1e6,c=r?40:1e7,d={type:"inertia",velocity:n?t[s]:0,bounceStiffness:u,bounceDamping:c,timeConstant:750,restDelta:1,restSpeed:10,...i,...l};return this.startAxisValueAnimation(s,d)});return Promise.all(l).then(s)}startAxisValueAnimation(t,e){let n=this.getAxisMotionValue(t);return it(this.visualElement,t),n.start(tt(t,n,0,e,this.visualElement,!1))}stopAnimation(){R(t=>this.getAxisMotionValue(t).stop())}getAxisMotionValue(t){let e=`_drag${t.toUpperCase()}`;return this.visualElement.getProps()[e]||this.visualElement.getValue(t,this.visualElement.latestValues[t]??0)}snapToCursor(t){R(e=>{let{drag:n}=this.getProps();if(!ln(e,n,this.currentDirection))return;let{projection:r}=this.visualElement,i=this.getAxisMotionValue(e);if(r&&r.layout){let{min:n,max:o}=r.layout.layoutBox[e],s=i.get()||0;i.set(t[e]-Q(n,o,.5)+s)}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;let{drag:t,dragConstraints:e}=this.getProps(),{projection:n}=this.visualElement;if(!Ve(e)||!n||!this.constraints)return;this.stopAnimation();let r={x:0,y:0};R(t=>{let e=this.getAxisMotionValue(t);if(e&&!1!==this.constraints){let n=e.get();r[t]=function(t,e){let n=.5,r=V(t),i=V(e);return i>r?n=Y(e.min,e.max-r,t.min):r>i&&(n=Y(t.min,t.max-i,e.min)),B(0,1,n)}({min:n,max:n},this.constraints[t])}});let{transformTemplate:i}=this.visualElement.getProps();this.visualElement.current.style.transform=i?i({},""):"none",n.root&&n.root.updateScroll(),n.updateLayout(),this.constraints=!1,this.resolveConstraints(),R(e=>{if(!ln(e,t,null))return;let n=this.getAxisMotionValue(e),{min:i,max:o}=this.constraints[e];n.set(Q(i,o,r[e]))}),this.visualElement.render()}addListeners(){if(!this.visualElement.current)return;on.set(this.visualElement,this);let t,e=this.visualElement.current,n=Ue(e,"pointerdown",t=>{let{drag:n,dragListener:r=!0}=this.getProps(),i=t.target,o=i!==e&&s(i);n&&r&&!o&&this.start(t)}),r=()=>{let{dragConstraints:n}=this.getProps();Ve(n)&&n.current&&(this.constraints=this.resolveRefConstraints(),t||(t=function(t,e,n){let r=l(t,an(n)),i=l(e,an(n));return()=>{r(),i()}}(e,n.current,()=>this.scalePositionWithinConstraints())))},{projection:i}=this.visualElement,o=i.addEventListener("measure",r);i&&!i.layout&&(i.root&&i.root.updateScroll(),i.updateLayout()),q.read(r);let a=_(window,"resize",()=>this.scalePositionWithinConstraints()),u=i.addEventListener("didUpdate",({delta:t,hasLayoutChanged:e})=>{this.isDragging&&e&&(R(e=>{let n=this.getAxisMotionValue(e);n&&(this.originPoint[e]+=t[e].translate,n.set(n.get()+t[e].translate))}),this.visualElement.render())});return()=>{a(),n(),o(),u&&u(),t&&t()}}getProps(){let t=this.visualElement.getProps(),{drag:e=!1,dragDirectionLock:n=!1,dragPropagation:r=!1,dragConstraints:i=!1,dragElastic:o=en,dragMomentum:s=!0}=t;return{...t,drag:e,dragDirectionLock:n,dragPropagation:r,dragConstraints:i,dragElastic:o,dragMomentum:s}}};function an(t){let e=!0;return()=>{e?e=!1:t()}}function ln(t,e,n){return!(!0!==e&&e!==t||null!==n&&n!==t)}var un=t=>(e,n)=>{t&&q.update(()=>t(e,n),!1,!0)};import{jsx as cn}from"react/jsx-runtime";import{useContext as dn,Component as hn}from"react";var mn=!1,pn=class extends hn{componentDidMount(){let{visualElement:t,layoutGroup:e,switchLayoutGroup:n,layoutId:r}=this.props,{projection:i}=t;i&&(e.group&&e.group.add(i),n&&n.register&&r&&n.register(i),mn&&i.root.didUpdate(),i.addEventListener("animationComplete",()=>{this.safeToRemove()}),i.setOptions({...i.options,layoutDependency:this.props.layoutDependency,onExitComplete:()=>this.safeToRemove()})),W.hasEverUpdated=!0}getSnapshotBeforeUpdate(t){let{layoutDependency:e,visualElement:n,drag:r,isPresent:i}=this.props,{projection:o}=n;return o&&(o.isPresent=i,t.layoutDependency!==e&&o.setOptions({...o.options,layoutDependency:e}),mn=!0,r||t.layoutDependency!==e||void 0===e||t.isPresent!==i?o.willUpdate():this.safeToRemove(),t.isPresent!==i&&(i?o.promote():o.relegate()||q.postRender(()=>{let t=o.getStack();(!t||!t.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){let{visualElement:t,layoutAnchor:e}=this.props,{projection:r}=t;r&&(r.options.layoutAnchor=e,r.root.didUpdate(),n.postRender(()=>{!r.currentAnimation&&r.isLead()&&this.safeToRemove()}))}componentWillUnmount(){let{visualElement:t,layoutGroup:e,switchLayoutGroup:n}=this.props,{projection:r}=t;mn=!0,r&&(r.scheduleCheckAfterUnmount(),e&&e.group&&e.group.remove(r),n&&n.deregister&&n.deregister(r))}safeToRemove(){let{safeToRemove:t}=this.props;t&&t()}render(){return null}};function fn(t){let[e,n]=function(t=!0){let e=Rt(It);if(null===e)return[!0,null];let{isPresent:n,onExitComplete:r,register:i}=e,o=_t();Ot(()=>{if(t)return i(o)},[t]);let s=Wt(()=>t&&r&&r(o),[o,r,t]);return!n&&r?[!1,s]:[!0]}(),r=dn(Mt);return cn(pn,{...t,layoutGroup:r,switchLayoutGroup:dn(je),isPresent:e,safeToRemove:n})}var gn={pan:{Feature:class extends x{constructor(){super(...arguments),this.removePointerDownListener=$}onPointerDown(t){this.session=new Ye(t,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:$e(this.node)})}createPanHandlers(){let{onPanSessionStart:t,onPanStart:e,onPan:n,onPanEnd:r}=this.node.getProps();return{onSessionStart:un(t),onStart:un(e),onMove:un(n),onEnd:(t,e)=>{delete this.session,r&&q.postRender(()=>r(t,e))}}}mount(){this.removePointerDownListener=Ue(this.node.current,"pointerdown",t=>this.onPointerDown(t))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}},drag:{Feature:class extends x{constructor(t){super(t),this.removeGroupControls=$,this.removeListeners=$,this.controls=new sn(t)}mount(){let{dragControls:t}=this.node.getProps();t&&(this.removeGroupControls=t.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||$}update(){let{dragControls:t}=this.node.getProps(),{dragControls:e}=this.node.prevProps||{};t!==e&&(this.removeGroupControls(),t&&(this.removeGroupControls=t.subscribe(this.controls)))}unmount(){this.removeGroupControls(),this.removeListeners(),this.controls.isDragging||this.controls.endPanSession()}},ProjectionNode:N,MeasureLayout:fn}};function vn(t,e,n){let{props:r}=t;t.animationState&&r.whileHover&&t.animationState.setActive("whileHover","Start"===n);let i=r["onHover"+n];i&&q.postRender(()=>i(e,He(e)))}function yn(t,e,n){let{props:r}=t;if(t.current instanceof HTMLButtonElement&&t.current.disabled)return;t.animationState&&r.whileTap&&t.animationState.setActive("whileTap","Start"===n);let i=r["onTap"+("End"===n?"":n)];i&&q.postRender(()=>i(e,He(e)))}var xn=new WeakMap,wn=new WeakMap,En=t=>{let e=xn.get(t.target);e&&e(t)},Pn=t=>{t.forEach(En)};function Sn(t,e,n){let r=function({root:t,...e}){let n=t||document;wn.has(n)||wn.set(n,{});let r=wn.get(n),i=JSON.stringify(e);return r[i]||(r[i]=new IntersectionObserver(Pn,{root:t,...e})),r[i]}(e);return xn.set(t,n),r.observe(t),()=>{xn.delete(t),r.unobserve(t)}}var bn={some:0,all:1};var Cn={inView:{Feature:class extends x{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){this.stopObserver?.();let{viewport:t={}}=this.node.getProps(),{root:e,margin:n,amount:r="some",once:i}=t,o={root:e?e.current:void 0,rootMargin:n,threshold:"number"==typeof r?r:bn[r]};this.stopObserver=Sn(this.node.current,o,t=>{let{isIntersecting:e}=t;if(this.isInView===e||(this.isInView=e,i&&!e&&this.hasEnteredView))return;e&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",e);let{onViewportEnter:n,onViewportLeave:r}=this.node.getProps(),o=e?n:r;o&&o(t)})}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;let{props:t,prevProps:e}=this.node;["amount","margin","root"].some(function({viewport:t={}},{viewport:e={}}={}){return n=>t[n]!==e[n]}(t,e))&&this.startObserver()}unmount(){this.stopObserver?.(),this.hasEnteredView=!1,this.isInView=!1}}},tap:{Feature:class extends x{mount(){let{current:t}=this.node;if(!t)return;let{globalTapTarget:e,propagate:n}=this.node.props;this.unmount=a(t,(t,e)=>(yn(this.node,e,"Start"),(t,{success:e})=>yn(this.node,t,e?"End":"Cancel")),{useGlobalTarget:e,stopPropagation:!1===n?.tap})}unmount(){}}},focus:{Feature:class extends x{constructor(){super(...arguments),this.isActive=!1}onFocus(){let t=!1;try{t=this.node.current.matches(":focus-visible")}catch{t=!0}!t||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=G(_(this.node.current,"focus",()=>this.onFocus()),_(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}},hover:{Feature:class extends x{mount(){let{current:t}=this.node;t&&(this.unmount=i(t,(t,e)=>(vn(this.node,e,"Start"),t=>vn(this.node,t,"End"))))}unmount(){}}}},Mn=function(t,e){if(typeof Proxy>"u")return Oe;let n=new Map,r=(n,r)=>Oe(n,r,t,e);return new Proxy((t,e)=>r(t,e),{get:(i,o)=>"create"===o?r:(n.has(o)||n.set(o,Oe(o,void 0,t,e)),n.get(o))})}({...Fe,...Cn,...gn,...{layout:{ProjectionNode:N,MeasureLayout:fn}}},(t,e)=>e.isSVG??ge(t)?new D(e):new M(e,{allowProjection:t!==Ne}));import{useState as kn}from"react";var Tn=Mn;import{Fragment as An,jsx as Ln,jsxs as Dn}from"react/jsx-runtime";function In({items:t,defaultActiveId:e,activeId:n,edge:r="bottom",alignEnd:i=!1,onActiveChange:o,label:s="App navigation",moreLabel:a="More",backLabel:l="Back",className:u="",style:c}){let d=Et(),[h,m]=bt({kind:"collapsed"}),[v,y]=bt(e??t[0]?.id),[x,w]=bt(null),E=St(null),P=St(null),S=St(r),b="left"===r||"right"===r;Pt(()=>{let t=P.current;if(!t||!x)return;let e=0,n=0,r=document.documentElement.clientWidth,i=window.innerHeight;for(let o=t.parentNode;o instanceof Element&&o!==document.body;o=o.parentNode instanceof ShadowRoot?o.parentNode.host:o.parentNode){let t=getComputedStyle(o),s=o.getBoundingClientRect();"visible"!==t.overflowX&&(e=Math.max(e,s.left),r=Math.min(r,s.right)),"visible"!==t.overflowY&&(n=Math.max(n,s.top),i=Math.min(i,s.bottom))}t.style.maxWidth=`${Math.max(0,r-e-16)}px`,t.style.left=`${x.x}px`,t.style.top=`${x.y}px`;let o=t.getBoundingClientRect(),s=Math.max(e+8-o.left,Math.min(0,r-8-o.right)),a=Math.max(n+8-o.top,Math.min(0,i-8-o.bottom));t.style.left=`${x.x+s}px`,t.style.top=`${x.y+a}px`},[x]);let C=St(null),M=St(null),k=St(h),A=St("more"),D=St(!1),j=St(!1),V=St(!1),R=St(null),_=St(void 0),O=St(void 0),W=St(!1),N=St(!1),B=function(){!f.current&&g();let[t]=kn(p.current);return t}(),H=n??v,U="collapsed"!==h.kind,$=t.filter(t=>!1!==t.showInBar),G=$.find(t=>"dismiss"===t.id),Y=$.filter(t=>"dismiss"!==t.id),X=t.filter(t=>t.children?.length);function z(){clearTimeout(_.current),w(null)}function q(){z(),clearTimeout(O.current),W.current=!1}function K(t,e,n=!1){clearTimeout(_.current);let i=E.current,o=M.current;if(!i||!o||U||j.current||V.current&&!n)return;let s=i.getBoundingClientRect(),a=t.getBoundingClientRect(),l={label:e,x:"left"===r?s.width+8:"right"===r?-8:a.left-s.left+a.width/2,y:"top"===r?s.height+8:"bottom"===r?-8:a.top-s.top+a.height/2};clearTimeout(O.current);let u=()=>{W.current=!0,w(l)};n||W.current?u():_.current=setTimeout(u,400)}function Z(t,e,n){q(),U||(A.current=e,D.current=n),R.current="first",m(t)}function J(t=!0,e=A.current){q(),V.current=!0,R.current=t&&D.current?e:null,m({kind:"collapsed"})}function Q(){"group"===h.kind&&(R.current=h.id,m({kind:"main"}))}function tt(t,e){let n=!!t.children?.length,r=H===t.id||!!t.children?.some(t=>t.id===H),i=!e&&t.keepOpenOnSelect,s=(e,n=!1)=>Ln(Vn,{label:t.label,icon:n,reduced:!!B,children:e}),a=r&&t.activeIcon?t.activeIcon:t.icon,l=Dn(An,{children:[Ln("span",{className:"morphing-menu__icon","aria-hidden":"true",style:i?{display:"grid"}:void 0,children:i?s(a,!0):a}),!e&&Ln("span",{className:"morphing-menu__label",style:i?{display:"grid"}:void 0,children:i?s(t.label):t.label}),!e&&n&&Ln(jn,{})]}),u={className:e?"morphing-menu__shortcut":"morphing-menu__row","data-menu-item":t.id,"aria-label":t.label,"aria-current":r?n?"true":"page":void 0,"aria-expanded":n?"group"===h.kind&&h.id===t.id:void 0,"aria-controls":n?`${d}-group-${t.id}`:void 0,onClick:e=>n?Z({kind:"group",id:t.id},t.id,0===e.detail):function(t){y(t.id),o?.(t.id),U&&!t.keepOpenOnSelect?J(!0,"group"===h.kind?h.id:t.id):q(),t.onSelect?.()}(t),onPointerEnter:n=>{e&&"mouse"===n.pointerType&&K(n.currentTarget,t.label)},onPointerLeave:z,onPointerDown:q,onFocus:n=>{e&&n.currentTarget.matches(":focus-visible")&&K(n.currentTarget,t.label,!0)},onBlur:z};return t.href&&!n?Ln("a",{href:t.href,...u,children:l},t.id):Ln(Tn.button,{layout:!!e&&"position",transition:B?{duration:0}:T,type:"button",...u,children:l},t.id)}Pt(()=>{let t=E.current,e=C.current,n=M.current;if(!t||!e||!n)return;let i=S.current!==r;S.current=r;let o=k.current;k.current=h;let s=[...t.querySelectorAll(".morphing-menu__panel")],a=s.find(t=>"false"===t.getAttribute("aria-hidden")),l=[],u=!1,c=t=>(l.push(t),t),d=()=>({width:a?.offsetWidth??n.offsetWidth,height:a?.offsetHeight??n.offsetHeight}),p=i||o.kind!==h.kind||"group"===o.kind&&"group"===h.kind&&o.id!==h.id,f="collapsed"===o.kind!=("collapsed"===h.kind),g=B||!p;if(g)(()=>{let t=d();e.style.width=`${t.width}px`,e.style.height=`${t.height}px`})();else if(f&&!U)c(F(e,d(),I));else if(f){let t=Math.min(n.offsetWidth,n.offsetWidth>250?280:200);c(F(e,{width:t,height:n.offsetHeight>52?32:28},L)).finished.then(()=>{u||c(F(e,d(),{...T,bounce:U?.24:.15}))}).catch(()=>{})}else c(F(e,d(),{...T,duration:.25,bounce:.1}));c(F(n,{opacity:U?0:1,scale:U&&!B?.8:1,filter:U&&!B?"blur(8px)":"blur(0px)"},{duration:g?0:U?.15:.22,delay:g||U?0:.08,...U?{}:{ease:"easeOut"}}));for(let t of s){let e=t===a;for(let[n,r]of[...t.querySelectorAll(".morphing-menu__row")].entries())e&&f&&!g&&Object.assign(r.style,{opacity:"0",transform:"translateY(48px)",filter:"blur(4px)"}),c(F(r,{opacity:e?1:0,y:e||B?0:16,filter:e||B?"blur(0px)":"blur(2px)"},{...T,duration:g?0:e?f?.4:.25:.12,bounce:f?.3:0,delay:!g&&e?(f?.2:0)+.02*n:0}))}let v=[...(U?a:n)?.querySelectorAll("[data-menu-item]")??[]],y=R.current;R.current=null,y&&(j.current=!0,(("first"===y?v[0]:v.find(t=>t.dataset.menuItem===y))??(U?void 0:v.find(t=>"more"===t.dataset.menuItem)))?.focus({preventScroll:!0}),j.current=!1);let x=()=>m(t=>({...t}));return window.addEventListener("resize",x),()=>{u=!0,l.forEach(t=>t.stop()),window.removeEventListener("resize",x)}},[h,B,r,t.length,$.length]),wt(()=>{if(!U)return;let t=new AbortController;return st(E.current,"pointerdown",t=>{t.target instanceof Node&&!t.composedPath().includes(E.current)&&J(!1)},{signal:t.signal}),()=>t.abort()},[U]),wt(()=>()=>{clearTimeout(_.current),clearTimeout(O.current)},[]);let et=Dn("button",{type:"button",className:"morphing-menu__row","data-menu-item":"close",onClick:()=>J(!0,"more"),children:[Ln(ft,{"aria-hidden":"true"}),Ln("span",{className:"morphing-menu__label",children:"Close drawer"})]});return Dn("nav",{ref:E,"aria-label":s,className:["morphing-menu",u].filter(Boolean).join(" "),"data-view":h.kind,"data-edge":r,"data-vertical":b,"data-align-end":i,style:{"--mm-count":$.length+1,...c},onPointerMove:t=>{if(!V.current||"mouse"!==t.pointerType||!t.movementX&&!t.movementY)return;V.current=!1;let e=t.target instanceof Element?t.target.closest(".morphing-menu__shortcut"):null;e&&K(e,e.getAttribute("aria-label")??"")},onKeyDown:t=>{"Escape"===t.key&&(V.current=!0,q(),U&&(t.preventDefault(),t.stopPropagation(),"group"===h.kind?Q():J()))},onBlur:t=>{t.relatedTarget instanceof Node&&t.currentTarget.contains(t.relatedTarget)||(U?t.relatedTarget instanceof Node&&J(!1):N.current||q())},children:[Dn("div",{ref:C,className:"morphing-menu__shell",children:[Dn("div",{ref:M,className:"morphing-menu__bar","aria-hidden":U,inert:U,onPointerEnter:t=>{"mouse"===t.pointerType&&(N.current=!0,clearTimeout(O.current))},onPointerLeave:t=>{"mouse"===t.pointerType&&(N.current=!1,z(),clearTimeout(O.current),O.current=setTimeout(()=>{W.current=!1},300))},children:[Y.map(t=>tt(t,!0)),Ln(Tn.button,{layout:"position",transition:B?{duration:0}:T,type:"button",className:"morphing-menu__shortcut","data-menu-item":"more","aria-label":a,"aria-expanded":U,"aria-controls":`${d}-main`,onClick:t=>Z({kind:"main"},"more",0===t.detail),onPointerEnter:t=>{"mouse"===t.pointerType&&K(t.currentTarget,a)},onPointerLeave:z,onPointerDown:q,onBlur:z,onFocus:t=>{t.currentTarget.matches(":focus-visible")&&K(t.currentTarget,a,!0)},children:Ln(mt,{"aria-hidden":"true"})}),G&&tt(G,!0)]}),Dn("div",{id:`${d}-main`,className:"morphing-menu__panel","aria-hidden":"main"!==h.kind,inert:"main"!==h.kind,children:[[...t].sort((t,e)=>(t.expandedOrder??0)-(e.expandedOrder??0)).map(t=>tt(t,!1)),et]}),X.map(t=>{let e="group"===h.kind&&h.id===t.id;return Dn("div",{id:`${d}-group-${t.id}`,className:"morphing-menu__panel","aria-label":t.label,"aria-hidden":!e,inert:!e,children:[Dn("button",{type:"button",className:"morphing-menu__row","data-menu-item":"back",onClick:Q,children:[Ln(vt,{"aria-hidden":"true"}),Ln("span",{children:l})]}),t.children.map(t=>tt(t,!1)),et]},t.id)})]}),x&&!U&&Ln("div",{ref:P,className:"morphing-menu__tooltip","aria-hidden":"true",style:{left:x.x,top:x.y},children:x.label})]})}function jn(){return Ln(xt,{className:"morphing-menu__chevron","aria-hidden":"true"})}function Vn({label:t,icon:e,reduced:n,children:r}){let i=St(null),o=St(null);return Pt(()=>{let r=i.current,s=o.current;if(o.current={label:t,node:r.cloneNode(!0)},!s||s.label===t||n)return;let a=s.node;a.setAttribute("aria-hidden","true"),r.parentElement.append(a);let l={duration:200,easing:"cubic-bezier(.22,1,.36,1)"},u=r.animate([{opacity:0,transform:e?"scale(.7)":"translateY(4px)",filter:"blur(2px)"},{opacity:1,transform:"none",filter:"blur(0px)"}],l),c=a.animate([{opacity:1,transform:"none",filter:"blur(0px)"},{opacity:0,transform:e?"scale(.7)":"translateY(-4px)",filter:"blur(2px)"}],l);return c.finished.then(()=>a.remove()).catch(()=>{}),()=>{u.cancel(),c.cancel(),a.remove()}},[t,e,n]),Ln("span",{ref:i,style:{gridArea:"1 / 1",display:"flex",alignItems:"center"},children:r})}function Rn(t){return"glyph"in t?dt("span",{style:{display:"contents"},dangerouslySetInnerHTML:{__html:ot[t.glyph]}}):dt("span",{className:"review-avatar"},t.user?.avatarUrl?dt("img",{src:t.user.avatarUrl,alt:"",referrerPolicy:"no-referrer"}):t.user?at(t.user.name):Rn({glyph:"person"}))}var _n=t=>dt(In,{...t,items:t.items.map(t=>({...t,icon:Rn(t.icon)}))});function On(t,e){t.replaceChildren();let n=ut(t);return ct(()=>n.render(_n(e))),{render:t=>n.render(_n(t)),unmount:()=>n.unmount()}}export{On as mountToolbar};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { DesignSystem } from "./design-system.js";
|
|
2
|
+
export type * from "./design-system.js";
|
|
1
3
|
export interface Identity {
|
|
2
4
|
id: string;
|
|
3
5
|
name: string;
|
|
@@ -128,6 +130,11 @@ export interface CommentsOptions {
|
|
|
128
130
|
* Defaults to true; set false if the host needs to observe them.
|
|
129
131
|
*/
|
|
130
132
|
isolateEvents?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Design-system adapters for Design mode: tokens, theme axes, and component
|
|
135
|
+
* identity. All optional; see DesignSystem.
|
|
136
|
+
*/
|
|
137
|
+
design?: DesignSystem;
|
|
131
138
|
/** Resolve an anchor to a repository-relative source path. */
|
|
132
139
|
source?: (element: Element) => string | undefined;
|
|
133
140
|
/** Defaults to GitHub's source viewer. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hazem3500/komo",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Point, area, and threaded comments for website branches.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"server/node-webhooks.ts",
|
|
28
28
|
"server/import-project.ts",
|
|
29
29
|
"server/digest.ts",
|
|
30
|
-
"server/project-sites.ts"
|
|
30
|
+
"server/project-sites.ts",
|
|
31
|
+
"server/iap.ts"
|
|
31
32
|
],
|
|
32
33
|
"main": "./dist/index.js",
|
|
33
34
|
"types": "./dist/index.d.ts",
|
|
@@ -45,6 +46,14 @@
|
|
|
45
46
|
"types": "./dist/react.d.ts",
|
|
46
47
|
"import": "./dist/react.js"
|
|
47
48
|
},
|
|
49
|
+
"./adapters/tailwind": {
|
|
50
|
+
"types": "./dist/adapters/tailwind.d.ts",
|
|
51
|
+
"import": "./dist/adapters/tailwind.js"
|
|
52
|
+
},
|
|
53
|
+
"./adapters/class-theme": {
|
|
54
|
+
"types": "./dist/adapters/class-theme.d.ts",
|
|
55
|
+
"import": "./dist/adapters/class-theme.js"
|
|
56
|
+
},
|
|
48
57
|
"./node": {
|
|
49
58
|
"import": "./dist/node.mjs"
|
|
50
59
|
}
|
package/server/iap.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Google Cloud Identity-Aware Proxy (IAP) sign-in. When KOMO_IAP_AUDIENCE names
|
|
2
|
+
// the IAP-protected backend (/projects/<number>/global/backendServices/<id>),
|
|
3
|
+
// the load balancer routes the sign-in paths through IAP. Sessions are minted
|
|
4
|
+
// from IAP's signed identity instead of a Google OAuth client, and reading
|
|
5
|
+
// comments requires one of those sessions.
|
|
6
|
+
import { check, HttpError } from "./validation";
|
|
7
|
+
|
|
8
|
+
const KEYS_URL = "https://www.gstatic.com/iap/verify/public_key-jwk";
|
|
9
|
+
const ISSUER = "https://cloud.google.com/iap";
|
|
10
|
+
let cached: { keys: Map<string, CryptoKey>; expires: number } | undefined;
|
|
11
|
+
|
|
12
|
+
async function keys(refresh = false) {
|
|
13
|
+
if (!refresh && cached && cached.expires > Date.now()) return cached.keys;
|
|
14
|
+
const response = await fetch(KEYS_URL);
|
|
15
|
+
check(response.ok, 503, "Could not verify sign-in. Try again shortly.");
|
|
16
|
+
const { keys: list } = (await response.json()) as {
|
|
17
|
+
keys?: (JsonWebKey & { kid?: string })[];
|
|
18
|
+
};
|
|
19
|
+
const imported = new Map<string, CryptoKey>();
|
|
20
|
+
for (const { kid, ...key } of list ?? [])
|
|
21
|
+
if (kid && key.kty === "EC" && key.crv === "P-256")
|
|
22
|
+
imported.set(
|
|
23
|
+
kid,
|
|
24
|
+
await crypto.subtle.importKey(
|
|
25
|
+
"jwk",
|
|
26
|
+
key,
|
|
27
|
+
{ name: "ECDSA", namedCurve: "P-256" },
|
|
28
|
+
false,
|
|
29
|
+
["verify"],
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
cached = { keys: imported, expires: Date.now() + 3600000 };
|
|
33
|
+
return imported;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const decode = (part: string) =>
|
|
37
|
+
Uint8Array.from(atob(part.replace(/-/g, "+").replace(/_/g, "/")), (c) =>
|
|
38
|
+
c.charCodeAt(0),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export type IapIdentity = { id: string; email: string };
|
|
42
|
+
|
|
43
|
+
/** Verify IAP's signed header and return the Google account it vouches for. */
|
|
44
|
+
export async function iapIdentity(
|
|
45
|
+
request: Request,
|
|
46
|
+
audience: string,
|
|
47
|
+
): Promise<IapIdentity> {
|
|
48
|
+
const jwt = request.headers.get("x-goog-iap-jwt-assertion") ?? "";
|
|
49
|
+
const [head, payload, signature, extra] = jwt.split(".");
|
|
50
|
+
check(
|
|
51
|
+
head && payload && signature && extra === undefined,
|
|
52
|
+
401,
|
|
53
|
+
"Sign in with your Google account.",
|
|
54
|
+
);
|
|
55
|
+
let header: { alg?: unknown; kid?: unknown };
|
|
56
|
+
let claims: Record<string, unknown>;
|
|
57
|
+
try {
|
|
58
|
+
header = JSON.parse(new TextDecoder().decode(decode(head)));
|
|
59
|
+
claims = JSON.parse(new TextDecoder().decode(decode(payload)));
|
|
60
|
+
} catch {
|
|
61
|
+
throw new HttpError(401, "Invalid sign-in.");
|
|
62
|
+
}
|
|
63
|
+
check(
|
|
64
|
+
header.alg === "ES256" && typeof header.kid === "string",
|
|
65
|
+
401,
|
|
66
|
+
"Invalid sign-in.",
|
|
67
|
+
);
|
|
68
|
+
const kid = header.kid;
|
|
69
|
+
// IAP rotates keys; refetch once before rejecting an unknown key id.
|
|
70
|
+
const key = (await keys()).get(kid) ?? (await keys(true)).get(kid);
|
|
71
|
+
check(key, 401, "Invalid sign-in.");
|
|
72
|
+
const valid = await crypto.subtle.verify(
|
|
73
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
74
|
+
key,
|
|
75
|
+
decode(signature),
|
|
76
|
+
new TextEncoder().encode(`${head}.${payload}`),
|
|
77
|
+
);
|
|
78
|
+
const now = Date.now() / 1000;
|
|
79
|
+
check(
|
|
80
|
+
valid &&
|
|
81
|
+
claims.iss === ISSUER &&
|
|
82
|
+
claims.aud === audience &&
|
|
83
|
+
typeof claims.exp === "number" &&
|
|
84
|
+
claims.exp > now &&
|
|
85
|
+
typeof claims.iat === "number" &&
|
|
86
|
+
claims.iat < now + 60,
|
|
87
|
+
401,
|
|
88
|
+
"Invalid sign-in.",
|
|
89
|
+
);
|
|
90
|
+
// IAP's subject is the same numeric Google account id the OAuth flow stores.
|
|
91
|
+
const sub =
|
|
92
|
+
typeof claims.sub === "string"
|
|
93
|
+
? claims.sub.match(/^accounts\.google\.com:(\d{1,40})$/)?.[1]
|
|
94
|
+
: undefined;
|
|
95
|
+
check(
|
|
96
|
+
sub &&
|
|
97
|
+
typeof claims.email === "string" &&
|
|
98
|
+
claims.email.length <= 254 &&
|
|
99
|
+
claims.email.includes("@"),
|
|
100
|
+
401,
|
|
101
|
+
"Invalid sign-in.",
|
|
102
|
+
);
|
|
103
|
+
return { id: `google:${sub}`, email: claims.email.toLowerCase() };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Path prefix for IAP sign-in handlers, e.g. "/backoffice"; "" when unset. */
|
|
107
|
+
export function authPrefix(value: string | undefined): string {
|
|
108
|
+
if (!value) return "";
|
|
109
|
+
const prefix = value.replace(/\/+$/, "");
|
|
110
|
+
if (!/^(\/[A-Za-z0-9._~-]+)+$/.test(prefix))
|
|
111
|
+
throw new Error("KOMO_AUTH_PREFIX must be a path such as /backoffice");
|
|
112
|
+
return prefix;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Split PUBLIC_URL into its origin and an optional path the app is served under. */
|
|
116
|
+
export function publicLocation(value: string): { origin: string; path: string } {
|
|
117
|
+
const url = new URL(value);
|
|
118
|
+
const path = url.pathname.replace(/\/+$/, "");
|
|
119
|
+
if (
|
|
120
|
+
url.search ||
|
|
121
|
+
url.hash ||
|
|
122
|
+
url.username ||
|
|
123
|
+
url.password ||
|
|
124
|
+
(path && !/^(\/[A-Za-z0-9._~-]+)+$/.test(path)) ||
|
|
125
|
+
`${url.origin}${path}` !== value.replace(/\/+$/, "") ||
|
|
126
|
+
(url.protocol !== "https:" &&
|
|
127
|
+
!["localhost", "127.0.0.1"].includes(url.hostname))
|
|
128
|
+
)
|
|
129
|
+
throw new Error(
|
|
130
|
+
"PUBLIC_URL must be an HTTPS origin, optionally with a path such as https://example.com/komo (localhost allowed for development)",
|
|
131
|
+
);
|
|
132
|
+
return { origin: url.origin, path };
|
|
133
|
+
}
|