@atom.io/template-preact-svg-editor 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +11 -0
- package/_gitignore +24 -0
- package/dist/assets/index-DhFJjzdn.js +14 -0
- package/dist/assets/index-jy4_OpZh.css +1 -0
- package/dist/index.html +15 -0
- package/dist/preact.svg +6 -0
- package/eslint.config.ts +179 -0
- package/eslint.d.ts +31 -0
- package/index.html +14 -0
- package/package.json +28 -0
- package/public/preact.svg +6 -0
- package/src/BezierPlayground.tsx +458 -0
- package/src/index.tsx +50 -0
- package/src/msg.md +105 -0
- package/src/style.css +126 -0
- package/tsconfig.json +21 -0
- package/vite.config.ts +10 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @atom.io/template-preact-svg-editor@0.0.0 build /Users/jem/dojo/wayforge/templates/preact-svg-editor
|
|
4
|
+
> vite build
|
|
5
|
+
|
|
6
|
+
[36mvite v7.1.12 [32mbuilding for production...[36m[39m
|
|
7
|
+
[2K[1Gtransforming (1) [2msrc/index.tsx[22m[2K[1G[2K[1G[2K[1G[2K[1G[32m✓[39m 16 modules transformed.
|
|
8
|
+
[2K[1Grendering chunks (1)...[2K[1G[2K[1Gcomputing gzip size (0)...[2K[1Gcomputing gzip size (1)...[2K[1Gcomputing gzip size (2)...[2K[1Gcomputing gzip size (3)...[2K[1G[2mdist/[22m[32mindex.html [39m[1m[2m 0.52 kB[22m[1m[22m[2m │ gzip: 0.33 kB[22m
|
|
9
|
+
[2mdist/[22m[2massets/[22m[35mindex-jy4_OpZh.css [39m[1m[2m 1.60 kB[22m[1m[22m[2m │ gzip: 0.72 kB[22m
|
|
10
|
+
[2mdist/[22m[2massets/[22m[36mindex-DhFJjzdn.js [39m[1m[2m73.06 kB[22m[1m[22m[2m │ gzip: 23.49 kB[22m
|
|
11
|
+
[32m✓ built in 276ms[39m
|
package/_gitignore
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
|
|
15
|
+
# Editor directories and files
|
|
16
|
+
.vscode/*
|
|
17
|
+
!.vscode/extensions.json
|
|
18
|
+
.idea
|
|
19
|
+
.DS_Store
|
|
20
|
+
*.suo
|
|
21
|
+
*.ntvs*
|
|
22
|
+
*.njsproj
|
|
23
|
+
*.sln
|
|
24
|
+
*.sw?
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const s of r)if(s.type==="childList")for(const i of s.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&o(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const s={};return r.integrity&&(s.integrity=r.integrity),r.referrerPolicy&&(s.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?s.credentials="include":r.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function o(r){if(r.ep)return;r.ep=!0;const s=n(r);fetch(r.href,s)}})();var Re,m,Wt,H,yt,zt,Gt,Bt,tt,We,ze,Jt,se={},Yt=[],Vn=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,de=Array.isArray;function j(e,t){for(var n in t)e[n]=t[n];return e}function nt(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function Ge(e,t,n){var o,r,s,i={};for(s in t)s=="key"?o=t[s]:s=="ref"?r=t[s]:i[s]=t[s];if(arguments.length>2&&(i.children=arguments.length>3?Re.call(arguments,2):n),typeof e=="function"&&e.defaultProps!=null)for(s in e.defaultProps)i[s]===void 0&&(i[s]=e.defaultProps[s]);return we(e,i,o,r,null)}function we(e,t,n,o,r){var s={type:e,props:t,key:n,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:r??++Wt,__i:-1,__u:0};return r==null&&m.vnode!=null&&m.vnode(s),s}function E(e){return e.children}function D(e,t){this.props=e,this.context=t}function X(e,t){if(t==null)return e.__?X(e.__,e.__i+1):null;for(var n;t<e.__k.length;t++)if((n=e.__k[t])!=null&&n.__e!=null)return n.__e;return typeof e.type=="function"?X(e):null}function qt(e){var t,n;if((e=e.__)!=null&&e.__c!=null){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if((n=e.__k[t])!=null&&n.__e!=null){e.__e=e.__c.base=n.__e;break}return qt(e)}}function Be(e){(!e.__d&&(e.__d=!0)&&H.push(e)&&!Se.__r++||yt!=m.debounceRendering)&&((yt=m.debounceRendering)||zt)(Se)}function Se(){for(var e,t,n,o,r,s,i,l=1;H.length;)H.length>l&&H.sort(Gt),e=H.shift(),l=H.length,e.__d&&(n=void 0,o=void 0,r=(o=(t=e).__v).__e,s=[],i=[],t.__P&&((n=j({},o)).__v=o.__v+1,m.vnode&&m.vnode(n),ot(t.__P,n,o,t.__n,t.__P.namespaceURI,32&o.__u?[r]:null,s,r??X(o),!!(32&o.__u),i),n.__v=o.__v,n.__.__k[n.__i]=n,Qt(s,n,i),o.__e=o.__=null,n.__e!=r&&qt(n)));Se.__r=0}function Zt(e,t,n,o,r,s,i,l,c,u,f){var a,d,_,p,y,w,h,g=o&&o.__k||Yt,K=t.length;for(c=Un(n,t,g,c,K),a=0;a<K;a++)(_=n.__k[a])!=null&&(d=_.__i==-1?se:g[_.__i]||se,_.__i=a,w=ot(e,_,d,r,s,i,l,c,u,f),p=_.__e,_.ref&&d.ref!=_.ref&&(d.ref&&rt(d.ref,null,_),f.push(_.ref,_.__c||p,_)),y==null&&p!=null&&(y=p),(h=!!(4&_.__u))||d.__k===_.__k?c=Xt(_,c,e,h):typeof _.type=="function"&&w!==void 0?c=w:p&&(c=p.nextSibling),_.__u&=-7);return n.__e=y,c}function Un(e,t,n,o,r){var s,i,l,c,u,f=n.length,a=f,d=0;for(e.__k=new Array(r),s=0;s<r;s++)(i=t[s])!=null&&typeof i!="boolean"&&typeof i!="function"?(c=s+d,(i=e.__k[s]=typeof i=="string"||typeof i=="number"||typeof i=="bigint"||i.constructor==String?we(null,i,null,null,null):de(i)?we(E,{children:i},null,null,null):i.constructor==null&&i.__b>0?we(i.type,i.props,i.key,i.ref?i.ref:null,i.__v):i).__=e,i.__b=e.__b+1,l=null,(u=i.__i=Ln(i,n,c,a))!=-1&&(a--,(l=n[u])&&(l.__u|=2)),l==null||l.__v==null?(u==-1&&(r>f?d--:r<f&&d++),typeof i.type!="function"&&(i.__u|=4)):u!=c&&(u==c-1?d--:u==c+1?d++:(u>c?d--:d++,i.__u|=4))):e.__k[s]=null;if(a)for(s=0;s<f;s++)(l=n[s])!=null&&(2&l.__u)==0&&(l.__e==o&&(o=X(l)),tn(l,l));return o}function Xt(e,t,n,o){var r,s;if(typeof e.type=="function"){for(r=e.__k,s=0;r&&s<r.length;s++)r[s]&&(r[s].__=e,t=Xt(r[s],t,n,o));return t}e.__e!=t&&(o&&(t&&e.type&&!t.parentNode&&(t=X(e)),n.insertBefore(e.__e,t||null)),t=e.__e);do t=t&&t.nextSibling;while(t!=null&&t.nodeType==8);return t}function $e(e,t){return t=t||[],e==null||typeof e=="boolean"||(de(e)?e.some(function(n){$e(n,t)}):t.push(e)),t}function Ln(e,t,n,o){var r,s,i,l=e.key,c=e.type,u=t[n],f=u!=null&&(2&u.__u)==0;if(u===null&&e.key==null||f&&l==u.key&&c==u.type)return n;if(o>(f?1:0)){for(r=n-1,s=n+1;r>=0||s<t.length;)if((u=t[i=r>=0?r--:s++])!=null&&(2&u.__u)==0&&l==u.key&&c==u.type)return i}return-1}function ht(e,t,n){t[0]=="-"?e.setProperty(t,n??""):e[t]=n==null?"":typeof n!="number"||Vn.test(t)?n:n+"px"}function me(e,t,n,o,r){var s,i;e:if(t=="style")if(typeof n=="string")e.style.cssText=n;else{if(typeof o=="string"&&(e.style.cssText=o=""),o)for(t in o)n&&t in n||ht(e.style,t,"");if(n)for(t in n)o&&n[t]==o[t]||ht(e.style,t,n[t])}else if(t[0]=="o"&&t[1]=="n")s=t!=(t=t.replace(Bt,"$1")),i=t.toLowerCase(),t=i in e||t=="onFocusOut"||t=="onFocusIn"?i.slice(2):t.slice(2),e.l||(e.l={}),e.l[t+s]=n,n?o?n.u=o.u:(n.u=tt,e.addEventListener(t,s?ze:We,s)):e.removeEventListener(t,s?ze:We,s);else{if(r=="http://www.w3.org/2000/svg")t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(t!="width"&&t!="height"&&t!="href"&&t!="list"&&t!="form"&&t!="tabIndex"&&t!="download"&&t!="rowSpan"&&t!="colSpan"&&t!="role"&&t!="popover"&&t in e)try{e[t]=n??"";break e}catch{}typeof n=="function"||(n==null||n===!1&&t[4]!="-"?e.removeAttribute(t):e.setAttribute(t,t=="popover"&&n==1?"":n))}}function mt(e){return function(t){if(this.l){var n=this.l[t.type+e];if(t.t==null)t.t=tt++;else if(t.t<n.u)return;return n(m.event?m.event(t):t)}}}function ot(e,t,n,o,r,s,i,l,c,u){var f,a,d,_,p,y,w,h,g,K,R,I,oe,pt,he,re,Ne,P=t.type;if(t.constructor!=null)return null;128&n.__u&&(c=!!(32&n.__u),s=[l=t.__e=n.__e]),(f=m.__b)&&f(t);e:if(typeof P=="function")try{if(h=t.props,g="prototype"in P&&P.prototype.render,K=(f=P.contextType)&&o[f.__c],R=f?K?K.props.value:f.__:o,n.__c?w=(a=t.__c=n.__c).__=a.__E:(g?t.__c=a=new P(h,R):(t.__c=a=new D(h,R),a.constructor=P,a.render=Wn),K&&K.sub(a),a.props=h,a.state||(a.state={}),a.context=R,a.__n=o,d=a.__d=!0,a.__h=[],a._sb=[]),g&&a.__s==null&&(a.__s=a.state),g&&P.getDerivedStateFromProps!=null&&(a.__s==a.state&&(a.__s=j({},a.__s)),j(a.__s,P.getDerivedStateFromProps(h,a.__s))),_=a.props,p=a.state,a.__v=t,d)g&&P.getDerivedStateFromProps==null&&a.componentWillMount!=null&&a.componentWillMount(),g&&a.componentDidMount!=null&&a.__h.push(a.componentDidMount);else{if(g&&P.getDerivedStateFromProps==null&&h!==_&&a.componentWillReceiveProps!=null&&a.componentWillReceiveProps(h,R),!a.__e&&a.shouldComponentUpdate!=null&&a.shouldComponentUpdate(h,a.__s,R)===!1||t.__v==n.__v){for(t.__v!=n.__v&&(a.props=h,a.state=a.__s,a.__d=!1),t.__e=n.__e,t.__k=n.__k,t.__k.some(function(J){J&&(J.__=t)}),I=0;I<a._sb.length;I++)a.__h.push(a._sb[I]);a._sb=[],a.__h.length&&i.push(a);break e}a.componentWillUpdate!=null&&a.componentWillUpdate(h,a.__s,R),g&&a.componentDidUpdate!=null&&a.__h.push(function(){a.componentDidUpdate(_,p,y)})}if(a.context=R,a.props=h,a.__P=e,a.__e=!1,oe=m.__r,pt=0,g){for(a.state=a.__s,a.__d=!1,oe&&oe(t),f=a.render(a.props,a.state,a.context),he=0;he<a._sb.length;he++)a.__h.push(a._sb[he]);a._sb=[]}else do a.__d=!1,oe&&oe(t),f=a.render(a.props,a.state,a.context),a.state=a.__s;while(a.__d&&++pt<25);a.state=a.__s,a.getChildContext!=null&&(o=j(j({},o),a.getChildContext())),g&&!d&&a.getSnapshotBeforeUpdate!=null&&(y=a.getSnapshotBeforeUpdate(_,p)),re=f,f!=null&&f.type===E&&f.key==null&&(re=en(f.props.children)),l=Zt(e,de(re)?re:[re],t,n,o,r,s,i,l,c,u),a.base=t.__e,t.__u&=-161,a.__h.length&&i.push(a),w&&(a.__E=a.__=null)}catch(J){if(t.__v=null,c||s!=null)if(J.then){for(t.__u|=c?160:128;l&&l.nodeType==8&&l.nextSibling;)l=l.nextSibling;s[s.indexOf(l)]=null,t.__e=l}else{for(Ne=s.length;Ne--;)nt(s[Ne]);Je(t)}else t.__e=n.__e,t.__k=n.__k,J.then||Je(t);m.__e(J,t,n)}else s==null&&t.__v==n.__v?(t.__k=n.__k,t.__e=n.__e):l=t.__e=Hn(n.__e,t,n,o,r,s,i,c,u);return(f=m.diffed)&&f(t),128&t.__u?void 0:l}function Je(e){e&&e.__c&&(e.__c.__e=!0),e&&e.__k&&e.__k.forEach(Je)}function Qt(e,t,n){for(var o=0;o<n.length;o++)rt(n[o],n[++o],n[++o]);m.__c&&m.__c(t,e),e.some(function(r){try{e=r.__h,r.__h=[],e.some(function(s){s.call(r)})}catch(s){m.__e(s,r.__v)}})}function en(e){return typeof e!="object"||e==null||e.__b&&e.__b>0?e:de(e)?e.map(en):j({},e)}function Hn(e,t,n,o,r,s,i,l,c){var u,f,a,d,_,p,y,w=n.props,h=t.props,g=t.type;if(g=="svg"?r="http://www.w3.org/2000/svg":g=="math"?r="http://www.w3.org/1998/Math/MathML":r||(r="http://www.w3.org/1999/xhtml"),s!=null){for(u=0;u<s.length;u++)if((_=s[u])&&"setAttribute"in _==!!g&&(g?_.localName==g:_.nodeType==3)){e=_,s[u]=null;break}}if(e==null){if(g==null)return document.createTextNode(h);e=document.createElementNS(r,g,h.is&&h),l&&(m.__m&&m.__m(t,s),l=!1),s=null}if(g==null)w===h||l&&e.data==h||(e.data=h);else{if(s=s&&Re.call(e.childNodes),w=n.props||se,!l&&s!=null)for(w={},u=0;u<e.attributes.length;u++)w[(_=e.attributes[u]).name]=_.value;for(u in w)if(_=w[u],u!="children"){if(u=="dangerouslySetInnerHTML")a=_;else if(!(u in h)){if(u=="value"&&"defaultValue"in h||u=="checked"&&"defaultChecked"in h)continue;me(e,u,null,_,r)}}for(u in h)_=h[u],u=="children"?d=_:u=="dangerouslySetInnerHTML"?f=_:u=="value"?p=_:u=="checked"?y=_:l&&typeof _!="function"||w[u]===_||me(e,u,_,w[u],r);if(f)l||a&&(f.__html==a.__html||f.__html==e.innerHTML)||(e.innerHTML=f.__html),t.__k=[];else if(a&&(e.innerHTML=""),Zt(t.type=="template"?e.content:e,de(d)?d:[d],t,n,o,g=="foreignObject"?"http://www.w3.org/1999/xhtml":r,s,i,s?s[0]:n.__k&&X(n,0),l,c),s!=null)for(u=s.length;u--;)nt(s[u]);l||(u="value",g=="progress"&&p==null?e.removeAttribute("value"):p!=null&&(p!==e[u]||g=="progress"&&!p||g=="option"&&p!=w[u])&&me(e,u,p,w[u],r),u="checked",y!=null&&y!=e[u]&&me(e,u,y,w[u],r))}return e}function rt(e,t,n){try{if(typeof e=="function"){var o=typeof e.__u=="function";o&&e.__u(),o&&t==null||(e.__u=e(t))}else e.current=t}catch(r){m.__e(r,n)}}function tn(e,t,n){var o,r;if(m.unmount&&m.unmount(e),(o=e.ref)&&(o.current&&o.current!=e.__e||rt(o,null,t)),(o=e.__c)!=null){if(o.componentWillUnmount)try{o.componentWillUnmount()}catch(s){m.__e(s,t)}o.base=o.__P=null}if(o=e.__k)for(r=0;r<o.length;r++)o[r]&&tn(o[r],t,n||typeof e.type!="function");n||nt(e.__e),e.__c=e.__=e.__e=void 0}function Wn(e,t,n){return this.constructor(e,n)}function zn(e,t,n){var o,r,s,i;t==document&&(t=document.documentElement),m.__&&m.__(e,t),r=(o=!1)?null:t.__k,s=[],i=[],ot(t,e=t.__k=Ge(E,null,[e]),r||se,se,t.namespaceURI,r?null:t.firstChild?Re.call(t.childNodes):null,s,r?r.__e:t.firstChild,o,i),Qt(s,e,i)}function Gn(e){function t(n){var o,r;return this.getChildContext||(o=new Set,(r={})[t.__c]=this,this.getChildContext=function(){return r},this.componentWillUnmount=function(){o=null},this.shouldComponentUpdate=function(s){this.props.value!=s.value&&o.forEach(function(i){i.__e=!0,Be(i)})},this.sub=function(s){o.add(s);var i=s.componentWillUnmount;s.componentWillUnmount=function(){o&&o.delete(s),i&&i.call(s)}}),n.children}return t.__c="__cC"+Jt++,t.__=e,t.Provider=t.__l=(t.Consumer=function(n,o){return n.children(o)}).contextType=t,t}Re=Yt.slice,m={__e:function(e,t,n,o){for(var r,s,i;t=t.__;)if((r=t.__c)&&!r.__)try{if((s=r.constructor)&&s.getDerivedStateFromError!=null&&(r.setState(s.getDerivedStateFromError(e)),i=r.__d),r.componentDidCatch!=null&&(r.componentDidCatch(e,o||{}),i=r.__d),i)return r.__E=r}catch(l){e=l}throw e}},Wt=0,D.prototype.setState=function(e,t){var n;n=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=j({},this.state),typeof e=="function"&&(e=e(j({},n),this.props)),e&&j(n,e),e!=null&&this.__v&&(t&&this._sb.push(t),Be(this))},D.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),Be(this))},D.prototype.render=E,H=[],zt=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,Gt=function(e,t){return e.__v.__b-t.__v.__b},Se.__r=0,Bt=/(PointerCapture)$|Capture$/i,tt=0,We=mt(!1),ze=mt(!0),Jt=0;var Bn=0;function b(e,t,n,o,r,s){t||(t={});var i,l,c=t;if("ref"in c)for(l in c={},t)l=="ref"?i=t[l]:c[l]=t[l];var u={type:e,props:c,key:n,ref:i,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Bn,__i:-1,__u:0,__source:r,__self:s};if(typeof e=="function"&&(i=e.defaultProps))for(l in i)c[l]===void 0&&(c[l]=i[l]);return m.vnode&&m.vnode(u),u}function te(e){return JSON.parse(e)}const x=e=>JSON.stringify(e);function nn(e=Math.random){return e().toString(36).slice(2)}function v(e){for(;e.child!==null;)e=e.child;return e}function Jn(e){for(;e.parent!==null;)e=e.parent;return e}const Yn=/^\[object (?:Async|Generator|AsyncGenerator)?Function\]$/;function W(e){const t=Object.prototype.toString.call(e);return Yn.test(t)}function gt(e,t){return W(e)?e(t):e}var Ye=class extends Promise{fate;resolve;reject;done=!1;constructor(e){let t,n;super((o,r)=>{t=o,n=r}),this.resolve=t,this.reject=n,this.use(e instanceof Promise?e:new Promise(e))}pass(e,t){e===this.fate&&(this.resolve(t),this.done=!0)}fail(e,t){e===this.fate&&(this.reject(t),this.done=!0)}use(e){if(this!==e)if(e instanceof Promise){const t=e;this.fate=t,t.then(n=>{this.pass(t,n)},n=>{this.fail(t,n)})}else this.resolve(e),this.fate=void 0}},S=class{Subscriber;subscribers=new Map;subscribe(e,t){return this.subscribers.set(e,t),()=>{this.unsubscribe(e)}}unsubscribe(e){this.subscribers.delete(e)}next(e){const t=this.subscribers.values();for(const n of t)n(e)}},qn=class extends S{state;constructor(e){super(),this.state=e}next(e){this.state=e,super.next(e)}},Zn=class on{_buffer;_index=0;constructor(t){let n;typeof t=="number"?n=t:n=t.length,this._buffer=Array.from({length:n})}get buffer(){return this._buffer}get index(){return this._index}add(t){this._buffer[this._index]=t,this._index=(this._index+1)%this._buffer.length}copy(){const t=new on([...this._buffer]);return t._index=this._index,t}};function Q(e){const t={key:e.key,type:e.type};return"family"in e&&(t.family=e.family),t}var O=class extends Map{deleted=new Set;changed=new Set;source;constructor(e){super(),this.source=e}get(e){if(super.has(e))return super.get(e);if(!this.deleted.has(e)&&this.source.has(e))return this.source.get(e)}set(e,t){return this.deleted.delete(e),this.source.has(e)&&this.changed.add(e),super.set(e,t)}hasOwn(e){return super.has(e)}has(e){return!this.deleted.has(e)&&(super.has(e)||this.source.has(e))}delete(e){return this.source.has(e)&&(this.deleted.add(e),this.changed.delete(e)),super.delete(e)}clear(){this.deleted=new Set(this.source.keys()),this.changed.clear(),super.clear()}*[Symbol.iterator](){yield*super[Symbol.iterator]();for(const[e,t]of this.source)!this.deleted.has(e)&&!this.changed.has(e)&&(yield[e,t])}*entries(){yield*this[Symbol.iterator]()}*keys(){yield*super.keys();for(const e of this.source.keys())!this.deleted.has(e)&&!this.changed.has(e)&&(yield e)}*values(){for(const[,e]of this[Symbol.iterator]())yield e}forEach(e){for(const[t,n]of this[Symbol.iterator]())e(n,t,this)}get size(){return super.size+this.source.size-this.changed.size-this.deleted.size}},rn=class extends Set{deleted=new Set;source;constructor(e){super(),this.source=e}add(e){return this.source.has(e)?(this.deleted.delete(e),this):super.add(e)}hasOwn(e){return super.has(e)}has(e){return!this.deleted.has(e)&&(super.has(e)||this.source.has(e))}delete(e){return this.source.has(e)?(this.deleted.add(e),!0):super.delete(e)}clear(){this.deleted=new Set(this.source),super.clear()}*[Symbol.iterator](){yield*super[Symbol.iterator]();for(const e of this.source)this.deleted.has(e)||(yield e)}*iterateOwn(){yield*super[Symbol.iterator]()}get size(){return super.size+this.source.size-this.deleted.size}},Xn=class extends Map{deleted=new Set;source;constructor(e){super(),this.source=e}get(e){if(super.has(e))return super.get(e);if(!this.deleted.has(e)&&this.source.has(e)){const t=new rn(this.source.get(e));return super.set(e,t),t}}set(e,t){return this.deleted.delete(e),super.set(e,t)}has(e){return!this.deleted.has(e)&&(super.has(e)||this.source.has(e))}delete(e){return this.deleted.add(e),super.delete(e)}},V=class sn{a;b;cardinality;relations=new Map;contents=new Map;isAType;isBType;isContent;makeContentKey=(t,n)=>`${t}:${n}`;warn;getRelatedKeys(t){return this.relations.get(t)}addRelation(t,n){let o=this.relations.get(t),r=this.relations.get(n);o?o.add(n):(o=new Set([n]),this.relations.set(t,o)),r?r.add(t):(r=new Set([t]),this.relations.set(n,r))}deleteRelation(t,n){const o=this.relations.get(t);if(o){o.delete(n),o.size===0&&this.relations.delete(t);const r=this.relations.get(n);r&&(r.delete(t),r.size===0&&this.relations.delete(n))}}replaceRelationsUnsafely(t,n){this.relations.set(t,new Set(n));for(const o of n){const r=new Set().add(t);this.relations.set(o,r)}}replaceRelationsSafely(t,n){const o=this.relations.get(t);let r=this.isAType?.(t)?t:void 0,s=r===void 0?t:void 0;if(o)for(const i of o){r??=i,s??=i;const l=this.relations.get(i);l&&(l.size===1?this.relations.delete(i):l.delete(t),this.contents.delete(this.makeContentKey(r,s)))}this.relations.set(t,new Set(n));for(const i of n){let l=this.relations.get(i);l?l.add(t):(l=new Set().add(t),this.relations.set(i,l))}}getContentInternal(t){return this.contents.get(t)}setContent(t,n){this.contents.set(t,n)}deleteContent(t){this.contents.delete(t)}constructor(t,n){if(this.a=t.between[0],this.b=t.between[1],this.cardinality=t.cardinality,this.isAType=n?.isAType??null,this.isBType=n?.isBType??null,this.isContent=n?.isContent??null,n?.makeContentKey&&(this.makeContentKey=n.makeContentKey),!n?.externalStore){const o=n?.source;o===void 0&&(this.relations=new Map(t.relations?.map(([r,s])=>[r,new Set(s)])),this.contents=new Map(t.contents)),o&&(this.relations=new Xn(o.relations),this.contents=new O(o.contents))}if(n?.externalStore){const o=n.externalStore;this.has=(r,s)=>o.has(r,s),this.addRelation=(r,s)=>{o.addRelation(r,s)},this.deleteRelation=(r,s)=>{o.deleteRelation(r,s)},this.replaceRelationsSafely=(r,s)=>{o.replaceRelationsSafely(r,s)},this.replaceRelationsUnsafely=(r,s)=>{o.replaceRelationsUnsafely(r,s)},this.getRelatedKeys=(r=>o.getRelatedKeys(r)),o.getContent&&(this.getContentInternal=r=>o.getContent(r),this.setContent=(r,s)=>{o.setContent(r,s)},this.deleteContent=r=>{o.deleteContent(r)});for(const[r,s]of t.relations??[]){let i=this.isAType?.(r)?r:void 0,l=i===void 0?r:void 0;for(const c of s)i??=c,l??=c,this.addRelation(i,l)}for(const[r,s]of t.contents??[])this.setContent(r,s)}n?.warn&&(this.warn=n.warn)}toJSON(){return{between:[this.a,this.b],cardinality:this.cardinality,relations:[...this.relations.entries()].map(([t,n])=>[t,[...n]]),contents:[...this.contents.entries()]}}set(...t){let n,o,r;switch(t.length){case 1:{const s=t[0];n=s[this.a],o=s[this.b],r=void 0;break}case 2:{const s=t[0];typeof s=="string"?[n,o]=t:(n=s[this.a],o=s[this.b],r=t[1]);break}default:n=t[0],o=t[1],r=t[2];break}switch(this.cardinality){case"1:1":{const s=this.getRelatedKey(n);s&&s!==o&&this.delete(n,s)}case"1:n":{const s=this.getRelatedKey(o);s&&s!==n&&this.delete(s,o)}break}if(r){const s=this.makeContentKey(n,o);this.setContent(s,r)}return this.addRelation(n,o),this}delete(t,n){n=typeof n=="string"?n:t[this.b];const o=typeof t=="string"?t:t[this.a];if(o===void 0&&typeof n=="string"){const r=this.getRelatedKeys(n);if(r)for(const s of r)this.delete(s,n)}else if(typeof o=="string"&&n===void 0){const r=this.getRelatedKeys(o);if(r)for(const s of r)this.delete(o,s)}else if(typeof o=="string"&&typeof n=="string"){this.deleteRelation(o,n);const r=this.makeContentKey(o,n);this.deleteContent(r)}return this}getRelatedKey(t){const n=this.getRelatedKeys(t);if(n){n.size>1&&this.warn?.(`${n.size} related keys were found for key "${t}": (${[...n].map(r=>`"${r}"`).join(", ")}). Only one related key was expected.`);let o;for(const r of n){o=r;break}return o}}replaceRelations(t,n,o){const r=!Array.isArray(n),s=r?Object.keys(n):n;if(o?.reckless?this.replaceRelationsUnsafely(t,s):this.replaceRelationsSafely(t,s),r)for(const i of s){const l=this.makeContentKey(t,i),c=n[i];this.setContent(l,c)}return this}getContent(t,n){const o=this.makeContentKey(t,n);return this.getContentInternal(o)}getRelationEntries(t){const n=t[this.a],o=t[this.b];if(n!==void 0&&o===void 0){const r=this.getRelatedKeys(n);if(r)return[...r].map(s=>[s,this.getContent(n,s)])}if(n===void 0&&o!==void 0){const r=this.getRelatedKeys(o);if(r)return[...r].map(s=>[s,this.getContent(s,o)])}return[]}has(t,n){return n?this.getRelatedKeys(t)?.has(n)??!1:this.relations.has(t)}overlay(){const t={source:this,makeContentKey:this.makeContentKey};return this.isAType&&(t.isAType=this.isAType),this.isBType&&(t.isBType=this.isBType),this.isContent&&(t.isContent=this.isContent),this.warn&&(t.warn=this.warn),new sn({between:[this.a,this.b],cardinality:this.cardinality},t)}incorporate(t){const{relations:n,contents:o}=t;for(const[r,s]of n)if(s instanceof rn){const{source:i}=s;for(const l of s.iterateOwn())i.add(l)}else this.relations.set(r,s);for(const r of n.deleted)this.relations.delete(r);for(const[r,s]of o)this.contents.set(r,s);for(const r of o.deleted)this.contents.delete(r)}};function Qn(e){return e.startsWith("🔍 ")}const eo=e=>{e.logger.info("🪂","transaction",e.transactionMeta.update.token.key,"Aborting transaction"),e.parent.child=null};function ln(e,t,n){return(...o)=>C(e,t).run(o,n)}function to(e,t,n){const{token:o,update:{newValue:r,oldValue:s}}=t;U(e,o,r)}function no(e){const{stack:t}=e;return t?`
|
|
2
|
+
`+t.split(`
|
|
3
|
+
`)?.slice(1)?.join(`
|
|
4
|
+
`):""}function an(e,t,n,o="any"){const r=t,s=x(n),i=[],l=v(e);if(Array.isArray(r))for(const f of r){const a=x(f);l.molecules.get(a)?e.moleculeGraph.set(a,s,{source:a}):i.push(a)}else{const f=x(r);l.molecules.get(f)?e.moleculeGraph.set(f,s,{source:f}):i.push(f)}const c=new S;i.length===0&&l.molecules.set(s,{key:n,stringKey:s,dependsOn:o,subject:c});const u={type:"molecule_creation",key:n,provenance:r,timestamp:Date.now()};T(l)&&l.transactionMeta.phase==="building"?l.transactionMeta.update.subEvents.push(u):l.on.moleculeCreation.next(u);for(const f of i){const a=e.disposalTraces.buffer.find(d=>d?.key===f);e.logger.error("❌","key",n,"allocation failed:",`Could not allocate to ${f} in store "${e.config.name}".`,a?`
|
|
5
|
+
${f} was most recently disposed
|
|
6
|
+
${a.trace}`:`No previous disposal trace for ${f} was found.`)}return n}function st(e,t){const n=x(t),o=e.molecules.get(n);if(!o){const d=e.disposalTraces.buffer.find(_=>_?.key===n);e.logger.error("❌","key",t,"deallocation failed:",`Could not find allocation for ${n} in store "${e.config.name}".`,d?`
|
|
7
|
+
This state was most recently deallocated
|
|
8
|
+
${d.trace}`:`No previous disposal trace for ${n} was found.`);return}o.subject.next();const r=e.keyRefsInJoins.getRelatedKeys(n);if(r)for(const d of r){const _=e.joins.get(d);_&&_.relations.delete(t)}else{const d=Ao(t);if(d){const[,_,p]=d,y=e.keyRefsInJoins.getRelatedKey(Oo(_,p));if(y){const w=e.joins.get(y);w&&w.relations.delete(_,p)}}}e.keyRefsInJoins.delete(n);const s=[],i=[],l=e.moleculeGraph.getRelationEntries({downstreamMoleculeKey:n});if(l)for(const[d,{source:_}]of l)_===n?st(e,te(d)):s.push(_);const c=e.moleculeData.getRelatedKeys(o.stringKey);if(c)for(const d of c){const _=e.families.get(d),p=F(e,_,t);i.push([_.key,p]),Me(e,_,t)}const u={type:"molecule_disposal",key:o.key,values:i,provenance:s,timestamp:Date.now()};e.molecules.delete(n);const f=T(e)&&e.transactionMeta.phase==="building";f&&e.transactionMeta.update.subEvents.push(u),e.moleculeGraph.delete(o.stringKey),e.keyRefsInJoins.delete(o.stringKey),e.moleculeData.delete(o.stringKey),f||e.on.moleculeDisposal.next(u),e.molecules.delete(o.stringKey);const a=no(new Error);e.disposalTraces.add({key:n,trace:a})}function bt(e,t,n,o){const r=x(n),s=v(e),i=s.molecules.get(r);if(!i){const a=e.disposalTraces.buffer.find(d=>d?.key===r);return e.logger.error("❌","key",r,"claim failed:",`Could not allocate to ${r} in store "${e.config.name}".`,a?`
|
|
9
|
+
${r} was most recently disposed
|
|
10
|
+
${a.trace}`:`No previous disposal trace for ${r} was found.`),n}const l=x(t),c=s.molecules.get(l);if(!c){const a=e.disposalTraces.buffer.find(d=>d?.key===l);return e.logger.error("❌","key",n,"claim failed:",`Could not allocate to ${l} in store "${e.config.name}".`,a?`
|
|
11
|
+
${l} was most recently disposed
|
|
12
|
+
${a.trace}`:`No previous disposal trace for ${l} was found.`),n}const u=e.moleculeGraph.getRelationEntries({downstreamMoleculeKey:i.stringKey}).filter(([,{source:a}])=>a!==r).map(([a])=>te(a));o&&s.moleculeGraph.delete(r),s.moleculeGraph.set({upstreamMoleculeKey:c.stringKey,downstreamMoleculeKey:i.stringKey},{source:c.stringKey});const f={type:"molecule_transfer",key:i.key,exclusive:!!o,from:u,to:[c.key],timestamp:Date.now()};return T(s)&&s.transactionMeta.phase==="building"&&s.transactionMeta.update.subEvents.push(f),n}function oo(e,t,n){switch(n){case"newValue":cn(e,t);break;case"oldValue":Me(e,t.token);break}}function ro(e,t,n){switch(n){case"newValue":Me(e,t.token);break;case"oldValue":cn(e,t),t.subType==="atom"&&e.valueMap.set(t.token.key,t.value);break}}function cn(e,t){const{token:n}=t;t.subType==="writable"&&t.value?U(e,n,t.value):F(e,n)}function so(e,t,n){switch(n){case"newValue":an(e,t.provenance,t.key);break;case"oldValue":st(e,t.key);break}}function io(e,t,n){switch(n){case"newValue":st(e,t.key);break;case"oldValue":an(e,t.provenance.map(te),t.key);for(const[o,r]of t.values){const s=e.families.get(o);if(s){F(e,s,t.key);const i=`${o}(${x(t.key)})`;e.valueMap.set(i,r)}}break}}function lo(e,t,n){switch(n){case"newValue":for(const o of t.to)bt(e,o,t.key,t.exclusive?"exclusive":void 0);break;case"oldValue":{let o="exclusive";for(const r of t.from)bt(e,r,t.key,o),o=void 0}break}}function un(e,t,n){const o=t.subEvents;for(const r of o)switch(r.type){case"atom_update":to(e,r);break;case"state_creation":oo(e,r,n);break;case"state_disposal":ro(e,r,n);break;case"molecule_creation":so(e,r,n);break;case"molecule_disposal":io(e,r,n);break;case"molecule_transfer":lo(e,r,n);break;case"transaction_outcome":un(e,r,n);break}}function ie(e){return"epoch"in e.transactionMeta}function T(e){return"phase"in e.transactionMeta}function fn(e,t){return e.transactionMeta.actionContinuities.getRelatedKey(t)}function ao(e,t){return e.transactionMeta.epoch.get(t)}function co(e,t){const n=fn(e,t);if(n!==void 0)return ao(e,n)}function uo(e,t,n){const o=fn(e,t);o!==void 0&&e.transactionMeta.epoch.set(o,n)}function fo(e,t){const n=v(e),{parent:o}=n;n.transactionMeta.phase="applying",n.transactionMeta.update.output=t,o.child=null,o.on.transactionApplying.next(n.transactionMeta);const{subEvents:r}=n.transactionMeta.update;e.logger.info("🛄","transaction",n.transactionMeta.update.token.key,`applying ${r.length} subEvents:`,r),un(o,n.transactionMeta.update,"newValue"),ie(o)?(uo(o,n.transactionMeta.update.token.key,n.transactionMeta.update.epoch),C(e,{key:n.transactionMeta.update.token.key,type:"transaction"})?.subject.next(n.transactionMeta.update),e.logger.info("🛬","transaction",n.transactionMeta.update.token.key,"applied")):T(o)&&o.transactionMeta.update.subEvents.push(n.transactionMeta.update),o.on.transactionApplying.next(null)}function _o(e){return{store:e}}const po=(e,t,n,o)=>{const r=v(e),s={parent:r,child:null,on:r.on,loggers:r.loggers,logger:r.logger,config:r.config,atoms:new O(r.atoms),atomsThatAreDefault:new Set(r.atomsThatAreDefault),families:new O(r.families),joins:new O(r.joins),operation:{open:!1},readonlySelectors:new O(r.readonlySelectors),timelines:new O(r.timelines),timelineTopics:r.timelineTopics.overlay(),trackers:new Map,transactions:new O(r.transactions),selectorAtoms:r.selectorAtoms.overlay(),selectorGraph:r.selectorGraph.overlay(),writableSelectors:new O(r.writableSelectors),valueMap:new O(r.valueMap),defaults:r.defaults,disposalTraces:e.disposalTraces.copy(),molecules:new O(r.molecules),moleculeGraph:r.moleculeGraph.overlay(),moleculeData:r.moleculeData.overlay(),keyRefsInJoins:r.keyRefsInJoins.overlay(),miscResources:new O(r.miscResources)},i=co(e,t.key),l={phase:"building",update:{type:"transaction_outcome",token:t,id:o,epoch:i===void 0?NaN:i+1,timestamp:Date.now(),subEvents:[],params:n,output:void 0},toolkit:{get:((...u)=>F(c,...u)),set:((...u)=>{U(c,...u)}),reset:((...u)=>{at(c,...u)}),run:(u,f=nn())=>ln(c,u,f),find:((...u)=>G(e,...u)),json:u=>pe(c,u),dispose:((...u)=>{Me(c,...u)}),env:()=>_o(c)}},c=Object.assign(s,{transactionMeta:l});return r.child=c,e.logger.info("🛫","transaction",t.key,"building with params:",n),c};function _n(e,t){const{key:n}=t,o=e.transactions.has(n),r={key:n,type:"transaction",run:(i,l)=>{const c=po(e,Q(r),i,l);try{const{toolkit:u}=c.transactionMeta,f=t.do(u,...i);return fo(c,f),f}catch(u){throw eo(c),e.logger.warn("💥","transaction",n,"caught:",u),u}},install:i=>_n(i,t),subject:new S};v(e).transactions.set(n,r);const s=Q(r);return o||e.on.transactionCreation.next(s),s}var yo=class{parent=null;child=null;valueMap=new Map;defaults=new Map;atoms=new Map;writableSelectors=new Map;readonlySelectors=new Map;atomsThatAreDefault=new Set;selectorAtoms=new V({between:["selectorKey","atomKey"],cardinality:"n:n"});selectorGraph=new V({between:["upstreamSelectorKey","downstreamSelectorKey"],cardinality:"n:n"},{makeContentKey:(...e)=>e.sort().join(":")});trackers=new Map;families=new Map;joins=new Map;transactions=new Map;transactionMeta={epoch:new Map,actionContinuities:new V({between:["continuity","action"],cardinality:"1:n"})};timelines=new Map;timelineTopics=new V({between:["timelineKey","topicKey"],cardinality:"1:n"});disposalTraces=new Zn(100);molecules=new Map;moleculeGraph=new V({between:["upstreamMoleculeKey","downstreamMoleculeKey"],cardinality:"n:n"},{makeContentKey:(...e)=>e.sort().join(":")});moleculeData=new V({between:["moleculeKey","stateFamilyKey"],cardinality:"n:n"},{makeContentKey:(...e)=>e.sort().join(":")});keyRefsInJoins=new V({between:["moleculeKey","joinKey"],cardinality:"n:n"},{makeContentKey:(...e)=>e.sort().join(":")});miscResources=new Map;on={atomCreation:new S,atomDisposal:new S,selectorCreation:new S,selectorDisposal:new S,timelineCreation:new S,transactionCreation:new S,transactionApplying:new qn(null),operationClose:new S,moleculeCreation:new S,moleculeDisposal:new S};operation={open:!1};config={name:"IMPLICIT_STORE",lifespan:"ephemeral",isProduction:!0};loggers=[new Eo("warn",(e,t,n)=>!Qn(n))];logger={error:(...e)=>{for(const t of this.loggers)t.error(...e)},info:(...e)=>{for(const t of this.loggers)t.info(...e)},warn:(...e)=>{for(const t of this.loggers)t.warn(...e)}};constructor(e,t=null){if(this.config={...t?.config,...e},t!==null){this.operation={...t?.operation},ie(t)&&(this.transactionMeta={epoch:new Map(t?.transactionMeta.epoch),actionContinuities:new V(t?.transactionMeta.actionContinuities.toJSON())});for(const[,o]of t.families)o.internalRoles?.includes("mutable")||o.internalRoles?.includes("join")||o.install(this);const n=new Set;for(const[,o]of t.atoms)if(!n.has(o.key)&&(o.install(this),o.type==="mutable_atom")){const r=pe(t,o),s=Tn(o);n.add(r.key),n.add(s.key)}for(const[,o]of t.readonlySelectors)o.install(this);for(const[,o]of t.writableSelectors)n.has(o.key)||o.install(this);for(const[,o]of t.transactions)o.install(this);for(const[,o]of t.timelines)o.install(this)}}};const N={get STORE(){return globalThis.ATOM_IO_IMPLICIT_STORE??=new yo({name:"IMPLICIT_STORE",lifespan:"ephemeral",isProduction:!0}),globalThis.ATOM_IO_IMPLICIT_STORE}};var ho=class extends Error{constructor(e,t){super(`${B[e.type]} ${x(e.key)} not found in store "${t.config.name}".`)}};function C(e,t){let n,o=e;for(;o!==null;){switch(t.type){case"atom":case"mutable_atom":n=o.atoms.get(t.key);break;case"writable_pure_selector":case"writable_held_selector":n=o.writableSelectors.get(t.key);break;case"readonly_pure_selector":case"readonly_held_selector":n=o.readonlySelectors.get(t.key);break;case"atom_family":case"mutable_atom_family":case"writable_pure_selector_family":case"readonly_pure_selector_family":case"writable_held_selector_family":case"readonly_held_selector_family":n=o.families.get(t.key);break;case"timeline":n=o.timelines.get(t.key);break;case"transaction":n=o.transactions.get(t.key);break}if(n)return n;o=o.child}throw new ho(t,e)}function dn(e,t,n,o){const r=e.disposalTraces.buffer.find(s=>s?.key===x(o));switch(e.logger.error("❌",t.type,t.key,"gets a fallback value because key",o,"is not allocated",r?`This key was previously disposed:
|
|
13
|
+
${r.trace}`:"(no previous disposal trace found)"),n.type){case"mutable_atom_family":{if(e.defaults.has(n.key))return e.defaults.get(n.key);const s=new n.class;return e.defaults.set(n.key,s),s.READONLY_VIEW}case"atom_family":{if(e.defaults.has(n.key))return e.defaults.get(n.key);const s=n.default,i=s(o);return e.defaults.set(n.key,i),i}case"readonly_pure_selector_family":case"writable_pure_selector_family":case"readonly_held_selector_family":case"writable_held_selector_family":{if(e.defaults.has(n.key))return e.defaults.get(n.key);const s=n.default(o);return e.defaults.set(n.key,s),s}}}function Ce(e,t){const{type:n,key:o,catch:r}=t;switch(n){case"readonly_pure_selector":case"writable_pure_selector":{let s;e.logger.info("🧮",n,o,"computing value");try{if(s=t.getFrom(e),s instanceof Promise)return s.catch(i=>{if(e.logger.error("💥",n,o,"rejected:",i),r){for(const l of r)if(i instanceof l)return i}throw i})}catch(i){if(e.logger.error("💥",n,o,"rejected:",i),r){for(const l of r)if(i instanceof l)return M(e,t,i)}throw i}return M(e,t,s)}case"atom":{let s;if(W(t.default))try{s=t.default(),s instanceof Promise&&(s=s.catch(i=>{if(e.logger.error("💥",n,o,"rejected:",i),r){for(const l of r)if(i instanceof l)return i}throw i}))}catch(i){if(e.logger.error("💥",n,o,"rejected:",i),r){for(const l of r)if(i instanceof l)return s=M(e,t,i),e.logger.info("✨",t.type,o,"computed default",s),s}throw i}else s=t.default,e.logger.info("✨",t.type,o,"using static default",s);return M(e,t,s)}}}function z(e,t,n){if(e.valueMap.has(t.key))return Rn(e,t,n);e.logger.info("❔",t.type,t.key,"value not found in cache");const{key:o}=t;switch(t.type){case"readonly_held_selector":case"writable_held_selector":return e.logger.info("🧮",t.type,o,"computing value"),t.getFrom(e);case"writable_pure_selector":case"readonly_pure_selector":case"atom":return Ce(e,t);case"mutable_atom":{const r=new t.class;return e.logger.info("✨",t.type,o,"created new instance",r),M(e,t,r)}}}function it(e,t){return C(e,{key:t.family.key,type:`${t.type}_family`})}const wt={atom_family:"atom",molecule_family:"molecule",mutable_atom_family:"mutable_atom",readonly_held_selector_family:"readonly_held_selector",readonly_pure_selector_family:"readonly_pure_selector",writable_held_selector_family:"writable_held_selector",writable_pure_selector_family:"writable_pure_selector"},le=Symbol("MUST_CREATE"),mo=Symbol("DO_NOT_CREATE");function ae(e,t,n,o){const r=x(o),s=t.molecules.get(r);if(!s&&t.config.lifespan==="immortal"){const{type:l,key:c}=n;return t.logger.warn("💣","key",r,"was used to mint a counterfeit token for",l,`"${c}"`),{counterfeit:!0,key:`${c}(${r})`,type:wt[l],family:{key:c,subKey:r}}}let i;if(e===le)t.logger.info("👪",n.type,n.key,"adds member",typeof o=="string"?`\`${o}\``:o),i=n.create(o),s&&t.moleculeData.set(r,n.key);else{const{type:l,key:c}=n;return{key:`${c}(${r})`,type:wt[l],family:{key:c,subKey:r}}}return i}function lt(e,...t){let n,o,r,s,i;if(t.length===1){if(i=t[0],"family"in i){const c=it(e,i);if(r=C(e,c),s=te(i.family.subKey),n=ce(e,c,s),"counterfeit"in i)return{token:i,family:r,subKey:s,isNew:!1};n?i=n:(o=ae(le,e,c,s),i=o)}}else r=C(e,t[0]),s=t[1],n=ce(e,r,s),n?i=n:(o=ae(le,e,r,s),i=o);const l="counterfeit"in i;if(o&&l===!1&&r){let c;switch(i.type){case"readonly_pure_selector":case"readonly_held_selector":c="readable";break;case"atom":case"mutable_atom":case"writable_pure_selector":case"writable_held_selector":c="writable";break}const u={type:"state_creation",subType:c,token:i,timestamp:Date.now()};r.subject.next(u);const f=v(e);if(i.family)if(ie(f))switch(i.type){case"atom":case"mutable_atom":e.on.atomCreation.next(i);break;case"writable_pure_selector":case"readonly_pure_selector":case"writable_held_selector":case"readonly_held_selector":e.on.selectorCreation.next(i);break}else T(f)&&f.on.transactionApplying.state===null&&f.transactionMeta.update.subEvents.push(u)}return{token:i,family:r,subKey:s,isNew:!!o}}function F(e,...t){const{token:n,family:o,subKey:r}=lt(e,...t);return"counterfeit"in n&&o&&r?dn(e,n,o,r):z(e,C(e,n))}function ce(e,t,n){const o=x(n),r=`${t.key}(${o})`,s=v(e);let i;switch(t.type){case"atom_family":case"mutable_atom_family":i=s.atoms.get(r);break;case"writable_held_selector_family":case"writable_pure_selector_family":i=s.writableSelectors.get(r);break;case"readonly_held_selector_family":case"readonly_pure_selector_family":i=s.readonlySelectors.get(r);break}return i&&Q(i)}function G(e,t,n){const o=C(e,t),r=ce(e,t,n);return r||ae(mo,e,o,n)}function pn(e,t,n){const o=t.key,r="readonly_pure_selector_family",s={key:o,type:r},i=e.families.get(o);i&&e.config.isProduction===!0&&e.logger.error("❗",r,o,`Overwriting an existing ${B[i.type]} "${i.key}" in store "${e.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);const l=new S,u={...s,create:f=>{const a=x(f),d={key:o,subKey:a},_=`${o}(${a})`,p=v(e),y={key:_,get:t.get(f)};return t.catch&&(y.catch=t.catch),Cn(p,y,d)},internalRoles:n,subject:l,install:f=>pn(f,t),default:f=>t.get(f)({get:((...a)=>F(e,...a)),find:((...a)=>G(e,...a)),json:a=>pe(e,a)})};return e.families.set(o,u),s}function yn(e,t,n){const o={key:t.key,type:"atom_family"},r=e.families.get(t.key);r&&e.config.isProduction===!0&&e.logger.error("❗","atom_family",t.key,`Overwriting an existing ${B[r.type]} "${r.key}" in store "${e.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);const s=new S,l={...o,create:c=>{const u=x(c),f={key:t.key,subKey:u},a=`${t.key}(${u})`,d=v(e),_=t.default,p={key:a,default:W(_)?()=>_(c):_};return t.effects&&(p.effects=t.effects(c)),t.catch&&(p.catch=t.catch),Pe(d,p,f)},default:t.default,subject:s,install:c=>yn(c,t),internalRoles:n};return e.families.set(t.key,l),W(t.default)===!1&&e.defaults.set(t.key,t.default),o}function hn(e,t,n){const o=t.key,r="readonly_held_selector_family",s={key:o,type:r},i=e.families.get(o);i&&e.config.isProduction===!0&&e.logger.error("❗",r,o,`Overwriting an existing ${B[i.type]} "${i.key}" in store "${e.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);const l=new S,u={...s,create:f=>{const a=x(f),d={key:o,subKey:a},_=`${o}(${a})`;return $n(v(e),{key:_,const:t.const(f),get:t.get(f)},d)},internalRoles:n,subject:l,install:f=>hn(f,t),default:t.const};return e.families.set(o,u),s}function mn(e,t,n){const o=t.key,r="writable_held_selector_family",s={key:o,type:r},i=e.families.get(o);i&&e.config.isProduction===!0&&e.logger.error("❗",r,o,`Overwriting an existing ${B[i.type]} "${i.key}" in store "${e.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);const l=new S,u={...s,create:f=>{const a=x(f),d={key:o,subKey:a},_=`${o}(${a})`;return xn(v(e),{key:_,const:t.const(f),get:t.get(f),set:t.set(f)},d)},internalRoles:n,subject:l,install:f=>mn(f,t),default:t.const};return e.families.set(o,u),s}function gn(e,t,n){const o=t.key,r="writable_pure_selector_family",s={key:o,type:r},i=e.families.get(o);i&&e.config.isProduction===!0&&e.logger.error("❗",r,o,`Overwriting an existing ${B[i.type]} "${i.key}" in store "${e.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);const l=new S,u={...s,create:f=>{const a=x(f),d={key:o,subKey:a},_=`${o}(${a})`,p=v(e),y={key:_,get:t.get(f),set:t.set(f)};return t.catch&&(y.catch=t.catch),Kn(p,y,d)},internalRoles:n,subject:l,install:f=>gn(f,t),default:f=>t.get(f)({get:((...a)=>F(e,...a)),find:((...a)=>G(e,...a)),json:a=>pe(e,a)})};return e.families.set(o,u),s}function go(e,t){const n="set"in t,o="const"in t;return o&&n?mn(e,t,void 0):o?hn(e,t,void 0):n?gn(e,t):pn(e,t)}function Me(e,...t){let n;if(t.length===1)n=t[0];else{const o=t[0],r=t[1];n=G(e,o,r)}try{C(e,n)}catch{e.logger.error("❌",n.type,n.key,`could not be disposed because it was not found in the store "${e.config.name}".`);return}switch(n.type){case"atom":case"mutable_atom":On(e,n);break;case"writable_pure_selector":case"readonly_pure_selector":case"writable_held_selector":case"readonly_held_selector":xo(e,n);break}}function bn(e,t){if(e.operation.open){const n=performance.now();return e.logger.info("🚫",t.type,t.key,`deferring setState at T-${n} until setState for "${e.operation.token.key}" is done`),n}return e.operation={open:!0,done:new Set,prev:new Map,timestamp:Date.now(),token:t,subEvents:[]},e.logger.info("⭕",t.type,t.key,`operation start in store "${e.config.name}"${T(e)?` ${e.transactionMeta.phase} "${e.transactionMeta.update.token.key}"`:""}`),e}function wn(e){e.operation.open&&e.logger.info("🔴",e.operation.token.type,e.operation.token.key,`operation done in store "${e.config.name}"`),e.operation={open:!1},e.on.operationClose.next(e.operation)}const vn=(e,t)=>e.operation.open?e.operation.done.has(t):(e.logger.error("🐞","unknown",t,"isDone called outside of an operation. This is probably a bug in AtomIO."),!0),Ee=(e,t)=>{if(!e.operation.open){e.logger.error("🐞","unknown",t,"markDone called outside of an operation. This is probably a bug in AtomIO.");return}e.operation.done.add(t)};function qe(e,t,n,o,r){const{oldValue:s,newValue:i}=n,l="oldValue"in n,c=Q(t);if(o&&r){t.subject.next({newValue:i});const _={checkpoint:!0,type:"state_creation",subType:"writable",token:c,timestamp:Date.now(),value:i};e.operation.subEvents.push(_),r.subject.next(_);const p=v(e);if(c.family)if(ie(p))switch(c.type){case"atom":case"mutable_atom":e.on.atomCreation.next(c);break;case"writable_pure_selector":case"writable_held_selector":e.on.selectorCreation.next(c);break}else T(p)&&p.on.transactionApplying.state===null&&p.transactionMeta.update.subEvents.push(_);return}const{key:u,subject:f,type:a}=t;let d;if(l?d={oldValue:ge(s)?s.READONLY_VIEW:s,newValue:ge(i)?i.READONLY_VIEW:i}:d={newValue:ge(i)?i.READONLY_VIEW:i},ie(e)){switch(a){case"mutable_atom":e.logger.info("📢",a,u,"is now (",i,") subscribers:",f.subscribers.keys());break;case"atom":case"writable_pure_selector":case"writable_held_selector":e.logger.info("📢",a,u,"went (",s,"->",i,") subscribers:",f.subscribers.keys())}f.next(d)}if(T(e)&&(a==="mutable_atom"||a==="atom")){if(e.on.transactionApplying.state===null){if(ge(i))return;const{timestamp:_}=e.operation,p={type:"atom_update",token:c,timestamp:_,update:d};e.transactionMeta.update.subEvents.push(p),e.logger.info("📁","atom",u,"stowed (",s,"->",i,")");return}if(ut(t,"tracker:signal")){const _=u.slice(1),p=e.atoms.get(_);z(e,p,"mut").do(d.newValue)===null&&ct(e,p)}}}const vt=Symbol("UNSET"),Ze=(e,t,n)=>{let o,r;if(W(n)){const s=z(e,t,"mut");o=s,r=n(s)}else e.valueMap.has(t.key)?o=Rn(e,t,"mut"):t.type==="atom"&&!W(t.default)?o=t.default:o=vt,r=n;return e.logger.info("⭐","atom",t.key,"setting value",r),r=M(e,t,r),Ee(e,t.key),ct(e,t),o===vt?{newValue:r}:{oldValue:o,newValue:r}};function Fe(e,t){switch(t.type){case"mutable_atom":return Ze(e,t,new t.class);case"atom":{let n;return W(t.default)?n=Ce(e,t):n=t.default,Ze(e,t,n)}}}function bo(e,t){let n;switch(t.type){case"atom":case"mutable_atom":n=Fe(e,t);break;case"writable_held_selector":{const o=ue(e,t.key);for(const s of o.values())qe(e,t,Fe(e,s),!1);const r=t.getFrom(e);n={oldValue:r,newValue:r}}break;case"writable_pure_selector":{const o=Ce(e,t),r=ue(e,t.key);for(const s of r.values())qe(e,t,Fe(e,s),!1);n={oldValue:o,newValue:Ce(e,t)}}break}return n}function U(e,...t){Oe(Qe,e,...t)}const Xe=Symbol("RESET");function at(e,...t){U(e,...t,Xe)}function wo(e,t,n){let o,r,s;const{type:i,key:l}=t;switch(t.type){case"writable_pure_selector":o=z(e,t,"mut"),r=gt(n,o),r=M(e,t,r);break;case"writable_held_selector":s=t.const,gt(n,s),o=s,r=s}return e.logger.info("⭐",i,l,"setting to",r),Ee(e,l),t.setSelf(r),{oldValue:o,newValue:r}}const vo=(e,t,n)=>{let o;switch(t.type){case"atom":case"mutable_atom":o=Ze(e,t,n);break;case"writable_pure_selector":case"writable_held_selector":o=wo(e,t,n);break}return o},Qe=Symbol("OWN_OP"),kn=Symbol("JOIN_OP");function Oe(e,t,...n){let o,r,s,i,l,c;n.length===2?(s=n[0],c=n[1],"family"in s&&(i=it(t,s),l=te(s.family.subKey),o=ce(t,i,l),o?s=o:s=r=ae(le,t,i,l))):(i=C(t,n[0]),l=n[1],c=n[2],o=ce(t,i,l),o?s=o:s=r=ae(le,t,i,l));const u=c===Xe?"reset":"set";let f;if(e===Qe){const _=bn(t,s);if(typeof _=="number"){const p=_,y=t.on.operationClose.subscribe(`waiting to ${u} "${s.key}" at T-${p}`,function(){y(),t.logger.info("🟢",s.type,s.key,"resuming deferred",u,`from T-${p}`),Oe(e,t,s,c)});return}f=_}else f=t;if("counterfeit"in s&&"family"in s){const _=s.family.subKey,p=t.disposalTraces.buffer.find(y=>y?.key===_);t.logger.error("❌",s.type,s.key,"could not be",u,"because key",_,"is not allocated.",p?`this key was previously disposed:${p.trace}`:"(no previous disposal trace found)");return}const a=C(f,s);let d;c===Xe?d=bo(f,a):d=vo(f,a,c),qe(f,a,d,!!r,i),e===Qe&&wn(f)}const Sn=(e,t)=>v(e).atoms.has(t),ko=(e,t)=>v(e).writableSelectors.has(t),So=(e,t)=>v(e).readonlySelectors.has(t),$o=(e,t)=>Sn(e,t)||ko(e,t)||So(e,t);function kt(e,t){return v(e).selectorGraph.getRelationEntries({downstreamSelectorKey:t}).filter(([n,{source:o}])=>o!==t).map(([n,{source:o}])=>o).filter(n=>$o(e,n))}function ue(e,t,n=new Set){const o=kt(e,t),r=new Map;for(;o.length>0;){const s=o.pop();if(!n.has(s))if(n.add(s),Sn(e,s)){const i=e.atoms.get(s);r.set(i.key,i)}else o.push(...kt(e,s))}return r}function Co(e,t,n,o,r){const s=v(e),{type:i,key:l}=o;if(i==="atom"||i==="mutable_atom")s.selectorAtoms.set({selectorKey:n,atomKey:l}),e.logger.info("🔍",t,n,`discovers root atom "${l}"`);else{const c=ue(e,l,r);e.logger.info("🔍",t,n,`discovers root atoms: [ ${[...c.values()].map(u=>`"${u.key}"`).join(", ")} ]`);for(const{key:u}of c.values())s.selectorAtoms=s.selectorAtoms.set({selectorKey:n,atomKey:u})}r.add(l)}function Ae(e,t,n,o){return{get:(...r)=>{const s=v(e),{token:i,family:l,subKey:c}=lt(e,...r);let u;return"counterfeit"in i&&l&&c?u=dn(e,i,l,c):u=z(e,C(e,i)),e.logger.info("🔌",t,n,`registers dependency ( "${i.key}" =`,u,")"),s.selectorGraph.set({upstreamSelectorKey:i.key,downstreamSelectorKey:n},{source:i.key}),Co(e,t,n,i,o),u},set:((...r)=>{Oe(kn,v(e),...r)}),find:((...r)=>G(e,...r)),json:r=>pe(e,r)}}function $n(e,t,n){const o=v(e),r=new S,s=new Set,{key:i,const:l}=t,c="readonly_held_selector";e.logger.info("🔨",c,i,"is being created");const{get:u,find:f,json:a}=Ae(o,c,i,s),_={...t,type:c,subject:r,getFrom:y=>{const w=y.selectorGraph.getRelationEntries({downstreamSelectorKey:i});for(const[h,{source:g}]of w)g!==i&&y.selectorGraph.delete(h,i);return y.selectorAtoms.delete(i),t.get({get:u,find:f,json:a},l),M(y,_,l),e.logger.info("✨",c,i,"=",l),s.clear(),l},install:y=>$n(y,t,n)};n&&(_.family=n),o.readonlySelectors.set(i,_);const p={key:i,type:c};return n&&(p.family=n),p}function Cn(e,t,n){const o=v(e),r=new S,s=new Set,i=t.key,l="readonly_pure_selector";e.logger.info("🔨",l,i,"is being created");const{get:c,find:u,json:f}=Ae(o,l,i,s),d={...t,type:l,subject:r,getFrom:()=>{const p=v(e),y=p.selectorGraph.getRelationEntries({downstreamSelectorKey:i});for(const[h,{source:g}]of y)g!==i&&p.selectorGraph.delete(h,i);p.selectorAtoms.delete(i);const w=M(p,d,t.get({get:c,find:u,json:f}));return e.logger.info("✨",l,i,"=",w),s.clear(),w},install:p=>Cn(p,t,n)};n&&(d.family=n),o.readonlySelectors.set(i,d);const _={key:i,type:l};return n&&(_.family=n),_}function xn(e,t,n){const o=v(e),r=new S,s=new Set,{key:i,const:l}=t,c="writable_held_selector";e.logger.info("🔨",c,i,"is being created");const u=Ae(o,c,i,s),{find:f,get:a,json:d}=u,_={find:f,get:a,json:d},w={...t,type:c,subject:r,getFrom:g=>{const K=g.selectorGraph.getRelationEntries({downstreamSelectorKey:i});for(const[R,{source:I}]of K)I!==i&&g.selectorGraph.delete(R,i);return g.selectorAtoms.delete(i),t.get(_,l),M(g,w,l),e.logger.info("✨",c,i,"=",l),s.clear(),l},setSelf:()=>{t.set(u,l)},install:g=>xn(g,t,n)};n&&(w.family=n),o.writableSelectors.set(i,w);const h={key:i,type:c};return n&&(h.family=n),h}function Kn(e,t,n){const o=v(e),r=new S,s=new Set,i=t.key,l="writable_pure_selector";e.logger.info("🔨",l,i,"is being created");const c=Ae(o,l,i,s),{find:u,get:f,json:a}=c,d={find:u,get:f,json:a},y={...t,type:l,subject:r,getFrom:h=>{const g=h.selectorGraph.getRelationEntries({downstreamSelectorKey:i});for(const[R,{source:I}]of g)I!==i&&h.selectorGraph.delete(R,i);h.selectorAtoms.delete(i);const K=M(h,y,t.get(d));return e.logger.info("✨",l,i,"=",K),s.clear(),K},setSelf:h=>{t.set(c,h)},install:h=>Kn(h,t,n)};n&&(y.family=n),o.writableSelectors.set(i,y);const w={key:i,type:l};return n&&(w.family=n),w}function xo(e,t){const n=v(e),{key:o,type:r,family:s}=t;if(!s)e.logger.error("❌",r,o,"Standalone selectors cannot be disposed.");else{n.molecules.get(s.subKey)&&n.moleculeData.delete(s.subKey,s.key);let i;switch(t.type){case"writable_held_selector":n.writableSelectors.delete(o),i={key:s.key,type:"writable_held_selector_family"},C(e,i).subject.next({type:"state_disposal",subType:"selector",token:t,timestamp:Date.now()});break;case"writable_pure_selector":n.writableSelectors.delete(o),i={key:s.key,type:"writable_pure_selector_family"},C(e,i).subject.next({type:"state_disposal",subType:"selector",token:t,timestamp:Date.now()});break;case"readonly_held_selector":n.readonlySelectors.delete(o),i={key:s.key,type:"readonly_held_selector_family"},C(e,i).subject.next({type:"state_disposal",subType:"selector",token:t,timestamp:Date.now()});break;case"readonly_pure_selector":n.readonlySelectors.delete(o),i={key:s.key,type:"readonly_pure_selector_family"},C(e,i).subject.next({type:"state_disposal",subType:"selector",token:t,timestamp:Date.now()});break}n.valueMap.delete(o),n.selectorAtoms.delete(o),n.selectorGraph.delete(o),n.moleculeData.delete(s.key,s.subKey),e.logger.info("🔥",t.type,o,"deleted"),T(n)&&n.transactionMeta.phase==="building"?n.transactionMeta.update.subEvents.push({type:"state_disposal",subType:"selector",token:t,timestamp:Date.now()}):e.on.selectorDisposal.next(t)}}const Ko=(e,t)=>{const n=v(e);return n.operation.open?n.operation.prev.get(t.key):n.valueMap.get(t.key)},St=(e,t,n)=>n.subject.subscribe(`${t.type}:${t.key}`,o=>{e.logger.info("📢",t.type,t.key,"root",n.key,"went",o.oldValue,"->",o.newValue);const r=Ko(e,t),s=z(e,t);e.logger.info("✨",t.type,t.key,"went",r,"->",s),t.subject.next({newValue:s,oldValue:r})});function xe(e,t,n,o){function r(a){if(e.operation.open){if(s?.type==="atom"&&ut(s,"tracker:signal")&&"*"+e.operation.token.key===t.key&&"inboundTracker"in o)return;const d=e.on.operationClose.subscribe(`state subscription ${n}`,()=>{d(),o(a)})}else o(a)}lt(e,t);const s=C(e,t);e.logger.info("👀",s.type,s.key,`Adding subscription "${n}"`);const i=s.type==="writable_pure_selector"||s.type==="readonly_pure_selector",l=new Map;let c=r;if(i){z(e,s);for(const[a,d]of ue(e,s.key))l.set(a,St(e,s,d));c=function(d){const _=ue(e,s.key);for(const[p,y]of l)_.get(p)?_.delete(p):(y(),l.delete(p));for(const[p,y]of _)l.set(p,St(e,s,y));r(d)}}const u=s.subject.subscribe(n,c);return()=>{e.logger.info("🙈",s.type,s.key,`Removing subscription "${n}"`),u();for(const a of l.values())a()}}const To=(e,t,n,o)=>{const r=C(e,t);e.logger.info("👀","timeline",t.key,`Adding subscription "${n}"`);const s=r.subject.subscribe(n,o);return()=>{e.logger.info("🙈","timeline",t.key,`Removing subscription "${n}" from timeline`),s()}};var Ro=class{initializeSignalAtom(e,t){const n=`*${e.key}`;t.atoms.delete(n),t.valueMap.delete(n);const o=e.family?{key:`*${e.family.key}`,subKey:e.family.subKey}:void 0,r=Pe(t,{key:n,default:null},o,["tracker:signal"]);if(t.parent?.valueMap.has(n)){const s=t.parent.valueMap.get(n);t.valueMap.set(n,s)}return r}unsubscribeFromInnerValue;unsubscribeFromState;captureSignalsFromCore(e,t,n){const o=e.key,r=`tracker-from-core:${n.config.name}:${T(n)?n.transactionMeta.update.token.key:"main"}:${o}`,s=i=>{Oe(kn,n,t,i)};this.unsubscribeFromInnerValue=F(n,e).subscribe(r,s),this.unsubscribeFromState=xe(n,e,r,(function(l){l.newValue!==l.oldValue&&(this.unsubscribeFromInnerValue(),this.unsubscribeFromInnerValue=l.newValue.subscribe(r,s))}).bind(this))}supplySignalsToCore(e,t,n){const o=e.key,r=`tracker-to-core:${n.config.name}:${T(n)?n.transactionMeta.update.token.key:"main"}:${o}`;xe(n,t,r,Object.assign(function({newValue:i,oldValue:l}){const c=n.timelineTopics.getRelatedKey(t.key);if(c&&n.timelines.get(c)?.timeTraveling){const u=To(n,{key:c,type:"timeline"},r,function(a){u(),U(n,e,d=>(a==="redo"&&i?d.do(i):a==="undo"&&l&&d.undo(l),d))});return}U(n,e,u=>(u.do(i),u))},{inboundTracker:!0}))}mutableAtomToken;latestSignalToken;[Symbol.dispose];constructor(e,t){const n=v(t),o=this.initializeSignalAtom(e,n);this.mutableAtomToken=e,this.latestSignalToken=o,this.captureSignalsFromCore(e,o,n),this.supplySignalsToCore(e,o,n),n.trackers.set(e.key,this),this[Symbol.dispose]=()=>{this.unsubscribeFromInnerValue(),this.unsubscribeFromState(),n.trackers.delete(e.key)}}};const pe=(e,t)=>t.family?G(e,C(v(e),{key:`${t.family.key}:JSON`,type:"writable_pure_selector_family"}),te(t.family.subKey)):{type:"writable_pure_selector",key:`${t.key}:JSON`},Tn=e=>{const t={type:"atom",key:`*${e.key}`};return e.family&&(t.family={key:`*${e.family.key}`,subKey:e.family.subKey}),t};function ge(e){return typeof e=="object"&&e!==null&&"do"in e&&"undo"in e&&"subscribe"in e&&"READONLY_VIEW"in e&&"toJSON"in e}function M(e,t,n){const{key:o,subject:r,type:s}=t,i=e.valueMap.get(o);if(i instanceof Ye&&!i.done){const l=i;return n instanceof Promise?(l.use(n),l):(e.valueMap.set(o,n),n)}if(n instanceof Promise){const l=new Ye(n);return e.valueMap.set(o,l),l.then(function(u){if(e.valueMap.get(o)===l){switch(bn(e,t),M(e,t,u),s){case"atom":ct(e,t);break;case"readonly_pure_selector":case"writable_pure_selector":En(e,o);break}wn(e),r.next({newValue:u,oldValue:l})}}).catch(c=>{e.logger.error("💥",t.type,o,"rejected:",c)}),l}return e.logger.info("📝",t.type,t.key,"writing to cache",n),e.valueMap.set(o,n),n}function Rn(e,t,n){e.logger.info("📖",t.type,t.key,"reading cached value");let o=e.valueMap.get(t.key);if(n==="mut"&&t.type==="mutable_atom"&&T(e)){const r=t,{parent:s}=e;if(e.valueMap.hasOwn(r.key))return o;const i=s.valueMap.get(r.key);e.logger.info("📃","atom",r.key,"copying");const l=i.toJSON(),c=r.class.fromJSON(l);e.valueMap.set(r.key,c),new Ro(r,s),o=c}return o}function Mn(e,t){const n=e.valueMap.get(t);if(n instanceof Ye){const o=e.writableSelectors.get(t)??e.readonlySelectors.get(t);o&&o.getFrom(e);return}e.operation.open&&e.operation.prev.set(t,n),e.valueMap.delete(t),e.logger.info("🗑","state",t,"evicted")}function ct(e,t){const n=v(e),{key:o,type:r}=t,s=n.selectorAtoms.getRelatedKeys(o);if(n.logger.info("🧹",r,o,s?`evicting ${s.size} states downstream:`:"no downstream states",s??"to evict"),s){n.operation.open&&n.logger.info("🧹",r,o,`[ ${[...n.operation.done].join(", ")} ] already done`);for(const i of s)vn(n,i)||(Mn(n,i),Ee(n,i))}}function En(e,t){const n=v(e),o=n.selectorGraph.getRelationEntries({upstreamSelectorKey:t}).filter(([r,{source:s}])=>s===t);for(const[r]of o)vn(n,r)||(Mn(n,r),Ee(n,r),En(e,r))}function Pe(e,t,n,o){const r="atom",{key:s}=t;e.logger.info("🔨",r,s,"is being created");const i=v(e),l=i.atoms.get(s);if(l?.type===r&&e.config.isProduction===!0)return e.logger.error("❌","atom",s,"Tried to create atom, but it already exists in the store."),Q(l);const c=new S,u={...t,type:r,install:a=>(a.logger.info("🛠️",r,s,`installing in store "${a.config.name}"`),Pe(a,t,n)),subject:c};n&&(u.family=n),o&&(u.internalRoles=o),i.atoms.set(s,u);const f=Q(u);if(t.effects){let a=0;const d=[];for(const _ of t.effects){const p=_({resetSelf:()=>{at(e,f)},setSelf:y=>{U(e,f,y)},onSet:y=>xe(e,f,`effect[${a}]`,y),token:f,store:Jn(e)});p&&d.push(p),++a}u.cleanup=()=>{for(const _ of d)_()}}return e.on.atomCreation.next(f),f}function ut(e,t){return"internalRoles"in e?e.internalRoles.includes(t):!1}function On(e,t){const n=v(e),{key:o,family:r}=t,s=C(n,t);if(!r)e.logger.error("❌","atom",o,"Standalone atoms cannot be disposed.");else{s.cleanup?.();const i=e.valueMap.get(s.key),l=C(e,it(e,t)).subject,c={type:"state_disposal",subType:"atom",token:t,value:i,timestamp:Date.now()};l.next(c);const u=T(n);if(n.atoms.delete(o),n.valueMap.delete(o),n.selectorAtoms.delete(o),n.atomsThatAreDefault.delete(o),n.moleculeData.delete(r.key,r.subKey),e.timelineTopics.delete(o),t.type==="mutable_atom"&&(On(e,Tn(t)),e.trackers.delete(o)),e.logger.info("🔥","atom",o,"deleted"),u&&n.transactionMeta.phase==="building"){const f=n.transactionMeta.update.subEvents.at(-1),a=f?.type==="molecule_disposal"&&f.values.some(([_])=>_===s.family?.key),d=ut(s,"tracker:signal");!a&&!d&&n.transactionMeta.update.subEvents.push(c)}else e.on.atomDisposal.next(t)}}function je(e){return Pe(N.STORE,e,void 0)}function ft(e){return yn(N.STORE,e)}function Ke(...e){return F(N.STORE,...e)}const B={atom_family:"atom family",atom:"atom",continuity:"continuity",key:"key",mutable_atom_family:"atom family [m]",mutable_atom:"atom [m]",readonly_held_selector_family:"selector family [h]",readonly_held_selector:"selector [h]",readonly_pure_selector_family:"selector family",readonly_pure_selector:"selector",state:"state",timeline:"timeline",transaction:"transaction",unknown:"unknown",writable_held_selector_family:"selector family [wh]",writable_held_selector:"selector [wh]",writable_pure_selector_family:"selector family [w]",writable_pure_selector:"selector [w]"},Ie=e=>(t,n,o,r,...s)=>{console[e](`${t} ${B[n]} \`${o}\` ${r}`,...s)},Mo={error:Ie("error"),info:Ie("info"),warn:Ie("warn")};var Eo=class{logLevel;filter;logger;constructor(e,t,n=Mo){this.logLevel=e,this.filter=t,this.logger=n}error=(...e)=>{if(this.logLevel!==null){const t=this.filter?.(...e)??!0;t===!0?this.logger.error(...e):t&&this.logger.error(...t)}};info=(...e)=>{if(this.logLevel==="info"){const t=this.filter?.(...e)??!0;t===!0?this.logger.info(...e):t&&this.logger.info(...t)}};warn=(...e)=>{if(this.logLevel!=="error"&&this.logLevel!==null){const t=this.filter?.(...e)??!0;t===!0?this.logger.warn(...e):t&&this.logger.warn(...t)}}};function Oo(e,t){return[e,t].sort().join("")}function Ao(e){if(typeof e!="string")return null;const[t,n]=e.split("==");if(!n)return null;const o=t.slice(4),[r,s]=n.split("++");return o&&r&&s?[o,r,s]:null}function $t(...e){at(N.STORE,...e)}function Po(e){return go(N.STORE,e)}function A(...e){U(N.STORE,...e)}function jo(e){return _n(N.STORE,e)}function Do(e,t=nn()){return ln(N.STORE,e,t)}var L,k,Ve,Ct,fe=0,An=[],$=m,xt=$.__b,Kt=$.__r,Tt=$.diffed,Rt=$.__c,Mt=$.unmount,Et=$.__;function ne(e,t){$.__h&&$.__h(k,e,fe||t),fe=0;var n=k.__H||(k.__H={__:[],__h:[]});return e>=n.__.length&&n.__.push({}),n.__[e]}function No(e){return fe=1,Fo(jn,e)}function Fo(e,t,n){var o=ne(L++,2);if(o.t=e,!o.__c&&(o.__=[n?n(t):jn(void 0,t),function(l){var c=o.__N?o.__N[0]:o.__[0],u=o.t(c,l);c!==u&&(o.__N=[u,o.__[1]],o.__c.setState({}))}],o.__c=k,!k.__f)){var r=function(l,c,u){if(!o.__c.__H)return!0;var f=o.__c.__H.__.filter(function(d){return!!d.__c});if(f.every(function(d){return!d.__N}))return!s||s.call(this,l,c,u);var a=o.__c.props!==l;return f.forEach(function(d){if(d.__N){var _=d.__[0];d.__=d.__N,d.__N=void 0,_!==d.__[0]&&(a=!0)}}),s&&s.call(this,l,c,u)||a};k.__f=!0;var s=k.shouldComponentUpdate,i=k.componentWillUpdate;k.componentWillUpdate=function(l,c,u){if(this.__e){var f=s;s=void 0,r(l,c,u),s=f}i&&i.call(this,l,c,u)},k.shouldComponentUpdate=r}return o.__N||o.__}function _t(e,t){var n=ne(L++,3);!$.__s&&dt(n.__H,t)&&(n.__=e,n.u=t,k.__H.__h.push(n))}function Io(e,t){var n=ne(L++,4);!$.__s&&dt(n.__H,t)&&(n.__=e,n.u=t,k.__h.push(n))}function Vo(e){return fe=5,Pn(function(){return{current:e}},[])}function Pn(e,t){var n=ne(L++,7);return dt(n.__H,t)&&(n.__=e(),n.__H=t,n.__h=e),n.__}function Uo(e,t){return fe=8,Pn(function(){return e},t)}function Lo(e){var t=k.context[e.__c],n=ne(L++,9);return n.c=e,t?(n.__==null&&(n.__=!0,t.sub(k)),t.props.value):e.__}function Ho(){var e=ne(L++,11);if(!e.__){for(var t=k.__v;t!==null&&!t.__m&&t.__!==null;)t=t.__;var n=t.__m||(t.__m=[0,0]);e.__="P"+n[0]+"-"+n[1]++}return e.__}function Wo(){for(var e;e=An.shift();)if(e.__P&&e.__H)try{e.__H.__h.forEach(ve),e.__H.__h.forEach(et),e.__H.__h=[]}catch(t){e.__H.__h=[],$.__e(t,e.__v)}}$.__b=function(e){k=null,xt&&xt(e)},$.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),Et&&Et(e,t)},$.__r=function(e){Kt&&Kt(e),L=0;var t=(k=e.__c).__H;t&&(Ve===k?(t.__h=[],k.__h=[],t.__.forEach(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(t.__h.forEach(ve),t.__h.forEach(et),t.__h=[],L=0)),Ve=k},$.diffed=function(e){Tt&&Tt(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(An.push(t)!==1&&Ct===$.requestAnimationFrame||((Ct=$.requestAnimationFrame)||zo)(Wo)),t.__H.__.forEach(function(n){n.u&&(n.__H=n.u),n.u=void 0})),Ve=k=null},$.__c=function(e,t){t.some(function(n){try{n.__h.forEach(ve),n.__h=n.__h.filter(function(o){return!o.__||et(o)})}catch(o){t.some(function(r){r.__h&&(r.__h=[])}),t=[],$.__e(o,n.__v)}}),Rt&&Rt(e,t)},$.unmount=function(e){Mt&&Mt(e);var t,n=e.__c;n&&n.__H&&(n.__H.__.forEach(function(o){try{ve(o)}catch(r){t=r}}),n.__H=void 0,t&&$.__e(t,n.__v))};var Ot=typeof requestAnimationFrame=="function";function zo(e){var t,n=function(){clearTimeout(o),Ot&&cancelAnimationFrame(t),setTimeout(e)},o=setTimeout(n,35);Ot&&(t=requestAnimationFrame(n))}function ve(e){var t=k,n=e.__c;typeof n=="function"&&(e.__c=void 0,n()),k=t}function et(e){var t=k;e.__c=e.__(),k=t}function dt(e,t){return!e||e.length!==t.length||t.some(function(n,o){return n!==e[o]})}function jn(e,t){return typeof t=="function"?t(e):t}function Go(e,t){for(var n in t)e[n]=t[n];return e}function At(e,t){for(var n in e)if(n!=="__source"&&!(n in t))return!0;for(var o in t)if(o!=="__source"&&e[o]!==t[o])return!0;return!1}function Bo(e,t){var n=t(),o=No({t:{__:n,u:t}}),r=o[0].t,s=o[1];return Io(function(){r.__=n,r.u=t,Ue(r)&&s({t:r})},[e,n,t]),_t(function(){return Ue(r)&&s({t:r}),e(function(){Ue(r)&&s({t:r})})},[e]),n}function Ue(e){var t,n,o=e.u,r=e.__;try{var s=o();return!((t=r)===(n=s)&&(t!==0||1/t==1/n)||t!=t&&n!=n)}catch{return!0}}function Pt(e,t){this.props=e,this.context=t}(Pt.prototype=new D).isPureReactComponent=!0,Pt.prototype.shouldComponentUpdate=function(e,t){return At(this.props,e)||At(this.state,t)};var jt=m.__b;m.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),jt&&jt(e)};var Jo=m.__e;m.__e=function(e,t,n,o){if(e.then){for(var r,s=t;s=s.__;)if((r=s.__c)&&r.__c)return t.__e==null&&(t.__e=n.__e,t.__k=n.__k),r.__c(e,t)}Jo(e,t,n,o)};var Dt=m.unmount;function Dn(e,t,n){return e&&(e.__c&&e.__c.__H&&(e.__c.__H.__.forEach(function(o){typeof o.__c=="function"&&o.__c()}),e.__c.__H=null),(e=Go({},e)).__c!=null&&(e.__c.__P===n&&(e.__c.__P=t),e.__c.__e=!0,e.__c=null),e.__k=e.__k&&e.__k.map(function(o){return Dn(o,t,n)})),e}function Nn(e,t,n){return e&&n&&(e.__v=null,e.__k=e.__k&&e.__k.map(function(o){return Nn(o,t,n)}),e.__c&&e.__c.__P===t&&(e.__e&&n.appendChild(e.__e),e.__c.__e=!0,e.__c.__P=n)),e}function Le(){this.__u=0,this.o=null,this.__b=null}function Fn(e){var t=e.__.__c;return t&&t.__a&&t.__a(e)}function be(){this.i=null,this.l=null}m.unmount=function(e){var t=e.__c;t&&t.__R&&t.__R(),t&&32&e.__u&&(e.type=null),Dt&&Dt(e)},(Le.prototype=new D).__c=function(e,t){var n=t.__c,o=this;o.o==null&&(o.o=[]),o.o.push(n);var r=Fn(o.__v),s=!1,i=function(){s||(s=!0,n.__R=null,r?r(l):l())};n.__R=i;var l=function(){if(!--o.__u){if(o.state.__a){var c=o.state.__a;o.__v.__k[0]=Nn(c,c.__c.__P,c.__c.__O)}var u;for(o.setState({__a:o.__b=null});u=o.o.pop();)u.forceUpdate()}};o.__u++||32&t.__u||o.setState({__a:o.__b=o.__v.__k[0]}),e.then(i,i)},Le.prototype.componentWillUnmount=function(){this.o=[]},Le.prototype.render=function(e,t){if(this.__b){if(this.__v.__k){var n=document.createElement("div"),o=this.__v.__k[0].__c;this.__v.__k[0]=Dn(this.__b,n,o.__O=o.__P)}this.__b=null}var r=t.__a&&Ge(E,null,e.fallback);return r&&(r.__u&=-33),[Ge(E,null,t.__a?null:e.children),r]};var Nt=function(e,t,n){if(++n[1]===n[0]&&e.l.delete(t),e.props.revealOrder&&(e.props.revealOrder[0]!=="t"||!e.l.size))for(n=e.i;n;){for(;n.length>3;)n.pop()();if(n[1]<n[0])break;e.i=n=n[2]}};(be.prototype=new D).__a=function(e){var t=this,n=Fn(t.__v),o=t.l.get(e);return o[0]++,function(r){var s=function(){t.props.revealOrder?(o.push(r),Nt(t,e,o)):r()};n?n(s):s()}},be.prototype.render=function(e){this.i=null,this.l=new Map;var t=$e(e.children);e.revealOrder&&e.revealOrder[0]==="b"&&t.reverse();for(var n=t.length;n--;)this.l.set(t[n],this.i=[1,0,this.i]);return e.children},be.prototype.componentDidUpdate=be.prototype.componentDidMount=function(){var e=this;this.l.forEach(function(t,n){Nt(e,n,t)})};var Yo=typeof Symbol<"u"&&Symbol.for&&Symbol.for("react.element")||60103,qo=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,Zo=/^on(Ani|Tra|Tou|BeforeInp|Compo)/,Xo=/[A-Z0-9]/g,Qo=typeof document<"u",er=function(e){return(typeof Symbol<"u"&&typeof Symbol()=="symbol"?/fil|che|rad/:/fil|che|ra/).test(e)};D.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(e){Object.defineProperty(D.prototype,e,{configurable:!0,get:function(){return this["UNSAFE_"+e]},set:function(t){Object.defineProperty(this,e,{configurable:!0,writable:!0,value:t})}})});var Ft=m.event;function tr(){}function nr(){return this.cancelBubble}function or(){return this.defaultPrevented}m.event=function(e){return Ft&&(e=Ft(e)),e.persist=tr,e.isPropagationStopped=nr,e.isDefaultPrevented=or,e.nativeEvent=e};var rr={enumerable:!1,configurable:!0,get:function(){return this.class}},It=m.vnode;m.vnode=function(e){typeof e.type=="string"&&(function(t){var n=t.props,o=t.type,r={},s=o.indexOf("-")===-1;for(var i in n){var l=n[i];if(!(i==="value"&&"defaultValue"in n&&l==null||Qo&&i==="children"&&o==="noscript"||i==="class"||i==="className")){var c=i.toLowerCase();i==="defaultValue"&&"value"in n&&n.value==null?i="value":i==="download"&&l===!0?l="":c==="translate"&&l==="no"?l=!1:c[0]==="o"&&c[1]==="n"?c==="ondoubleclick"?i="ondblclick":c!=="onchange"||o!=="input"&&o!=="textarea"||er(n.type)?c==="onfocus"?i="onfocusin":c==="onblur"?i="onfocusout":Zo.test(i)&&(i=c):c=i="oninput":s&&qo.test(i)?i=i.replace(Xo,"-$&").toLowerCase():l===null&&(l=void 0),c==="oninput"&&r[i=c]&&(i="oninputCapture"),r[i]=l}}o=="select"&&r.multiple&&Array.isArray(r.value)&&(r.value=$e(n.children).forEach(function(u){u.props.selected=r.value.indexOf(u.props.value)!=-1})),o=="select"&&r.defaultValue!=null&&(r.value=$e(n.children).forEach(function(u){u.props.selected=r.multiple?r.defaultValue.indexOf(u.props.value)!=-1:r.defaultValue==u.props.value})),n.class&&!n.className?(r.class=n.class,Object.defineProperty(r,"className",rr)):(n.className&&!n.class||n.class&&n.className)&&(r.class=r.className=n.className),t.props=r})(e),e.$$typeof=Yo,It&&It(e)};var Vt=m.__r;m.__r=function(e){Vt&&Vt(e),e.__c};var Ut=m.diffed;m.diffed=function(e){Ut&&Ut(e);var t=e.props,n=e.__e;n!=null&&e.type==="textarea"&&"value"in t&&t.value!==n.value&&(n.value=t.value==null?"":t.value)};const sr=Gn(N.STORE);function ir(e,...t){let n;if(t.length===2){const o=t[0],r=t[1];n=G(e,o,r)}else n=t[0];return n}function ee(...e){const t=Lo(sr),n=ir(t,...e),o=Ho();return Bo(r=>xe(t,n,`use-o:${o}`,r),()=>F(t,n))}const ke=je({key:"pathKeys",default:[]}),Te=ft({key:"subpathKeys",default:[]}),ye=ft({key:"nodeAtoms",default:null}),_e=ft({key:"edgeAtoms",default:!0}),lr=Po({key:"pathDrawSelectors",get:e=>({get:t})=>t(Te,e).map((o,r)=>{const s=t(ye,o),i=t(_e,o);return s===null?"Z":r===0?`M ${s.x} ${s.y}`:i===!1?`M ${s.x} ${s.y}`:i===!0?`L ${s.x} ${s.y}`:"c"in i?`C ${i.c.x} ${i.c.y} ${i.s.x} ${i.s.y} ${s.x} ${s.y}`:`S ${i.s.x} ${i.s.y} ${s.x} ${s.y}`}).join(" ")});function ar(e){const t=Vo(null);return _t(()=>{A(e,t.current)},[e]),t}function Y(e,t,n){return Math.max(t,Math.min(n,e))}function Lt({at:e,subpathKey:t,prevSubpathKey:n,node:o}){let r;switch(typeof o){case"undefined":r=ee(ye,n);break;default:r=o}return r===null?null:b(E,{children:[b("line",{class:"bezier",x1:r.x,y1:r.y,x2:e.x,y2:e.y,stroke:"#777","stroke-width":1}),b("circle",{class:"bezier",fill:"#777",stroke:"#aaa","stroke-width":1,cx:e.x,cy:e.y,r:2}),b("circle",{class:"bezier-draggable",fill:"transparent",cx:e.x,cy:e.y,r:6,onPointerDown:s=>{s.currentTarget.setPointerCapture(s.pointerId),A(De,{key:t,by:o?"s":"c"})}})]})}function cr({subpathKey:e,nextSubpathKey:t}){const n=ee(ye,e),o=ee(_e,e);return n===null?null:b(E,{children:[typeof o=="boolean"?b("rect",{class:"node",x:n.x-3,y:n.y-3,width:6,height:6}):b(E,{children:[b(Lt,{at:o.s,node:n,subpathKey:e,prevSubpathKey:t}),o.c?b(Lt,{at:o.c,subpathKey:e,prevSubpathKey:t}):null,b("circle",{class:"node",cx:n.x,cy:n.y,r:3})]}),b("circle",{class:"node-draggable",fill:"transparent",cx:n.x,cy:n.y,r:10,onPointerDown:r=>{r.currentTarget.setPointerCapture(r.pointerId),A(De,{key:e})}})]})}function ur({pathKey:e}){const t=ee(lr,e);return b("path",{d:`${t} Z`,class:"path",style:{pointerEvents:"none"}})}function fr({pathKey:e}){const t=ee(Te,e);return b(E,{children:[b(ur,{pathKey:e}),t.toReversed().map((n,o,r)=>b(cr,{subpathKey:n,nextSubpathKey:r[o+1]??r[0]},n))]})}function _r(){const e=ee(ke);return b(E,{children:e.map(t=>b(fr,{pathKey:t},t))})}const In=je({key:"svgRef",default:null}),De=je({key:"currentlyDragging",default:null});function dr(e){e.preventDefault();const{key:t,by:n}=Ke(De)??{},o=Ke(In);if(!o||!t)return;const r=o.createSVGPoint();r.x=e.clientX,r.y=e.clientY;const s=o.getScreenCTM()?.inverse(),{x:i,y:l}=r.matrixTransform(s);switch(n){case void 0:A(ye,t,{x:Y(i,-185,q+185),y:Y(l,-10,Z+10)});break;case"s":A(_e,t,c=>({...c,s:{x:Y(i,-185,q+185),y:Y(l,-10,Z+10)}}));break;case"c":A(_e,t,c=>({...c,c:{x:Y(i,-185,q+185),y:Y(l,-10,Z+10)}}));break}}const pr=["m","M","l","L","c","C","v","V","z","Z"],yr=je({key:"preactLogo",default:()=>fetch("preact.svg").then(e=>e.text())}),hr=jo({key:"reset",do:async()=>{const e=await Ke(yr);for(const r of Ke(ke))$t(Te,r);$t(ke);const t=e.split(`
|
|
14
|
+
`).filter(r=>r.startsWith(" <path")).map(r=>{const s=r.split('d="')[1].slice(0,-9);let i,l="",c=[];const u=[];for(const d of s){if(pr.includes(d)){l&&(c.push(Number.parseFloat(l)),l=""),i&&u.push({letter:i,numbers:c}),i=d,c=[];continue}if(d===" "){c.push(Number.parseFloat(l)),l="";continue}if(d==="-"&&l){c.push(Number.parseFloat(l)),l="-";continue}l+=d}let f={x:0,y:0};return u.map(({letter:d,numbers:_})=>{let p,y;switch(d){case"m":p={x:f.x+_[0],y:f.y+_[1]},y=!1;break;case"M":p={x:_[0],y:_[1]},y=!1;break;case"l":p={x:f.x+_[0],y:f.y+_[1]},y=!0;break;case"L":p={x:_[0],y:_[1]},y=!0;break;case"c":p={x:f.x+_[4],y:f.y+_[5]},y={c:{x:f.x+_[0],y:f.y+_[1]},s:{x:f.x+_[2],y:f.y+_[3]}};break;case"C":p={x:_[4],y:_[5]},y={c:{x:_[0],y:_[1]},s:{x:_[2],y:_[3]}};break;case"v":p={x:f.x,y:f.y+_[0]},y=!0;break;case"V":p={x:f.x,y:_[0]},y=!0;break;case"z":case"Z":p=null,y=!0}return p&&(f=p),{node:p,edge:y}})});let n=0,o=0;for(const r of t){const s=o;for(const{node:l,edge:c}of r)A(_e,`subpath${o}`,c),A(ye,`subpath${o}`,l),o++;const i=o-s;A(Te,`path${n}`,Array.from({length:i},(l,c)=>`subpath${s+c}`)),A(ke,l=>[...l,`path${n}`]),n++}}}),Ht=Do(hr),q=256,Z=296;function mr(){const e=ar(In),t=Uo(n=>{n.currentTarget.releasePointerCapture(n.pointerId),A(De,null)},[]);return _t(()=>void Ht(),[]),b("div",{style:{display:"flex",flexFlow:"column",position:"relative",overflow:"hidden",maxWidth:"1280px",width:"100vw",alignItems:"center"},children:[b("svg",{ref:e,viewBox:`-185 -15 ${q+370} ${Z+30}`,width:1e3,height:500,onPointerMove:dr,onPointerUp:t,onPointerCancel:t,children:[b("title",{children:"Bezier Playground"}),b("defs",{children:b("pattern",{id:"grid",width:"5",height:"5",patternUnits:"userSpaceOnUse",children:b("rect",{x:"0",y:"0",width:".5",height:".5",fill:"none",stroke:"#aaa"})})}),b("rect",{x:0,y:0,width:q,height:Z,fill:"#aaa3"}),b("rect",{x:-185,y:-10,width:q+370,height:Z+20,fill:"url(#grid)"}),b(_r,{})]}),b("button",{type:"button",class:"flat",onClick:Ht,children:"Reset"})]})}function gr(){return b(E,{children:[b("h1",{children:"Atom.io in Preact on Vite"}),b("main",{children:[b(mr,{}),b("article",{children:[b(He,{title:"Learn Atom.io",description:"Atom.io is where data lives.",href:"https://atom.io.fyi/docs/getting-started"}),b(He,{title:"Learn Preact",description:"If you're new to Preact, try the interactive tutorial to learn important concepts",href:"https://preactjs.com/tutorial"}),b(He,{title:"Learn Vite",description:"To learn more about Vite and how you can customize it to fit your needs, take a look at their excellent documentation",href:"https://vitejs.dev"})]})]})]})}function He(e){return b("a",{href:e.href,target:"_blank",class:"resource",rel:"noreferrer",children:[b("h2",{children:e.title}),b("p",{children:e.description})]})}zn(b(gr,{}),document.getElementById("app"));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--fg: #ccc;--bg-shd1: #0e0e0e;--bg: #1a1a1a;--bg-tnt1: #262626;--bg-tnt2: #444;font-family:Charter,serif;line-height:1.5;font-weight:400;color:var(--fg);background:var(--bg);font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}@media(prefers-color-scheme:light){:root{--fg: #222;--bg-shd1: #e0e0e0;--bg: #eee;--bg-tnt1: #f3f3f3;--bg-tnt2: #f6f6f6}}body{margin:0;display:flex;flex-flow:column;align-items:center;justify-content:center;min-height:100vh;width:100vw}#app{text-align:center;display:flex;flex-flow:column;align-items:center}img{margin-bottom:1.5rem}img:hover{filter:drop-shadow(0 0 2em #673ab8aa)}main{display:flex;flex-flow:column;align-items:center}article{margin-top:5rem;padding:0 2rem;display:flex;gap:10px;width:100vw;justify-content:center;align-items:stretch;max-width:1280px}.resource{padding:.75rem 1.5rem;border-radius:.5rem;text-align:left;text-decoration:none;color:var(--fg);background:var(--bg-tnt1);border:1px solid transparent;flex:1}.resource:hover{background:var(--bg-tnt2);border:1px solid var(--fg);box-shadow:0 25px 50px -12px #673ab888}.node{fill:#673ab8;stroke:#aaa}.path{fill:#aaa1;stroke:#aaa}@media(max-width:639px){article{flex-flow:column}}button{font-family:Verdana,sans-serif}button.flat{color:var(--fg);background:var(--bg);border:1px solid var(--fg);height:40px;font-size:20px;position:absolute;bottom:10px;right:10px;padding:2px 10px 4px}button.flat:hover{background:var(--bg-tnt1)}button.flat:active{background:var(--bg-shd1);transform:scale(.98)}
|
package/dist/index.html
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<meta name="color-scheme" content="light dark" />
|
|
8
|
+
<title>Vite + Preact + Atom.io</title>
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-DhFJjzdn.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="/assets/index-jy4_OpZh.css">
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<div id="app"></div>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
package/dist/preact.svg
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="27.68" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 296">
|
|
2
|
+
<path fill="#673AB8" d="m128 0l128 73.9v147.8l-128 73.9L0 221.7V73.9z"></path>
|
|
3
|
+
<path fill="#FFF" d="M34.865 220.478c17.016 21.78 71.095 5.185 122.15-34.704c51.055-39.888 80.24-88.345 63.224-110.126c-17.017-21.78-71.095-5.184-122.15 34.704c-51.055 39.89-80.24 88.346-63.224 110.126Zm7.27-5.68c-5.644-7.222-3.178-21.402 7.573-39.253c11.322-18.797 30.541-39.548 54.06-57.923c23.52-18.375 48.303-32.004 69.281-38.442c19.922-6.113 34.277-5.075 39.92 2.148c5.644 7.223 3.178 21.403-7.573 39.254c-11.322 18.797-30.541 39.547-54.06 57.923c-23.52 18.375-48.304 32.004-69.281 38.441c-19.922 6.114-34.277 5.076-39.92-2.147Z"></path>
|
|
4
|
+
<path fill="#FFF" d="M220.239 220.478c17.017-21.78-12.169-70.237-63.224-110.126C105.96 70.464 51.88 53.868 34.865 75.648c-17.017 21.78 12.169 70.238 63.224 110.126c51.055 39.889 105.133 56.485 122.15 34.704Zm-7.27-5.68c-5.643 7.224-19.998 8.262-39.92 2.148c-20.978-6.437-45.761-20.066-69.28-38.441c-23.52-18.376-42.74-39.126-54.06-57.923c-10.752-17.851-13.218-32.03-7.575-39.254c5.644-7.223 19.999-8.261 39.92-2.148c20.978 6.438 45.762 20.067 69.281 38.442c23.52 18.375 42.739 39.126 54.06 57.923c10.752 17.85 13.218 32.03 7.574 39.254Z"></path>
|
|
5
|
+
<path fill="#FFF" d="M127.552 167.667c10.827 0 19.603-8.777 19.603-19.604c0-10.826-8.776-19.603-19.603-19.603c-10.827 0-19.604 8.777-19.604 19.603c0 10.827 8.777 19.604 19.604 19.604Z"></path>
|
|
6
|
+
</svg>
|
package/eslint.config.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { default as TypeScriptPlugin } from "@typescript-eslint/eslint-plugin"
|
|
2
|
+
import * as parser from "@typescript-eslint/parser"
|
|
3
|
+
import AtomIOPlugin from "atom.io/eslint-plugin"
|
|
4
|
+
import type { ESLint, Linter } from "eslint"
|
|
5
|
+
import PreactConfig from "eslint-config-preact"
|
|
6
|
+
import * as ImportPlugin from "eslint-plugin-import-x"
|
|
7
|
+
import { default as SimpleImportSortPlugin } from "eslint-plugin-simple-import-sort"
|
|
8
|
+
|
|
9
|
+
const ERROR = 2
|
|
10
|
+
|
|
11
|
+
const parserOptions = {
|
|
12
|
+
project: [`./tsconfig.json`],
|
|
13
|
+
sourceType: `module`,
|
|
14
|
+
} satisfies parser.ParserOptions
|
|
15
|
+
|
|
16
|
+
const commonRules = {
|
|
17
|
+
"@typescript-eslint/adjacent-overload-signatures": ERROR,
|
|
18
|
+
"@typescript-eslint/array-type": 0,
|
|
19
|
+
"@typescript-eslint/await-thenable": 0,
|
|
20
|
+
"@typescript-eslint/ban-ts-comment": ERROR,
|
|
21
|
+
"@typescript-eslint/ban-tslint-comment": 0,
|
|
22
|
+
"@typescript-eslint/class-literal-property-style": ERROR,
|
|
23
|
+
"@typescript-eslint/consistent-generic-constructors": 0,
|
|
24
|
+
"@typescript-eslint/consistent-indexed-object-style": 0,
|
|
25
|
+
"@typescript-eslint/consistent-return": 0,
|
|
26
|
+
"@typescript-eslint/consistent-type-assertions": 0,
|
|
27
|
+
"@typescript-eslint/consistent-type-definitions": 0,
|
|
28
|
+
"@typescript-eslint/consistent-type-exports": ERROR,
|
|
29
|
+
"@typescript-eslint/consistent-type-imports": [
|
|
30
|
+
ERROR,
|
|
31
|
+
{
|
|
32
|
+
fixStyle: `separate-type-imports`,
|
|
33
|
+
prefer: `type-imports`,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
"@typescript-eslint/default-param-last": ERROR,
|
|
37
|
+
"@typescript-eslint/dot-notation": 0,
|
|
38
|
+
"@typescript-eslint/explicit-function-return-type": 0,
|
|
39
|
+
"@typescript-eslint/explicit-member-accessibility": ERROR,
|
|
40
|
+
"@typescript-eslint/explicit-module-boundary-types": ERROR,
|
|
41
|
+
"@typescript-eslint/init-declarations": 0,
|
|
42
|
+
"@typescript-eslint/max-params": 0,
|
|
43
|
+
"@typescript-eslint/member-ordering": 0,
|
|
44
|
+
"@typescript-eslint/method-signature-style": 0,
|
|
45
|
+
"@typescript-eslint/naming-convention": [
|
|
46
|
+
0,
|
|
47
|
+
{
|
|
48
|
+
selector: `variable`,
|
|
49
|
+
format: [`strictCamelCase`, `StrictPascalCase`, `UPPER_CASE`],
|
|
50
|
+
leadingUnderscore: `allow`,
|
|
51
|
+
trailingUnderscore: `allow`,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
"@typescript-eslint/no-array-constructor": ERROR,
|
|
55
|
+
"@typescript-eslint/no-array-delete": ERROR,
|
|
56
|
+
"@typescript-eslint/no-base-to-string": ERROR,
|
|
57
|
+
"@typescript-eslint/no-confusing-non-null-assertion": ERROR,
|
|
58
|
+
"@typescript-eslint/no-confusing-void-expression": ERROR,
|
|
59
|
+
"@typescript-eslint/no-duplicate-enum-values": ERROR,
|
|
60
|
+
"@typescript-eslint/no-duplicate-type-constituents": ERROR,
|
|
61
|
+
"@typescript-eslint/no-dynamic-delete": ERROR,
|
|
62
|
+
"@typescript-eslint/no-empty-function": 0,
|
|
63
|
+
"@typescript-eslint/no-empty-interface": ERROR,
|
|
64
|
+
"@typescript-eslint/no-explicit-any": 0,
|
|
65
|
+
"@typescript-eslint/no-extra-non-null-assertion": ERROR,
|
|
66
|
+
"@typescript-eslint/no-extraneous-class": 0,
|
|
67
|
+
"@typescript-eslint/no-floating-promises": ERROR,
|
|
68
|
+
"@typescript-eslint/no-for-in-array": ERROR,
|
|
69
|
+
"@typescript-eslint/no-implied-eval": ERROR,
|
|
70
|
+
"@typescript-eslint/no-import-type-side-effects": ERROR,
|
|
71
|
+
"@typescript-eslint/no-inferrable-types": 0, // not compatible with isolatedDeclarations
|
|
72
|
+
"@typescript-eslint/no-invalid-void-type": 0, // void is good in unions sometimes?
|
|
73
|
+
"@typescript-eslint/no-loop-func": 0,
|
|
74
|
+
"@typescript-eslint/no-loss-of-precision": ERROR,
|
|
75
|
+
"@typescript-eslint/no-magic-numbers": 0,
|
|
76
|
+
"@typescript-eslint/no-meaningless-void-operator": ERROR,
|
|
77
|
+
"@typescript-eslint/no-misused-new": ERROR,
|
|
78
|
+
"@typescript-eslint/no-misused-promises": 0,
|
|
79
|
+
"@typescript-eslint/no-mixed-enums": ERROR,
|
|
80
|
+
"@typescript-eslint/no-namespace": 0,
|
|
81
|
+
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": ERROR,
|
|
82
|
+
"@typescript-eslint/no-non-null-asserted-optional-chain": ERROR,
|
|
83
|
+
"@typescript-eslint/no-non-null-assertion": 0,
|
|
84
|
+
"@typescript-eslint/no-redundant-type-constituents": ERROR,
|
|
85
|
+
"@typescript-eslint/no-require-imports": ERROR,
|
|
86
|
+
"@typescript-eslint/no-restricted-imports": 0,
|
|
87
|
+
"@typescript-eslint/no-shadow": ERROR,
|
|
88
|
+
"@typescript-eslint/no-this-alias": ERROR,
|
|
89
|
+
"@typescript-eslint/no-throw-literal": 0,
|
|
90
|
+
"@typescript-eslint/no-unnecessary-boolean-literal-compare": 0,
|
|
91
|
+
"@typescript-eslint/no-unnecessary-condition": 0,
|
|
92
|
+
"@typescript-eslint/no-unnecessary-qualifier": 0,
|
|
93
|
+
"@typescript-eslint/no-unnecessary-type-arguments": 0,
|
|
94
|
+
"@typescript-eslint/no-unnecessary-type-assertion": ERROR,
|
|
95
|
+
"@typescript-eslint/no-unnecessary-type-constraint": ERROR,
|
|
96
|
+
"@typescript-eslint/no-unnecessary-type-conversion": ERROR,
|
|
97
|
+
"@typescript-eslint/no-unsafe-argument": 0,
|
|
98
|
+
"@typescript-eslint/no-unsafe-assignment": 0,
|
|
99
|
+
"@typescript-eslint/no-unsafe-call": 0,
|
|
100
|
+
"@typescript-eslint/no-unsafe-member-access": 0,
|
|
101
|
+
"@typescript-eslint/no-unsafe-return": 0,
|
|
102
|
+
"@typescript-eslint/no-unsafe-unary-minus": ERROR,
|
|
103
|
+
"@typescript-eslint/no-unused-expressions": 0,
|
|
104
|
+
"@typescript-eslint/no-unused-vars": 0,
|
|
105
|
+
"@typescript-eslint/no-use-before-define": 0,
|
|
106
|
+
"@typescript-eslint/no-useless-constructor": ERROR,
|
|
107
|
+
"@typescript-eslint/no-useless-empty-export": ERROR,
|
|
108
|
+
"@typescript-eslint/no-var-requires": ERROR,
|
|
109
|
+
"@typescript-eslint/non-nullable-type-assertion-style": 0,
|
|
110
|
+
"@typescript-eslint/only-throw-error": ERROR,
|
|
111
|
+
"@typescript-eslint/parameter-properties": 0,
|
|
112
|
+
"@typescript-eslint/prefer-as-const": ERROR,
|
|
113
|
+
"@typescript-eslint/prefer-destructuring": 0,
|
|
114
|
+
"@typescript-eslint/prefer-enum-initializers": ERROR,
|
|
115
|
+
"@typescript-eslint/prefer-find": ERROR,
|
|
116
|
+
"@typescript-eslint/prefer-for-of": ERROR,
|
|
117
|
+
"@typescript-eslint/prefer-function-type": ERROR,
|
|
118
|
+
"@typescript-eslint/prefer-includes": ERROR,
|
|
119
|
+
"@typescript-eslint/prefer-literal-enum-member": ERROR,
|
|
120
|
+
"@typescript-eslint/prefer-namespace-keyword": ERROR,
|
|
121
|
+
"@typescript-eslint/prefer-nullish-coalescing": ERROR,
|
|
122
|
+
"@typescript-eslint/prefer-optional-chain": ERROR,
|
|
123
|
+
"@typescript-eslint/prefer-promise-reject-errors": 0,
|
|
124
|
+
"@typescript-eslint/prefer-readonly": 0,
|
|
125
|
+
"@typescript-eslint/prefer-readonly-parameter-types": 0,
|
|
126
|
+
"@typescript-eslint/prefer-reduce-type-parameter": 0,
|
|
127
|
+
"@typescript-eslint/prefer-regexp-exec": 0,
|
|
128
|
+
"@typescript-eslint/prefer-return-this-type": ERROR,
|
|
129
|
+
"@typescript-eslint/prefer-string-starts-ends-with": ERROR,
|
|
130
|
+
"@typescript-eslint/prefer-ts-expect-error": ERROR,
|
|
131
|
+
"@typescript-eslint/promise-function-async": 0,
|
|
132
|
+
"@typescript-eslint/require-array-sort-compare": 0,
|
|
133
|
+
"@typescript-eslint/require-await": ERROR,
|
|
134
|
+
"@typescript-eslint/restrict-plus-operands": ERROR,
|
|
135
|
+
"@typescript-eslint/restrict-template-expressions": ERROR,
|
|
136
|
+
"@typescript-eslint/return-await": ERROR,
|
|
137
|
+
"@typescript-eslint/sort-type-constituents": ERROR,
|
|
138
|
+
"@typescript-eslint/strict-boolean-expressions": 0,
|
|
139
|
+
"@typescript-eslint/switch-exhaustiveness-check": [
|
|
140
|
+
ERROR,
|
|
141
|
+
{ requireDefaultForNonUnion: true },
|
|
142
|
+
],
|
|
143
|
+
"@typescript-eslint/triple-slash-reference": ERROR,
|
|
144
|
+
"@typescript-eslint/typedef": 0,
|
|
145
|
+
"@typescript-eslint/unbound-method": 0,
|
|
146
|
+
"@typescript-eslint/unified-signatures": ERROR,
|
|
147
|
+
|
|
148
|
+
"atom.io/explicit-state-types": ERROR,
|
|
149
|
+
|
|
150
|
+
"import/newline-after-import": ERROR,
|
|
151
|
+
"import/no-duplicates": ERROR,
|
|
152
|
+
|
|
153
|
+
"simple-import-sort/imports": ERROR,
|
|
154
|
+
"simple-import-sort/exports": ERROR,
|
|
155
|
+
|
|
156
|
+
"no-mixed-spaces-and-tabs": 0,
|
|
157
|
+
"no-duplicate-imports": 0,
|
|
158
|
+
quotes: [ERROR, `backtick`],
|
|
159
|
+
} satisfies Linter.Config[`rules`]
|
|
160
|
+
|
|
161
|
+
const configs: Linter.Config[] = [
|
|
162
|
+
...PreactConfig,
|
|
163
|
+
{
|
|
164
|
+
ignores: [`**/dist/**`, `**/gen/**`, `**/node_modules/**`],
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
languageOptions: { parser, parserOptions },
|
|
168
|
+
files: [`**/*.ts{,x}`, `eslint.config.ts`],
|
|
169
|
+
plugins: {
|
|
170
|
+
"@typescript-eslint": TypeScriptPlugin,
|
|
171
|
+
"atom.io": AtomIOPlugin as ESLint.Plugin,
|
|
172
|
+
import: ImportPlugin,
|
|
173
|
+
"simple-import-sort": SimpleImportSortPlugin,
|
|
174
|
+
},
|
|
175
|
+
rules: commonRules,
|
|
176
|
+
},
|
|
177
|
+
]
|
|
178
|
+
|
|
179
|
+
export default configs
|
package/eslint.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// eslint-disable-next-line quotes
|
|
2
|
+
declare module "eslint-plugin-import-x" {
|
|
3
|
+
import type { ESLint } from "eslint"
|
|
4
|
+
|
|
5
|
+
const plugin: ESLint.Plugin
|
|
6
|
+
export = plugin
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line quotes
|
|
10
|
+
declare module "eslint-plugin-simple-import-sort" {
|
|
11
|
+
import type { ESLint } from "eslint"
|
|
12
|
+
|
|
13
|
+
const plugin: ESLint.Plugin
|
|
14
|
+
export = plugin
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// eslint-disable-next-line quotes
|
|
18
|
+
declare module "@typescript-eslint/eslint-plugin" {
|
|
19
|
+
import type { ESLint } from "eslint"
|
|
20
|
+
|
|
21
|
+
const plugin: ESLint.Plugin
|
|
22
|
+
export = plugin
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// eslint-disable-next-line quotes
|
|
26
|
+
declare module "eslint-config-preact" {
|
|
27
|
+
import type { Linter } from "eslint"
|
|
28
|
+
|
|
29
|
+
const configs: Linter.Config[]
|
|
30
|
+
export = configs
|
|
31
|
+
}
|
package/index.html
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<meta name="color-scheme" content="light dark" />
|
|
8
|
+
<title>Vite + Preact + Atom.io</title>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="app"></div>
|
|
12
|
+
<script type="module" src="/src/index.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atom.io/template-preact-svg-editor",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"type": "module",
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"preact": "10.27.2",
|
|
10
|
+
"react": "npm:@preact/compat@18.3.1",
|
|
11
|
+
"react-dom": "npm:@preact/compat@18.3.1",
|
|
12
|
+
"atom.io": "0.44.1"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@preact/preset-vite": "2.10.2",
|
|
16
|
+
"@typescript-eslint/eslint-plugin": "8.46.3",
|
|
17
|
+
"@typescript-eslint/parser": "8.46.3",
|
|
18
|
+
"eslint-config-preact": "2.0.0",
|
|
19
|
+
"eslint-plugin-import-x": "4.16.1",
|
|
20
|
+
"eslint-plugin-simple-import-sort": "12.1.1",
|
|
21
|
+
"vite": "7.1.12"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"dev": "vite",
|
|
25
|
+
"build": "vite build",
|
|
26
|
+
"preview": "vite preview"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="27.68" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 296">
|
|
2
|
+
<path fill="#673AB8" d="m128 0l128 73.9v147.8l-128 73.9L0 221.7V73.9z"></path>
|
|
3
|
+
<path fill="#FFF" d="M34.865 220.478c17.016 21.78 71.095 5.185 122.15-34.704c51.055-39.888 80.24-88.345 63.224-110.126c-17.017-21.78-71.095-5.184-122.15 34.704c-51.055 39.89-80.24 88.346-63.224 110.126Zm7.27-5.68c-5.644-7.222-3.178-21.402 7.573-39.253c11.322-18.797 30.541-39.548 54.06-57.923c23.52-18.375 48.303-32.004 69.281-38.442c19.922-6.113 34.277-5.075 39.92 2.148c5.644 7.223 3.178 21.403-7.573 39.254c-11.322 18.797-30.541 39.547-54.06 57.923c-23.52 18.375-48.304 32.004-69.281 38.441c-19.922 6.114-34.277 5.076-39.92-2.147Z"></path>
|
|
4
|
+
<path fill="#FFF" d="M220.239 220.478c17.017-21.78-12.169-70.237-63.224-110.126C105.96 70.464 51.88 53.868 34.865 75.648c-17.017 21.78 12.169 70.238 63.224 110.126c51.055 39.889 105.133 56.485 122.15 34.704Zm-7.27-5.68c-5.643 7.224-19.998 8.262-39.92 2.148c-20.978-6.437-45.761-20.066-69.28-38.441c-23.52-18.376-42.74-39.126-54.06-57.923c-10.752-17.851-13.218-32.03-7.575-39.254c5.644-7.223 19.999-8.261 39.92-2.148c20.978 6.438 45.762 20.067 69.281 38.442c23.52 18.375 42.739 39.126 54.06 57.923c10.752 17.85 13.218 32.03 7.574 39.254Z"></path>
|
|
5
|
+
<path fill="#FFF" d="M127.552 167.667c10.827 0 19.603-8.777 19.603-19.604c0-10.826-8.776-19.603-19.603-19.603c-10.827 0-19.604 8.777-19.604 19.603c0 10.827 8.777 19.604 19.604 19.604Z"></path>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import type { Loadable, RegularAtomToken } from "atom.io"
|
|
2
|
+
import {
|
|
3
|
+
atom,
|
|
4
|
+
atomFamily,
|
|
5
|
+
getState,
|
|
6
|
+
resetState,
|
|
7
|
+
runTransaction,
|
|
8
|
+
selectorFamily,
|
|
9
|
+
setState,
|
|
10
|
+
transaction,
|
|
11
|
+
} from "atom.io"
|
|
12
|
+
import { useO } from "atom.io/react"
|
|
13
|
+
import type { PointerEventHandler, TargetedPointerEvent, VNode } from "preact"
|
|
14
|
+
import type { MutableRef } from "preact/hooks"
|
|
15
|
+
import { useCallback, useEffect, useRef } from "preact/hooks"
|
|
16
|
+
|
|
17
|
+
type PointXY = { x: number; y: number }
|
|
18
|
+
type EdgeXY = { c?: PointXY; s: PointXY }
|
|
19
|
+
|
|
20
|
+
const pathKeysAtom = atom<string[]>({
|
|
21
|
+
key: `pathKeys`,
|
|
22
|
+
default: [],
|
|
23
|
+
})
|
|
24
|
+
const subpathKeysAtoms = atomFamily<string[], string>({
|
|
25
|
+
key: `subpathKeys`,
|
|
26
|
+
default: [],
|
|
27
|
+
})
|
|
28
|
+
const nodeAtoms = atomFamily<PointXY | null, string>({
|
|
29
|
+
key: `nodeAtoms`,
|
|
30
|
+
default: null,
|
|
31
|
+
})
|
|
32
|
+
const edgeAtoms = atomFamily<EdgeXY | boolean, string>({
|
|
33
|
+
key: `edgeAtoms`,
|
|
34
|
+
default: true,
|
|
35
|
+
})
|
|
36
|
+
const pathDrawSelectors = selectorFamily<string, string>({
|
|
37
|
+
key: `pathDrawSelectors`,
|
|
38
|
+
get:
|
|
39
|
+
(pathKey) =>
|
|
40
|
+
({ get }) => {
|
|
41
|
+
const subpathKeys = get(subpathKeysAtoms, pathKey)
|
|
42
|
+
return subpathKeys
|
|
43
|
+
.map((subpathKey, idx) => {
|
|
44
|
+
const node = get(nodeAtoms, subpathKey)
|
|
45
|
+
const edge = get(edgeAtoms, subpathKey)
|
|
46
|
+
|
|
47
|
+
if (node === null) {
|
|
48
|
+
return `Z`
|
|
49
|
+
}
|
|
50
|
+
if (idx === 0) {
|
|
51
|
+
return `M ${node.x} ${node.y}`
|
|
52
|
+
}
|
|
53
|
+
if (edge === false) {
|
|
54
|
+
return `M ${node.x} ${node.y}`
|
|
55
|
+
}
|
|
56
|
+
if (edge === true) {
|
|
57
|
+
return `L ${node.x} ${node.y}`
|
|
58
|
+
}
|
|
59
|
+
if (`c` in edge) {
|
|
60
|
+
return `C ${edge.c.x} ${edge.c.y} ${edge.s.x} ${edge.s.y} ${node.x} ${node.y}`
|
|
61
|
+
}
|
|
62
|
+
return `S ${edge.s.x} ${edge.s.y} ${node.x} ${node.y}`
|
|
63
|
+
})
|
|
64
|
+
.join(` `)
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
export function useAtomicRef<T>(
|
|
69
|
+
token: RegularAtomToken<T | null>,
|
|
70
|
+
): MutableRef<T | null> {
|
|
71
|
+
const ref = useRef<T | null>(null)
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
setState(token, ref.current)
|
|
74
|
+
}, [token])
|
|
75
|
+
return ref
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function clamp(n: number, min: number, max: number) {
|
|
79
|
+
return Math.max(min, Math.min(max, n))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function Bezier({
|
|
83
|
+
at,
|
|
84
|
+
subpathKey,
|
|
85
|
+
prevSubpathKey,
|
|
86
|
+
node: maybeNode,
|
|
87
|
+
}: {
|
|
88
|
+
at: PointXY
|
|
89
|
+
subpathKey: string
|
|
90
|
+
prevSubpathKey: string
|
|
91
|
+
node?: PointXY
|
|
92
|
+
}) {
|
|
93
|
+
let node: PointXY | null
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
95
|
+
switch (typeof maybeNode) {
|
|
96
|
+
case `undefined`:
|
|
97
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
98
|
+
node = useO(nodeAtoms, prevSubpathKey)
|
|
99
|
+
break
|
|
100
|
+
default:
|
|
101
|
+
node = maybeNode
|
|
102
|
+
}
|
|
103
|
+
return node === null ? null : (
|
|
104
|
+
<>
|
|
105
|
+
<line
|
|
106
|
+
class="bezier"
|
|
107
|
+
x1={node.x}
|
|
108
|
+
y1={node.y}
|
|
109
|
+
x2={at.x}
|
|
110
|
+
y2={at.y}
|
|
111
|
+
stroke="#777"
|
|
112
|
+
stroke-width={1}
|
|
113
|
+
/>
|
|
114
|
+
<circle
|
|
115
|
+
class="bezier"
|
|
116
|
+
fill="#777"
|
|
117
|
+
stroke="#aaa"
|
|
118
|
+
stroke-width={1}
|
|
119
|
+
cx={at.x}
|
|
120
|
+
cy={at.y}
|
|
121
|
+
r={2}
|
|
122
|
+
/>
|
|
123
|
+
<circle
|
|
124
|
+
class="bezier-draggable"
|
|
125
|
+
fill="transparent"
|
|
126
|
+
cx={at.x}
|
|
127
|
+
cy={at.y}
|
|
128
|
+
r={6}
|
|
129
|
+
onPointerDown={(evt) => {
|
|
130
|
+
evt.currentTarget.setPointerCapture(evt.pointerId)
|
|
131
|
+
setState(currentlyDraggingAtom, {
|
|
132
|
+
key: subpathKey,
|
|
133
|
+
by: !maybeNode ? `c` : `s`,
|
|
134
|
+
})
|
|
135
|
+
}}
|
|
136
|
+
/>
|
|
137
|
+
</>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function Node({
|
|
142
|
+
subpathKey,
|
|
143
|
+
nextSubpathKey,
|
|
144
|
+
}: {
|
|
145
|
+
subpathKey: string
|
|
146
|
+
nextSubpathKey: string
|
|
147
|
+
}) {
|
|
148
|
+
const node = useO(nodeAtoms, subpathKey)
|
|
149
|
+
const edge = useO(edgeAtoms, subpathKey)
|
|
150
|
+
return node === null ? null : (
|
|
151
|
+
<>
|
|
152
|
+
{typeof edge === `boolean` ? (
|
|
153
|
+
<rect class="node" x={node.x - 3} y={node.y - 3} width={6} height={6} />
|
|
154
|
+
) : (
|
|
155
|
+
<>
|
|
156
|
+
<Bezier
|
|
157
|
+
at={edge.s}
|
|
158
|
+
node={node}
|
|
159
|
+
subpathKey={subpathKey}
|
|
160
|
+
prevSubpathKey={nextSubpathKey}
|
|
161
|
+
/>
|
|
162
|
+
{edge.c ? (
|
|
163
|
+
<Bezier
|
|
164
|
+
at={edge.c}
|
|
165
|
+
subpathKey={subpathKey}
|
|
166
|
+
prevSubpathKey={nextSubpathKey}
|
|
167
|
+
/>
|
|
168
|
+
) : null}
|
|
169
|
+
<circle class="node" cx={node.x} cy={node.y} r={3} />
|
|
170
|
+
</>
|
|
171
|
+
)}
|
|
172
|
+
<circle
|
|
173
|
+
class="node-draggable"
|
|
174
|
+
fill="transparent"
|
|
175
|
+
cx={node.x}
|
|
176
|
+
cy={node.y}
|
|
177
|
+
r={10}
|
|
178
|
+
onPointerDown={(evt) => {
|
|
179
|
+
evt.currentTarget.setPointerCapture(evt.pointerId)
|
|
180
|
+
setState(currentlyDraggingAtom, { key: subpathKey })
|
|
181
|
+
}}
|
|
182
|
+
/>
|
|
183
|
+
</>
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function RenderedPath({ pathKey }: { pathKey: string }) {
|
|
188
|
+
const draw = useO(pathDrawSelectors, pathKey)
|
|
189
|
+
return <path d={`${draw} Z`} class="path" style={{ pointerEvents: `none` }} />
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function Path({ pathKey }: { pathKey: string }) {
|
|
193
|
+
const subpathKeys = useO(subpathKeysAtoms, pathKey)
|
|
194
|
+
return (
|
|
195
|
+
<>
|
|
196
|
+
<RenderedPath pathKey={pathKey} />
|
|
197
|
+
{subpathKeys.toReversed().map((spk, idx, arr) => (
|
|
198
|
+
<Node
|
|
199
|
+
subpathKey={spk}
|
|
200
|
+
nextSubpathKey={arr[idx + 1] ?? arr[0]}
|
|
201
|
+
key={spk}
|
|
202
|
+
/>
|
|
203
|
+
))}
|
|
204
|
+
</>
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function PathsDemo() {
|
|
209
|
+
const pathKeys = useO(pathKeysAtom)
|
|
210
|
+
return (
|
|
211
|
+
<>
|
|
212
|
+
{pathKeys.map((pathKey) => {
|
|
213
|
+
return <Path pathKey={pathKey} key={pathKey} />
|
|
214
|
+
})}
|
|
215
|
+
</>
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const svgRefAtom = atom<SVGSVGElement | null>({
|
|
220
|
+
key: `svgRef`,
|
|
221
|
+
default: null,
|
|
222
|
+
})
|
|
223
|
+
const currentlyDraggingAtom = atom<{ key: string; by?: `c` | `s` } | null>({
|
|
224
|
+
key: `currentlyDragging`,
|
|
225
|
+
default: null,
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
function onPointerMove(evt: TargetedPointerEvent<SVGSVGElement>): void {
|
|
229
|
+
evt.preventDefault()
|
|
230
|
+
const { key: currentlyDragging, by: draggingBy } =
|
|
231
|
+
getState(currentlyDraggingAtom) ?? {}
|
|
232
|
+
const svg = getState(svgRefAtom)
|
|
233
|
+
if (!svg || !currentlyDragging) {
|
|
234
|
+
return
|
|
235
|
+
}
|
|
236
|
+
const pt = svg.createSVGPoint()
|
|
237
|
+
pt.x = evt.clientX
|
|
238
|
+
pt.y = evt.clientY
|
|
239
|
+
const ctm = svg.getScreenCTM()?.inverse()
|
|
240
|
+
const { x, y } = pt.matrixTransform(ctm)
|
|
241
|
+
|
|
242
|
+
switch (draggingBy) {
|
|
243
|
+
case undefined:
|
|
244
|
+
setState(nodeAtoms, currentlyDragging, {
|
|
245
|
+
x: clamp(x, -185, WIDTH + 185),
|
|
246
|
+
y: clamp(y, -10, HEIGHT + 10),
|
|
247
|
+
})
|
|
248
|
+
break
|
|
249
|
+
case `s`:
|
|
250
|
+
setState(edgeAtoms, currentlyDragging, (prev) => ({
|
|
251
|
+
...(prev as EdgeXY),
|
|
252
|
+
s: { x: clamp(x, -185, WIDTH + 185), y: clamp(y, -10, HEIGHT + 10) },
|
|
253
|
+
}))
|
|
254
|
+
break
|
|
255
|
+
case `c`:
|
|
256
|
+
setState(edgeAtoms, currentlyDragging, (prev) => ({
|
|
257
|
+
...(prev as EdgeXY),
|
|
258
|
+
c: { x: clamp(x, -185, WIDTH + 185), y: clamp(y, -10, HEIGHT + 10) },
|
|
259
|
+
}))
|
|
260
|
+
break
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const CODES = [`m`, `M`, `l`, `L`, `c`, `C`, `v`, `V`, `z`, `Z`] as const
|
|
265
|
+
|
|
266
|
+
const preactLogoAtom = atom<Loadable<string>>({
|
|
267
|
+
key: `preactLogo`,
|
|
268
|
+
default: () => fetch(`preact.svg`).then((res) => res.text()),
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
const resetTX = transaction<() => Promise<void>>({
|
|
272
|
+
key: `reset`,
|
|
273
|
+
do: async () => {
|
|
274
|
+
const logo = await getState(preactLogoAtom)
|
|
275
|
+
for (const pathKey of getState(pathKeysAtom)) {
|
|
276
|
+
resetState(subpathKeysAtoms, pathKey)
|
|
277
|
+
}
|
|
278
|
+
resetState(pathKeysAtom)
|
|
279
|
+
|
|
280
|
+
const shapes = logo
|
|
281
|
+
.split(`\n`)
|
|
282
|
+
.filter((line) => line.startsWith(`\t<path`))
|
|
283
|
+
.map((line) => {
|
|
284
|
+
const raw = line.split(`d="`)[1].slice(0, -9)
|
|
285
|
+
|
|
286
|
+
type Letter = (typeof CODES)[number]
|
|
287
|
+
let letter: Letter | undefined
|
|
288
|
+
let number = ``
|
|
289
|
+
let numbers: number[] = []
|
|
290
|
+
|
|
291
|
+
const instructions: { letter: Letter; numbers: number[] }[] = []
|
|
292
|
+
for (const c of raw) {
|
|
293
|
+
if (CODES.includes(c as Letter)) {
|
|
294
|
+
if (number) {
|
|
295
|
+
numbers.push(Number.parseFloat(number))
|
|
296
|
+
number = ``
|
|
297
|
+
}
|
|
298
|
+
if (letter) {
|
|
299
|
+
instructions.push({ letter, numbers })
|
|
300
|
+
}
|
|
301
|
+
letter = c as Letter
|
|
302
|
+
numbers = []
|
|
303
|
+
continue
|
|
304
|
+
}
|
|
305
|
+
if (c === ` `) {
|
|
306
|
+
numbers.push(Number.parseFloat(number))
|
|
307
|
+
number = ``
|
|
308
|
+
continue
|
|
309
|
+
}
|
|
310
|
+
if (c === `-` && number) {
|
|
311
|
+
numbers.push(Number.parseFloat(number))
|
|
312
|
+
number = `-`
|
|
313
|
+
continue
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
number += c
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let prev: PointXY = { x: 0, y: 0 }
|
|
320
|
+
const edgeNodes = instructions.map<{
|
|
321
|
+
node: PointXY | null
|
|
322
|
+
edge: boolean | { c?: PointXY; s: PointXY }
|
|
323
|
+
}>(({ letter: l, numbers: ns }) => {
|
|
324
|
+
let node: PointXY | null
|
|
325
|
+
let edge: boolean | { c?: PointXY; s: PointXY }
|
|
326
|
+
switch (l) {
|
|
327
|
+
case `m`:
|
|
328
|
+
node = { x: prev.x + ns[0], y: prev.y + ns[1] }
|
|
329
|
+
edge = false
|
|
330
|
+
break
|
|
331
|
+
case `M`:
|
|
332
|
+
node = { x: ns[0], y: ns[1] }
|
|
333
|
+
edge = false
|
|
334
|
+
break
|
|
335
|
+
case `l`:
|
|
336
|
+
node = { x: prev.x + ns[0], y: prev.y + ns[1] }
|
|
337
|
+
edge = true
|
|
338
|
+
break
|
|
339
|
+
case `L`:
|
|
340
|
+
node = { x: ns[0], y: ns[1] }
|
|
341
|
+
edge = true
|
|
342
|
+
break
|
|
343
|
+
case `c`:
|
|
344
|
+
node = { x: prev.x + ns[4], y: prev.y + ns[5] }
|
|
345
|
+
edge = {
|
|
346
|
+
c: { x: prev.x + ns[0], y: prev.y + ns[1] },
|
|
347
|
+
s: { x: prev.x + ns[2], y: prev.y + ns[3] },
|
|
348
|
+
}
|
|
349
|
+
break
|
|
350
|
+
case `C`:
|
|
351
|
+
node = { x: ns[4], y: ns[5] }
|
|
352
|
+
edge = {
|
|
353
|
+
c: { x: ns[0], y: ns[1] },
|
|
354
|
+
s: { x: ns[2], y: ns[3] },
|
|
355
|
+
}
|
|
356
|
+
break
|
|
357
|
+
case `v`:
|
|
358
|
+
node = { x: prev.x, y: prev.y + ns[0] }
|
|
359
|
+
edge = true
|
|
360
|
+
break
|
|
361
|
+
case `V`:
|
|
362
|
+
node = { x: prev.x, y: ns[0] }
|
|
363
|
+
edge = true
|
|
364
|
+
break
|
|
365
|
+
case `z`:
|
|
366
|
+
case `Z`:
|
|
367
|
+
node = null
|
|
368
|
+
edge = true
|
|
369
|
+
}
|
|
370
|
+
if (node) {
|
|
371
|
+
prev = node
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return { node, edge }
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
return edgeNodes
|
|
378
|
+
})
|
|
379
|
+
|
|
380
|
+
let i = 0
|
|
381
|
+
let j = 0
|
|
382
|
+
for (const shape of shapes) {
|
|
383
|
+
const jj = j
|
|
384
|
+
for (const { node, edge } of shape) {
|
|
385
|
+
setState(edgeAtoms, `subpath${j}`, edge)
|
|
386
|
+
setState(nodeAtoms, `subpath${j}`, node)
|
|
387
|
+
j++
|
|
388
|
+
}
|
|
389
|
+
const numberOfNodes = j - jj
|
|
390
|
+
setState(
|
|
391
|
+
subpathKeysAtoms,
|
|
392
|
+
`path${i}`,
|
|
393
|
+
Array.from(
|
|
394
|
+
{ length: numberOfNodes },
|
|
395
|
+
(_, nodeNum) => `subpath${jj + nodeNum}`,
|
|
396
|
+
),
|
|
397
|
+
)
|
|
398
|
+
setState(pathKeysAtom, (prev) => [...prev, `path${i}`])
|
|
399
|
+
i++
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
})
|
|
403
|
+
const reset = runTransaction(resetTX)
|
|
404
|
+
|
|
405
|
+
const WIDTH = 256
|
|
406
|
+
const HEIGHT = 296
|
|
407
|
+
export default function BezierPlayground(): VNode {
|
|
408
|
+
const svgRef = useAtomicRef(svgRefAtom)
|
|
409
|
+
const onPointerUp: PointerEventHandler<SVGSVGElement> = useCallback((evt) => {
|
|
410
|
+
evt.currentTarget.releasePointerCapture(evt.pointerId)
|
|
411
|
+
setState(currentlyDraggingAtom, null)
|
|
412
|
+
}, [])
|
|
413
|
+
|
|
414
|
+
useEffect(() => void reset(), [])
|
|
415
|
+
|
|
416
|
+
return (
|
|
417
|
+
<div
|
|
418
|
+
style={{
|
|
419
|
+
display: `flex`,
|
|
420
|
+
flexFlow: `column`,
|
|
421
|
+
position: `relative`,
|
|
422
|
+
overflow: `hidden`,
|
|
423
|
+
maxWidth: `1280px`,
|
|
424
|
+
width: `100vw`,
|
|
425
|
+
alignItems: `center`,
|
|
426
|
+
}}
|
|
427
|
+
>
|
|
428
|
+
<svg
|
|
429
|
+
ref={svgRef}
|
|
430
|
+
viewBox={`-185 -15 ${WIDTH + 370} ${HEIGHT + 30}`}
|
|
431
|
+
width={1000}
|
|
432
|
+
height={500}
|
|
433
|
+
onPointerMove={onPointerMove}
|
|
434
|
+
onPointerUp={onPointerUp}
|
|
435
|
+
onPointerCancel={onPointerUp}
|
|
436
|
+
>
|
|
437
|
+
<title>Bezier Playground</title>
|
|
438
|
+
<defs>
|
|
439
|
+
<pattern id="grid" width="5" height="5" patternUnits="userSpaceOnUse">
|
|
440
|
+
<rect x="0" y="0" width=".5" height=".5" fill="none" stroke="#aaa" />
|
|
441
|
+
</pattern>
|
|
442
|
+
</defs>
|
|
443
|
+
<rect x={0} y={0} width={WIDTH} height={HEIGHT} fill="#aaa3" />
|
|
444
|
+
<rect
|
|
445
|
+
x={-185}
|
|
446
|
+
y={-10}
|
|
447
|
+
width={WIDTH + 370}
|
|
448
|
+
height={HEIGHT + 20}
|
|
449
|
+
fill="url(#grid)"
|
|
450
|
+
/>
|
|
451
|
+
<PathsDemo />
|
|
452
|
+
</svg>
|
|
453
|
+
<button type="button" class="flat" onClick={reset}>
|
|
454
|
+
Reset
|
|
455
|
+
</button>
|
|
456
|
+
</div>
|
|
457
|
+
)
|
|
458
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import "./style.css"
|
|
2
|
+
|
|
3
|
+
import type { VNode } from "preact"
|
|
4
|
+
import { render } from "preact"
|
|
5
|
+
|
|
6
|
+
import BezierPlayground from "./BezierPlayground.tsx"
|
|
7
|
+
|
|
8
|
+
export function App(): VNode {
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<h1>Atom.io in Preact on Vite</h1>
|
|
12
|
+
<main>
|
|
13
|
+
<BezierPlayground />
|
|
14
|
+
<article>
|
|
15
|
+
<Resource
|
|
16
|
+
title="Learn Atom.io"
|
|
17
|
+
description="Atom.io is where data lives."
|
|
18
|
+
href="https://atom.io.fyi/docs/getting-started"
|
|
19
|
+
/>
|
|
20
|
+
<Resource
|
|
21
|
+
title="Learn Preact"
|
|
22
|
+
description="If you're new to Preact, try the interactive tutorial to learn important concepts"
|
|
23
|
+
href="https://preactjs.com/tutorial"
|
|
24
|
+
/>
|
|
25
|
+
<Resource
|
|
26
|
+
title="Learn Vite"
|
|
27
|
+
description="To learn more about Vite and how you can customize it to fit your needs, take a look at their excellent documentation"
|
|
28
|
+
href="https://vitejs.dev"
|
|
29
|
+
/>
|
|
30
|
+
</article>
|
|
31
|
+
</main>
|
|
32
|
+
</>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type ResourceProps = {
|
|
37
|
+
title: string
|
|
38
|
+
description: string
|
|
39
|
+
href: string
|
|
40
|
+
}
|
|
41
|
+
function Resource(props: ResourceProps) {
|
|
42
|
+
return (
|
|
43
|
+
<a href={props.href} target="_blank" class="resource" rel="noreferrer">
|
|
44
|
+
<h2>{props.title}</h2>
|
|
45
|
+
<p>{props.description}</p>
|
|
46
|
+
</a>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
render(<App />, document.getElementById(`app`)!)
|
package/src/msg.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Great question — the `d` attribute in an SVG `<path>` element is one of the most powerful but also most cryptic parts of SVG. It defines the shape of the path by listing a series of **commands** and **parameters**. Let’s break it down step by step so you can confidently read (and write) it.
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## 🧭 1. What the `d` Attribute Is
|
|
6
|
+
|
|
7
|
+
The `d` attribute contains **a mini language** consisting of:
|
|
8
|
+
|
|
9
|
+
- Single-letter commands (e.g. `M`, `L`, `C`, `Z`)
|
|
10
|
+
- A series of numbers following those commands (coordinates or parameters)
|
|
11
|
+
- Optional spaces and commas
|
|
12
|
+
|
|
13
|
+
For example:
|
|
14
|
+
|
|
15
|
+
```svg
|
|
16
|
+
<path d="M10 10 L50 50 L90 10 Z" />
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This draws a triangle:
|
|
20
|
+
|
|
21
|
+
1. Move to `(10,10)`
|
|
22
|
+
2. Draw a line to `(50,50)`
|
|
23
|
+
3. Draw a line to `(90,10)`
|
|
24
|
+
4. Close the shape
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ✍️ 2. Absolute vs Relative Commands
|
|
29
|
+
|
|
30
|
+
Each command can be:
|
|
31
|
+
|
|
32
|
+
- **Uppercase** → Absolute coordinates
|
|
33
|
+
- **Lowercase** → Relative coordinates (relative to the current point)
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
|
|
37
|
+
```svg
|
|
38
|
+
M 100 100 // Move to (100,100)
|
|
39
|
+
l 50 0 // Draw line relative +50 in x, +0 in y → ends at (150,100)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 🧱 3. Common Path Commands
|
|
45
|
+
|
|
46
|
+
| Command | Name | Parameters | What it does |
|
|
47
|
+
| --------- | ------------------- | --------------------------------------------------- | -------------------------------------------------------- |
|
|
48
|
+
| `M` / `m` | moveto | x y | Moves the “pen” to a new position without drawing |
|
|
49
|
+
| `L` / `l` | lineto | x y | Draws a straight line from current point to new point |
|
|
50
|
+
| `H` / `h` | horizontal lineto | x | Line horizontally (only x changes) |
|
|
51
|
+
| `V` / `v` | vertical lineto | y | Line vertically (only y changes) |
|
|
52
|
+
| `C` / `c` | cubic Bézier curve | x1 y1 x2 y2 x y | Curve with 2 control points and an endpoint |
|
|
53
|
+
| `S` / `s` | smooth cubic Bézier | x2 y2 x y | Like `C` but assumes first control point is a reflection |
|
|
54
|
+
| `Q` / `q` | quadratic Bézier | x1 y1 x y | Curve with 1 control point and an endpoint |
|
|
55
|
+
| `T` / `t` | smooth quadratic | x y | Like `Q` but auto-control point |
|
|
56
|
+
| `A` / `a` | elliptical arc | rx ry x-axis-rotation large-arc-flag sweep-flag x y | Draws an arc |
|
|
57
|
+
| `Z` / `z` | closepath | _(none)_ | Closes the path (line back to start) |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 🧮 4. How to Read a Complex Example
|
|
62
|
+
|
|
63
|
+
Here’s a more complex example:
|
|
64
|
+
|
|
65
|
+
```svg
|
|
66
|
+
<path d="M 100 100 C 100 50, 200 50, 200 100 S 300 150, 300 100 Z" />
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Let’s break it down:
|
|
70
|
+
|
|
71
|
+
1. `M 100 100` — move to `(100,100)`
|
|
72
|
+
2. `C 100 50, 200 50, 200 100` — draw cubic Bézier curve with control points `(100,50)` and `(200,50)`, endpoint `(200,100)`
|
|
73
|
+
3. `S 300 150, 300 100` — smooth curve, auto control point from previous, second control `(300,150)`, endpoint `(300,100)`
|
|
74
|
+
4. `Z` — close the path (draw a line back to `(100,100)`)
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🧠 5. Tips for Reading
|
|
79
|
+
|
|
80
|
+
- Think of the “pen” moving around.
|
|
81
|
+
- Break the path at each command letter.
|
|
82
|
+
- Translate relative commands (`l`, `c`, etc.) into absolute positions step by step if needed.
|
|
83
|
+
- Visualization tools like [SVG Path Editor](https://yqnn.github.io/svg-path-editor/) can help you see what’s happening interactively.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 🧰 6. Handy Shortcuts
|
|
88
|
+
|
|
89
|
+
- Repeating commands can omit the command letter.
|
|
90
|
+
|
|
91
|
+
```svg
|
|
92
|
+
M10 10 L20 20 30 10
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
is equivalent to:
|
|
96
|
+
|
|
97
|
+
```svg
|
|
98
|
+
M10 10 L20 20 L30 10
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- For curves (`C`, `S`, `Q`, `T`), the number of coordinates tells you how many segments there are.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
Would you like me to **deconstruct a specific `d` string** you have? (e.g. paste one and I’ll walk through it step by step.)
|
package/src/style.css
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--fg: #ccc;
|
|
3
|
+
--bg-shd1: #0e0e0e;
|
|
4
|
+
--bg: #1a1a1a;
|
|
5
|
+
--bg-tnt1: #262626;
|
|
6
|
+
--bg-tnt2: #444;
|
|
7
|
+
|
|
8
|
+
font-family: Charter, serif;
|
|
9
|
+
line-height: 1.5;
|
|
10
|
+
font-weight: 400;
|
|
11
|
+
|
|
12
|
+
color: var(--fg);
|
|
13
|
+
background: var(--bg);
|
|
14
|
+
|
|
15
|
+
font-synthesis: none;
|
|
16
|
+
text-rendering: optimizeLegibility;
|
|
17
|
+
-webkit-font-smoothing: antialiased;
|
|
18
|
+
-moz-osx-font-smoothing: grayscale;
|
|
19
|
+
-webkit-text-size-adjust: 100%;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@media (prefers-color-scheme: light) {
|
|
23
|
+
:root {
|
|
24
|
+
--fg: #222;
|
|
25
|
+
--bg-shd1: #e0e0e0;
|
|
26
|
+
--bg: #eee;
|
|
27
|
+
--bg-tnt1: #f3f3f3;
|
|
28
|
+
--bg-tnt2: #f6f6f6;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
body {
|
|
33
|
+
margin: 0;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-flow: column;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
min-height: 100vh;
|
|
39
|
+
width: 100vw;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#app {
|
|
43
|
+
text-align: center;
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-flow: column;
|
|
46
|
+
align-items: center;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
img {
|
|
50
|
+
margin-bottom: 1.5rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
img:hover {
|
|
54
|
+
filter: drop-shadow(0 0 2em #673ab8aa);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main {
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-flow: column;
|
|
60
|
+
align-items: center;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
article {
|
|
64
|
+
margin-top: 5rem;
|
|
65
|
+
padding: 0 2rem;
|
|
66
|
+
display: flex;
|
|
67
|
+
gap: 10px;
|
|
68
|
+
width: 100vw;
|
|
69
|
+
justify-content: center;
|
|
70
|
+
align-items: stretch;
|
|
71
|
+
max-width: 1280px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.resource {
|
|
75
|
+
padding: 0.75rem 1.5rem;
|
|
76
|
+
border-radius: 0.5rem;
|
|
77
|
+
text-align: left;
|
|
78
|
+
text-decoration: none;
|
|
79
|
+
color: var(--fg);
|
|
80
|
+
background: var(--bg-tnt1);
|
|
81
|
+
border: 1px solid transparent;
|
|
82
|
+
flex: 1;
|
|
83
|
+
&:hover {
|
|
84
|
+
background: var(--bg-tnt2);
|
|
85
|
+
border: 1px solid var(--fg);
|
|
86
|
+
box-shadow: 0 25px 50px -12px #673ab888;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.node {
|
|
91
|
+
fill: #673ab8;
|
|
92
|
+
stroke: #aaa;
|
|
93
|
+
}
|
|
94
|
+
.path {
|
|
95
|
+
fill: #aaa1;
|
|
96
|
+
stroke: #aaa;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@media (max-width: 639px) {
|
|
100
|
+
article {
|
|
101
|
+
flex-flow: column;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
button {
|
|
106
|
+
font-family: Verdana, sans-serif;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
button.flat {
|
|
110
|
+
color: var(--fg);
|
|
111
|
+
background: var(--bg);
|
|
112
|
+
border: 1px solid var(--fg);
|
|
113
|
+
height: 40px;
|
|
114
|
+
font-size: 20px;
|
|
115
|
+
position: absolute;
|
|
116
|
+
bottom: 10px;
|
|
117
|
+
right: 10px;
|
|
118
|
+
padding: 2px 10px 4px;
|
|
119
|
+
&:hover {
|
|
120
|
+
background: var(--bg-tnt1);
|
|
121
|
+
}
|
|
122
|
+
&:active {
|
|
123
|
+
background: var(--bg-shd1);
|
|
124
|
+
transform: scale(0.98);
|
|
125
|
+
}
|
|
126
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"noEmit": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"allowImportingTsExtensions": true,
|
|
9
|
+
"exactOptionalPropertyTypes": true,
|
|
10
|
+
|
|
11
|
+
/* Preact Config */
|
|
12
|
+
"jsx": "react-jsx",
|
|
13
|
+
"jsxImportSource": "preact",
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"paths": {
|
|
16
|
+
"react": ["./node_modules/preact/compat/"],
|
|
17
|
+
"react-dom": ["./node_modules/preact/compat/"]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"include": ["node_modules/vite/client.d.ts", "**/*", "eslint.d.ts"]
|
|
21
|
+
}
|
package/vite.config.ts
ADDED