commit 92c237f83d5dad4cbc54240e410c24de2248bd3b Author: Gogs Date: Mon Jun 8 23:26:12 2026 +0200 Initial Commit diff --git a/appinfo/info.xml b/appinfo/info.xml new file mode 100644 index 0000000..afc52da --- /dev/null +++ b/appinfo/info.xml @@ -0,0 +1,15 @@ + + + kicanvasviewer + KiCanvas Viewer + View KiCad files with KiCanvas + Opens KiCad schematic and PCB files using KiCanvas. + 0.1.0 + agpl + Herwig Birke + KiCanvasViewer + files + + + + diff --git a/appinfo/routes.php b/appinfo/routes.php new file mode 100644 index 0000000..59f455d --- /dev/null +++ b/appinfo/routes.php @@ -0,0 +1,21 @@ + [ + [ + 'name' => 'viewer#view', + 'url' => '/view/{fileId}', + 'verb' => 'GET', + ], + [ + 'name' => 'viewer#file', + 'url' => '/file/{fileId}/{name}', + 'verb' => 'GET', + ], + [ + 'name' => 'viewer#resolve', + 'url' => '/resolve/{etag}', + 'verb' => 'GET', + ], + ], +]; diff --git a/css/viewer.css b/css/viewer.css new file mode 100644 index 0000000..3f9fb0b --- /dev/null +++ b/css/viewer.css @@ -0,0 +1,60 @@ +@import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0"); +@import url("https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;500;600;700&display=swap"); + +*, +*::before, +*::after { + box-sizing: border-box; +} + +* { + margin: 0; +} + +html, +body { + height: 100vh; + font-family: + "Nunito", ui-rounded, "Hiragino Maru Gothic ProN", Quicksand, Comfortaa, + Manjari, "Arial Rounded MT Bold", Calibri, source-sans-pro, sans-serif; + line-height: 1.5; + width: 100%; + margin: 0 auto; +} + +img, +picture, +video, +canvas, +svg { + display: block; + max-width: 100%; +} + +main { + max-width: 1024px; + margin: 1rem auto; +} + +p { + margin-bottom: 1rem; + margin-top: 1rem; +} + +/* Styles for KiCanvas */ + +kicanvas-embed { + display: block; + width: 100%; + max-height: 100%; + aspect-ratio: 1.414; + background-color: aqua; + margin-bottom: 1rem; + margin-top: 1rem; +} + +kc-kicanvas-shell { + width: 100%; + height: 100vh; + overflow: hidden; +} diff --git a/img/github-mark-white.svg b/img/github-mark-white.svg new file mode 100644 index 0000000..28e741b --- /dev/null +++ b/img/github-mark-white.svg @@ -0,0 +1,5 @@ + + + diff --git a/img/kicanvas.png b/img/kicanvas.png new file mode 100644 index 0000000..73012f2 Binary files /dev/null and b/img/kicanvas.png differ diff --git a/js/kicanvas/kicanvas.js b/js/kicanvas/kicanvas.js new file mode 100644 index 0000000..69bea70 --- /dev/null +++ b/js/kicanvas/kicanvas.js @@ -0,0 +1,1991 @@ +var Ks=Object.defineProperty;var vn=Object.getOwnPropertyDescriptor;var c=(s,e)=>Ks(s,"name",{value:e,configurable:!0});var P=(s,e,t,r)=>{for(var i=r>1?void 0:r?vn(e,t):e,n=s.length-1,o;n>=0;n--)(o=s[n])&&(i=(r?o(e,t,i):o(i))||i);return r&&i&&Ks(e,t,i),i};function Re(s){window.setTimeout(()=>{s()},0)}c(Re,"later");var Ve=class{static{c(this,"DeferredPromise")}#e;#t;#r;#i;#s;constructor(){this.#e=new Promise((e,t)=>{this.#t=e,this.#r=t})}get rejected(){return this.#i===1}get resolved(){return this.#i===0}get settled(){return!!this.#i}get value(){return this.#s}then(e,t){return this.#e.then(e,t)}resolve(e){this.#i=0,this.#s=e,this.#t(e)}reject(e){this.#i=1,this.#s=e,this.#r(e)}},Pe=class extends Ve{static{c(this,"Barrier")}get isOpen(){return this.resolved&&this.value===!0}open(){this.resolve(!0)}};function pt(s){return s instanceof URL&&(s=s.pathname),s.split("/").slice(0,-1).join("/")}c(pt,"dirname");function we(s){return s instanceof URL&&(s=s.pathname),s.split("/").at(-1)}c(we,"basename");function s3(s){let e=s.split(".");return e.length<=1?"":e.at(-1)}c(s3,"extension");function We(...s){return s.flatMap(e=>e.split("/")).filter(e=>e!=="").join("/")}c(We,"normalize_join");function ve(s,e){if(s===e)return"";let t=We(s),r=t.length>0?t+"/":"";return e.startsWith(r)?e.slice(r.length):e}c(ve,"based_on");function Hs(s){let e,t;s instanceof File?(e=URL.createObjectURL(s),t=s.name):(e=s.href,t=we(e));let r=document.createElement("a");r.href=e,r.download=t,r.target="_blank",console.log(r),r.click(),s instanceof File&&URL.revokeObjectURL(e)}c(Hs,"initiate_download");var Qe=class s{static{c(this,"FileSystemBase")}constructor(e=new Map){this.entries=e}*list(){for(let[e,t]of this.entries)t.type==="file"&&(yield e)}async setup(){await this.walk("")}async get(e){if(!await this.has(e))throw new Error(`File ${e} not found`);return await this.load_file(e)}async has(e){let t=pt(e);if(!this.entries.has(t)&&!this.entries.has(e))return!1;await this.walk(t);let r=this.entries.get(e);return!!r&&r.type==="file"}async download(e){Hs(await this.get(e))}static is_kicad_file(e){return["kicad_pcb","kicad_pro","kicad_sch"].includes(s3(e))}async walk(e){if(this.entries.get(e)?.type==="visited-directory")return;let t=await this.enumerate(e);this.entries.set(e,{path:e,type:"visited-directory"});for(let r of t)r.type==="file"&&!s.is_kicad_file(r.path)||this.entries.set(r.path,r)}},n3=class{static{c(this,"MergedFileSystem")}constructor(e){this.fs_list=e.filter(t=>t!==null)}*list(){for(let e of this.fs_list)yield*e.list()}async setup(){for(let e of this.fs_list)await e.setup()}async has(e){for(let t of this.fs_list)if(await t.has(e))return!0;return!1}async get(e){for(let t of this.fs_list)if(await t.has(e))return await t.get(e);throw new Error(`File ${e} not found`)}async download(e){for(let t of this.fs_list)if(await t.has(e))return await t.download(e);throw new Error(`File ${e} not found`)}},o3=class s extends Qe{constructor(t){super(s.into_entries(t));this.file_list=t}static{c(this,"LocalFileSystemBase")}async load_file(t){let r=this.file_list.get(t);if(!r)throw new Error(`File ${t} not found!`);return r}async enumerate(t){return[]}static into_entries(t){let r=new Map;for(let i of t.keys())r.set(i,{path:i,type:"file"});return r}},ut=class extends Qe{constructor(t,r=null){super();this.urls=new Map;this.resolver=r??this.#e;for(let i of t)this.#t(i)}static{c(this,"FetchFileSystem")}#e(t){return new URL(t,window.location.toString())}#t(t){if(typeof t=="string"){let r=this.urls.get(t);if(r)return r;{let i=this.resolver(t),n=we(i);return this.urls.set(n,i),i}}return t}async load_file(t){let r=this.#t(t);if(!r)throw new Error(`File ${t} not found!`);let i=new Request(r,{method:"GET"}),n=await fetch(i);if(!n.ok)throw new Error(`Unable to load ${r}: ${n.status} ${n.statusText}`);let o=await n.blob();return new File([o],t)}async enumerate(t){return Array.from(this.urls.keys()).map(r=>({path:r,type:"file"}))}},a3=class s extends o3{static{c(this,"DragAndDropFileSystem")}static async fromDataTransfer(e){let t=[];for(let l=0;l[ve(n,l),p]));return new s(o)}static lcp(e){if(e.length===0)return"";let t=e.map(n=>n.split("/").filter(Boolean).slice(0,-1)),r=t[0],i=r.length;for(let n of t.slice(1)){let o=0;for(;o{e.file(t,r)})}static async walk(e){let t=[];for(;e.length>0;){let r=e.pop();if(r.isFile)t.push(r);else if(r.isDirectory){let i=r.createReader();await new Promise((n,o)=>{i.readEntries(l=>{for(let p of l)p.isFile?t.push(p):p.isDirectory&&e.push(p);n(!0)},o)})}}return t}},ht=class extends o3{static{c(this,"LocalFileSystem")}constructor(e){super(new Map(e.map(t=>[t.name,t])))}};var l3=class{static{c(this,"DropTarget")}constructor(e,t){e.addEventListener("dragenter",r=>{r.preventDefault()},!1),e.addEventListener("dragover",r=>{r.dataTransfer&&(r.preventDefault(),r.dataTransfer.dropEffect="move")},!1),e.addEventListener("drop",async r=>{r.stopPropagation(),r.preventDefault();let i=r.dataTransfer;if(!i)return;let n=await a3.fromDataTransfer(i);t(n)},!1)}};var c3=class s{static{c(this,"FilePicker")}static async pick(e){let t=await s.open_picker();t.length>0&&await e(new ht(t))}static open_picker(){return new Promise(e=>{let t=document.createElement("input");t.type="file",t.style.display="none",t.multiple=!0,t.accept=".kicad_pcb,.kicad_pro,.kicad_sch",t.onchange=r=>{let i=r.target.files;i&&i.length>0?e(Array.from(i)):e([])},t.oncancel=()=>{e([])},t.click()})}};var R3=class s extends Event{constructor(t,r){super(s.type,{bubbles:!0,cancelable:!0,composed:!0});this.context_name=t;this._callback=r}static{c(this,"ContextRequestEvent")}static{this.type="context-request"}callback(t){this.stopPropagation(),this._callback(t)}};async function Gs(s,e){return new Promise(t=>{s.dispatchEvent(new R3(e,r=>{t(r)}))})}c(Gs,"requestContext");function Es(s,e,t){s.addEventListener(R3.type,r=>{let i=r;i.context_name==e&&i.callback(t)})}c(Es,"provideContext");async function Qn(s,e){return(await Gs(s,e))()}c(Qn,"requestLazyContext");async function Yn(s,e,t){Es(s,e,t)}c(Yn,"provideLazyContext");function Js(s){return class extends s{static{c(this,"WithContext")}constructor(...t){super(...t)}async requestContext(t){return await Gs(this,t)}provideContext(t,r){Es(this,t,r)}async requestLazyContext(t){return await Qn(this,t)}provideLazyContext(t,r){Yn(this,t,r)}}}c(Js,"WithContext");function br(s){return s===null||typeof s!="object"&&typeof s!="function"}c(br,"is_primitive");function E(s){return typeof s=="string"}c(E,"is_string");function le(s){return typeof s=="number"&&!isNaN(s)}c(le,"is_number");function t2(s){return Array.isArray(s)||typeof s?.[Symbol.iterator]=="function"}c(t2,"is_iterable");function r2(s){return Array.isArray(s)}c(r2,"is_array");function ks(s){return typeof s=="object"&&s!==null&&!Array.isArray(s)&&!(s instanceof RegExp)&&!(s instanceof Date)}c(ks,"is_object");var Is=new Map,Ze=class{constructor(e){this.css_string=e}static{c(this,"CSS")}get stylesheet(){let e=Is.get(this.css_string);return e==null&&(e=new CSSStyleSheet,e.replaceSync(this.css_string),Is.set(this.css_string,e)),e}};function y(s,...e){let t="";for(let r=0;rt instanceof CSSStyleSheet?t:t.stylesheet))}c(As,"adopt_styles");function p3(s){return r2(s)?s:[s]}c(p3,"as_array");function Cs(s){return r2(s)?s:t2(s)?Array.from(s):[s]}c(Cs,"iterable_as_array");var Kn=new Intl.Collator(void 0,{numeric:!0});function pe(s,e){return s.slice().sort((t,r)=>Kn.compare(e(t),e(r)))}c(pe,"sorted_by_numeric_strings");var dt=class{constructor(){this._disposables=new Set;this._is_disposed=!1}static{c(this,"Disposables")}add(e){if(this._is_disposed)throw new Error("Tried to add item to a DisposableStack that's already been disposed");return this._disposables.add(e),e}disposeAndRemove(e){e&&(e.dispose(),this._disposables.delete(e))}get isDisposed(){return this._is_disposed}dispose(){if(this._is_disposed){console.trace("dispose() called on an already disposed resource");return}for(let e of this._disposables.values())e.dispose();this._disposables.clear(),this._is_disposed=!0}};function Hn(s){return typeof HTMLElement=="object"&&s instanceof HTMLElement}c(Hn,"is_HTMLElement");function f(s,...e){let t=document.createElement("template");t.innerHTML=Gn(s,e);let r=t.content;return r=document.importNode(r,!0),En(r,e),r.childElementCount==1?r.firstElementChild:r}c(f,"html");var fr=class{constructor(e){this.text=e}static{c(this,"Literal")}},Mr=/\$\$:(\d+):\$\$/g;function Gn(s,e){let t=[];for(let i=0;i or + ${this.canvas}`}};P([L({type:Boolean})],Ue.prototype,"loaded",2),P([L({type:String})],Ue.prototype,"theme",2),P([L({type:Boolean})],Ue.prototype,"disableinteraction",2);var is=class extends N{static{c(this,"KCContextMenuElement")}static{this.styles=[...N.styles,y` + :host { + position: fixed; + z-index: 1000; + display: none; + } + + :host([visible]) { + display: block; + } + + .menu { + background: var(--dropdown-bg); + border-radius: 5px; + overflow: hidden; + min-width: 150px; + max-width: 300px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + } + + .menu-item { + display: block; + padding: 0.4em 0.8em; + cursor: pointer; + color: var(--dropdown-fg); + user-select: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .menu-item:hover { + background: var(--dropdown-hover-bg); + color: var(--dropdown-hover-fg); + } + `]}#e=null;#t=null;#r=null;#i=null;show(e,t,r,i){this.#e=r,this.#t=i,this.style.left=`${e}px`,this.style.top=`${t}px`,this.setAttribute("visible",""),requestAnimationFrame(()=>{this.updateMenuItems(),this.adjustPosition(),this.setupDismissListeners()})}hide(){this.removeAttribute("visible"),this.#e=null,this.#t=null,this.removeDismissListeners()}updateMenuItems(){let e=this.shadowRoot?.querySelector(".menu");e&&(e.innerHTML="",this.#e?.forEach((t,r)=>{let i=document.createElement("div");i.className="menu-item",i.textContent=r,e.appendChild(i)}))}adjustPosition(){let e=this.getBoundingClientRect(),t=window.innerWidth,r=window.innerHeight,i=parseFloat(this.style.left),n=parseFloat(this.style.top);i+e.width>t&&(i=t-e.width-10),n+e.height>r&&(n=r-e.height-10),this.style.left=`${Math.max(10,i)}px`,this.style.top=`${Math.max(10,n)}px`}setupDismissListeners(){this.removeDismissListeners(),this.#r=e=>{let t=this.getBoundingClientRect();e.clientX>=t.left&&e.clientX<=t.right&&e.clientY>=t.top&&e.clientY<=t.bottom||this.hide()},this.#i=()=>this.hide(),setTimeout(()=>{this.#r&&document.addEventListener("pointerdown",this.#r),this.#i&&(window.addEventListener("resize",this.#i),window.addEventListener("scroll",this.#i,!0))},100)}removeDismissListeners(){this.#r&&(document.removeEventListener("pointerdown",this.#r),this.#r=null),this.#i&&(window.removeEventListener("resize",this.#i),window.removeEventListener("scroll",this.#i,!0),this.#i=null)}initialContentCallback(){super.initialContentCallback(),this.shadowRoot?.addEventListener("click",e=>{let t=e.target;t.classList.contains("menu-item")&&this.#e&&(this.#t&&this.#t(this.#e.get(t.textContent??"")),this.hide())})}render(){return f``}};window.customElements.define("kc-context-menu",is);var $2=class extends Ue{static{c(this,"KCBoardViewerElement")}#e=null;update_theme(){this.viewer.theme=this.themeObject.board}make_viewer(){let e=new tr(this.canvas,!this.disableinteraction,this.themeObject.board);return e.contextMenuCallback=(t,r,i,n)=>{this.#e&&this.#e.show(t,r,i,n)},e}render(){return this.canvas=f``,this.#e=f``,f` + ${this.canvas} ${this.#e}`}};window.customElements.define("kc-board-viewer",$2);var ss=class extends N{static{c(this,"KCHelpPanel")}static{this.styles=[...N.styles,y` + p { + margin: 0; + padding: 0.5em; + } + + a { + color: var(--button-bg); + } + + a:hover { + color: var(--button-hover-bg); + } + `]}render(){return f` + + + +

+ You're using + KiCanvas, an + interactive, browser-based viewer for KiCad schematics + and boards. +

+

+ KiCanvas is very much in alpha, so + please + file an issue on GitHub + if you run into any bugs. +

+

+ KiCanvas is developed by + Thea Flowers + and supported by + community donations. +

+
+ `}};window.customElements.define("kc-help-panel",ss);var z2=ce.INSTANCE,rr=class extends N{static{c(this,"KCPreferencesPanel")}static{this.styles=[...N.styles,y` + select { + box-sizing: border-box; + display: block; + width: 100%; + max-width: 100%; + margin-top: 0.25em; + font-family: inherit; + font-size: inherit; + font-weight: 300; + margin-top: 0.25em; + border-radius: 0.25em; + text-align: left; + padding: 0.25em; + background: var(--input-bg); + color: var(--input-fg); + border: var(--input-border); + transition: + color var(--transition-time-medium) ease, + box-shadow var(--transition-time-medium) ease, + outline var(--transition-time-medium) ease, + background var(--transition-time-medium) ease, + border var(--transition-time-medium) ease; + } + + select::after { + display: block; + content: "â–¾"; + color: var(--input-fg); + } + + select:hover { + z-index: 10; + box-shadow: var(--input-hover-shadow); + } + + select:focus { + z-index: 10; + box-shadow: none; + outline: var(--input-focus-outline); + } + `]}initialContentCallback(){this.renderRoot.addEventListener("input",e=>{let t=e.target;t.name==="theme"&&(z2.theme=Xe.by_name(this.theme_control.value)),t.name==="align-controls-kicad"&&(z2.alignControlsWithKiCad=t.checked),z2.save()})}render(){let e=Xe.list().map(t=>f``);return f` + + + + + + + + + + + + + + + `}};P([v("[name=theme]",!0)],rr.prototype,"theme_control",2);window.customElements.define("kc-preferences-panel",rr);var ir=class extends N{static{c(this,"KCProjectPanelElement")}static{this.styles=[...N.styles,y` + .page { + display: flex; + align-items: center; + } + + .page span.name { + margin-right: 1em; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + + .page span.filename { + flex: 1; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + margin-left: 1em; + text-align: right; + color: #aaa; + } + + .page kc-ui-button { + margin-left: 0.5em; + } + + .page span.number { + flex: 0; + background: var(--dropdown-hover-bg); + border: 1px solid transparent; + border-radius: 0.5em; + font-size: 0.8em; + padding: 0px 0.3em; + margin-right: 0.5em; + } + + kc-ui-menu-item:hover span.number { + background: var(--dropdown-bg); + } + + kc-ui-menu-item[selected]:hover span.number { + background: var(--dropdown-hover-bg); + } + `]}#e;connectedCallback(){(async()=>(this.project=await this.requestContext("project"),super.connectedCallback()))()}initialContentCallback(){super.initialContentCallback(),this.addDisposable(I(this.project,"load",e=>{this.update()})),this.addDisposable(I(this.project,"change",e=>{this.selected=this.project.active_page?.project_path??null})),this.addEventListener("kc-ui-menu:select",e=>{let t=e.detail;this.selected=t?.name??null,this.change_current_project_page(this.selected)}),ue(this.renderRoot,"kc-ui-button","click",(e,t)=>{let r=t.closest("kc-ui-menu-item");this.project.download(r.name)})}get selected(){return this.#e.selected?.name??null}set selected(e){this.#e.selected=e}change_current_project_page(e){this.project.set_active_page(e)}render(){let e=[];if(!this.project)return f``;for(let t of this.project.pages()){let r=t.type=="schematic"?"svg:schematic_file":"svg:pcb_file",i=t.page?f`${t.page}`:"";e.push(f` + + ${i} + + ${t.name??t.filename} + + + ${t.name&&t.name!==t.filename?t.filename:""} + + + + `)}return this.#e=f` + ${e} + `,f` + + ${this.#e} + `}};P([_t],ir.prototype,"change_current_project_page",1);window.customElements.define("kc-project-panel",ir);var ns=class extends N{static{c(this,"KCViewerBottomToolbarElement")}static{this.styles=[...N.styles,y` + output { + width: unset; + margin: unset; + padding: 0.5em; + color: var(--button-toolbar-fg); + background: var(--button-toolbar-bg); + border: 1px solid var(--button-toolbar-bg); + border-radius: 0.25em; + font-weight: 300; + font-size: 0.9em; + box-shadow: var(--input-hover-shadow); + user-select: none; + } + `]}#e;#t;#r;connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback(),this.addDisposable(this.viewer.addEventListener(Yt.type,()=>{this.update_position()})),this.addDisposable(this.viewer.addEventListener(z.type,e=>{this.#r.disabled=!e.detail.item})),this.#t.addEventListener("click",e=>{e.preventDefault(),this.viewer.zoom_to_page()}),this.#r.addEventListener("click",e=>{e.preventDefault(),this.viewer.zoom_to_selection()})))()}update_position(){let e=this.viewer.mouse_position;this.#e.value=`${e.x.toFixed(2)}, ${e.y.toFixed(2)} mm`}render(){return this.#e=f``,this.#t=f` + `,this.#r=f` + `,this.update_position(),f` + ${this.#e} ${this.#r} + ${this.#t} + `}};window.customElements.define("kc-viewer-bottom-toolbar",ns);var Fe=class extends N{constructor(){super();this.viewerReady=new Ve;this.provideLazyContext("viewer",()=>this.viewer)}static{c(this,"KCViewerAppElement")}#e;#t;get viewer(){return this.#e.viewer}connectedCallback(){this.hidden=!0,(async()=>(this.project=await this.requestContext("project"),await this.project.loaded,super.connectedCallback()))()}initialContentCallback(){this.project.active_page&&this.load(this.project.active_page),this.addDisposable(I(this.project,"change",async t=>{let r=this.project.active_page;r?await this.load(r):this.hidden=!0})),this.addDisposable(this.viewer.addEventListener(z.type,t=>{this.on_viewer_select(t.detail.item,t.detail.previous)})),ue(this.renderRoot,"kc-ui-button","click",t=>{switch(t.target.name){case"download":this.project.active_page&&this.project.download(this.project.active_page.filename);break;case"flip_view":this.#e.viewer.flip_view();break;default:console.warn("Unknown button",t)}})}async load(t){await this.viewerReady,this.can_load(t)?(await this.#e.load(t),this.hidden=!1):this.hidden=!0}#r(){return l2(this.project.pages())>1}make_pre_activities(){let t=[];return this.#r()&&t.push(f` + + `),t}make_post_activities(){return[f` + + `,f` + + `]}change_activity(t){this.#t?.change_activity(t)}render(){let t=this.controls??"none",r=un(this.controlslist??"",t=="none"?{fullscreen:!1,download:!1,flipview:!1}:{fullscreen:!0,download:!0,flipview:!0});this.#e=this.make_viewer_element(),this.#e.disableinteraction=t=="none";let i=null;if(t=="full"){let p=this.make_pre_activities(),u=this.make_post_activities(),m=this.make_activities();this.#t=f` + ${p} ${m} ${u} + `,i=f``}else this.#t=null;let n=[];r.download&&!this.#r()&&n.push(f` + `),r.flipview&&this.#e instanceof $2&&n.push(f` + `);let o=f` + ${n} + `,l=null;return t!="none"&&(l=f``),f` + + ${o} ${this.#e} ${l} + + ${i} ${this.#t} + `}renderedCallback(){window.requestAnimationFrame(()=>{this.viewerReady.resolve(!0)})}};P([L({type:String})],Fe.prototype,"controls",2),P([L({type:String})],Fe.prototype,"controlslist",2),P([L({type:Boolean})],Fe.prototype,"sidebarcollapsed",2);var Dt=class extends N{static{c(this,"KCBoardFootprintsPanelElement")}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,this.sort_footprints(),super.connectedCallback()))()}sort_footprints(){this.sorted_footprints=pe(this.viewer.board.footprints,e=>e.reference||"REF")}initialContentCallback(){this.addEventListener("kc-ui-menu:select",e=>{let t=e.detail;t.name&&this.viewer.select(t.name)}),this.addDisposable(this.viewer.addEventListener(z.type,()=>{this.menu.selected=this.viewer.selected?.context.uuid_text??null})),this.search_input_elm.addEventListener("input",e=>{this.item_filter_elem.filter_text=this.search_input_elm.value??null})}render(){return f` + + + + + + + ${this.render_list()} + + + + + `}render_list(){let e=[],t=[];for(let r of this.sorted_footprints){let i=r.reference||"REF",n=r.value||"VAL",o=`${r.library_link} ${r.descr} ${r.layer} ${i} ${n} ${r.tags}`,l=f` + ${i}${n} + `;r.layer=="F.Cu"?e.push(l):t.push(l)}return f`Front + ${e} + Back + ${t}`}};P([v("kc-ui-menu",!0)],Dt.prototype,"menu",2),P([v("kc-ui-text-filter-input",!0)],Dt.prototype,"search_input_elm",2),P([v("kc-ui-filtered-list",!0)],Dt.prototype,"item_filter_elem",2);window.customElements.define("kc-board-footprints-panel",Dt);var os=class extends N{static{c(this,"KCBoardInfoPanelElement")}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback()))()}render(){let e=this.viewer.drawing_sheet,t=this.viewer.board,r=t.edge_cuts_bbox,i=c(l=>f``,"header"),n=c((l,p,u="")=>f` + ${p} ${u} + `,"entry"),o=Object.entries(t.title_block?.comment||{}).map(([l,p])=>n(`Comment ${l}`,p));return f` + + + + + ${i("Page properties")} + ${n("Size",e.paper?.size)} + ${n("Width",e.width,"mm")} + ${n("Height",e.height,"mm")} + ${i("Board properties")} + ${n("KiCad version",t.version)} + ${n("Generator",t.generator)} + ${n("Thickness",t.general?.thickness??1.6,"mm")} + ${n("Title",t.title_block?.title)} + ${n("Date",t.title_block?.date)} + ${n("Revision",t.title_block?.rev)} + ${n("Company",t.title_block?.company)} + ${o} + ${n("Dimensions",`${r.w.toFixed(1)} x + ${r.h.toFixed(1)} mm`)} + ${n("Footprints",t.footprints.length)} + ${n("Nets",t.nets.length)} + ${n("Track segments",t.segments.length)} + ${n("Vias",t.vias.length)} + ${n("Zones",t.zones.length)} + ${n("Pad to mask clearance",t.setup?.pad_to_mask_clearance??0,"mm")} + ${n("Soldermask min width",t.setup?.solder_mask_min_width??0,"mm")} + ${n("Pad to paste clearance",t.setup?.pad_to_paste_clearance??0,"mm")} + ${n("Pad to paste clearance ratio",t.setup?.pad_to_paste_clearance_ratio??0)} + ${n("Grid origin",`${t.setup?.grid_origin?.x??0}, ${t.setup?.grid_origin?.y??0}`)} + + + + `}};window.customElements.define("kc-board-info-panel",os);var q2=class extends N{static{c(this,"KCBoardLayersPanelElement")}static{this.styles=[...N.styles,y` + :host { + display: block; + height: 100%; + overflow-y: auto; + overflow-x: hidden; + user-select: none; + } + + kc-ui-panel-title button { + all: unset; + flex-shrink: 0; + margin-left: 1em; + color: white; + border: 0 none; + background: transparent; + padding: 0 0.25em 0 0.25em; + margin-right: -0.25em; + display: flex; + align-items: center; + } + `]}get items(){return Array.from(this.panel_body.querySelectorAll("kc-board-layer-control")??[])}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback()))()}initialContentCallback(){this.panel_body.addEventListener(e3.select_event,e=>{let t=e.detail;for(let i of this.items)i.layer_highlighted=!1;let r=this.viewer.layers.by_name(t.layer_name);r.highlighted?this.viewer.layers.highlight(null):(this.viewer.layers.highlight(r),r.visible=!0,t.layer_visible=!0,t.layer_highlighted=!0),this.viewer.draw()}),this.panel_body.addEventListener(e3.visibility_event,e=>{let t=e.detail,r=this.viewer.layers.by_name(t.layer_name);r.visible=!r.visible,t.layer_visible=r.visible,this.presets_menu.deselect(),this.viewer.draw()}),this.renderRoot.querySelector("button")?.addEventListener("click",e=>{e.stopPropagation();let t=this.viewer.layers.in_ui_order();if(this.items.some(r=>r.layer_visible))for(let r of t)r.visible=!1;else for(let r of t)r.visible=!0;this.viewer.draw(),this.presets_menu.deselect(),this.update_item_states()}),this.presets_menu.addEventListener("kc-ui-menu:select",e=>{let t=e.detail,r=this.viewer.layers.in_ui_order();switch(t.name){case"all":for(let i of r)i.visible=!0;break;case"front":for(let i of r)i.visible=i.name.startsWith("F.")||i.name=="Edge.Cuts";break;case"back":for(let i of r)i.visible=i.name.startsWith("B.")||i.name=="Edge.Cuts";break;case"copper":for(let i of r)i.visible=i.name.includes(".Cu")||i.name=="Edge.Cuts";break;case"outer-copper":for(let i of r)i.visible=i.name=="F.Cu"||i.name=="B.Cu"||i.name=="Edge.Cuts";break;case"inner-copper":for(let i of r)i.visible=i.name.includes(".Cu")&&!(i.name=="F.Cu"||i.name=="B.Cu")||i.name=="Edge.Cuts";break;case"drawings":for(let i of r)i.visible=!i.name.includes(".Cu")&&!i.name.includes(".Mask")&&!i.name.includes(".Paste")&&!i.name.includes(".Adhes")}this.viewer.draw(),this.update_item_states()})}update_item_states(){for(let e of this.items){let t=this.viewer.layers.by_name(e.layer_name);e.layer_visible=t?.visible??!1,e.layer_highlighted=t?.highlighted??!1}}render(){let e=this.viewer.layers,t=[];for(let r of e.in_ui_order()){let i=r.visible?"":void 0,n=r.color.to_css();t.push(f``)}return f` + + + + + + ${t} + Presets + + All + Front + Back + Copper + + Outer copper + + + Inner copper + + + Drawings + + + + + `}};P([v("kc-ui-panel-body",!0)],q2.prototype,"panel_body",2),P([v("#presets",!0)],q2.prototype,"presets_menu",2);var Be=class Be extends N{static{c(this,"KCBoardLayerControlElement")}static{this.styles=[...N.styles,y` + :host { + box-sizing: border-box; + padding: 0.1em 0.8em 0.1em 0.4em; + color: white; + text-align: left; + display: flex; + flex-direction: row; + width: 100%; + align-items: center; + } + + button { + all: unset; + cursor: pointer; + flex-shrink: 0; + margin-left: 1em; + color: white; + border: 0 none; + background: transparent; + padding: 0 0.25em 0 0.25em; + margin-right: -0.25em; + display: flex; + align-items: center; + } + + .color { + flex-shrink: 0; + display: block; + width: 1em; + height: 1em; + margin-right: 0.5em; + } + + .name { + display: block; + flex-grow: 1; + } + + .for-hidden { + color: #888; + } + + :host { + background: var(--list-item-disabled-bg); + color: var(--list-item-disabled-fg); + } + + :host(:hover) { + background: var(--list-item-hover-bg); + color: var(--list-item-hover-fg); + } + + :host(:hover) button { + color: var(--list-item-bg); + } + + :host(:hover) button:hover { + color: var(--list-item-fg); + } + + :host([layer-visible]) { + background: var(--list-item-bg); + color: var(--list-item-fg); + } + + :host([layer-highlighted]) { + background: var(--list-item-active-bg); + color: var(--list-item-active-fg); + } + + :host([layer-highlighted]:hover) button { + color: var(--list-item-fg); + } + + :host kc-ui-icon.for-visible, + :host([layer-visible]) kc-ui-icon.for-hidden { + display: none; + } + + :host kc-ui-icon.for-hidden, + :host([layer-visible]) kc-ui-icon.for-visible { + display: revert; + } + `]}static{this.select_event="kicanvas:layer-control:select"}static{this.visibility_event="kicanvas:layer-control:visibility"}initialContentCallback(){super.initialContentCallback(),this.renderRoot.addEventListener("click",e=>{e.stopPropagation();let t=e.target?.closest("button"),r;t?r=Be.visibility_event:r=Be.select_event,this.dispatchEvent(new CustomEvent(r,{detail:this,bubbles:!0}))})}render(){return f` + ${this.layer_name} + `}};P([L({type:String})],Be.prototype,"layer_name",2),P([L({type:String})],Be.prototype,"layer_color",2),P([L({type:Boolean})],Be.prototype,"layer_highlighted",2),P([L({type:Boolean})],Be.prototype,"layer_visible",2);var e3=Be;window.customElements.define("kc-board-layer-control",e3);window.customElements.define("kc-board-layers-panel",q2);var t3=class extends N{static{c(this,"KCBoardNetsPanelElement")}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback()))()}initialContentCallback(){this.addEventListener("kc-ui-menu:select",e=>{let t=e.detail,r=parseInt(t?.name,10);r&&this.viewer.highlight_net(r)}),this.search_input_elm.addEventListener("input",e=>{this.item_filter_elem.filter_text=this.search_input_elm.value??null})}render(){let e=this.viewer.board,t=[];for(let r of e.nets)t.push(f` + ${r.number} + ${r.name} + `);return f` + + + + + + ${t} + + + + `}};P([v("kc-ui-text-filter-input",!0)],t3.prototype,"search_input_elm",2),P([v("kc-ui-filtered-list",!0)],t3.prototype,"item_filter_elem",2);window.customElements.define("kc-board-nets-panel",t3);var as=class extends N{static{c(this,"KCBoardObjectsPanelElement")}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback(),this.setup_events()))()}setup_events(){ue(this.renderRoot,"kc-ui-range","kc-ui-range:input",e=>{let t=e.target,r=t.valueAsNumber;switch(t.name){case"tracks":this.viewer.track_opacity=r;break;case"vias":this.viewer.via_opacity=r;break;case"pads":this.viewer.pad_opacity=r;break;case"holes":this.viewer.pad_hole_opacity=r;break;case"zones":this.viewer.zone_opacity=r;break;case"grid":this.viewer.grid_opacity=r;break;case"page":this.viewer.page_opacity=r;break}})}render(){return f` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `}};window.customElements.define("kc-board-objects-panel",as);var ls=class extends N{static{c(this,"KCBoardPropertiesPanelElement")}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback(),this.setup_events()))()}setup_events(){this.addDisposable(this.viewer.addEventListener(z.type,e=>{this.selected_item=e.detail.item,this.update()}))}render(){let e=c(n=>f` + `,"header"),t=c((n,o,l="")=>f` + ${o??""} ${l} + `,"entry"),r=c(n=>n?f`check`:f`close`,"checkbox"),i;if(!this.selected_item)i=e("No item selected");else{let n=this.selected_item,o=Object.entries(n.properties).map(([l,p])=>t(l,p.value));i=f` + ${e("Basic properties")} + ${t("X",n.at.position.x.toFixed(4),"mm")} + ${t("Y",n.at.position.y.toFixed(4),"mm")} + ${t("Orientation",n.at.rotation,"\xB0")} + ${t("Layer",n.layer)} ${e("Footprint properties")} + ${t("Reference",n.reference)} + ${t("Value",n.value)} + ${t("Type",n.attr.through_hole?"through hole":n.attr.smd?"smd":"unspecified")} + ${t("Pads",n.pads.length)} + ${t("Library link",n.library_link)} + ${t("Description",n.descr)} + ${t("Keywords",n.tags)} ${o} + ${e("Fabrication attributes")} + ${t("Not in schematic",r(n.attr.board_only))} + ${t("Exclude from position files",r(n.attr.exclude_from_pos_files))} + ${t("Exclude from BOM",r(n.attr.exclude_from_bom))} + ${e("Overrides")} + ${t("Exempt from courtyard requirement",r(n.attr.allow_missing_courtyard))} + ${t("Clearance",n.clearance??0,"mm")} + ${t("Solderpaste margin",n.solder_paste_margin??0,"mm")} + ${t("Solderpaste margin ratio",n.solder_paste_ratio??0)} + ${t("Zone connection",n.zone_connect??"inherited")} + `}return f` + + + + ${i} + + + `}};window.customElements.define("kc-board-properties-panel",ls);var cs=class extends Fe{static{c(this,"KCBoardAppElement")}on_viewer_select(e,t){e&&e==t&&this.change_activity("properties")}can_load(e){return e.document instanceof de}make_viewer_element(){return f``}make_activities(){return[f` + + `,f` + + `,f` + + `,f` + + `,f` + + `,f` + + `]}};window.customElements.define("kc-board-app",cs);var sr=class extends ke{constructor(t){super(t);this.#e=[];this.state=new H2}static{c(this,"Canvas2DRenderer")}#e;#t;async setup(){let t=this.canvas.getContext("2d",{alpha:!1,desynchronized:!0});if(t==null)throw new Error("Unable to create Canvas2d context");this.ctx2d=t,this.update_canvas_size()}dispose(){this.ctx2d=void 0;for(let t of this.#e)t.dispose()}update_canvas_size(){let t=window.devicePixelRatio,r=this.canvas.getBoundingClientRect(),i=Math.round(r.width*t),n=Math.round(r.height*t);(this.canvas.width!=i||this.canvas.height!=n)&&(this.canvas.width=i,this.canvas.height=n)}clear_canvas(){this.update_canvas_size(),this.ctx2d.setTransform(),this.ctx2d.scale(window.devicePixelRatio,window.devicePixelRatio),this.ctx2d.fillStyle=this.background_color.to_css(),this.ctx2d.fillRect(0,0,this.canvas.width,this.canvas.height),this.ctx2d.lineCap="round",this.ctx2d.lineJoin="round"}start_layer(t){this.#t=new Rs(this,t)}end_layer(){if(!this.#t)throw new Error("No active layer");return this.#e.push(this.#t),this.#t=null,this.#e.at(-1)}arc(t,r,i,n,o,l){super.prep_arc(t,r,i,n,o,l)}circle(t,r,i){let n=super.prep_circle(t,r,i);if(!n.color||n.color.is_transparent_black)return;let o=n.color.to_css(),l=new Path2D;l.arc(n.center.x,n.center.y,n.radius,0,Math.PI*2),this.#t.commands.push(new Bt(l,o,null,0))}line(t,r,i){let n=super.prep_line(t,r,i);if(!n.color||n.color.is_transparent_black)return;let o=n.color.to_css(),l=new Path2D,p=!1;for(let u of n.points)p?l.lineTo(u.x,u.y):(l.moveTo(u.x,u.y),p=!0);this.#t.commands.push(new Bt(l,null,o,n.width))}polygon(t,r){let i=super.prep_polygon(t,r);if(!i.color||i.color.is_transparent_black)return;let n=i.color.to_css(),o=new Path2D,l=!1;for(let p of i.points)l?o.lineTo(p.x,p.y):(o.moveTo(p.x,p.y),l=!0);o.closePath(),this.#t.commands.push(new Bt(o,n,null,0))}get layers(){let t=this.#e;return{*[Symbol.iterator](){for(let r of t)yield r}}}remove_layer(t){let r=this.#e.indexOf(t);r!=-1&&this.#e.splice(r,1)}},Bt=class{constructor(e,t,r,i){this.path=e;this.fill=t;this.stroke=r;this.stroke_width=i;this.path_count=1}static{c(this,"DrawCommand")}render(e){e.fillStyle=this.fill??"black",e.strokeStyle=this.stroke??"black",e.lineWidth=this.stroke_width,this.fill&&e.fill(this.path),this.stroke&&e.stroke(this.path)}},Rs=class extends Ie{constructor(t,r,i=[]){super(t,r);this.renderer=t;this.name=r;this.commands=i}static{c(this,"Canvas2dRenderLayer")}dispose(){this.clear()}clear(){this.commands=[]}push_path(t,r,i,n){let o=this.commands.at(-1);o&&(o.path_count<20,o.fill==r&&o.stroke==i&&o.stroke_width==n)?(o.path.addPath(t),o.path_count++):this.commands.push(new Bt(t,r,i,n))}render(t,r,i=1){let n=this.renderer.ctx2d;if(!n)throw new Error("No CanvasRenderingContext2D!");n.save(),n.globalCompositeOperation=this.composite_operation,n.globalAlpha=i;let o=U.from_DOMMatrix(n.getTransform());o.multiply_self(t),n.setTransform(o.to_DOMMatrix());for(let l of this.commands)l.render(n);n.globalCompositeOperation="source-over",n.globalAlpha=1,n.restore()}};var je=(M=>(M.interactive=":Interactive",M.marks=":Marks",M.symbol_field=":Symbol:Field",M.label=":Label",M.junction=":Junction",M.wire=":Wire",M.symbol_foreground=":Symbol:Foreground",M.notes=":Notes",M.bitmap=":Bitmap",M.symbol_pin=":Symbol:Pin",M.symbol_background=":Symbol:Background",M[M.drawing_sheet=":DrawingSheet"]="drawing_sheet",M[M.grid=":Grid"]="grid",M))(je||{}),jt=class extends It{constructor(t){super();this.theme=t;for(let r of Object.values(je))this.add(new ae(this,r));this.by_name(":Interactive").visible=!1,this.by_name(":Interactive").interactive=!0,this.by_name(je.drawing_sheet).color=this.theme.worksheet??h.white}static{c(this,"LayerSet")}*interactive_layers(){yield this.by_name(":Interactive")}};var nr=class extends Ce{static{c(this,"BaseSchematicPainter")}},Y=class extends Me{static{c(this,"SchematicItemPainter")}get theme(){return this.view_painter.theme}get is_dimmed(){return this.view_painter.current_symbol?.dnp??!1}dim_color(e){return e=e.desaturate(),e.mix(this.theme.background,.5)}dim_if_needed(e){return this.is_dimmed?this.dim_color(e):e}determine_stroke(e,t){let r=t.stroke?.width||this.gfx.state.stroke_width;if(r<0)return{width:0,color:null};if((t.stroke?.type??"none")=="none")return{width:0,color:null};let n=e.name==":Symbol:Foreground"?this.theme.component_outline:this.theme.note,o=this.dim_if_needed(t.stroke?.color??n);return{width:r,color:o}}determine_fill(e,t){let r=t.fill?.type??"none";if(r=="none"||r=="background"&&e.name!=":Symbol:Background")return null;let i;switch(r){case"background":i=this.theme.component_body;break;case"outline":i=this.theme.component_outline;break;case"color":i=t.fill.color;break}return this.dim_if_needed(i)}};var r3=class extends Y{constructor(){super(...arguments);this.classes=[]}static{c(this,"LabelPainter")}layers_for(t){return[":Label"]}paint(t,r){if(r.effects.hide)return;let i=new st(r.shown_text);i.apply_at(r.at),i.apply_effects(r.effects),this.after_apply(r,i),r.at.rotation==0||r.at.rotation==180?i.text_angle.degrees=0:(r.at.rotation==90||r.at.rotation==270)&&(i.text_angle.degrees=90);let n=i.text_pos.add(this.get_schematic_text_offset(r,i));this.gfx.state.push(),this.gfx.state.stroke=this.color,this.gfx.state.fill=this.color,Q.default().draw(this.gfx,i.shown_text,n,i.attributes);let o=this.create_shape(r,i);o&&this.gfx.line(o,i.attributes.stroke_width/1e4),this.gfx.state.pop()}create_shape(t,r){return[]}get color(){return new h(1,0,1,1)}after_apply(t,r){}get_text_offset(t){return Math.round(B.text_offset_ratio*t.text_size.x)}get_box_expansion(t){return Math.round(B.label_size_ratio*t.text_size.y)}get_schematic_text_offset(t,r){let i=Math.round(this.get_text_offset(r)+r.get_effective_text_thickness());return r.text_angle.is_vertical?new d(-i,0):new d(0,-i)}},or=class extends r3{constructor(){super(...arguments);this.classes=[L2]}static{c(this,"NetLabelPainter")}get color(){return this.theme.label_local}},ar=class extends r3{constructor(){super(...arguments);this.classes=[X2]}static{c(this,"GlobalLabelPainter")}get color(){return this.theme.label_global}get_schematic_text_offset(t,r){let i=t,n=r.text_size.y,o=this.get_box_expansion(r),l=n*.0715;switch(["input","bidirectional","tri_state"].includes(i.shape)&&(o+=n*.75),o=Math.round(o),l=Math.round(l),t.at.rotation){case 0:return new d(o,l);case 90:return new d(l,-o);case 180:return new d(-o,l);case 270:return new d(l,o);default:throw new Error(`Unexpected label rotation ${t.at.rotation}`)}}create_shape(t,r){let i=t,n=r.text_pos,o=W.from_degrees(t.at.rotation+180),l=r.text_size.y,p=this.get_box_expansion(r),u=l/2+p,m=r.get_text_box().w+2*p,_=r.attributes.stroke_width,b=m+_+3,M=u+_+3,g=[new d(0,0),new d(0,-M),new d(-b,-M),new d(-b,0),new d(-b,M),new d(0,M),new d(0,0)],Z=new d;switch(i.shape){case"input":Z.x=-u,g[0].x+=u,g[6].x+=u;break;case"output":g[3].x-=u;break;case"bidirectional":case"tri_state":Z.x=-u,g[0].x+=u,g[6].x+=u,g[3].x-=u;break;default:break}return g=g.map(T=>T.add(Z).rotate(o).add(n).multiply(1/1e4)),g}},lr=class extends r3{constructor(){super(...arguments);this.classes=[et]}static{c(this,"HierarchicalLabelPainter")}get color(){return this.theme.label_hier}after_apply(t,r){r.v_align="center"}get_schematic_text_offset(t,r){let i=Math.round(this.get_text_offset(r)+r.text_width);switch(t.at.rotation){case 0:return new d(i,0);case 90:return new d(0,-i);case 180:return new d(-i,0);case 270:return new d(0,i);default:throw new Error(`Unexpected label rotation ${t.at.rotation}`)}}create_shape(t,r){let i=r.text_pos,n=W.from_degrees(t.at.rotation),o=r.text_width,l;switch(t.shape){case"output":l=[new d(0,o/2),new d(o/2,o/2),new d(o,0),new d(o/2,-o/2),new d(0,-o/2),new d(0,o/2)];break;case"input":l=[new d(o,o/2),new d(o/2,o/2),new d(0,0),new d(o/2,-o/2),new d(o,-o/2),new d(o,o/2)];break;case"bidirectional":case"tri_state":l=[new d(o/2,o/2),new d(o,0),new d(o/2,-o/2),new d(0,0),new d(o/2,o/2)];break;case"passive":default:l=[new d(0,o/2),new d(o,o/2),new d(o,-o/2),new d(0,-o/2),new d(0,o/2)];break}return l=l.map(p=>p.rotate(n).add(i).multiply(1/1e4)),l}},cr=class extends Y{constructor(){super(...arguments);this.classes=[O2]}static{c(this,"DirectiveLabelPainter")}get default_shape_color(){return this.theme.netclass_flag}get default_property_color(){return this.theme.netclass_flag}layers_for(t){return[":Label"]}paint(t,r){this.paint_shape(t,r);for(let i of r.properties)this.paint_property(t,i)}paint_shape(t,r){let i=r.effects.font.color.is_transparent_black?this.default_shape_color:r.effects.font.color,n=r.length,o=20*.0254;this.gfx.state.push(),this.gfx.state.matrix.translate_self(r.at.position.x,r.at.position.y),this.gfx.state.matrix.rotate_self(W.from_degrees(r.at.rotation)),this.gfx.state.stroke=i;let l=r.shape;if(l==="dot"){let p=o*.7;this.gfx.line([new d(0,0),new d(0,-(n-p))]),this.gfx.circle(new A(new d(0,-n),p,i))}else if(l==="round"){let p=o,u=new d(0,-n),m=this.gfx.state.stroke_width;this.gfx.line([new d(0,0),new d(0,-(n-p))]),this.gfx.arc(new fe(u,p,new W(0),new W(Math.PI*2),m,i))}else if(l==="diamond"){let p=o,m=[new d(0,0),new d(0,n-p),new d(-2*p,n),new d(0,n+p),new d(2*p,n),new d(0,n-p),new d(0,0)].map(_=>new d(_.x,-_.y));this.gfx.line(m)}else if(l==="rectangle"){let p=o*.8,m=[new d(0,0),new d(0,n-p),new d(-2*p,n-p),new d(-2*p,n+p),new d(2*p,n+p),new d(2*p,n-p),new d(0,n-p),new d(0,0)].map(_=>new d(_.x,-_.y));this.gfx.line(m)}this.gfx.state.pop()}paint_property(t,r){let i=r.effects.font.color.is_transparent_black?this.default_property_color:r.effects.font.color,n=new st(r.shown_text);n.apply_at(r.at),n.apply_effects(r.effects),r.at.rotation==0||r.at.rotation==180?n.text_angle.degrees=0:(r.at.rotation==90||r.at.rotation==270)&&(n.text_angle.degrees=90),this.gfx.state.push(),this.gfx.state.stroke=i,this.gfx.state.fill=i,Q.default().draw(this.gfx,n.shown_text,n.text_pos,n.attributes),this.gfx.state.pop()}};var Rr=class s extends Y{constructor(){super(...arguments);this.classes=[F2]}static{c(this,"PinPainter")}layers_for(t){return[":Symbol:Pin",":Symbol:Foreground",":Interactive"]}paint(t,r){if(r.definition.hide)return;let i={pin:r,def:r.definition,position:r.definition.at.position.copy(),orientation:vo(r.definition.at.rotation)},n=this.view_painter.current_symbol_transform,o=this.dim_if_needed(this.theme.pin);s.apply_symbol_transformations(i,n),this.gfx.state.push(),this.gfx.state.matrix=U.identity(),this.gfx.state.stroke=o,(t.name==":Symbol:Pin"||t.name==":Interactive")&&this.draw_pin_shape(this.gfx,i),t.name==":Symbol:Foreground"&&this.draw_name_and_number(this.gfx,i),this.gfx.state.pop()}static apply_symbol_transformations(t,r){for(let n=0;n0?(T=u?void 0:$t.place_inside(b,Z,p,r.orientation),w=m?void 0:$t.place_above(M,_,g,p,r.orientation)):(T=u?void 0:$t.place_above(M,_,Z,p,r.orientation),w=m?void 0:$t.place_below(M,_,Z,p,r.orientation)),T&&$t.draw(t,o,r.position,T,i.name.effects,t.state.stroke),w&&$t.draw(t,l,r.position,w,i.number.effects,t.state.stroke)}};function vo(s){switch(s){case 0:return"right";case 90:return"up";case 180:return"left";case 270:return"down";default:throw new Error(`Unexpected pin angle ${s}`)}}c(vo,"angle_to_orientation");var xn={stem(s,e,t){let r=new d,i=new d;switch(e){case"up":r.set(s.x,s.y-t),i.set(0,1);break;case"down":r.set(s.x,s.y+t),i.set(0,-1);break;case"left":r.set(s.x-t,s.y),i.set(1,0);break;case"right":r.set(s.x+t,s.y),i.set(-1,0);break}return{p0:r,dir:i}},draw(s,e,t,r,i,n){let o=B.pinsymbol_size,l=o*2,p=B.target_pin_radius;if(e=="no_connect"){s.line([i,r]),s.line([r.add(new d(-p,-p)),r.add(new d(p,p))]),s.line([r.add(new d(p,-p)),r.add(new d(-p,p))]);return}let u=c(()=>{n.y?s.line([i.add(new d(o,0)),i.add(new d(0,-n.y*o)),i.add(new d(-o,0))]):s.line([i.add(new d(0,o)),i.add(new d(-n.x*o,0)),i.add(new d(0,-o))])},"clock_notch"),m=c(()=>{n.y?s.line([i.add(new d(0,n.y).multiply(l)),i.add(new d(-1,n.y).multiply(l)),i]):s.line([i.add(new d(n.x,0).multiply(l)),i.add(new d(n.x,-1).multiply(l)),i])},"low_in_tri");switch(t){case"line":s.line([i,r]);return;case"inverted":s.arc(i.add(n.multiply(o)),o),s.line([i.add(n.multiply(l)),r]);return;case"inverted_clock":s.arc(i.add(n.multiply(o)),o),s.line([i.add(n.multiply(l)),r]),u();return;case"clock":s.line([i,r]),u();return;case"clock_low":case"edge_clock_high":s.line([i,r]),u(),m();break;case"input_low":s.line([i,r]),m();break;case"output_low":s.line([i,r]),n.y?s.line([i.sub(new d(l,0)),i.add(new d(0,n.y*l))]):s.line([i.sub(new d(0,l)),i.add(new d(n.x*l,0))]);break;case"non_logic":s.line([i,r]),s.line([i.sub(new d(n.x+n.y,n.y-n.x).multiply(o)),i.add(new d(n.x+n.y,n.y-n.x).multiply(o))]),s.line([i.sub(new d(n.x-n.y,n.y+n.x).multiply(o)),i.add(new d(n.x-n.y,n.y+n.x).multiply(o))]);break}}},$t={orient_label(s,e,t,r){switch(e){case"right":break;case"left":s.x*=-1,t=="left"&&(t="right");break;case"up":s=new d(s.y,-s.x);break;case"down":s=new d(s.y,s.x),t=="left"&&(t="right");break}return{offset:s,h_align:t,v_align:r,orientation:e}},place_inside(s,e,t,r){let i=new d(s-e/2+t,0);return this.orient_label(i,r,"left","center")},place_above(s,e,t,r,i){let n=new d(r/2,-(s+e/2+t/2));return this.orient_label(n,i,"center","bottom")},place_below(s,e,t,r,i){let n=new d(r/2,s+e/2+t/2);return this.orient_label(n,i,"center","top")},draw(s,e,t,r,i,n){let o=new j(e);switch(o.apply_effects(i),o.attributes.h_align=r.h_align,o.attributes.v_align=r.v_align,o.attributes.color=n,o.text_pos=t.add(r.offset).multiply(1e4),r.orientation){case"up":case"down":o.text_angle=W.from_degrees(90);break;case"left":case"right":o.text_angle=W.from_degrees(0);break}Q.default().draw(s,o.shown_text,o.text_pos,o.attributes)}};var ps=class extends Ie{constructor(){super(...arguments);this.shapes=[]}static{c(this,"NullRenderLayer")}dispose(){this.clear()}clear(){this.shapes=[]}render(t){}},pr=class extends ke{static{c(this,"NullRenderer")}#e;constructor(){super(null)}set background_color(e){}async setup(){}async dispose(){}update_canvas_size(){}clear_canvas(){}start_layer(e){this.#e=new ps(this,e)}end_layer(){return this.#e}get layers(){return[]}circle(e,t,r){this.#e.shapes.push(super.prep_circle(e,t,r))}arc(e,t,r,i,n,o){this.#e.shapes.push(super.prep_arc(e,t,r,i,n,o))}line(e,t,r){this.#e.shapes.push(super.prep_line(e,t,r))}polygon(e,t){this.#e.shapes.push(super.prep_polygon(e,t))}remove_layer(e){}};var ur=class extends Y{constructor(){super(...arguments);this.classes=[Ut]}static{c(this,"LibSymbolPainter")}layers_for(t){return[":Symbol:Background",":Symbol:Foreground",":Symbol:Field"]}paint(t,r,i=1){if(![":Symbol:Background",":Symbol:Foreground",":Interactive"].includes(t.name))return;let n=r.units.get(0);n&&this.#e(t,n,i);let o=this.view_painter.current_symbol,l=r.units.get(o?.unit||1);l&&this.#e(t,l,i)}#e(t,r,i=1){for(let n of r)if(!(n.style>0&&i!=n.style))for(let o of n.drawings)this.view_painter.paint_item(t,o)}},hr=class extends Y{constructor(){super(...arguments);this.classes=[re]}static{c(this,"SchematicSymbolPainter")}layers_for(t){let r=[":Interactive",":Symbol:Foreground",":Symbol:Background",":Symbol:Field",":Symbol:Pin"];return t.dnp&&r.push(":Marks"),r}paint(t,r){if(t.name==":Interactive"&&r.lib_symbol.power)return;let i=Qo(r);this.view_painter.current_symbol=r,this.view_painter.current_symbol_transform=i,this.gfx.state.push(),this.gfx.state.matrix=U.translation(r.at.position.x,r.at.position.y),this.gfx.state.multiply(i.matrix);let n=r.convert??1;if(this.view_painter.paint_item(t,r.lib_symbol,n),this.gfx.state.pop(),[":Symbol:Pin",":Symbol:Foreground",":Interactive"].includes(t.name))for(let o of r.unit_pins)this.view_painter.paint_item(t,o);if(t.name==":Symbol:Field"||t.name==":Interactive")for(let[o,l]of r.properties)this.view_painter.paint_item(t,l);if(r.dnp&&t.name==":Marks"){let o=Yo(this.theme,r),l=B.line_width*3,p=this.theme.erc_error;this.gfx.line([o.top_left,o.bottom_right],l,p),this.gfx.line([o.bottom_left,o.top_right],l,p)}this.view_painter.current_symbol=void 0,this.view_painter.current_symbol_transform=void 0}};function Qo(s){let e=new U([1,0,0,0,-1,0,0,0,1]),t=new U([0,-1,0,-1,0,0,0,0,1]),r=new U([-1,0,0,0,1,0,0,0,1]),i=new U([0,1,0,1,0,0,0,0,1]),n=0,o=e;if(s.at.rotation!=0)if(s.at.rotation==90)n=1,o=t;else if(s.at.rotation==180)n=2,o=r;else if(s.at.rotation==270)n=3,o=i;else throw new Error(`unexpected rotation ${s.at.rotation}`);if(s.mirror=="y"){let l=o.elements[0]*-1,p=o.elements[3]*-1,u=o.elements[1],m=o.elements[4];o.elements[0]=l,o.elements[1]=u,o.elements[3]=p,o.elements[4]=m}else if(s.mirror=="x"){let l=o.elements[0],p=o.elements[3],u=o.elements[1]*-1,m=o.elements[4]*-1;o.elements[0]=l,o.elements[1]=u,o.elements[3]=p,o.elements[4]=m}return{matrix:o,position:s.at.position,rotations:n,mirror_x:s.mirror=="x",mirror_y:s.mirror=="y"}}c(Qo,"get_symbol_transform");function Yo(s,e){let t=new pr,r=new jt(s),i=new zt(t,r,s),n=[":Symbol:Foreground",":Symbol:Background",":Symbol:Pin"],o=[];for(let l of n){let p=r.by_name(l);p.items.push(e),i.paint_layer(p),o.push(p.bbox)}return O.combine(o)}c(Yo,"get_symbol_body_and_pins_bbox");var us=class extends Y{constructor(){super(...arguments);this.classes=[Xt]}static{c(this,"RectanglePainter")}layers_for(t){return[":Notes"]}paint(t,r){let i=[r.start,new d(r.end.x,r.start.y),r.end,new d(r.start.x,r.end.y),r.start];this.#t(t,r,i),this.#e(t,r,i)}#e(t,r,i){let{width:n,color:o}=this.determine_stroke(t,r);!n||!o||this.gfx.line(new x(i,r.stroke?.width||this.gfx.state.stroke_width,o))}#t(t,r,i){let n=this.determine_fill(t,r);n&&this.gfx.polygon(new J(i,n))}},hs=class extends Y{constructor(){super(...arguments);this.classes=[qe]}static{c(this,"PolylinePainter")}layers_for(t){return[":Notes"]}paint(t,r){this.#t(t,r),this.#e(t,r)}#e(t,r){let{width:i,color:n}=this.determine_stroke(t,r);if(!i||!n)return;let o=c(l=>{this.gfx.line(l,i,n)},"draw_line");nt.line(r.pts,i,r.stroke_params,o)}#t(t,r){let i=this.determine_fill(t,r);i&&this.gfx.polygon(new J(r.pts,i))}},ds=class extends Y{constructor(){super(...arguments);this.classes=[U2]}static{c(this,"RuleAreaPainter")}layers_for(t){return[":Notes"]}paint(t,r){let i=[...r.polyline.pts,r.polyline.pts[0].copy()],n=this.determine_fill(t,r.polyline);n&&this.gfx.polygon(new J(i,n));let o=r.polyline.stroke?.width||this.gfx.state.stroke_width,l=r.polyline.stroke?.color||this.theme.rule_area;if(o&&l){let p=c(u=>{this.gfx.line(u,o,l)},"draw_line");nt.line(i,o,r.polyline.stroke_params,p)}}},ms=class extends Y{constructor(){super(...arguments);this.classes=[P2]}static{c(this,"WirePainter")}layers_for(t){return[":Wire"]}paint(t,r){this.gfx.line(new x(r.pts,this.gfx.state.stroke_width,this.theme.wire))}},_s=class extends Y{constructor(){super(...arguments);this.classes=[W2]}static{c(this,"BusPainter")}layers_for(t){return[":Wire"]}paint(t,r){this.gfx.line(new x(r.pts,B.bus_width,this.theme.bus))}},bs=class extends Y{constructor(){super(...arguments);this.classes=[Z2]}static{c(this,"BusEntryPainter")}layers_for(t){return[":Junction"]}paint(t,r){this.gfx.line(new x([r.at.position,r.at.position.add(r.size)],B.wire_width,this.theme.wire))}},fs=class extends Y{constructor(){super(...arguments);this.classes=[Lt]}static{c(this,"CirclePainter")}layers_for(t){return[":Notes"]}paint(t,r){this.#t(t,r),this.#e(t,r)}#e(t,r){let{width:i,color:n}=this.determine_stroke(t,r);!i||!n||this.gfx.arc(new fe(r.center,r.radius,new W(0),new W(Math.PI*2),i,n))}#t(t,r){let i=this.determine_fill(t,r);i&&this.gfx.circle(new A(r.center,r.radius,i))}},Ms=class extends Y{constructor(){super(...arguments);this.classes=[yt]}static{c(this,"ArcPainter")}layers_for(t){return[":Notes"]}paint(t,r){let i=q.from_three_points(r.start,r.mid,r.end,r.stroke?.width);this.#t(t,r,i),this.#e(t,r,i)}#e(t,r,i){let{width:n,color:o}=this.determine_stroke(t,r);!n||!o||this.gfx.arc(new fe(i.center,i.radius,i.start_angle,i.end_angle,n,o))}#t(t,r,i){let n=this.determine_fill(t,r);n&&this.gfx.polygon(new J(i.to_polygon(),n))}},gs=class extends Y{constructor(){super(...arguments);this.classes=[S2]}static{c(this,"JunctionPainter")}layers_for(t){return[":Junction"]}paint(t,r){let i=this.theme.junction;this.gfx.circle(new A(r.at.position,(r.diameter||1)/2,i))}},Ns=class extends Y{constructor(){super(...arguments);this.classes=[T2]}static{c(this,"NoConnectPainter")}layers_for(t){return[":Junction"]}paint(t,r){let i=this.theme.no_connect,n=B.line_width,o=B.noconnect_size/2;this.gfx.state.push(),this.gfx.state.matrix.translate_self(r.at.position.x,r.at.position.y),this.gfx.line(new x([new d(-o,-o),new d(o,o)],n,i)),this.gfx.line(new x([new d(o,-o),new d(-o,o)],n,i)),this.gfx.state.pop()}},Vs=class extends Y{constructor(){super(...arguments);this.classes=[Ot]}static{c(this,"TextPainter")}layers_for(t){return[":Notes"]}paint(t,r){if(r.effects.hide||!r.text)return;let i=new st(r.shown_text);i.apply_at(r.at),i.apply_effects(r.effects);let n=r.effects.font.color;if(n.is_transparent_black){let o=this.theme.note;i.attributes.color=this.dim_if_needed(o)}else i.attributes.color=this.dim_if_needed(n);this.gfx.state.push(),Q.default().draw(this.gfx,i.shown_text,i.text_pos,i.attributes),this.gfx.state.pop()}},Ps=class extends Y{constructor(){super(...arguments);this.classes=[ye]}static{c(this,"PropertyPainter")}layers_for(t){return[":Symbol:Field",":Interactive"]}paint(t,r){if(r.hide||!r.text)return;let i=this.theme.fields;r.parent instanceof ne&&(i=this.theme.sheet_fields);let n=r.effects.font.color;if(n.is_transparent_black){switch(r.name){case"Reference":i=this.theme.reference;break;case"Value":i=this.theme.value;break;case"Sheet name":i=this.theme.sheet_name;break;case"Sheet file":i=this.theme.sheet_filename;break}i=this.dim_if_needed(i)}else i=this.dim_if_needed(n);let o=r.parent,p=this.view_painter.current_symbol_transform?.matrix??U.identity(),u=r.shown_text;r.name=="Reference"&&o.unit&&(u+=o.unit_suffix);let m=new E3(u,{position:o.at.position.multiply(1e4),transform:p,is_symbol:o instanceof re});m.apply_effects(r.effects),m.attributes.angle=W.from_degrees(r.at.rotation);let _=r.at.position.multiply(1e4).sub(m.parent.position);_=p.inverse().transform(_),_=_.add(m.parent.position),m.text_pos=_;let b=m.draw_rotation,M=m.bounding_box,g=M.center;m.attributes.angle=b,m.attributes.h_align="center",m.attributes.v_align="center",m.attributes.stroke_width=m.get_effective_text_thickness(B.line_width*1e4),m.attributes.color=i;let Z=U.scaling(1e-4,1e-4).transform_all([M.top_left,M.top_right,M.bottom_right,M.bottom_left,M.top_left]);t.name==":Interactive"?this.gfx.line(new x(Array.from(Z),.1,h.white)):(this.gfx.state.push(),Q.default().draw(this.gfx,m.shown_text,g,m.attributes),this.gfx.state.pop())}},Ws=class extends Y{constructor(){super(...arguments);this.classes=[y2]}static{c(this,"LibTextPainter")}layers_for(t){return[":Symbol:Foreground"]}paint(t,r){if(r.effects.hide||!r.text)return;let i=this.view_painter.current_symbol_transform,n=new G3(r.shown_text);n.apply_effects(r.effects),n.apply_at(r.at),n.apply_symbol_transformations(i),n.attributes.color=this.dim_if_needed(this.theme.component_outline);let o=n.world_pos;n.attributes.v_align="center",this.gfx.state.push(),this.gfx.state.matrix=U.identity(),Q.default().draw(this.gfx,n.shown_text,o,n.attributes),this.gfx.state.pop()}paint_debug(t){this.gfx.line(x.from_BBox(t.scale(1/1e4),.127,new h(0,0,1,1))),this.gfx.circle(new A(t.center.multiply(1/1e4),.2,new h(0,1,0,1)))}},Zs=class extends Y{constructor(){super(...arguments);this.classes=[ne]}static{c(this,"SchematicSheetPainter")}layers_for(t){return[":Interactive",":Label",":Symbol:Foreground",":Symbol:Background",":Symbol:Field"]}paint(t,r){let i=this.theme.sheet,n=this.theme.sheet_background,o=new O(r.at.position.x,r.at.position.y,r.size.x,r.size.y);if(t.name==":Interactive"&&this.gfx.polygon(J.from_BBox(o.grow(3),n)),t.name==":Symbol:Background"&&this.gfx.polygon(J.from_BBox(o,n)),t.name==":Symbol:Foreground"&&this.gfx.line(x.from_BBox(o,this.gfx.state.stroke_width,i)),t.name==":Symbol:Field")for(let l of r.properties.values())this.view_painter.paint_item(t,l);if(t.name==":Label")for(let l of r.pins){let p=new et;switch(p.at=l.at.copy(),p.effects=l.effects,p.text=l.name,p.shape=l.shape,p.at.rotation){case 0:p.at.rotation=180;break;case 180:p.at.rotation=0;break;case 90:p.at.rotation=270;break;case 270:p.at.rotation=90;break}l.shape=="input"?p.shape="output":l.shape=="output"&&(p.shape="input"),this.view_painter.paint_item(t,p)}}},zt=class extends nr{static{c(this,"SchematicPainter")}constructor(e,t,r){super(e,t,r),this.painter_list=[new us(this,e),new hs(this,e),new ds(this,e),new ms(this,e),new _s(this,e),new bs(this,e),new fs(this,e),new Ms(this,e),new gs(this,e),new Ns(this,e),new Vs(this,e),new Ws(this,e),new Rr(this,e),new ur(this,e),new Ps(this,e),new hr(this,e),new or(this,e),new cr(this,e),new ar(this,e),new lr(this,e),new Zs(this,e)]}};var dr=class extends At{static{c(this,"SchematicViewer")}get schematic(){return this.document}create_renderer(e){let t=new sr(e);return t.state.fill=this.theme.note,t.state.stroke=this.theme.note,t.state.stroke_width=.1524,t}async load(e){if(e instanceof _e)return await super.load(e);this.document=null;let t=e.document;return t.update_hierarchical_data(e.sheet_path),await super.load(t)}create_painter(){return new zt(this.renderer,this.layers,this.theme)}create_layer_set(){return new jt(this.theme)}select(e){if(E(e)&&(e=this.schematic.find_symbol(e)??this.schematic.find_sheet(e)),e instanceof re||e instanceof ne){let t=this.layers.query_item_bboxes(e);e=a2(t)??null}super.select(e)}};var Ss=class extends Ue{static{c(this,"KCSchematicViewerElement")}update_theme(){this.viewer.theme=this.themeObject.schematic}make_viewer(){return new dr(this.canvas,!this.disableinteraction,this.themeObject.schematic)}};window.customElements.define("kc-schematic-viewer",Ss);var Ts=class extends N{static{c(this,"KCSchematicInfoPanel")}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback(),this.addDisposable(this.viewer.addEventListener(ie.type,e=>{this.update()}))))()}render(){let e=this.viewer.drawing_sheet,t=this.viewer.schematic,r=c(o=>f``,"header"),i=c((o,l,p="")=>f` + ${l} ${p} + `,"entry"),n=Object.entries(t.title_block?.comment||{}).map(([o,l])=>i(`Comment ${o}`,l));return f` + + + + + ${r("Page properties")} + ${i("Size",e.paper?.size)} + ${i("Width",e.width,"mm")} + ${i("Height",e.height,"mm")} + ${r("Schematic properties")} + ${i("KiCad version",t.version)} + ${i("Generator",t.generator)} + ${i("Title",t.title_block?.title)} + ${i("Date",t.title_block?.date)} + ${i("Revision",t.title_block?.rev)} + ${i("Company",t.title_block?.company)} + ${n} + ${i("Symbols",t.symbols.size)} + ${i("Unique symbols",t.lib_symbols?.symbols.length??0)} + ${i("Wires",t.wires.length)} + ${i("Buses",t.buses.length)} + ${i("Junctions",t.junctions.length)} + ${i("Net labels",t.net_labels.length)} + ${i("Global labels",t.global_labels.length)} + ${i("Hierarchical labels",t.hierarchical_labels.length)} + ${i("No connects",t.no_connects.length)} + + + + `}};window.customElements.define("kc-schematic-info-panel",Ts);var ys=class extends N{static{c(this,"KCSchematicPropertiesPanelElement")}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback(),this.setup_events()))()}setup_events(){this.addDisposable(this.viewer.addEventListener(z.type,e=>{this.selected_item=e.detail.item,this.update()})),this.addDisposable(this.viewer.addEventListener(ie.type,e=>{this.selected_item=void 0,this.update()}))}render(){let e=c(o=>f``,"header"),t=c((o,l,p="")=>f` + ${l??""} ${p} + `,"entry"),r=c(o=>o?f`check`:f`close`,"checkbox"),i,n=this.selected_item;if(!n)i=e("No item selected");else if(n instanceof re){let o=n.lib_symbol,l=Array.from(n.properties.values()).map(u=>t(u.name,u.text)),p=pe(n.unit_pins,u=>u.number).map(u=>t(u.number,u.definition.name.text));i=f` + ${e("Basic properties")} + ${t("X",n.at.position.x.toFixed(4),"mm")} + ${t("Y",n.at.position.y.toFixed(4),"mm")} + ${t("Orientation",n.at.rotation,"\xB0")} + ${t("Mirror",n.mirror=="x"?"Around X axis":n.mirror=="y"?"Around Y axis":"Not mirrored")} + ${e("Instance properties")} + ${t("Library link",n.lib_name??n.lib_id)} + ${n.unit?t("Unit",String.fromCharCode(65+n.unit-1)):""} + ${t("In BOM",r(n.in_bom))} + ${t("On board",r(n.in_bom))} + ${t("Populate",r(!n.dnp))} ${e("Fields")} + ${l} ${e("Symbol properties")} + ${t("Name",o.name)} + ${t("Description",o.description)} + ${t("Keywords",o.keywords)} + ${t("Power",r(o.power))} + ${t("Units",o.unit_count)} + ${t("Units are interchangeable",r(o.units_interchangable))} + ${e("Pins")} ${p} + `}else if(n instanceof ne){let o=Array.from(n.properties.values()).map(p=>t(p.name,p.text)),l=pe(n.pins,p=>p.name).map(p=>t(p.name,p.shape));i=f` + ${e("Basic properties")} + ${t("X",n.at.position.x.toFixed(4),"mm")} + ${t("Y",n.at.position.y.toFixed(4),"mm")} + ${e("Fields")} ${o} ${e("Pins")} ${l} + `}return f` + + + + ${i} + + + `}};window.customElements.define("kc-schematic-properties-panel",ys);var qt=class extends N{static{c(this,"KCSchematicSymbolsPanelElement")}connectedCallback(){(async()=>(this.viewer=await this.requestLazyContext("viewer"),await this.viewer.loaded,super.connectedCallback(),this.setup_initial_events()))()}setup_initial_events(){let e=!1;this.addEventListener("kc-ui-menu:select",t=>{if(e)return;let r=t.detail;r.name&&this.viewer.select(r.name)}),this.addDisposable(this.viewer.addEventListener(z.type,()=>{e=!0,this.menu.selected=this.viewer.selected?.context.uuid??null,e=!1})),this.addDisposable(this.viewer.addEventListener(ie.type,()=>{this.update()}))}renderedCallback(){this.search_input_elm.addEventListener("input",e=>{this.item_filter_elem.filter_text=this.search_input_elm.value??null})}render(){let e=this.viewer.schematic,t=[],r=[],i=[],n=pe(Array.from(e.symbols.values()),l=>l.reference);for(let l of n){let p=`${l.reference} ${l.value} ${l.id} ${l.lib_symbol.name}`,u=f` + ${l.reference} + ${l.value} + `;l.lib_symbol.power?r.push(u):t.push(u)}let o=pe(e.sheets,l=>l.sheetname??l.sheetfile??"");for(let l of o){let p=`${l.sheetname} ${l.sheetfile}`;i.push(f` + ${l.sheetname} + ${l.sheetfile} + `)}return f` + + + + + + + ${t} + ${r.length?f`Power symbols`:null} + ${r} + ${i.length?f`Sheets`:null} + ${i} + + + + + `}};P([v("kc-ui-menu")],qt.prototype,"menu",2),P([v("kc-ui-text-filter-input",!0)],qt.prototype,"search_input_elm",2),P([v("kc-ui-filtered-list",!0)],qt.prototype,"item_filter_elem",2);window.customElements.define("kc-schematic-symbols-panel",qt);var Ls=class extends Fe{static{c(this,"KCSchematicAppElement")}on_viewer_select(e,t){if(!(!e||e!=t)){if(e instanceof ne){this.project.set_active_page(`${e.sheetfile}:${e.path}/${e.uuid}`);return}this.change_activity("properties")}}can_load(e){return e.document instanceof _e}make_viewer_element(){return f``}make_activities(){return[f` + + `,f` + + `,f` + + `]}};window.customElements.define("kc-schematic-app",Ls);var mr=`:host{font-size:var(--font-size, 16px);--transition-time-very-short: .1s;--transition-time-short: .2s;--transition-time-medium: .5s;--bg: #131218;--fg: #f8f8f0;--tooltip-bg: #8864cb;--tooltip-fg: #f8f8f0;--tooltip-border: 1px solid #131218;--scrollbar-bg: #131218;--scrollbar-fg: #ae81ff66;--scrollbar-active-fg: #ae81ff;--scrollbar-hover-bg: #ae81ffbb;--activity-bar-bg: #282634;--activity-bar-fg: #f8f8f0;--activity-bar-active-bg: #131218;--activity-bar-active-fg: #f8f8f0;--resizer-bg: #ae81ff;--resizer-active-bg: #ae81ffbb;--panel-bg: #131218;--panel-fg: #f8f8f0;--panel-border: 2px solid #282634;--panel-title-bg: #8077a8;--panel-title-fg: #f8f8f0;--panel-title-border: 1px solid #634e89;--panel-title-button-bg: transparent;--panel-title-button-fg: #dcc8ff;--panel-title-button-hover-bg: #ae81ff;--panel-title-button-hover-fg: inherit;--panel-title-button-disabled-bg: inherit;--panel-title-button-disabled-fg: #888;--panel-subtitle-bg: #634e89;--panel-subtitle-fg: var(--panel-fg);--dropdown-bg: #464258;--dropdown-fg: #f8f8f0;--button-bg: #81eeff;--button-fg: #131218;--button-hover-bg: #a3f3ff;--button-hover-fg: #131218;--button-focus-outline: 1px solid #ae81ff;--button-selected-bg: #ae81ff;--button-selected-fg: #131218;--button-disabled-bg: #131218;--button-disabled-fg: #888;--button-success-bg: #64cb96;--button-success-fg: #131218;--button-success-hover-bg: #81ffbe;--button-success-hover-fg: #131218;--button-danger-bg: #cb6488;--button-danger-fg: #131218;--button-danger-hover-bg: #ff81ad;--button-danger-hover-fg: #131218;--button-outline-bg: #282634;--button-outline-fg: #f8f8f0;--button-outline-hover-bg: #282634;--button-outline-hover-fg: #81eeff;--button-outline-disabled-bg: #131218;--button-outline-disabled-fg: #888;--button-toolbar-bg: #282634;--button-toolbar-fg: #f8f8f0;--button-toolbar-hover-bg: #282634;--button-toolbar-hover-fg: #81eeff;--button-toolbar-disabled-bg: #131218;--button-toolbar-disabled-fg: #888;--button-menu-bg: transparent;--button-menu-fg: #f8f8f0;--button-menu-hover-bg: transparent;--button-menu-hover-fg: #81eeff;--button-menu-disabled-bg: transparent;--button-menu-disabled-fg: #888;--input-bg: #131218;--input-fg: #f8f8f0;--input-border: 1px solid #8077a8;--input-accent: #ae81ff;--input-hover-shadow: 1px 1px 10px 5px rgba(0, 0, 0, .2);--input-focus-outline: 1px solid #ae81ff;--input-placeholder: #8077a8;--input-disabled-bg: #131218;--input-disabled-fg: #888;--input-range-bg: #8077a8;--input-range-fg: #f8f8f0;--input-range-hover-bg: #ae81ff;--input-range-disabled-bg: #131218;--input-range-hover-shadow: 1px 1px 10px 5px rgba(0, 0, 0, .2);--input-range-handle-shadow: 1px 1px 5px 5px rgba(180, 180, 180, .2);--list-item-bg: var(--panel-bg);--list-item-fg: var(--panel-fg);--list-item-active-bg: #634e89;--list-item-active-fg: var(--list-item-fg);--list-item-hover-bg: #64cb96;--list-item-hover-fg: var(--list-item-bg);--list-item-disabled-bg: var(--list-item-bg);--list-item-disabled-fg: #888;--grid-outline: #433e56}:host{--gradient-purple-green-light: linear-gradient( 190deg, hsl(261deg 27% 42%) 0%, hsl(243deg 27% 42%) 17%, hsl(224deg 27% 42%) 33%, hsl(205deg 27% 42%) 50%, hsl(187deg 27% 42%) 67%, hsl(168deg 27% 42%) 83%, hsl(149deg 27% 42%) 100% ) 0 0 fixed;--gradient-purple-blue-medium: linear-gradient( 190deg, hsl(261deg 28% 30%) 0%, hsl(248deg 30% 31%) 17%, hsl(235deg 32% 32%) 33%, hsl(222deg 34% 33%) 50%, hsl(209deg 35% 34%) 67%, hsl(197deg 37% 35%) 83%, hsl(183deg 38% 36%) 100% ) 0 0 fixed;--gradient-purple-blue-dark: linear-gradient(10deg, #111928, #1d162a) 0 0 fixed;--gradient-cyan-blue-light: linear-gradient( 190deg, hsl(183deg 63% 33%) 0%, hsl(189deg 69% 30%) 17%, hsl(194deg 74% 27%) 33%, hsl(199deg 79% 24%) 50%, hsl(203deg 85% 21%) 67%, hsl(209deg 89% 18%) 83%, hsl(214deg 95% 15%) 100% ) 0 0 fixed;--gradient-purple-green-highlight: linear-gradient( 190deg, hsl(261deg 27% 53%) 0%, hsl(243deg 27% 52%) 17%, hsl(224deg 27% 52%) 33%, hsl(205deg 27% 51%) 50%, hsl(186deg 27% 51%) 67%, hsl(168deg 27% 50%) 83%, hsl(149deg 27% 50%) 100% ) 0 0 fixed;--gradient-purple-red: linear-gradient(90deg, #8864cb, #cb6488) 0 0 fixed;--gradient-purple-red-highlight: linear-gradient(90deg, #b187ff, #ff80ac) 0 0 fixed;--scrollbar-bg: var(--gradient-purple-blue-dark);--scrollbar-fg: var(--gradient-purple-green-light);--scrollbar-hover-fg: var(--scrollbar-fg);--scrollbar-active-fg: var(--scrollbar-fg);--activity-bar-bg: var(--gradient-purple-green-light);--resizer-bg: var(--gradient-purple-blue-medium);--resizer-active-bg: var(--gradient-purple-green-highlight);--panel-bg: var(--gradient-purple-blue-dark);--panel-title-bg: var(--gradient-purple-green-light);--panel-subtitle-bg: var(--gradient-purple-blue-medium);--button-toolbar-bg: var(--gradient-purple-blue-dark);--button-toolbar-hover-bg: var(--gradient-purple-green-light);--button-toolbar-hover-fg: #f8f8f0;--button-toolbar-disabled-bg: var(--gradient-purple-blue-dark);--button-toolbar-alt-bg: var(--gradient-purple-green-light);--button-toolbar-alt-hover-bg: var(--gradient-purple-green-highlight);--button-toolbar-alt-hover-fg: #f8f8f0;--button-toolbar-alt-disabled-bg: var(--gradient-purple-blue-dark);--dropdown-bg: var(--gradient-purple-green-light);--dropdown-fg: #f8f8f0;--dropdown-hover-bg: var(--gradient-purple-green-highlight);--dropdown-hover-fg: #f8f8f0;--dropdown-active-bg: var(--gradient-purple-blue-dark);--dropdown-active-fg: #f8f8f0;--input-range-bg: var(--gradient-purple-green-light);--list-item-hover-bg: var(--gradient-purple-green-highlight);--list-item-active-bg: var(--gradient-cyan-blue-light);--focus-overlay-bg: var(--gradient-purple-green-light);--focus-overlay-opacity: .5;--focus-overlay-fg: #f8f8f0}::-webkit-scrollbar{position:absolute;width:6px;height:6px;margin-left:-6px;background:var(--scrollbar-bg)}::-webkit-scrollbar-thumb{position:absolute;background:var(--scrollbar-fg)}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-hover-fg)}::-webkit-scrollbar-thumb:active{background:var(--scrollbar-active-fg)}kc-ui-app{width:100%;height:100%;flex-grow:1;display:flex;flex-direction:row;overflow:hidden}label{display:block;width:100%;margin-top:.75em}input,select,textarea{all:unset;box-sizing:border-box;display:block;width:100%;max-width:100%;margin-top:.5em;font-family:inherit;border-radius:.25em;text-align:center;padding:.25em;background:var(--input-bg);color:var(--input-fg);transition:color var(--transition-time-medium) ease,box-shadow var(--transition-time-medium) ease,outline var(--transition-time-medium) ease,background var(--transition-time-medium) ease,border var(--transition-time-medium) ease}input:hover,select:hover,textarea:hover{z-index:10;box-shadow:var(--input-hover-shadow)}input:focus,select:focus,textarea:focus{z-index:10;box-shadow:none;outline:var(--input-focus-outline)}input:disabled,select:disabled,textarea:disabled{background:var(--input-disabled-bg);color:var(--input-disabled-fg)}input:disabled:hover,select:disabled:hover,textarea:disabled:hover{z-index:10;cursor:unset}input[type=color]::-webkit-color-swatch{border:1px solid transparent;border-radius:.25em}textarea{text-align:left;padding:.5em} +`;var wn=`*,*:before,*:after{box-sizing:border-box}:host{box-sizing:border-box;margin:0;display:flex;position:relative;width:100%;height:100%;color:var(--fg)}:host([loaded]) section.overlay,:host([loading]) section.overlay{display:none}:host main{display:contents}section.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;background:var(--gradient-purple-blue-dark)}section.overlay h1{display:flex;margin:0 auto;align-items:center;justify-content:center;font-size:5em;font-weight:300;text-shadow:0 0 5px var(--gradient-purple-red)}section.overlay h1 img{width:1.5em}section.overlay p{text-align:center;font-size:1.5em;max-width:50%}section.overlay strong{background:var(--gradient-purple-red-highlight);-webkit-background-clip:text;-moz-background-clip:text;background-clip:text;color:transparent}section.overlay a{color:#81eeff}section.overlay a:hover{color:#a3f3ff}section.overlay input{font-size:1.5em;color:var(--fg);background:var(--gradient-purple-red);max-width:50%}section.overlay input::placeholder{color:var(--fg)}section.overlay .link_button{color:#81eeff;background:transparent;font-size:1em;font-weight:400;text-decoration:underline;outline:none;border:none;box-sizing:border-box;transition:color var(--transition-time-medium) ease}section.overlay .link_button:focus{border:var(--button-focus-outline)}section.overlay .link_button:hover{color:var(--fg)}section.overlay p.note{color:var(--input-placeholder);font-size:1em}section.overlay p.github img{width:2em}kc-board-viewer,kc-schematic-viewer{width:100%;height:100%;flex:1}.split-horizontal{display:flex;flex-direction:column;height:100%;max-height:100%;overflow:hidden}.split-vertical{display:flex;flex-direction:row;width:100%;max-width:100%;height:100%;overflow:hidden}kc-board-app,kc-schematic-app{width:100%;height:100%;flex:1} +`;i2.sprites_url=qs;var $e=class extends N{constructor(){super();this.project=new vt;this.provideContext("project",this.project)}static{c(this,"KiCanvasShellElement")}static{this.styles=[...N.styles,new Ze(mr),new Ze(wn)]}#e;#t;initialContentCallback(){let t=new URLSearchParams(document.location.search),i=[...t.getAll("github"),...t.getAll("repo")][0];Re(async()=>{if(this.src){let n=new ut([this.src]);await this.setup_project(n);return}if(i){let n=await this.load_repo(i);if(!n)return;await this.setup_project(n);return}new l3(this,async n=>{await this.setup_project(n)})}),this.link_input.addEventListener("input",async n=>{let o=this.link_input.value,l=await this.load_repo(o);if(!l){console.error(`Invalid URL: ${o}`);return}await this.setup_project(l);let p=new URL(window.location.href);p.searchParams.set("repo",o),window.history.pushState(null,"",p)}),this.open_file_button.addEventListener("click",async n=>{c3.pick(async o=>{await this.setup_project(o)})})}async load_repo(t){return await L3.fromURLs(t)??await X3.fromURLs(t)}async setup_project(t){this.loaded=!1,this.loading=!0;try{await t.setup(),await this.project.load(t),this.project.set_active_page(this.project.first_page),this.loaded=!0}catch(r){console.error(r)}finally{this.loading=!1}}render(){return this.#e=f` + + `,this.#t=f` + + `,f` + +
+

+ + KiCanvas +

+

+ KiCanvas is an + interactive + , + browser-based + viewer for KiCad schematics and boards. You can learn + more from the + docs. It's in + alpha + so please + + report any bugs! +

+ +

+ or drag & drop your KiCad files, or +

+

+ KiCanvas is + free & open source + and supported by + community donations + with significant support from + PartsBox, + Blues, + Mithro, + Jeremy Gordon, + & + James Neal. KiCanvas runs entirely within your browser, so your + files don't ever leave your machine. +

+

+ + + +

+
+
${this.#e} ${this.#t}
+
+ `}};P([L({type:Boolean})],$e.prototype,"loading",2),P([L({type:Boolean})],$e.prototype,"loaded",2),P([L({type:String})],$e.prototype,"src",2),P([v('input[name="link"]',!0)],$e.prototype,"link_input",2),P([v('button[name="open_local"]',!0)],$e.prototype,"open_file_button",2);window.customElements.define("kc-kicanvas-shell",$e);var i3=new te("kicanvas:embedtag"),Ne=class extends N{constructor(){super();this.#e=new vt;this.custom_resolver=null;this.provideContext("project",this.#e)}static{c(this,"KiCanvasEmbedElement")}static{this.styles=[...N.styles,new Ze(mr),y` + :host { + margin: 0; + display: flex; + position: relative; + width: 100%; + max-height: 100%; + aspect-ratio: 1.414; + background-color: aqua; + color: var(--fg); + font-family: + "Nunito", ui-rounded, "Hiragino Maru Gothic ProN", + Quicksand, Comfortaa, Manjari, "Arial Rounded MT Bold", + Calibri, source-sans-pro, sans-serif; + contain: layout paint; + } + + main { + display: contents; + } + + kc-board-app, + kc-schematic-app { + width: 100%; + height: 100%; + flex: 1; + } + `]}#e;#t;#r;initialContentCallback(){this.#i(),Re(()=>{this.#s()})}async#i(){}async#s(){let t=[],r=[];this.src&&t.push(this.src);let i=0;for(let p of this.querySelectorAll("kicanvas-source"))if(p.src)t.push(p.src);else if(p.is_inline_source()){let u=`inline_${i}`;i+=1;let m=p.load_inline_source(u);m&&(i3.info(`Determined inline source ${m.name}, ${m.size} bytes`),r.push(m))}let n=t.length===0?null:new ut(t,this.custom_resolver),o=r.length===0?null:new ht(r);if(n===null&&o===null){i3.warn("No valid sources specified");return}let l=new n3([n,o]);await this.#n(l)}async#n(t){this.loaded=!1,this.loading=!0;try{await t.setup(),await this.#e.load(t),this.loaded=!0,await this.update(),this.#e.set_active_page(this.#e.root_schematic_page)}finally{this.loading=!1}}render(){if(!this.loaded)return f``;this.#e.has_schematics&&!this.#t&&(this.#t=f` + `),this.#e.has_boards&&!this.#r&&(this.#r=f` + `);let t=(this.controls??"none")=="none"||this.controlslist?.includes("nooverlay")?null:f``;return f`
+ ${this.#t} ${this.#r} ${t} +
`}};P([L({type:String})],Ne.prototype,"src",2),P([L({type:Boolean})],Ne.prototype,"loading",2),P([L({type:Boolean})],Ne.prototype,"loaded",2),P([L({type:String})],Ne.prototype,"controls",2),P([L({type:String})],Ne.prototype,"controlslist",2),P([L({type:String})],Ne.prototype,"theme",2),P([L({type:String})],Ne.prototype,"zoom",2);window.customElements.define("kicanvas-embed",Ne);var ct=class ct extends Ye{static{c(this,"KiCanvasSourceElement")}constructor(){super()}connectedCallback(){this.ariaHidden="true",this.hidden=!0,this.style.display="none",super.connectedCallback()}is_inline_source(){return this.src===null&&this.childNodes.length>0}load_inline_source(e=null){let t="";for(let o of this.childNodes)o.nodeType===Node.TEXT_NODE?t+=o.nodeValue??"":i3.warn(`kicanvas-source children ${o.nodeType} are invaild.`);t=t.trimStart();let r;if(this.name)r=this.name;else{let o=this.type??ct.determine_file_type(t);if(o===void 0){i3.warn(`Unknown file type, content: ${t.slice(0,64)}...`);return}let l=ct.get_file_ext(o);r=(e??"noname")+l}if(t.length===0){i3.warn(`kicanvas-source content ${r} is empty.`);return}let i=new Blob([t],{type:"text/plain"});return new File([i],r)}static determine_file_type(e){if(e.startsWith("(kicad_sch"))return"schematic";if(e.startsWith("(kicad_pcb"))return"board";if(e.startsWith("(kicad_wks"))return"worksheet";if(e.startsWith("{"))return"project"}static get_file_ext(e){switch(e){case"schematic":return".kicad_sch";case"board":return".kicad_pcb";case"worksheet":return".kicad_wks";case"project":return".kicad_prj"}}};P([L({type:String})],ct.prototype,"src",2),P([L({type:String})],ct.prototype,"type",2),P([L({type:String})],ct.prototype,"name",2);var Xs=ct;window.customElements.define("kicanvas-source",Xs);document.body.appendChild(f``); diff --git a/js/viewerhandler.js b/js/viewerhandler.js new file mode 100644 index 0000000..8a70137 --- /dev/null +++ b/js/viewerhandler.js @@ -0,0 +1,2 @@ +/*! For license information please see viewerhandler.js.LICENSE.txt */ +(()=>{"use strict";var e;(function(e){const{id:i,mimes:r,mimesAliases:a,component:n}=e;if(!i||""===i.trim()||"string"!=typeof i)throw new Error("The handler does not have a valid id");if(!(r&&Array.isArray(r)||a))throw new Error("Handler needs a valid mime array or mimesAliases");if(!n||"object"!=typeof n&&"function"!=typeof n)throw new Error("The handler does not have a valid component")})(e={id:"kicanvasviewer",group:"kicanvasviewer",mimes:["application/x-kicad-schematic","application/x-kicad-pcb"],component:{name:"KiCanvasInlineViewer",data:()=>({src:null,error:null,ready:!1,started:!1}),async mounted(){if(this.started)return;this.started=!0;const e=this.$attrs?.etag;if(e)try{const i=await fetch(OC.generateUrl("/apps/kicanvasviewer/resolve/"+encodeURIComponent(e)));if(!i.ok)return void(this.error="KiCanvas: could not resolve file");const r=await i.json();if(!r.fileId||!r.fileName)return void(this.error="KiCanvas: resolve returned no fileId/fileName");this.src=window.location.origin+OC.generateUrl("/apps/kicanvasviewer/file/"+encodeURIComponent(r.fileId)+"/"+encodeURIComponent(r.fileName)),await new Promise((e,i)=>{if(customElements.get("kc-kicanvas-shell"))return void e();const r=document.createElement("script");r.type="module",r.src=OC.linkTo("kicanvasviewer","js/kicanvas/kicanvas.js"),r.onload=e,r.onerror=i,document.head.appendChild(r)}),this.ready=!0,this.$forceUpdate()}catch(e){console.error(e),this.error="KiCanvas error"}else this.error="KiCanvas: no etag found"},render(e){return this.error?e("div",{style:{padding:"40px",fontSize:"20px"}},this.error):this.ready&&this.src?e("div",{style:{position:"absolute",inset:"0",zIndex:100,background:"var(--color-main-background)"}},[e("kc-kicanvas-shell",{key:this.src,attrs:{src:this.src},style:{display:"block",width:"100%",height:"100%"}})]):e("div",{style:{padding:"40px",fontSize:"20px"}},"Loading KiCanvas...")}}}),window._oca_viewer_handlers??(window._oca_viewer_handlers=new Map),window._oca_viewer_handlers.has(e.id)?console.warn(`Handler with id ${e.id} is already registered.`):window._oca_viewer_handlers.set(e.id,e)})(); \ No newline at end of file diff --git a/js/viewerhandler.js.LICENSE.txt b/js/viewerhandler.js.LICENSE.txt new file mode 100644 index 0000000..c0e8663 --- /dev/null +++ b/js/viewerhandler.js.LICENSE.txt @@ -0,0 +1,4 @@ +/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php new file mode 100644 index 0000000..6402f49 --- /dev/null +++ b/lib/AppInfo/Application.php @@ -0,0 +1,28 @@ +registerEventListener( + LoadAdditionalScriptsEvent::class, + LoadAdditionalScriptsListener::class + ); + } + + public function boot(IBootContext $context): void { + } +} diff --git a/lib/AppInfo/LoadAdditionalScriptsListener.php b/lib/AppInfo/LoadAdditionalScriptsListener.php new file mode 100644 index 0000000..c9aec62 --- /dev/null +++ b/lib/AppInfo/LoadAdditionalScriptsListener.php @@ -0,0 +1,18 @@ +getFileById($fileId); + $name = $file->getName(); + + return new TemplateResponse('kicanvasviewer', 'viewer', [ + 'fileId' => $fileId, + 'fileName' => $name, + ]); + } + + #[NoAdminRequired] + #[NoCSRFRequired] + public function file(int $fileId, string $name): DataDisplayResponse { + $file = $this->getFileById($fileId); + + if (!preg_match('/\.(kicad_sch|kicad_pcb)$/i', $file->getName())) { + return new DataDisplayResponse('Unsupported file type', 400); + } + + $response = new DataDisplayResponse($file->getContent()); + $response->addHeader('Content-Type', 'text/plain; charset=utf-8'); + $response->addHeader('Content-Disposition', 'inline; filename="' . basename($file->getName()) . '"'); + + return $response; + } + + private function getFileById(int $fileId) { + $user = $this->userSession->getUser(); + if ($user === null) { + throw new \Exception('Not logged in'); + } + + $userFolder = $this->rootFolder->getUserFolder($user->getUID()); + $nodes = $userFolder->getById($fileId); + + if (empty($nodes)) { + throw new \Exception('File not found'); + } + + return $nodes[0]; + } + + #[NoAdminRequired] + #[NoCSRFRequired] + public function resolve(string $etag): JSONResponse { + $user = $this->userSession->getUser(); + + if ($user === null) { + return new JSONResponse(['error' => 'not logged in'], 401); + } + + $userFolder = $this->rootFolder->getUserFolder($user->getUID()); + + $nodes = array_merge( + $userFolder->searchByMime('application/x-kicad-schematic'), + $userFolder->searchByMime('application/x-kicad-pcb') + ); + + foreach ($nodes as $node) { + if ($node->getEtag() === $etag) { + return new JSONResponse([ + 'fileId' => $node->getId(), + 'fileName' => $node->getName(), + 'mime' => $node->getMimeType(), + ]); + } + } + + return new JSONResponse(['error' => 'not found'], 404); + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..980f6a7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2125 @@ +{ + "name": "kicanvasviewer", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@nextcloud/files": "^4.0.0", + "@nextcloud/viewer": "^1.0.0" + }, + "devDependencies": { + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "peer": true, + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "peer": true, + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@buttercup/fetch": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@buttercup/fetch/-/fetch-0.2.1.tgz", + "integrity": "sha512-sCgECOx8wiqY8NN1xN22BqqKzXYIG2AicNLlakOAI4f0WgyLVUbAigMf8CZhBtJxdudTcB1gD5lciqi44jwJvg==", + "optionalDependencies": { + "node-fetch": "^3.3.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@file-type/xml": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@file-type/xml/-/xml-0.4.4.tgz", + "integrity": "sha512-NhCyXoHlVZ8TqM476hyzwGJ24+D5IPSaZhmrPj7qXnEVb3q6jrFzA3mM9TBpknKSI9EuQeGTKRg2DXGUwvBBoQ==", + "dependencies": { + "sax": "^1.4.1", + "strtok3": "^10.3.4" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nextcloud/auth": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@nextcloud/auth/-/auth-2.6.0.tgz", + "integrity": "sha512-VkT87+9UqpPi7O36bVEE4/MxWF8d90VQcuMlvKltsZyLSLkEGrPXgowtD75Y54k60/8SR6mXbeqBwapi8dDUbA==", + "dependencies": { + "@nextcloud/browser-storage": "^0.5.0", + "@nextcloud/event-bus": "^3.3.3", + "@nextcloud/router": "^3.1.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/browser-storage": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@nextcloud/browser-storage/-/browser-storage-0.5.0.tgz", + "integrity": "sha512-usYr4GlJQlK3hgZURvklqWb9ivi7sgsSuFqXrs7s4hl1LTS4enzPrnkQumm6nRsQruf0ITS+OBsK+oELEbvYPA==", + "engines": { + "node": "^24 || ^22 || ^20" + } + }, + "node_modules/@nextcloud/capabilities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@nextcloud/capabilities/-/capabilities-1.2.1.tgz", + "integrity": "sha512-snZ0/910zzwN6PDsIlx2Uvktr1S5x0ClhDUnfPlCj7ntNvECzuVHNY5wzby22LIkc+9ZjaDKtCwuCt2ye+9p/Q==", + "dependencies": { + "@nextcloud/initial-state": "^3.0.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/event-bus": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@nextcloud/event-bus/-/event-bus-3.3.3.tgz", + "integrity": "sha512-zIfvKmUGkXpVzRKoXrcO9hkoiKDm65fqNxy/XIbIxrQhZByPq3gDkjBpnu3V5Gs8JdYwa73R8DjzV9oH8HYhIg==", + "dependencies": { + "@types/semver": "^7.7.0", + "semver": "^7.7.2" + }, + "engines": { + "node": "^20 || ^22 || ^24" + } + }, + "node_modules/@nextcloud/files": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nextcloud/files/-/files-4.0.0.tgz", + "integrity": "sha512-TmecnZIS+PGWGtRh7RpGEboCT4K6iTbHULUcfR6hs3eEzjDVsCc1Ldf8popGY/70lbpdlfYle8xbXnPIo3qaXA==", + "dependencies": { + "@nextcloud/auth": "^2.5.3", + "@nextcloud/capabilities": "^1.2.1", + "@nextcloud/l10n": "^3.4.1", + "@nextcloud/logger": "^3.0.3", + "@nextcloud/paths": "^3.0.0", + "@nextcloud/router": "^3.1.0", + "@nextcloud/sharing": "^0.3.0", + "is-svg": "^6.1.0", + "typescript-event-target": "^1.1.2", + "webdav": "^5.9.0" + }, + "engines": { + "node": "^24.0.0" + } + }, + "node_modules/@nextcloud/initial-state": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nextcloud/initial-state/-/initial-state-3.0.0.tgz", + "integrity": "sha512-cV+HBdkQJGm8FxkBI5rFT/FbMNWNBvpbj6OPrg4Ae4YOOsQ15CL8InPOAw1t4XkOkQK2NEdUGQLVUz/19wXbdQ==", + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/l10n": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@nextcloud/l10n/-/l10n-3.4.1.tgz", + "integrity": "sha512-aTFinTcKiK2gEXwLgutXekpZZ8/v/4QiC8C3QCLH5m0o+WtxsBC+fqV142ebC/rfDnzCLhY4ZtswSu8bFbZocg==", + "dependencies": { + "@nextcloud/router": "^3.0.1", + "@nextcloud/typings": "^1.9.1", + "@types/escape-html": "^1.0.4", + "dompurify": "^3.2.6", + "escape-html": "^1.0.3" + }, + "engines": { + "node": "^20 || ^22 || ^24" + } + }, + "node_modules/@nextcloud/logger": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@nextcloud/logger/-/logger-3.0.3.tgz", + "integrity": "sha512-TcbVRL4/O5ffI1RXFmQAFD3gwwT15AAdr1770x+RNqVvfBdoGVyhzOwCIyA5Vfc3fA1iJXFa+rE6buJZSoqlcw==", + "dependencies": { + "@nextcloud/auth": "^2.5.3" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/paths": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@nextcloud/paths/-/paths-3.1.0.tgz", + "integrity": "sha512-vtFYA/kthaUDzu6KejTOL1OwnOy7/yynq5zdB/UBpYacAWjUX5Ddh4OMWx3rEavkBJ9/QGhrFryNJLjNfe8OQA==", + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/router": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@nextcloud/router/-/router-3.1.0.tgz", + "integrity": "sha512-e4dkIaxRSwdZJlZFpn9x03QgBn/Sa2hN1hp/BA7+AbzykmSAlKuWfdmX8j/8ewrLpQwYmZR23IZO9XwpJXq2Uw==", + "dependencies": { + "@nextcloud/typings": "^1.10.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/sharing": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@nextcloud/sharing/-/sharing-0.3.0.tgz", + "integrity": "sha512-kV7qeUZvd1fTKeFyH+W5Qq5rNOqG9rLATZM3U9MBxWXHJs3OxMqYQb8UQ3NYONzsX3zDGJmdQECIGHm1ei2sCA==", + "dependencies": { + "@nextcloud/initial-state": "^3.0.0", + "is-svg": "^6.1.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + }, + "optionalDependencies": { + "@nextcloud/files": "^3.12.0" + } + }, + "node_modules/@nextcloud/sharing/node_modules/@nextcloud/files": { + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@nextcloud/files/-/files-3.12.2.tgz", + "integrity": "sha512-vBo8tf3Xh6efiF8CrEo3pKj9AtvAF6RdDGO1XKL65IxV8+UUd9Uxl2lUExHlzoDRRczCqfGfaWfRRaFhYqce5Q==", + "optional": true, + "dependencies": { + "@nextcloud/auth": "^2.5.3", + "@nextcloud/capabilities": "^1.2.1", + "@nextcloud/l10n": "^3.4.1", + "@nextcloud/logger": "^3.0.3", + "@nextcloud/paths": "^3.0.0", + "@nextcloud/router": "^3.1.0", + "@nextcloud/sharing": "^0.3.0", + "cancelable-promise": "^4.3.1", + "is-svg": "^6.1.0", + "typescript-event-target": "^1.1.1", + "webdav": "^5.8.0" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/typings": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@nextcloud/typings/-/typings-1.10.0.tgz", + "integrity": "sha512-SMC42rDjOH3SspPTLMZRv76ZliHpj2JJkF8pGLP8l1QrVTZxE47Qz5qeKmbj2VL+dRv2e/NgixlAFmzVnxkhqg==", + "dependencies": { + "@types/jquery": "3.5.16" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || ^24.0.0" + } + }, + "node_modules/@nextcloud/viewer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nextcloud/viewer/-/viewer-1.0.0.tgz", + "integrity": "sha512-AaVXh+KyJ0q28AaqjBwDjjEuVB+v1GarIuuLCO2nfpkg/ekngQw25rmb4PzKVvbN8N35nb92GpQXBpG1ZtBrzg==", + "peerDependencies": { + "vue": "^2.7.16" + } + }, + "node_modules/@nodable/entities": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.1.tgz", + "integrity": "sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ] + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, + "node_modules/@types/escape-html": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-1.0.4.tgz", + "integrity": "sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true + }, + "node_modules/@types/jquery": { + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.16.tgz", + "integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==", + "dependencies": { + "@types/sizzle": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "25.9.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.2.tgz", + "integrity": "sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==", + "dev": true, + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==" + }, + "node_modules/@types/sizzle": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.10.tgz", + "integrity": "sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "optional": true + }, + "node_modules/@vue/compiler-sfc": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz", + "integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==", + "peer": true, + "dependencies": { + "@babel/parser": "^7.23.5", + "postcss": "^8.4.14", + "source-map": "^0.6.1" + }, + "optionalDependencies": { + "prettier": "^1.18.2 || ^2.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.34", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.34.tgz", + "integrity": "sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw==", + "dev": true, + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/byte-length/-/byte-length-1.0.2.tgz", + "integrity": "sha512-ovBpjmsgd/teRmgcPh23d4gJvxDoXtAzEL9xTfMU8Yc2kqCDb7L9jAG0XHl1nzuGl+h3ebCIF1i62UFyA9V/2Q==" + }, + "node_modules/cancelable-promise": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/cancelable-promise/-/cancelable-promise-4.3.1.tgz", + "integrity": "sha512-A/8PwLk/T7IJDfUdQ68NR24QHa8rIlnN/stiJEBo6dmVUkD4K14LswG0w3VwdeK/o7qOwRUR1k2MhK5Rpy2m7A==", + "optional": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001797", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001797.tgz", + "integrity": "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "peer": true + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/dompurify": { + "version": "3.4.8", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.8.tgz", + "integrity": "sha512-yb1cEmaOum7wFvOCSQxyfgVlv5D47Rc30iZWoMpbDIWTnJ6grDDQyu2KFJzB2k7u0pMuJcQ1zphH//fFnw2tjQ==", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.368", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.368.tgz", + "integrity": "sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.23.0.tgz", + "integrity": "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, + "node_modules/fast-xml-builder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", + "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "dependencies": { + "path-expression-matcher": "^1.5.0", + "xml-naming": "^0.1.0" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz", + "integrity": "sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "dependencies": { + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.2.0", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.3.0", + "xml-naming": "^0.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hot-patcher": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hot-patcher/-/hot-patcher-2.0.1.tgz", + "integrity": "sha512-ECg1JFG0YzehicQaogenlcs2qg6WsXQsxtnbr1i696u5tLUjtJdQAh0u2g0Q5YV45f263Ta1GnUJsc8WIfJf4Q==" + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-svg": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-6.1.0.tgz", + "integrity": "sha512-i7YPdvYuSCYcaLQrKwt8cvKTlwHcdA6Hp8N9SO3Q5jIzo8x6kH3N47W0BvPP7NdxVBmIHx7X9DK36czYYW7lHg==", + "dependencies": { + "@file-type/xml": "^0.4.3" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/layerr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/layerr/-/layerr-3.0.0.tgz", + "integrity": "sha512-tv754Ki2dXpPVApOrjTyRo4/QegVb9eVFq4mjqp4+NM5NaX7syQvN5BBNfV/ZpAHCEHV24XdUVrBAoka4jt3pA==" + }, + "node_modules/loader-runner": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", + "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", + "dev": true, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nested-property": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nested-property/-/nested-property-4.0.0.tgz", + "integrity": "sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA==" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-expression-matcher": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-posix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz", + "integrity": "sha512-1gJ0WpNIiYcQydgg3Ed8KzvIqTsDpNwq+cjBCssvBtuTWjEqY1AW+i+OepiEMqDCzyro9B2sLAe4RBPajMYFiA==" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "optional": true, + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.2.tgz", + "integrity": "sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/strnum": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz", + "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ] + }, + "node_modules/strtok3": { + "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz", + "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/typescript-event-target": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/typescript-event-target/-/typescript-event-target-1.1.2.tgz", + "integrity": "sha512-TvkrTUpv7gCPlcnSoEwUVUBwsdheKm+HF5u2tPAKubkIGMfovdSizCTaZRY/NhR8+Ijy8iZZUapbVQAsNrkFrw==" + }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/vue": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz", + "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==", + "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.", + "peer": true, + "dependencies": { + "@vue/compiler-sfc": "2.7.16", + "csstype": "^3.1.0" + } + }, + "node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webdav": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webdav/-/webdav-5.10.0.tgz", + "integrity": "sha512-fVPuRLtcduVGvSO7Tn/6TQCzIvI/g6BO/+xPRctCvi/GytYpjn4czxWbh4HsArsdom9qz9BI63k9/v2HBUui1A==", + "dependencies": { + "@buttercup/fetch": "^0.2.1", + "base-64": "^1.0.0", + "byte-length": "^1.0.2", + "entities": "^6.0.1", + "fast-xml-parser": "^5.7.2", + "hot-patcher": "^2.0.1", + "layerr": "^3.0.0", + "md5": "^2.3.0", + "minimatch": "^9.0.9", + "nested-property": "^4.0.0", + "node-fetch": "^3.3.2", + "path-posix": "^1.0.0", + "url-join": "^5.0.0", + "url-parse": "^1.5.10" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack": { + "version": "5.107.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.107.2.tgz", + "integrity": "sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.22.0", + "es-module-lexer": "^2.1.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "loader-runner": "^4.3.2", + "mime-db": "^1.54.0", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.5.0", + "watchpack": "^2.5.1", + "webpack-sources": "^3.5.0" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz", + "integrity": "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/xml-naming": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", + "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "engines": { + "node": ">=16.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e32669a --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "scripts": { + "build": "webpack --mode production" + }, + "dependencies": { + "@nextcloud/files": "^4.0.0", + "@nextcloud/viewer": "^1.0.0" + }, + "devDependencies": { + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4" + } +} diff --git a/src/viewerhandler.js b/src/viewerhandler.js new file mode 100644 index 0000000..ee53214 --- /dev/null +++ b/src/viewerhandler.js @@ -0,0 +1,127 @@ +import { registerHandler } from '@nextcloud/viewer' + +function loadKiCanvasScript() { + return new Promise((resolve, reject) => { + if (customElements.get('kc-kicanvas-shell')) { + resolve() + return + } + + const script = document.createElement('script') + script.type = 'module' + script.src = OC.linkTo('kicanvasviewer', 'js/kicanvas/kicanvas.js') + script.onload = resolve + script.onerror = reject + document.head.appendChild(script) + }) +} + +const KiCanvasInlineViewer = { + name: 'KiCanvasInlineViewer', + + data() { + return { + src: null, + error: null, + ready: false, + started: false, + } + }, + + async mounted() { + if (this.started) { + return + } + this.started = true + + const etag = this.$attrs?.etag + if (!etag) { + this.error = 'KiCanvas: no etag found' + return + } + + try { + const res = await fetch( + OC.generateUrl('/apps/kicanvasviewer/resolve/' + encodeURIComponent(etag)) + ) + + if (!res.ok) { + this.error = 'KiCanvas: could not resolve file' + return + } + + const data = await res.json() + + if (!data.fileId || !data.fileName) { + this.error = 'KiCanvas: resolve returned no fileId/fileName' + return + } + + this.src = window.location.origin + OC.generateUrl( + '/apps/kicanvasviewer/file/' + + encodeURIComponent(data.fileId) + + '/' + + encodeURIComponent(data.fileName) + ) + + await loadKiCanvasScript() + + this.ready = true + this.$forceUpdate() + } catch (e) { + console.error(e) + this.error = 'KiCanvas error' + } + }, + + render(h) { + if (this.error) { + return h('div', { + style: { + padding: '40px', + fontSize: '20px', + }, + }, this.error) + } + + if (!this.ready || !this.src) { + return h('div', { + style: { + padding: '40px', + fontSize: '20px', + }, + }, 'Loading KiCanvas...') + } + + return h('div', { + style: { + position: 'absolute', + inset: '0', + zIndex: 100, + background: 'var(--color-main-background)', + }, + }, [ + h('kc-kicanvas-shell', { + key: this.src, + attrs: { + src: this.src, + }, + style: { + display: 'block', + width: '100%', + height: '100%', + }, + }), + ]) + }, +} + +registerHandler({ + id: 'kicanvasviewer', + group: 'kicanvasviewer', + mimes: [ + 'application/x-kicad-schematic', + 'application/x-kicad-pcb', + ], + component: KiCanvasInlineViewer, +}) diff --git a/templates/viewer.php b/templates/viewer.php new file mode 100644 index 0000000..cc554df --- /dev/null +++ b/templates/viewer.php @@ -0,0 +1,22 @@ +getURLGenerator()->linkToRoute( + 'kicanvasviewer.viewer.file', + [ + 'fileId' => $fileId, + 'name' => $fileName, + ] +); +?> + +
+ +
diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..3a037bf --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,17 @@ +const path = require('path') + +module.exports = { + entry: { + viewerhandler: './src/viewerhandler.js', + }, + output: { + path: path.resolve(__dirname, 'js'), + filename: '[name].js', + clean: false, + }, + resolve: { + fallback: { + stream: false, + }, + }, +}