diff --git a/.gitignore b/.gitignore index 8317421..781d822 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -data/tokens.json \ No newline at end of file +data/tokens.json +dist/ diff --git a/dist/client/_astro/DeleteButton.CHpgpUL1.js b/dist/client/_astro/DeleteButton.CHpgpUL1.js deleted file mode 100644 index 1a64360..0000000 --- a/dist/client/_astro/DeleteButton.CHpgpUL1.js +++ /dev/null @@ -1 +0,0 @@ -import{c as m,a as o,d as v,t as h,l as C,g as x,w as D,v as T,b as k,T as E,h as S,i as d,m as B,o as c}from"./runtime-dom.esm-bundler.A7MyAQcw.js";import{_ as j}from"./_plugin-vue_export-helper.DlAUqK2U.js";const M=S({__name:"DeleteButton",props:{slug:{},authorEmail:{},authorName:{},authorHasToken:{type:Boolean}},setup(p,{expose:t}){t();const a=p,e=d(!1),u=d(!1),n=d(""),r=d(""),b=d();async function w(){if(a.authorEmail&&a.authorHasToken){const l=localStorage.getItem("skillshere-token")||"";if(l)try{if((await fetch("/api/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:a.authorEmail,token:l})})).ok){f(l);return}}catch{}u.value=!0,r.value="",n.value="",B(()=>b.value?.focus())}else f("")}async function _(){r.value="",e.value=!0;try{const l=await fetch("/api/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:a.authorEmail,token:n.value})});if(!l.ok){const s=await l.json();r.value=s.error||"Invalid token",e.value=!1;return}}catch{r.value="Could not verify token",e.value=!1;return}localStorage.setItem("skillshere-token",n.value),f(n.value)}async function f(l){if(!confirm(`Delete "${a.slug}"? This cannot be undone.`)){e.value=!1;return}e.value=!0,r.value="";try{const s={};l&&(s.Authorization=`Bearer ${l}`);const i=await fetch(`/api/skills/${a.slug}`,{method:"DELETE",headers:s});if(i.status===403){const y=await i.json();r.value=y.error||"Permission denied",u.value=!0,e.value=!1;return}if(!i.ok&&i.status!==204){const y=await i.json().catch(()=>({error:"Failed to delete"}));throw new Error(y.error||"Failed to delete")}window.location.href="/"}catch(s){r.value=s instanceof Error?s.message:"Failed to delete skill.",e.value=!1}}const g={props:a,deleting:e,showModal:u,token:n,error:r,tokenInput:b,handleClick:w,verifyAndDelete:_,doDelete:f};return Object.defineProperty(g,"__isScriptSetup",{enumerable:!1,value:!0}),g}}),N={class:"inline-flex"},P=["disabled"],I={class:"w-full max-w-md rounded-2xl border border-white/[0.08] bg-[var(--color-surface-200)] p-6 shadow-2xl"},O={class:"text-sm text-gray-500 mb-4"},V={class:"text-gray-300"},L={key:0,class:"mt-2 text-sm text-red-400"},z={class:"mt-4 flex items-center gap-3"},A=["disabled"],F={key:0,class:"h-4 w-4 animate-spin",fill:"none",viewBox:"0 0 24 24"};function H(p,t,a,e,u,n){return c(),m("div",N,[o("button",{onClick:e.handleClick,disabled:e.deleting,class:"inline-flex items-center gap-1.5 rounded-lg border border-red-500/20 bg-red-500/5 px-3.5 py-2 text-sm font-medium text-red-400 hover:bg-red-500/10 hover:border-red-500/30 disabled:opacity-50 active:scale-[0.97] transition-all"},[t[3]||(t[3]=o("svg",{class:"h-3.5 w-3.5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2"},[o("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"})],-1)),v(" "+h(e.deleting?"Deleting...":"Delete"),1)],8,P),(c(),C(E,{to:"body"},[e.showModal?(c(),m("div",{key:0,class:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm",onClick:t[2]||(t[2]=x(r=>e.showModal=!1,["self"]))},[o("div",I,[t[7]||(t[7]=o("h3",{class:"text-lg font-semibold text-red-400 mb-1"},"Delete Skill",-1)),o("p",O,[t[4]||(t[4]=v(" This skill is owned by ",-1)),o("strong",V,h(a.authorName||a.authorEmail),1),t[5]||(t[5]=v(". Enter your token to delete it. ",-1))]),o("form",{onSubmit:x(e.verifyAndDelete,["prevent"])},[D(o("input",{ref:"tokenInput","onUpdate:modelValue":t[0]||(t[0]=r=>e.token=r),type:"password",placeholder:"Paste your author token...",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white placeholder-gray-600 font-mono focus:border-red-500/50 focus:outline-none focus:ring-1 focus:ring-red-500/20 transition-all"},null,512),[[T,e.token]]),e.error?(c(),m("p",L,h(e.error),1)):k("",!0),o("div",z,[o("button",{type:"submit",disabled:e.deleting||!e.token,class:"inline-flex items-center gap-2 rounded-xl bg-red-500 px-5 py-2 text-sm font-semibold text-white hover:bg-red-600 disabled:opacity-50 active:scale-[0.97] transition-all"},[e.deleting?(c(),m("svg",F,[...t[6]||(t[6]=[o("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),o("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"},null,-1)])])):k("",!0),v(" "+h(e.deleting?"Deleting...":"Delete Permanently"),1)],8,A),o("button",{type:"button",onClick:t[1]||(t[1]=r=>e.showModal=!1),class:"ml-auto text-sm text-gray-600 hover:text-gray-300 transition-colors"}," Cancel ")])],32)])])):k("",!0)]))])}const U=j(M,[["render",H]]);export{U as default}; diff --git a/dist/client/_astro/EditGate.mFTQzSOo.js b/dist/client/_astro/EditGate.mFTQzSOo.js deleted file mode 100644 index 7e336d1..0000000 --- a/dist/client/_astro/EditGate.mFTQzSOo.js +++ /dev/null @@ -1 +0,0 @@ -import{c as d,a as o,d as u,l as b,g as p,t as f,w as C,v as _,b as m,T as S,F as T,h as E,i,m as M,o as c}from"./runtime-dom.esm-bundler.A7MyAQcw.js";import{_ as V}from"./_plugin-vue_export-helper.DlAUqK2U.js";const B=E({__name:"EditGate",props:{slug:{},authorEmail:{},authorName:{},authorHasToken:{type:Boolean}},setup(h,{expose:e}){e();const r=h,t=i(!1),s=i(""),a=i(""),n=i(!1),v=i();async function x(){if(!r.authorEmail||!r.authorHasToken){window.location.href=`/${r.slug}/edit`;return}const l=localStorage.getItem("skillshere-token")||"";if(l)try{if((await fetch("/api/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:r.authorEmail,token:l})})).ok){localStorage.setItem("skillshere-token",l),window.location.href=`/${r.slug}/edit`;return}}catch{}t.value=!0,a.value="",s.value="",M(()=>v.value?.focus())}async function g(){n.value=!0,a.value="";try{const l=await fetch("/api/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:r.authorEmail,token:s.value})});if(!l.ok){const y=await l.json();a.value=y.error||"Invalid token";return}localStorage.setItem("skillshere-token",s.value),window.location.href=`/${r.slug}/edit`}catch{a.value="Could not verify token"}finally{n.value=!1}}function w(){t.value=!1,window.location.href=`/new?from=${encodeURIComponent(r.slug)}`}const k={props:r,showModal:t,token:s,error:a,verifying:n,tokenInput:v,handleClick:x,verify:g,forkSkill:w};return Object.defineProperty(k,"__isScriptSetup",{enumerable:!1,value:!0}),k}}),I={class:"w-full max-w-md rounded-2xl border border-white/[0.08] bg-[var(--color-surface-200)] p-6 shadow-2xl"},N={class:"text-sm text-gray-500 mb-4"},j={class:"text-gray-300"},O={key:0,class:"mt-2 text-sm text-red-400"},A={class:"mt-4 flex items-center gap-3"},H=["disabled"],P={key:0,class:"h-4 w-4 animate-spin",fill:"none",viewBox:"0 0 24 24"};function F(h,e,r,t,s,a){return c(),d(T,null,[o("button",{onClick:t.handleClick,class:"inline-flex items-center gap-1.5 rounded-lg border border-white/[0.08] bg-surface-200 px-3.5 py-2 text-sm font-medium text-gray-300 hover:border-white/[0.15] hover:text-white transition-all"},[...e[3]||(e[3]=[o("svg",{class:"h-3.5 w-3.5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2"},[o("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"})],-1),u(" Edit ",-1)])]),(c(),b(S,{to:"body"},[t.showModal?(c(),d("div",{key:0,class:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm",onClick:e[2]||(e[2]=p(n=>t.showModal=!1,["self"]))},[o("div",I,[e[7]||(e[7]=o("h3",{class:"text-lg font-semibold text-white mb-1"},"Author Verification",-1)),o("p",N,[e[4]||(e[4]=u(" This skill is owned by ",-1)),o("strong",j,f(r.authorName||r.authorEmail),1),e[5]||(e[5]=u(". Enter your token to edit. ",-1))]),o("form",{onSubmit:p(t.verify,["prevent"])},[C(o("input",{ref:"tokenInput","onUpdate:modelValue":e[0]||(e[0]=n=>t.token=n),type:"password",placeholder:"Paste your author token...",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white placeholder-gray-600 font-mono focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},null,512),[[_,t.token]]),t.error?(c(),d("p",O,f(t.error),1)):m("",!0),o("div",A,[o("button",{type:"submit",disabled:t.verifying||!t.token,class:"inline-flex items-center gap-2 rounded-xl bg-[var(--color-accent-500)] px-5 py-2 text-sm font-semibold text-white shadow-lg shadow-[var(--color-accent-500)]/20 hover:bg-[var(--color-accent-600)] disabled:opacity-50 active:scale-[0.97] transition-all"},[t.verifying?(c(),d("svg",P,[...e[6]||(e[6]=[o("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),o("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"},null,-1)])])):m("",!0),u(" "+f(t.verifying?"Verifying...":"Continue to Edit"),1)],8,H),o("button",{type:"button",onClick:t.forkSkill,class:"text-sm text-[var(--color-accent-400)] hover:text-[var(--color-accent-300)] transition-colors"}," Fork instead "),o("button",{type:"button",onClick:e[1]||(e[1]=n=>t.showModal=!1),class:"ml-auto text-sm text-gray-600 hover:text-gray-300 transition-colors"}," Cancel ")])],32)])])):m("",!0)]))],64)}const D=V(B,[["render",F]]);export{D as default}; diff --git a/dist/client/_astro/SkillEditor.DYeR1V3X.js b/dist/client/_astro/SkillEditor.DYeR1V3X.js deleted file mode 100644 index a1296d3..0000000 --- a/dist/client/_astro/SkillEditor.DYeR1V3X.js +++ /dev/null @@ -1,66 +0,0 @@ -import{c as v,a as o,w as A,v as P,b as q,d as M,n as j,t as L,F as te,r as re,e as ge,f as Le,g as fe,h as lt,i as m,j as it,k as Q,o as S}from"./runtime-dom.esm-bundler.A7MyAQcw.js";import{_ as at}from"./_plugin-vue_export-helper.DlAUqK2U.js";function me(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var H=me();function _e(s){H=s}var D={exec:()=>null};function f(s,e=""){let t=typeof s=="string"?s:s.source,n={replace:(r,i)=>{let l=typeof i=="string"?i:i.source;return l=l.replace(T.caret,"$1"),t=t.replace(r,l),n},getRegex:()=>new RegExp(t,e)};return n}var ot=(()=>{try{return!!new RegExp("(?<=1)(?/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] +\S/,listReplaceTask:/^\[[ xX]\] +/,listTaskCheckbox:/\[[ xX]\]/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:s=>new RegExp(`^( {0,3}${s})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:s=>new RegExp(`^ {0,${Math.min(3,s-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),hrRegex:s=>new RegExp(`^ {0,${Math.min(3,s-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),fencesBeginRegex:s=>new RegExp(`^ {0,${Math.min(3,s-1)}}(?:\`\`\`|~~~)`),headingBeginRegex:s=>new RegExp(`^ {0,${Math.min(3,s-1)}}#`),htmlBeginRegex:s=>new RegExp(`^ {0,${Math.min(3,s-1)}}<(?:[a-z].*>|!--)`,"i"),blockquoteBeginRegex:s=>new RegExp(`^ {0,${Math.min(3,s-1)}}>`)},ct=/^(?:[ \t]*(?:\n|$))+/,ut=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,pt=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,X=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,ht=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,we=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,qe=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,De=f(qe).replace(/bull/g,we).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),dt=f(qe).replace(/bull/g,we).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),ye=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,gt=/^[^\n]+/,ve=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,ft=f(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",ve).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),kt=f(/^(bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,we).getRegex(),ae="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",Se=/|$))/,xt=f("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))","i").replace("comment",Se).replace("tag",ae).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Ne=f(ye).replace("hr",X).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",ae).getRegex(),bt=f(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",Ne).getRegex(),Te={blockquote:bt,code:ut,def:ft,fences:pt,heading:ht,hr:X,html:xt,lheading:De,list:kt,newline:ct,paragraph:Ne,table:D,text:gt},Ie=f("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",X).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",ae).getRegex(),mt={...Te,lheading:dt,table:Ie,paragraph:f(ye).replace("hr",X).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",Ie).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",ae).getRegex()},wt={...Te,html:f(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",Se).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:D,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:f(ye).replace("hr",X).replace("heading",` *#{1,6} *[^ -]`).replace("lheading",De).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},yt=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,vt=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,He=/^( {2,}|\\)\n(?!\s*$)/,St=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\`+)[^`]+\k(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-",ot?"(?`+)[^`]+\k(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),Ve=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,Lt=f(Ve,"u").replace(/punct/g,oe).getRegex(),It=f(Ve,"u").replace(/punct/g,je).getRegex(),Ue="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",Bt=f(Ue,"gu").replace(/notPunctSpace/g,Ze).replace(/punctSpace/g,Re).replace(/punct/g,oe).getRegex(),Et=f(Ue,"gu").replace(/notPunctSpace/g,At).replace(/punctSpace/g,Rt).replace(/punct/g,je).getRegex(),Pt=f("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,Ze).replace(/punctSpace/g,Re).replace(/punct/g,oe).getRegex(),Mt=f(/^~~?(?:((?!~)punct)|[^\s~])/,"u").replace(/punct/g,Fe).getRegex(),Ot="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",_t=f(Ot,"gu").replace(/notPunctSpace/g,Ct).replace(/punctSpace/g,zt).replace(/punct/g,Fe).getRegex(),qt=f(/\\(punct)/,"gu").replace(/punct/g,oe).getRegex(),Dt=f(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Nt=f(Se).replace("(?:-->|$)","-->").getRegex(),Ht=f("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment",Nt).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),se=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/,Zt=f(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label",se).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),Qe=f(/^!?\[(label)\]\[(ref)\]/).replace("label",se).replace("ref",ve).getRegex(),Ge=f(/^!?\[(ref)\](?:\[\])?/).replace("ref",ve).getRegex(),jt=f("reflink|nolink(?!\\()","g").replace("reflink",Qe).replace("nolink",Ge).getRegex(),Be=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,Ae={_backpedal:D,anyPunctuation:qt,autolink:Dt,blockSkip:$t,br:He,code:vt,del:D,delLDelim:D,delRDelim:D,emStrongLDelim:Lt,emStrongRDelimAst:Bt,emStrongRDelimUnd:Pt,escape:yt,link:Zt,nolink:Ge,punctuation:Tt,reflink:Qe,reflinkSearch:jt,tag:Ht,text:St,url:D},Ft={...Ae,link:f(/^!?\[(label)\]\((.*?)\)/).replace("label",se).getRegex(),reflink:f(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",se).getRegex()},ke={...Ae,emStrongRDelimAst:Et,emStrongLDelim:It,delLDelim:Mt,delRDelim:_t,url:f(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol",Be).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:f(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\":">",'"':""","'":"'"},Ee=s=>Ut[s];function E(s,e){if(e){if(T.escapeTest.test(s))return s.replace(T.escapeReplace,Ee)}else if(T.escapeTestNoEncode.test(s))return s.replace(T.escapeReplaceNoEncode,Ee);return s}function Pe(s){try{s=encodeURI(s).replace(T.percentDecode,"%")}catch{return null}return s}function Me(s,e){let t=s.replace(T.findPipe,(i,l,c)=>{let a=!1,p=l;for(;--p>=0&&c[p]==="\\";)a=!a;return a?"|":" |"}),n=t.split(T.splitPipe),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length0?-2:-1}function Gt(s,e=0){let t=e,n="";for(let r of s)if(r===" "){let i=4-t%4;n+=" ".repeat(i),t+=i}else n+=r,t++;return n}function Oe(s,e,t,n,r){let i=e.href,l=e.title||null,c=s[1].replace(r.other.outputLinkReplace,"$1");n.state.inLink=!0;let a={type:s[0].charAt(0)==="!"?"image":"link",raw:t,href:i,title:l,text:c,tokens:n.inlineTokens(c)};return n.state.inLink=!1,a}function Jt(s,e,t){let n=s.match(t.other.indentCodeCompensation);if(n===null)return e;let r=n[1];return e.split(` -`).map(i=>{let l=i.match(t.other.beginningSpace);if(l===null)return i;let[c]=l;return c.length>=r.length?i.slice(r.length):i}).join(` -`)}var le=class{options;rules;lexer;constructor(s){this.options=s||H}space(s){let e=this.rules.block.newline.exec(s);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(s){let e=this.rules.block.code.exec(s);if(e){let t=e[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?t:J(t,` -`)}}}fences(s){let e=this.rules.block.fences.exec(s);if(e){let t=e[0],n=Jt(t,e[3]||"",this.rules);return{type:"code",raw:t,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:n}}}heading(s){let e=this.rules.block.heading.exec(s);if(e){let t=e[2].trim();if(this.rules.other.endingHash.test(t)){let n=J(t,"#");(this.options.pedantic||!n||this.rules.other.endingSpaceChar.test(n))&&(t=n.trim())}return{type:"heading",raw:e[0],depth:e[1].length,text:t,tokens:this.lexer.inline(t)}}}hr(s){let e=this.rules.block.hr.exec(s);if(e)return{type:"hr",raw:J(e[0],` -`)}}blockquote(s){let e=this.rules.block.blockquote.exec(s);if(e){let t=J(e[0],` -`).split(` -`),n="",r="",i=[];for(;t.length>0;){let l=!1,c=[],a;for(a=0;a1,r={type:"list",raw:"",ordered:n,start:n?+t.slice(0,-1):"",loose:!1,items:[]};t=n?`\\d{1,9}\\${t.slice(-1)}`:`\\${t}`,this.options.pedantic&&(t=n?t:"[*+-]");let i=this.rules.other.listItemRegex(t),l=!1;for(;s;){let a=!1,p="",u="";if(!(e=i.exec(s))||this.rules.block.hr.test(s))break;p=e[0],s=s.substring(p.length);let g=Gt(e[2].split(` -`,1)[0],e[1].length),d=s.split(` -`,1)[0],w=!g.trim(),b=0;if(this.options.pedantic?(b=2,u=g.trimStart()):w?b=e[1].length+1:(b=g.search(this.rules.other.nonSpaceChar),b=b>4?1:b,u=g.slice(b),b+=e[1].length),w&&this.rules.other.blankLine.test(d)&&(p+=d+` -`,s=s.substring(d.length+1),a=!0),!a){let y=this.rules.other.nextBulletRegex(b),I=this.rules.other.hrRegex(b),F=this.rules.other.fencesBeginRegex(b),V=this.rules.other.headingBeginRegex(b),U=this.rules.other.htmlBeginRegex(b),Z=this.rules.other.blockquoteBeginRegex(b);for(;s;){let O=s.split(` -`,1)[0],B;if(d=O,this.options.pedantic?(d=d.replace(this.rules.other.listReplaceNesting," "),B=d):B=d.replace(this.rules.other.tabCharGlobal," "),F.test(d)||V.test(d)||U.test(d)||Z.test(d)||y.test(d)||I.test(d))break;if(B.search(this.rules.other.nonSpaceChar)>=b||!d.trim())u+=` -`+B.slice(b);else{if(w||g.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||F.test(g)||V.test(g)||I.test(g))break;u+=` -`+d}w=!d.trim(),p+=O+` -`,s=s.substring(O.length+1),g=B.slice(b)}}r.loose||(l?r.loose=!0:this.rules.other.doubleBlankLine.test(p)&&(l=!0)),r.items.push({type:"list_item",raw:p,task:!!this.options.gfm&&this.rules.other.listIsTask.test(u),loose:!1,text:u,tokens:[]}),r.raw+=p}let c=r.items.at(-1);if(c)c.raw=c.raw.trimEnd(),c.text=c.text.trimEnd();else return;r.raw=r.raw.trimEnd();for(let a of r.items){if(this.lexer.state.top=!1,a.tokens=this.lexer.blockTokens(a.text,[]),a.task){if(a.text=a.text.replace(this.rules.other.listReplaceTask,""),a.tokens[0]?.type==="text"||a.tokens[0]?.type==="paragraph"){a.tokens[0].raw=a.tokens[0].raw.replace(this.rules.other.listReplaceTask,""),a.tokens[0].text=a.tokens[0].text.replace(this.rules.other.listReplaceTask,"");for(let u=this.lexer.inlineQueue.length-1;u>=0;u--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[u].src)){this.lexer.inlineQueue[u].src=this.lexer.inlineQueue[u].src.replace(this.rules.other.listReplaceTask,"");break}}let p=this.rules.other.listTaskCheckbox.exec(a.raw);if(p){let u={type:"checkbox",raw:p[0]+" ",checked:p[0]!=="[ ]"};a.checked=u.checked,r.loose?a.tokens[0]&&["paragraph","text"].includes(a.tokens[0].type)&&"tokens"in a.tokens[0]&&a.tokens[0].tokens?(a.tokens[0].raw=u.raw+a.tokens[0].raw,a.tokens[0].text=u.raw+a.tokens[0].text,a.tokens[0].tokens.unshift(u)):a.tokens.unshift({type:"paragraph",raw:u.raw,text:u.raw,tokens:[u]}):a.tokens.unshift(u)}}if(!r.loose){let p=a.tokens.filter(g=>g.type==="space"),u=p.length>0&&p.some(g=>this.rules.other.anyLine.test(g.raw));r.loose=u}}if(r.loose)for(let a of r.items){a.loose=!0;for(let p of a.tokens)p.type==="text"&&(p.type="paragraph")}return r}}html(s){let e=this.rules.block.html.exec(s);if(e)return{type:"html",block:!0,raw:e[0],pre:e[1]==="pre"||e[1]==="script"||e[1]==="style",text:e[0]}}def(s){let e=this.rules.block.def.exec(s);if(e){let t=e[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),n=e[2]?e[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",r=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:t,raw:e[0],href:n,title:r}}}table(s){let e=this.rules.block.table.exec(s);if(!e||!this.rules.other.tableDelimiter.test(e[2]))return;let t=Me(e[1]),n=e[2].replace(this.rules.other.tableAlignChars,"").split("|"),r=e[3]?.trim()?e[3].replace(this.rules.other.tableRowBlankLine,"").split(` -`):[],i={type:"table",raw:e[0],header:[],align:[],rows:[]};if(t.length===n.length){for(let l of n)this.rules.other.tableAlignRight.test(l)?i.align.push("right"):this.rules.other.tableAlignCenter.test(l)?i.align.push("center"):this.rules.other.tableAlignLeft.test(l)?i.align.push("left"):i.align.push(null);for(let l=0;l({text:c,tokens:this.lexer.inline(c),header:!1,align:i.align[a]})));return i}}lheading(s){let e=this.rules.block.lheading.exec(s);if(e)return{type:"heading",raw:e[0],depth:e[2].charAt(0)==="="?1:2,text:e[1],tokens:this.lexer.inline(e[1])}}paragraph(s){let e=this.rules.block.paragraph.exec(s);if(e){let t=e[1].charAt(e[1].length-1)===` -`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:t,tokens:this.lexer.inline(t)}}}text(s){let e=this.rules.block.text.exec(s);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(s){let e=this.rules.inline.escape.exec(s);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(s){let e=this.rules.inline.tag.exec(s);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(s){let e=this.rules.inline.link.exec(s);if(e){let t=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(t)){if(!this.rules.other.endAngleBracket.test(t))return;let i=J(t.slice(0,-1),"\\");if((t.length-i.length)%2===0)return}else{let i=Qt(e[2],"()");if(i===-2)return;if(i>-1){let l=(e[0].indexOf("!")===0?5:4)+e[1].length+i;e[2]=e[2].substring(0,i),e[0]=e[0].substring(0,l).trim(),e[3]=""}}let n=e[2],r="";if(this.options.pedantic){let i=this.rules.other.pedanticHrefTitle.exec(n);i&&(n=i[1],r=i[3])}else r=e[3]?e[3].slice(1,-1):"";return n=n.trim(),this.rules.other.startAngleBracket.test(n)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(t)?n=n.slice(1):n=n.slice(1,-1)),Oe(e,{href:n&&n.replace(this.rules.inline.anyPunctuation,"$1"),title:r&&r.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(s,e){let t;if((t=this.rules.inline.reflink.exec(s))||(t=this.rules.inline.nolink.exec(s))){let n=(t[2]||t[1]).replace(this.rules.other.multipleSpaceGlobal," "),r=e[n.toLowerCase()];if(!r){let i=t[0].charAt(0);return{type:"text",raw:i,text:i}}return Oe(t,r,t[0],this.lexer,this.rules)}}emStrong(s,e,t=""){let n=this.rules.inline.emStrongLDelim.exec(s);if(!(!n||n[3]&&t.match(this.rules.other.unicodeAlphaNumeric))&&(!(n[1]||n[2])||!t||this.rules.inline.punctuation.exec(t))){let r=[...n[0]].length-1,i,l,c=r,a=0,p=n[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(p.lastIndex=0,e=e.slice(-1*s.length+r);(n=p.exec(e))!=null;){if(i=n[1]||n[2]||n[3]||n[4]||n[5]||n[6],!i)continue;if(l=[...i].length,n[3]||n[4]){c+=l;continue}else if((n[5]||n[6])&&r%3&&!((r+l)%3)){a+=l;continue}if(c-=l,c>0)continue;l=Math.min(l,l+c+a);let u=[...n[0]][0].length,g=s.slice(0,r+n.index+u+l);if(Math.min(r,l)%2){let w=g.slice(1,-1);return{type:"em",raw:g,text:w,tokens:this.lexer.inlineTokens(w)}}let d=g.slice(2,-2);return{type:"strong",raw:g,text:d,tokens:this.lexer.inlineTokens(d)}}}}codespan(s){let e=this.rules.inline.code.exec(s);if(e){let t=e[2].replace(this.rules.other.newLineCharGlobal," "),n=this.rules.other.nonSpaceChar.test(t),r=this.rules.other.startingSpaceChar.test(t)&&this.rules.other.endingSpaceChar.test(t);return n&&r&&(t=t.substring(1,t.length-1)),{type:"codespan",raw:e[0],text:t}}}br(s){let e=this.rules.inline.br.exec(s);if(e)return{type:"br",raw:e[0]}}del(s,e,t=""){let n=this.rules.inline.delLDelim.exec(s);if(n&&(!n[1]||!t||this.rules.inline.punctuation.exec(t))){let r=[...n[0]].length-1,i,l,c=r,a=this.rules.inline.delRDelim;for(a.lastIndex=0,e=e.slice(-1*s.length+r);(n=a.exec(e))!=null;){if(i=n[1]||n[2]||n[3]||n[4]||n[5]||n[6],!i||(l=[...i].length,l!==r))continue;if(n[3]||n[4]){c+=l;continue}if(c-=l,c>0)continue;l=Math.min(l,l+c);let p=[...n[0]][0].length,u=s.slice(0,r+n.index+p+l),g=u.slice(r,-r);return{type:"del",raw:u,text:g,tokens:this.lexer.inlineTokens(g)}}}}autolink(s){let e=this.rules.inline.autolink.exec(s);if(e){let t,n;return e[2]==="@"?(t=e[1],n="mailto:"+t):(t=e[1],n=t),{type:"link",raw:e[0],text:t,href:n,tokens:[{type:"text",raw:t,text:t}]}}}url(s){let e;if(e=this.rules.inline.url.exec(s)){let t,n;if(e[2]==="@")t=e[0],n="mailto:"+t;else{let r;do r=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(r!==e[0]);t=e[0],e[1]==="www."?n="http://"+e[0]:n=e[0]}return{type:"link",raw:e[0],text:t,href:n,tokens:[{type:"text",raw:t,text:t}]}}}inlineText(s){let e=this.rules.inline.text.exec(s);if(e){let t=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:t}}}},z=class xe{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||H,this.options.tokenizer=this.options.tokenizer||new le,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:T,block:ne.normal,inline:G.normal};this.options.pedantic?(t.block=ne.pedantic,t.inline=G.pedantic):this.options.gfm&&(t.block=ne.gfm,this.options.breaks?t.inline=G.breaks:t.inline=G.gfm),this.tokenizer.rules=t}static get rules(){return{block:ne,inline:G}}static lex(e,t){return new xe(t).lex(e)}static lexInline(e,t){return new xe(t).inlineTokens(e)}lex(e){e=e.replace(T.carriageReturn,` -`),this.blockTokens(e,this.tokens);for(let t=0;t(r=l.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),!0):!1))continue;if(r=this.tokenizer.space(e)){e=e.substring(r.raw.length);let l=t.at(-1);r.raw.length===1&&l!==void 0?l.raw+=` -`:t.push(r);continue}if(r=this.tokenizer.code(e)){e=e.substring(r.raw.length);let l=t.at(-1);l?.type==="paragraph"||l?.type==="text"?(l.raw+=(l.raw.endsWith(` -`)?"":` -`)+r.raw,l.text+=` -`+r.text,this.inlineQueue.at(-1).src=l.text):t.push(r);continue}if(r=this.tokenizer.fences(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.heading(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.hr(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.blockquote(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.list(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.html(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.def(e)){e=e.substring(r.raw.length);let l=t.at(-1);l?.type==="paragraph"||l?.type==="text"?(l.raw+=(l.raw.endsWith(` -`)?"":` -`)+r.raw,l.text+=` -`+r.raw,this.inlineQueue.at(-1).src=l.text):this.tokens.links[r.tag]||(this.tokens.links[r.tag]={href:r.href,title:r.title},t.push(r));continue}if(r=this.tokenizer.table(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.lheading(e)){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startBlock){let l=1/0,c=e.slice(1),a;this.options.extensions.startBlock.forEach(p=>{a=p.call({lexer:this},c),typeof a=="number"&&a>=0&&(l=Math.min(l,a))}),l<1/0&&l>=0&&(i=e.substring(0,l+1))}if(this.state.top&&(r=this.tokenizer.paragraph(i))){let l=t.at(-1);n&&l?.type==="paragraph"?(l.raw+=(l.raw.endsWith(` -`)?"":` -`)+r.raw,l.text+=` -`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):t.push(r),n=i.length!==e.length,e=e.substring(r.raw.length);continue}if(r=this.tokenizer.text(e)){e=e.substring(r.raw.length);let l=t.at(-1);l?.type==="text"?(l.raw+=(l.raw.endsWith(` -`)?"":` -`)+r.raw,l.text+=` -`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):t.push(r);continue}if(e){let l="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(l);break}else throw new Error(l)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n=e,r=null;if(this.tokens.links){let a=Object.keys(this.tokens.links);if(a.length>0)for(;(r=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)a.includes(r[0].slice(r[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(r=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,r.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let i;for(;(r=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)i=r[2]?r[2].length:0,n=n.slice(0,r.index+i)+"["+"a".repeat(r[0].length-i-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);n=this.options.hooks?.emStrongMask?.call({lexer:this},n)??n;let l=!1,c="";for(;e;){l||(c=""),l=!1;let a;if(this.options.extensions?.inline?.some(u=>(a=u.call({lexer:this},e,t))?(e=e.substring(a.raw.length),t.push(a),!0):!1))continue;if(a=this.tokenizer.escape(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.tag(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.link(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(a.raw.length);let u=t.at(-1);a.type==="text"&&u?.type==="text"?(u.raw+=a.raw,u.text+=a.text):t.push(a);continue}if(a=this.tokenizer.emStrong(e,n,c)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.codespan(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.br(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.del(e,n,c)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.autolink(e)){e=e.substring(a.raw.length),t.push(a);continue}if(!this.state.inLink&&(a=this.tokenizer.url(e))){e=e.substring(a.raw.length),t.push(a);continue}let p=e;if(this.options.extensions?.startInline){let u=1/0,g=e.slice(1),d;this.options.extensions.startInline.forEach(w=>{d=w.call({lexer:this},g),typeof d=="number"&&d>=0&&(u=Math.min(u,d))}),u<1/0&&u>=0&&(p=e.substring(0,u+1))}if(a=this.tokenizer.inlineText(p)){e=e.substring(a.raw.length),a.raw.slice(-1)!=="_"&&(c=a.raw.slice(-1)),l=!0;let u=t.at(-1);u?.type==="text"?(u.raw+=a.raw,u.text+=a.text):t.push(a);continue}if(e){let u="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(u);break}else throw new Error(u)}}return t}},ie=class{options;parser;constructor(s){this.options=s||H}space(s){return""}code({text:s,lang:e,escaped:t}){let n=(e||"").match(T.notSpaceStart)?.[0],r=s.replace(T.endingNewline,"")+` -`;return n?'
'+(t?r:E(r,!0))+`
-`:"
"+(t?r:E(r,!0))+`
-`}blockquote({tokens:s}){return`
-${this.parser.parse(s)}
-`}html({text:s}){return s}def(s){return""}heading({tokens:s,depth:e}){return`${this.parser.parseInline(s)} -`}hr(s){return`
-`}list(s){let e=s.ordered,t=s.start,n="";for(let l=0;l -`+n+" -`}listitem(s){return`
  • ${this.parser.parse(s.tokens)}
  • -`}checkbox({checked:s}){return" '}paragraph({tokens:s}){return`

    ${this.parser.parseInline(s)}

    -`}table(s){let e="",t="";for(let r=0;r${n}`),` - -`+e+` -`+n+`
    -`}tablerow({text:s}){return` -${s} -`}tablecell(s){let e=this.parser.parseInline(s.tokens),t=s.header?"th":"td";return(s.align?`<${t} align="${s.align}">`:`<${t}>`)+e+` -`}strong({tokens:s}){return`${this.parser.parseInline(s)}`}em({tokens:s}){return`${this.parser.parseInline(s)}`}codespan({text:s}){return`${E(s,!0)}`}br(s){return"
    "}del({tokens:s}){return`${this.parser.parseInline(s)}`}link({href:s,title:e,tokens:t}){let n=this.parser.parseInline(t),r=Pe(s);if(r===null)return n;s=r;let i='
    ",i}image({href:s,title:e,text:t,tokens:n}){n&&(t=this.parser.parseInline(n,this.parser.textRenderer));let r=Pe(s);if(r===null)return E(t);s=r;let i=`${t}{let l=r[i].flat(1/0);t=t.concat(this.walkTokens(l,e))}):r.tokens&&(t=t.concat(this.walkTokens(r.tokens,e)))}}return t}use(...s){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return s.forEach(t=>{let n={...t};if(n.async=this.defaults.async||n.async||!1,t.extensions&&(t.extensions.forEach(r=>{if(!r.name)throw new Error("extension name required");if("renderer"in r){let i=e.renderers[r.name];i?e.renderers[r.name]=function(...l){let c=r.renderer.apply(this,l);return c===!1&&(c=i.apply(this,l)),c}:e.renderers[r.name]=r.renderer}if("tokenizer"in r){if(!r.level||r.level!=="block"&&r.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let i=e[r.level];i?i.unshift(r.tokenizer):e[r.level]=[r.tokenizer],r.start&&(r.level==="block"?e.startBlock?e.startBlock.push(r.start):e.startBlock=[r.start]:r.level==="inline"&&(e.startInline?e.startInline.push(r.start):e.startInline=[r.start]))}"childTokens"in r&&r.childTokens&&(e.childTokens[r.name]=r.childTokens)}),n.extensions=e),t.renderer){let r=this.defaults.renderer||new ie(this.defaults);for(let i in t.renderer){if(!(i in r))throw new Error(`renderer '${i}' does not exist`);if(["options","parser"].includes(i))continue;let l=i,c=t.renderer[l],a=r[l];r[l]=(...p)=>{let u=c.apply(r,p);return u===!1&&(u=a.apply(r,p)),u||""}}n.renderer=r}if(t.tokenizer){let r=this.defaults.tokenizer||new le(this.defaults);for(let i in t.tokenizer){if(!(i in r))throw new Error(`tokenizer '${i}' does not exist`);if(["options","rules","lexer"].includes(i))continue;let l=i,c=t.tokenizer[l],a=r[l];r[l]=(...p)=>{let u=c.apply(r,p);return u===!1&&(u=a.apply(r,p)),u}}n.tokenizer=r}if(t.hooks){let r=this.defaults.hooks||new W;for(let i in t.hooks){if(!(i in r))throw new Error(`hook '${i}' does not exist`);if(["options","block"].includes(i))continue;let l=i,c=t.hooks[l],a=r[l];W.passThroughHooks.has(i)?r[l]=p=>{if(this.defaults.async&&W.passThroughHooksRespectAsync.has(i))return(async()=>{let g=await c.call(r,p);return a.call(r,g)})();let u=c.call(r,p);return a.call(r,u)}:r[l]=(...p)=>{if(this.defaults.async)return(async()=>{let g=await c.apply(r,p);return g===!1&&(g=await a.apply(r,p)),g})();let u=c.apply(r,p);return u===!1&&(u=a.apply(r,p)),u}}n.hooks=r}if(t.walkTokens){let r=this.defaults.walkTokens,i=t.walkTokens;n.walkTokens=function(l){let c=[];return c.push(i.call(this,l)),r&&(c=c.concat(r.call(this,l))),c}}this.defaults={...this.defaults,...n}}),this}setOptions(s){return this.defaults={...this.defaults,...s},this}lexer(s,e){return z.lex(s,e??this.defaults)}parser(s,e){return C.parse(s,e??this.defaults)}parseMarkdown(s){return(e,t)=>{let n={...t},r={...this.defaults,...n},i=this.onError(!!r.silent,!!r.async);if(this.defaults.async===!0&&n.async===!1)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof e>"u"||e===null)return i(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));if(r.hooks&&(r.hooks.options=r,r.hooks.block=s),r.async)return(async()=>{let l=r.hooks?await r.hooks.preprocess(e):e,c=await(r.hooks?await r.hooks.provideLexer():s?z.lex:z.lexInline)(l,r),a=r.hooks?await r.hooks.processAllTokens(c):c;r.walkTokens&&await Promise.all(this.walkTokens(a,r.walkTokens));let p=await(r.hooks?await r.hooks.provideParser():s?C.parse:C.parseInline)(a,r);return r.hooks?await r.hooks.postprocess(p):p})().catch(i);try{r.hooks&&(e=r.hooks.preprocess(e));let l=(r.hooks?r.hooks.provideLexer():s?z.lex:z.lexInline)(e,r);r.hooks&&(l=r.hooks.processAllTokens(l)),r.walkTokens&&this.walkTokens(l,r.walkTokens);let c=(r.hooks?r.hooks.provideParser():s?C.parse:C.parseInline)(l,r);return r.hooks&&(c=r.hooks.postprocess(c)),c}catch(l){return i(l)}}}onError(s,e){return t=>{if(t.message+=` -Please report this to https://github.com/markedjs/marked.`,s){let n="

    An error occurred:

    "+E(t.message+"",!0)+"
    ";return e?Promise.resolve(n):n}if(e)return Promise.reject(t);throw t}}},N=new Wt;function x(s,e){return N.parse(s,e)}x.options=x.setOptions=function(s){return N.setOptions(s),x.defaults=N.defaults,_e(x.defaults),x};x.getDefaults=me;x.defaults=H;x.use=function(...s){return N.use(...s),x.defaults=N.defaults,_e(x.defaults),x};x.walkTokens=function(s,e){return N.walkTokens(s,e)};x.parseInline=N.parseInline;x.Parser=C;x.parser=C.parse;x.Renderer=ie;x.TextRenderer=ze;x.Lexer=z;x.lexer=z.lex;x.Tokenizer=le;x.Hooks=W;x.parse=x;x.options;x.setOptions;x.use;x.walkTokens;x.parseInline;C.parse;z.lex;const Xt=lt({__name:"SkillEditor",props:{mode:{},slug:{},forkOf:{},initialName:{},initialDescription:{},initialAllowedTools:{},initialArgumentHint:{},initialModel:{},initialUserInvocable:{type:Boolean},initialDisableModelInvocation:{type:Boolean},initialContext:{},initialAgent:{},initialHooks:{},initialBody:{},initialAuthor:{},initialAuthorEmail:{},initialTags:{},availableTools:{},availableModels:{},availableTags:{}},setup(s,{expose:e}){e();const t=s,n=t.availableTools??["Bash","Read","Write","Edit","Glob","Grep","WebFetch","WebSearch","Task","NotebookEdit"],r=t.availableModels??[{id:"claude-opus-4-6",display_name:"Claude Opus 4.6"},{id:"claude-sonnet-4-5-20250929",display_name:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",display_name:"Claude Haiku 4.5"}],i=Q(()=>!!t.forkOf),l=m(t.initialName||""),c=m(t.initialDescription||""),a=m(t.initialArgumentHint||""),p=m(t.initialModel||""),u=m(t.initialUserInvocable??!0),g=m(t.initialDisableModelInvocation??!1),d=m(t.initialContext||""),w=m(t.initialAgent||""),b=m(t.initialHooks||""),y=m(t.initialTags?t.initialTags.split(",").map(h=>h.trim()).filter(Boolean):[]),I=m(""),F=m(!1),V=m(),U=t.availableTags?t.availableTags.split(",").map(h=>h.trim()).filter(Boolean):[],Z=m(t.initialBody||""),O=m(!1),B=m(""),ce=m(""),ue=m(""),pe=m(typeof localStorage<"u"&&localStorage.getItem("skillshere-token")||""),_=m(new Set(t.initialAllowedTools?t.initialAllowedTools.split(",").map(h=>h.trim()).filter(Boolean):[]));function Je(h){_.value.has(h)?_.value.delete(h):_.value.add(h),_.value=new Set(_.value)}const We=Q(()=>{const h=I.value.toLowerCase().trim(),k=new Set(y.value.map($=>$.toLowerCase())),R=U.filter($=>!k.has($.toLowerCase())&&(!h||$.toLowerCase().includes(h)));return h&&!k.has(h)&&!R.some($=>$.toLowerCase()===h)&&R.push(h),R}),Xe=h=>!U.some(k=>k.toLowerCase()===h.toLowerCase());function he(h){const k=h.trim().toLowerCase();k&&!y.value.some(R=>R.toLowerCase()===k)&&y.value.push(k),I.value="",V.value?.focus()}function Ke(h){y.value.splice(h,1)}function Ye(h){h.key==="Enter"||h.key===","?(h.preventDefault(),I.value.trim()&&he(I.value)):h.key==="Backspace"&&!I.value&&y.value.length&&y.value.pop()}let K;function et(){K=setTimeout(()=>{F.value=!1},200)}function tt(h){clearTimeout(K),he(h)}const Y=Q(()=>t.mode==="edit"&&t.slug?t.slug:l.value.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)||"my-skill"),rt=Q(()=>t.forkOf?Y.value===t.forkOf:!1),nt=Q(()=>Z.value.split(` -`).length);let de=m(""),ee;it(Z,h=>{clearTimeout(ee),ee=setTimeout(async()=>{de.value=await x(h||"")},300)},{immediate:!0});function Ce(){const h=[..._.value],k=["---"];if(k.push(`name: ${l.value}`),c.value&&k.push(`description: ${c.value}`),i.value?(ce.value&&k.push(`author: ${ce.value}`),ue.value&&k.push(`author-email: ${ue.value}`),k.push(`fork-of: ${t.forkOf}`)):(t.initialAuthor&&k.push(`author: ${t.initialAuthor}`),t.initialAuthorEmail&&k.push(`author-email: ${t.initialAuthorEmail}`)),a.value&&k.push(`argument-hint: ${a.value}`),h.length>0&&k.push(`allowed-tools: ${h.join(", ")}`),y.value.length>0&&k.push(`tags: ${y.value.join(", ")}`),p.value&&k.push(`model: ${p.value}`),u.value===!1&&k.push("user-invocable: false"),g.value&&k.push("disable-model-invocation: true"),d.value&&k.push(`context: ${d.value}`),w.value&&k.push(`agent: ${w.value}`),b.value.trim())try{const R=JSON.parse(b.value.trim());k.push(`hooks: ${JSON.stringify(R)}`)}catch{}return k.push("---"),k.join(` -`)+` - -`+Z.value.trim()+` -`}async function st(){O.value=!0,B.value="";try{const h=Ce(),k={"Content-Type":"application/json"};if(!i.value&&pe.value&&(k.Authorization=`Bearer ${pe.value}`),t.mode==="create"){const R=await fetch("/api/skills",{method:"POST",headers:k,body:JSON.stringify({slug:Y.value,content:h})});if(!R.ok){const $=await R.json();throw new Error($.error||"Failed to create skill")}window.location.href=`/${Y.value}`}else{const R=await fetch(`/api/skills/${t.slug}`,{method:"PUT",headers:k,body:JSON.stringify({content:h})});if(!R.ok){const $=await R.json();throw new Error($.error||"Failed to update skill")}window.location.href=`/${t.slug}`}}catch(h){B.value=h instanceof Error?h.message:"Something went wrong"}finally{O.value=!1}}const $e={props:t,AVAILABLE_TOOLS:n,AVAILABLE_MODELS:r,isFork:i,name:l,description:c,argumentHint:a,model:p,userInvocable:u,disableModelInvocation:g,context:d,agent:w,hooksJson:b,tags:y,tagQuery:I,tagSuggestionsOpen:F,tagInputEl:V,knownTags:U,body:Z,saving:O,error:B,forkAuthorName:ce,forkAuthorEmail:ue,authorToken:pe,selectedTools:_,toggleTool:Je,tagSuggestions:We,isNewTag:Xe,addTag:he,removeTag:Ke,onTagKeydown:Ye,get tagBlurTimer(){return K},set tagBlurTimer(h){K=h},onTagBlur:et,onTagSuggestionClick:tt,computedSlug:Y,slugMatchesOriginal:rt,bodyLines:nt,get previewHtml(){return de},set previewHtml(h){de=h},get debounceTimer(){return ee},set debounceTimer(h){ee=h},buildContent:Ce,save:st};return Object.defineProperty($e,"__isScriptSetup",{enumerable:!1,value:!0}),$e}}),Kt={key:0,class:"rounded-xl border border-[var(--color-accent-500)]/20 bg-[var(--color-accent-500)]/5 p-4 space-y-3"},Yt={class:"grid gap-3 sm:grid-cols-2"},er={key:1,class:"rounded-xl border border-amber-500/20 bg-amber-500/5 p-4"},tr={class:"grid gap-4 sm:grid-cols-2"},rr={class:"mt-1.5 text-xs text-gray-600 flex justify-between"},nr={class:"relative"},sr=["onClick"],lr={key:0,class:"absolute z-10 mt-1 w-full max-h-40 overflow-auto rounded-xl border border-white/[0.08] bg-[var(--color-surface-200)] shadow-xl"},ir=["onMousedown"],ar={key:0,class:"text-[var(--color-accent-500)] text-xs"},or={key:1,class:"text-xs text-gray-600"},cr={class:"flex flex-wrap gap-1.5 rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-3 py-2.5 min-h-[42px]"},ur=["onClick"],pr={class:"grid gap-4 sm:grid-cols-3"},hr=["value"],dr={class:"flex flex-wrap gap-6"},gr={class:"flex items-center gap-2.5 cursor-pointer group"},fr={class:"flex items-center gap-2.5 cursor-pointer group"},kr={class:"group"},xr={class:"mt-3"},br={class:"grid gap-4 lg:grid-cols-2"},mr={class:"flex justify-between text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},wr=["innerHTML"],yr={class:"flex items-center gap-4 pt-2"},vr=["disabled","title"],Sr={key:0,class:"h-4 w-4 animate-spin",fill:"none",viewBox:"0 0 24 24"},Tr={key:0,class:"text-sm text-red-400"};function Rr(s,e,t,n,r,i){return S(),v("form",{onSubmit:fe(n.save,["prevent"]),class:"space-y-6"},[n.isFork?(S(),v("div",Kt,[e[19]||(e[19]=o("p",{class:"text-sm text-[var(--color-accent-400)]"},"Claim this fork as yours. It will stay open for editing until you push from CLI, which registers a token and locks it to you.",-1)),o("div",Yt,[o("div",null,[e[17]||(e[17]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1"},"Your Name",-1)),A(o("input",{"onUpdate:modelValue":e[0]||(e[0]=l=>n.forkAuthorName=l),type:"text",placeholder:"Jane Doe",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white placeholder-gray-600 focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},null,512),[[P,n.forkAuthorName]])]),o("div",null,[e[18]||(e[18]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1"},"Your Email",-1)),A(o("input",{"onUpdate:modelValue":e[1]||(e[1]=l=>n.forkAuthorEmail=l),type:"email",placeholder:"jane@example.com",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white placeholder-gray-600 focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},null,512),[[P,n.forkAuthorEmail]])])])])):q("",!0),n.isFork&&n.slugMatchesOriginal?(S(),v("div",er,[...e[20]||(e[20]=[o("p",{class:"text-sm text-amber-400"},[M("Change the "),o("strong",null,"name"),M(" to generate a different slug. You can't save a fork with the same slug as the original.")],-1)])])):q("",!0),o("div",tr,[o("div",null,[e[22]||(e[22]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Name",-1)),A(o("input",{"onUpdate:modelValue":e[2]||(e[2]=l=>n.name=l),type:"text",required:"",maxlength:"64",placeholder:"My Awesome Skill",class:j(["w-full rounded-xl border px-4 py-2.5 text-sm text-white placeholder-gray-600 focus:outline-none focus:ring-1 transition-all",n.isFork&&n.slugMatchesOriginal?"border-amber-500/30 bg-[var(--color-surface-100)] focus:border-amber-500/50 focus:ring-amber-500/20":"border-white/[0.06] bg-[var(--color-surface-100)] focus:border-[var(--color-accent-500)]/50 focus:ring-[var(--color-accent-500)]/20"])},null,2),[[P,n.name]]),o("p",rr,[o("span",null,[e[21]||(e[21]=M("Slug: ",-1)),o("code",{class:j(["font-mono",n.isFork&&n.slugMatchesOriginal?"text-amber-500":"text-gray-500"])},L(n.computedSlug),3)]),o("span",{class:j(n.name.length>58?"text-amber-500":"")},L(n.name.length)+"/64",3)])]),o("div",null,[e[23]||(e[23]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Description",-1)),A(o("input",{"onUpdate:modelValue":e[3]||(e[3]=l=>n.description=l),type:"text",maxlength:"200",placeholder:"Brief description of what this skill does",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white placeholder-gray-600 focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},null,512),[[P,n.description]]),o("p",{class:j(["mt-1.5 text-xs text-gray-600 text-right",n.description.length>180?"text-amber-500":""])},L(n.description.length)+"/200",3)])]),o("div",nr,[e[25]||(e[25]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Tags",-1)),o("div",{class:"flex flex-wrap items-center gap-1.5 rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-3 py-2 min-h-[42px] cursor-text focus-within:border-[var(--color-accent-500)]/50 focus-within:ring-1 focus-within:ring-[var(--color-accent-500)]/20 transition-all",onClick:e[8]||(e[8]=l=>n.tagInputEl?.focus())},[(S(!0),v(te,null,re(n.tags,(l,c)=>(S(),v("span",{key:l,class:"inline-flex items-center gap-1 rounded-full bg-[var(--color-accent-500)]/15 border border-[var(--color-accent-500)]/25 pl-2.5 pr-1.5 py-0.5 text-xs font-medium text-[var(--color-accent-400)]"},[M(L(l)+" ",1),o("button",{type:"button",onClick:fe(a=>n.removeTag(c),["stop"]),class:"rounded-full p-0.5 hover:bg-[var(--color-accent-500)]/30 transition-colors"},[...e[24]||(e[24]=[o("svg",{class:"h-3 w-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2.5"},[o("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M6 18 18 6M6 6l12 12"})],-1)])],8,sr)]))),128)),A(o("input",{ref:"tagInputEl","onUpdate:modelValue":e[4]||(e[4]=l=>n.tagQuery=l),type:"text",placeholder:"Add tag...",class:"flex-1 min-w-[80px] bg-transparent text-sm text-white placeholder-gray-600 outline-none",onKeydown:n.onTagKeydown,onFocus:e[5]||(e[5]=l=>n.tagSuggestionsOpen=!0),onClick:e[6]||(e[6]=l=>n.tagSuggestionsOpen=!0),onInput:e[7]||(e[7]=l=>n.tagSuggestionsOpen=!0),onBlur:n.onTagBlur},null,544),[[P,n.tagQuery]])]),n.tagSuggestionsOpen&&n.tagSuggestions.length>0?(S(),v("div",lr,[(S(!0),v(te,null,re(n.tagSuggestions,l=>(S(),v("button",{key:l,type:"button",onMousedown:fe(c=>n.onTagSuggestionClick(l),["prevent"]),class:"flex w-full items-center gap-2 px-4 py-2 text-sm text-gray-300 hover:bg-white/[0.06] hover:text-white transition-colors text-left"},[n.isNewTag(l)?(S(),v("span",ar,"+")):q("",!0),M(" "+L(l)+" ",1),n.isNewTag(l)?(S(),v("span",or,"(new)")):q("",!0)],40,ir))),128))])):q("",!0),e[26]||(e[26]=o("p",{class:"mt-1.5 text-xs text-gray-600"},"Type and press Enter or comma. Click suggestions to add.",-1))]),o("div",null,[e[27]||(e[27]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Allowed Tools",-1)),o("div",cr,[(S(!0),v(te,null,re(n.AVAILABLE_TOOLS,l=>(S(),v("button",{key:l,type:"button",onClick:c=>n.toggleTool(l),class:j(["rounded-md px-2.5 py-1 text-xs font-medium transition-all",n.selectedTools.has(l)?"bg-[var(--color-accent-500)] text-white shadow-sm":"bg-white/[0.04] border border-white/[0.06] text-gray-500 hover:text-gray-300 hover:bg-white/[0.08]"])},L(l),11,ur))),128))])]),o("div",pr,[o("div",null,[e[29]||(e[29]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Model",-1)),A(o("select",{"onUpdate:modelValue":e[9]||(e[9]=l=>n.model=l),class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},[e[28]||(e[28]=o("option",{value:""},"Default",-1)),(S(!0),v(te,null,re(n.AVAILABLE_MODELS,l=>(S(),v("option",{key:l.id,value:l.id},L(l.display_name),9,hr))),128))],512),[[ge,n.model]])]),o("div",null,[e[30]||(e[30]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Argument Hint",-1)),A(o("input",{"onUpdate:modelValue":e[10]||(e[10]=l=>n.argumentHint=l),type:"text",placeholder:"e.g. ",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white placeholder-gray-600 focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},null,512),[[P,n.argumentHint]])]),o("div",null,[e[32]||(e[32]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Agent",-1)),A(o("select",{"onUpdate:modelValue":e[11]||(e[11]=l=>n.agent=l),class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},[...e[31]||(e[31]=[o("option",{value:""},"general-purpose (default)",-1),o("option",{value:"Explore"},"Explore",-1),o("option",{value:"Plan"},"Plan",-1)])],512),[[ge,n.agent]])])]),o("div",dr,[o("label",gr,[A(o("input",{type:"checkbox","onUpdate:modelValue":e[12]||(e[12]=l=>n.userInvocable=l),class:"sr-only peer"},null,512),[[Le,n.userInvocable]]),e[33]||(e[33]=o("div",{class:"h-5 w-9 rounded-full bg-white/[0.06] border border-white/[0.06] peer-checked:bg-[var(--color-accent-500)] peer-checked:border-[var(--color-accent-500)] relative transition-all after:content-[''] after:absolute after:top-0.5 after:left-0.5 after:h-4 after:w-4 after:rounded-full after:bg-gray-400 after:transition-all peer-checked:after:translate-x-4 peer-checked:after:bg-white"},null,-1)),e[34]||(e[34]=o("span",{class:"text-xs text-gray-500 group-hover:text-gray-300 transition-colors"},[M("User Invocable "),o("span",{class:"text-gray-600"},"(show in /menu)")],-1))]),o("label",fr,[A(o("input",{type:"checkbox","onUpdate:modelValue":e[13]||(e[13]=l=>n.disableModelInvocation=l),class:"sr-only peer"},null,512),[[Le,n.disableModelInvocation]]),e[35]||(e[35]=o("div",{class:"h-5 w-9 rounded-full bg-white/[0.06] border border-white/[0.06] peer-checked:bg-[var(--color-accent-500)] peer-checked:border-[var(--color-accent-500)] relative transition-all after:content-[''] after:absolute after:top-0.5 after:left-0.5 after:h-4 after:w-4 after:rounded-full after:bg-gray-400 after:transition-all peer-checked:after:translate-x-4 peer-checked:after:bg-white"},null,-1)),e[36]||(e[36]=o("span",{class:"text-xs text-gray-500 group-hover:text-gray-300 transition-colors"},[M("Disable Model Invocation "),o("span",{class:"text-gray-600"},"(manual only)")],-1))])]),o("div",null,[e[38]||(e[38]=o("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Context",-1)),A(o("select",{"onUpdate:modelValue":e[14]||(e[14]=l=>n.context=l),class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},[...e[37]||(e[37]=[o("option",{value:""},"Inline (default)",-1),o("option",{value:"fork"},"Fork (run in subagent)",-1)])],512),[[ge,n.context]]),e[39]||(e[39]=o("p",{class:"mt-1.5 text-xs text-gray-600"},"Fork runs the skill in an isolated subagent context",-1))]),o("details",kr,[e[41]||(e[41]=o("summary",{class:"text-xs font-medium uppercase tracking-wider text-gray-500 cursor-pointer hover:text-gray-400 transition-colors"},"Hooks (advanced)",-1)),o("div",xr,[A(o("textarea",{"onUpdate:modelValue":e[15]||(e[15]=l=>n.hooksJson=l),rows:"4",placeholder:'{ "preToolExecution": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "echo pre" }] }] }',class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-3 font-mono text-xs text-white placeholder-gray-700 focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all resize-y"},null,512),[[P,n.hooksJson]]),e[40]||(e[40]=o("p",{class:"mt-1.5 text-xs text-gray-600"},"JSON object. Leave empty to omit.",-1))])]),o("div",br,[o("div",null,[o("label",mr,[e[42]||(e[42]=o("span",null,"Skill Body",-1)),o("span",{class:j(n.bodyLines>400?"text-amber-500":"")},L(n.bodyLines)+"/500 lines",3)]),A(o("textarea",{"onUpdate:modelValue":e[16]||(e[16]=l=>n.body=l),rows:"20",placeholder:`# My Skill - -Instructions for Claude...`,class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-3 font-mono text-sm text-white placeholder-gray-600 focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all resize-y leading-relaxed"},null,512),[[P,n.body]])]),o("div",null,[e[43]||(e[43]=o("p",{class:"block text-xs font-medium uppercase tracking-wider text-gray-500 mb-1.5"},"Preview",-1)),o("div",{class:"skill-prose rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] p-5 min-h-[20rem] overflow-auto",innerHTML:n.previewHtml},null,8,wr)])]),o("div",yr,[o("button",{type:"submit",disabled:n.saving||n.isFork&&n.slugMatchesOriginal,title:n.isFork&&n.slugMatchesOriginal?"Change the name to generate a different slug":"",class:"inline-flex items-center gap-2 rounded-xl bg-[var(--color-accent-500)] px-6 py-2.5 text-sm font-semibold text-white shadow-lg shadow-[var(--color-accent-500)]/20 hover:bg-[var(--color-accent-600)] hover:shadow-[var(--color-accent-500)]/30 disabled:opacity-50 active:scale-[0.97] transition-all"},[n.saving?(S(),v("svg",Sr,[...e[44]||(e[44]=[o("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),o("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"},null,-1)])])):q("",!0),M(" "+L(n.saving?"Saving...":n.isFork?"Create Fork":t.mode==="create"?"Create Skill":"Save Changes"),1)],8,vr),e[45]||(e[45]=o("a",{href:"/",class:"text-sm text-gray-600 hover:text-gray-300 transition-colors"},"Cancel",-1)),n.error?(S(),v("p",Tr,L(n.error),1)):q("",!0)])],32)}const Cr=at(Xt,[["render",Rr]]);export{Cr as default}; diff --git a/dist/client/_astro/SkillSearch.A7FO5axR.js b/dist/client/_astro/SkillSearch.A7FO5axR.js deleted file mode 100644 index bd6489c..0000000 --- a/dist/client/_astro/SkillSearch.A7FO5axR.js +++ /dev/null @@ -1 +0,0 @@ -import{c as i,a as n,w as q,v as U,F as P,r as E,p as j,g as Q,b as Z,e as Ee,n as z,t as h,h as Le,i as c,q as Ie,j as Ve,k as f,m as Fe,o as u,d as le}from"./runtime-dom.esm-bundler.A7MyAQcw.js";import{_ as Oe}from"./_plugin-vue_export-helper.DlAUqK2U.js";const ae=12,se=20,qe=Le({__name:"SkillSearch",props:{authors:{},tags:{},totalCount:{}},setup(D,{expose:t}){t();const m=D,e=m.authors?m.authors.split(",").map(r=>r.trim()).filter(Boolean):[],H=m.tags?m.tags.split(",").map(r=>r.trim()).filter(Boolean):[],k=c(""),o=c(""),x=typeof localStorage<"u"&&localStorage.getItem("skillsViewMode"),w=c(x==="table"?"table":"grid"),g=c(1),T=c(m.totalCount||0),p=f(()=>w.value==="grid"?ae:se),K=f(()=>Math.max(1,Math.ceil(T.value/p.value))),ie=f(()=>T.value===0?0:(g.value-1)*p.value+1),ue=f(()=>Math.min(g.value*p.value,T.value)),ce=f(()=>{const r=[],l=K.value,s=g.value,C=7;if(l<=C)for(let b=1;b<=l;b++)r.push(b);else{const b=Math.floor(C/2);let M=Math.max(1,s-b),y=M+C-1;y>l&&(y=l,M=y-C+1);for(let F=M;F<=y;F++)r.push(F)}return r}),d=c([]),A=c(""),R=c(!1),J=c(),N=f(()=>{const r=A.value.toLowerCase().trim(),l=new Set(d.value.map(s=>s.toLowerCase()));return e.filter(s=>!l.has(s.toLowerCase())&&(!r||s.toLowerCase().includes(r)))});let L;function de(){L=setTimeout(()=>{R.value=!1},200)}function W(r){clearTimeout(L),d.value.some(l=>l.toLowerCase()===r.toLowerCase())||d.value.push(r),A.value="",J.value?.focus()}function ve(r){d.value=d.value.filter(l=>l!==r)}function ge(){N.value.length>0&&W(N.value[0])}function he(){!A.value&&d.value.length>0&&d.value.pop()}const v=c([]),B=c(""),X=c(!1),Y=c(),G=f(()=>{const r=B.value.toLowerCase().trim(),l=new Set(v.value.map(s=>s.toLowerCase()));return H.filter(s=>!l.has(s.toLowerCase())&&(!r||s.toLowerCase().includes(r)))});let I;function fe(){I=setTimeout(()=>{X.value=!1},200)}function $(r){clearTimeout(I),v.value.some(l=>l.toLowerCase()===r.toLowerCase())||v.value.push(r),B.value="",Y.value?.focus()}function me(r){v.value=v.value.filter(l=>l!==r)}function xe(){G.value.length>0&&$(G.value[0])}function we(){!B.value&&v.value.length>0&&v.value.pop()}function ee(r){w.value=r,localStorage.setItem("skillsViewMode",r);const l=document.getElementById("skills-grid"),s=document.getElementById("skills-table");l&&s&&(l.classList.toggle("hidden",r!=="grid"),s.classList.toggle("hidden",r!=="table")),g.value=1,Fe(()=>V())}Ie(()=>{w.value!=="grid"&&ee(w.value)});const pe=f(()=>k.value||d.value.length>0||v.value.length>0||o.value);function V(){const r=k.value.toLowerCase().trim(),l=d.value.map(a=>a.toLowerCase()),s=v.value.map(a=>a.toLowerCase()),C=o.value?parseInt(o.value):0,b=w.value==="grid"?"skills-grid":"skills-table",M=w.value==="grid"?"skills-table":"skills-grid",y=Array.from(document.querySelectorAll(`#${b} [data-skill]`));document.querySelectorAll(`#${M} [data-skill]`).forEach(a=>a.style.display="none");const O=[];y.forEach(a=>{const S=a.dataset.name||"",Ce=a.dataset.description||"",Te=a.dataset.tools||"",Ae=a.dataset.author||"",ne=(a.dataset.tags||"").split(",").filter(Boolean),Be=parseInt(a.dataset.forks||"0"),Me=!r||S.includes(r)||Ce.includes(r)||Te.includes(r)||ne.some(_=>_.includes(r)),Se=l.length===0||l.some(_=>Ae.includes(_)),_e=s.length===0||s.every(_=>ne.includes(_)),Pe=Be>=C;Me&&Se&&_e&&Pe&&O.push(a)}),T.value=O.length;const oe=Math.max(1,Math.ceil(O.length/p.value));g.value>oe&&(g.value=oe);const re=(g.value-1)*p.value,ke=re+p.value;y.forEach(a=>{const S=O.indexOf(a);S===-1?a.style.display="none":S>=re&&SK.value||(g.value=r,V())}function ye(){k.value="",d.value=[],A.value="",v.value=[],B.value="",o.value="",g.value=1}Ve([k,d,v,o],()=>{g.value=1,V()},{deep:!0});const te={props:m,authorList:e,tagList:H,query:k,forkFilter:o,savedView:x,viewMode:w,currentPage:g,filteredCount:T,PER_PAGE_GRID:ae,PER_PAGE_TABLE:se,perPage:p,totalPages:K,rangeStart:ie,rangeEnd:ue,visiblePages:ce,selectedAuthors:d,authorQuery:A,authorOpen:R,authorInputEl:J,authorSuggestions:N,get authorBlurTimer(){return L},set authorBlurTimer(r){L=r},onAuthorBlur:de,addAuthor:W,removeAuthor:ve,onAuthorEnter:ge,onAuthorBackspace:he,selectedTags:v,tagQuery:B,tagOpen:X,tagInputEl:Y,tagSuggestions:G,get tagBlurTimer(){return I},set tagBlurTimer(r){I=r},onTagBlur:fe,addTag:$,removeTag:me,onTagEnter:xe,onTagBackspace:we,setView:ee,hasActiveFilters:pe,applyFilters:V,goToPage:be,reset:ye};return Object.defineProperty(te,"__isScriptSetup",{enumerable:!1,value:!0}),te}}),je={class:"mb-6 space-y-4"},Qe={class:"flex flex-wrap items-end gap-3"},Ze={class:"w-full sm:w-auto sm:flex-1 sm:min-w-[180px]"},He={class:"relative"},Ke={class:"w-[calc(50%-6px)] sm:w-auto sm:flex-1 sm:min-w-[160px] relative"},Ne={class:"flex flex-wrap items-center gap-1.5 rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-3 py-2 min-h-[42px] focus-within:border-[var(--color-accent-500)]/50 focus-within:ring-1 focus-within:ring-[var(--color-accent-500)]/20 transition-all"},Ge=["onClick"],Ue=["placeholder","onKeydown"],ze={key:0,class:"absolute z-20 mt-1 w-full max-h-48 overflow-y-auto rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] shadow-xl"},De=["onMousedown"],Re={class:"w-[calc(50%-6px)] sm:w-auto sm:flex-1 sm:min-w-[160px] relative"},Je={class:"flex flex-wrap items-center gap-1.5 rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-3 py-2 min-h-[42px] focus-within:border-[var(--color-accent-500)]/50 focus-within:ring-1 focus-within:ring-[var(--color-accent-500)]/20 transition-all"},We=["onClick"],Xe=["placeholder","onKeydown"],Ye={key:0,class:"absolute z-20 mt-1 w-full max-h-48 overflow-y-auto rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] shadow-xl"},$e=["onMousedown"],et={class:"w-[calc(50%-6px)] sm:w-auto sm:min-w-[130px]"},tt={class:"flex rounded-xl border border-white/[0.06] overflow-hidden"},ot={key:0,class:"flex flex-wrap items-center justify-between gap-3"},rt={class:"text-sm text-gray-500"},nt={class:"flex items-center gap-1"},lt=["disabled"],at=["onClick"],st=["disabled"];function it(D,t,m,e,H,k){return u(),i("div",je,[n("div",Qe,[n("div",Ze,[t[15]||(t[15]=n("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-600 mb-1"},"Search",-1)),n("div",He,[t[14]||(t[14]=n("svg",{class:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2"},[n("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"})],-1)),q(n("input",{"onUpdate:modelValue":t[0]||(t[0]=o=>e.query=o),type:"text",placeholder:"Name, description, tools...",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] pl-10 pr-4 py-2.5 text-sm text-white placeholder-gray-600 focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},null,512),[[U,e.query]])])]),n("div",Ke,[t[16]||(t[16]=n("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-600 mb-1"},"Authors",-1)),n("div",Ne,[(u(!0),i(P,null,E(e.selectedAuthors,o=>(u(),i("span",{key:o,class:"inline-flex items-center gap-1 rounded-full bg-[var(--color-accent-500)]/15 text-[var(--color-accent-400)] px-2.5 py-0.5 text-xs font-medium"},[le(h(o)+" ",1),n("button",{onClick:x=>e.removeAuthor(o),class:"hover:text-white transition-colors"},"×",8,Ge)]))),128)),q(n("input",{ref:"authorInputEl","onUpdate:modelValue":t[1]||(t[1]=o=>e.authorQuery=o),type:"text",placeholder:e.selectedAuthors.length?"":"Filter by author...",onFocus:t[2]||(t[2]=o=>e.authorOpen=!0),onClick:t[3]||(t[3]=o=>e.authorOpen=!0),onInput:t[4]||(t[4]=o=>e.authorOpen=!0),onBlur:e.onAuthorBlur,onKeydown:[j(Q(e.onAuthorEnter,["prevent"]),["enter"]),j(e.onAuthorBackspace,["backspace"])],class:"flex-1 min-w-[80px] bg-transparent text-sm text-white placeholder-gray-600 outline-none"},null,40,Ue),[[U,e.authorQuery]])]),e.authorOpen&&e.authorSuggestions.length>0?(u(),i("div",ze,[(u(!0),i(P,null,E(e.authorSuggestions,o=>(u(),i("button",{key:o,onMousedown:Q(x=>e.addAuthor(o),["prevent"]),class:"block w-full text-left px-4 py-2 text-sm text-gray-400 hover:bg-white/[0.06] hover:text-white transition-colors"},h(o),41,De))),128))])):Z("",!0)]),n("div",Re,[t[17]||(t[17]=n("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-600 mb-1"},"Tags",-1)),n("div",Je,[(u(!0),i(P,null,E(e.selectedTags,o=>(u(),i("span",{key:o,class:"inline-flex items-center gap-1 rounded-full bg-[var(--color-accent-500)]/15 text-[var(--color-accent-400)] px-2.5 py-0.5 text-xs font-medium"},[le(h(o)+" ",1),n("button",{onClick:x=>e.removeTag(o),class:"hover:text-white transition-colors"},"×",8,We)]))),128)),q(n("input",{ref:"tagInputEl","onUpdate:modelValue":t[5]||(t[5]=o=>e.tagQuery=o),type:"text",placeholder:e.selectedTags.length?"":"Filter by tag...",onFocus:t[6]||(t[6]=o=>e.tagOpen=!0),onClick:t[7]||(t[7]=o=>e.tagOpen=!0),onInput:t[8]||(t[8]=o=>e.tagOpen=!0),onBlur:e.onTagBlur,onKeydown:[j(Q(e.onTagEnter,["prevent"]),["enter"]),j(e.onTagBackspace,["backspace"])],class:"flex-1 min-w-[80px] bg-transparent text-sm text-white placeholder-gray-600 outline-none"},null,40,Xe),[[U,e.tagQuery]])]),e.tagOpen&&e.tagSuggestions.length>0?(u(),i("div",Ye,[(u(!0),i(P,null,E(e.tagSuggestions,o=>(u(),i("button",{key:o,onMousedown:Q(x=>e.addTag(o),["prevent"]),class:"block w-full text-left px-4 py-2 text-sm text-gray-400 hover:bg-white/[0.06] hover:text-white transition-colors"},h(o),41,$e))),128))])):Z("",!0)]),n("div",et,[t[19]||(t[19]=n("label",{class:"block text-xs font-medium uppercase tracking-wider text-gray-600 mb-1"},"Forks",-1)),q(n("select",{"onUpdate:modelValue":t[9]||(t[9]=o=>e.forkFilter=o),class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},[...t[18]||(t[18]=[n("option",{value:""},"Any",-1),n("option",{value:"1"},"1+ forks",-1),n("option",{value:"3"},"3+ forks",-1),n("option",{value:"5"},"5+ forks",-1)])],512),[[Ee,e.forkFilter]])]),e.hasActiveFilters?(u(),i("button",{key:0,onClick:e.reset,class:"rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-gray-500 hover:text-white hover:bg-white/[0.06] transition-all"}," Clear ")):Z("",!0),n("div",tt,[n("button",{onClick:t[10]||(t[10]=o=>e.setView("grid")),class:z(["px-3 py-2.5 transition-all",e.viewMode==="grid"?"bg-white/[0.08] text-white":"text-gray-600 hover:text-gray-400 hover:bg-white/[0.03]"]),title:"Grid view"},[...t[20]||(t[20]=[n("svg",{class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2"},[n("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M3.75 6A2.25 2.25 0 0 1 6 3.75h2.25A2.25 2.25 0 0 1 10.5 6v2.25a2.25 2.25 0 0 1-2.25 2.25H6a2.25 2.25 0 0 1-2.25-2.25V6ZM3.75 15.75A2.25 2.25 0 0 1 6 13.5h2.25a2.25 2.25 0 0 1 2.25 2.25V18a2.25 2.25 0 0 1-2.25 2.25H6A2.25 2.25 0 0 1 3.75 18v-2.25ZM13.5 6a2.25 2.25 0 0 1 2.25-2.25H18A2.25 2.25 0 0 1 20.25 6v2.25A2.25 2.25 0 0 1 18 10.5h-2.25a2.25 2.25 0 0 1-2.25-2.25V6ZM13.5 15.75a2.25 2.25 0 0 1 2.25-2.25H18a2.25 2.25 0 0 1 2.25 2.25V18A2.25 2.25 0 0 1 18 20.25h-2.25A2.25 2.25 0 0 1 13.5 18v-2.25Z"})],-1)])],2),n("button",{onClick:t[11]||(t[11]=o=>e.setView("table")),class:z(["px-3 py-2.5 transition-all",e.viewMode==="table"?"bg-white/[0.08] text-white":"text-gray-600 hover:text-gray-400 hover:bg-white/[0.03]"]),title:"Table view"},[...t[21]||(t[21]=[n("svg",{class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2"},[n("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M3.75 12h16.5m-16.5 3.75h16.5M3.75 19.5h16.5M5.625 4.5h12.75a1.875 1.875 0 0 1 0 3.75H5.625a1.875 1.875 0 0 1 0-3.75Z"})],-1)])],2)])]),e.totalPages>1?(u(),i("div",ot,[n("span",rt," Showing "+h(e.rangeStart)+"–"+h(e.rangeEnd)+" of "+h(e.filteredCount),1),n("div",nt,[n("button",{onClick:t[12]||(t[12]=o=>e.goToPage(e.currentPage-1)),disabled:e.currentPage===1,class:"rounded-lg border border-white/[0.06] px-3 py-1.5 text-sm transition-all disabled:opacity-30 disabled:cursor-not-allowed text-gray-400 hover:text-white hover:bg-white/[0.06]"}," Prev ",8,lt),(u(!0),i(P,null,E(e.visiblePages,o=>(u(),i("button",{key:o,onClick:x=>e.goToPage(o),class:z(["rounded-lg px-3 py-1.5 text-sm transition-all",o===e.currentPage?"bg-[var(--color-accent-500)] text-white font-medium":"border border-white/[0.06] text-gray-400 hover:text-white hover:bg-white/[0.06]"])},h(o),11,at))),128)),n("button",{onClick:t[13]||(t[13]=o=>e.goToPage(e.currentPage+1)),disabled:e.currentPage===e.totalPages,class:"rounded-lg border border-white/[0.06] px-3 py-1.5 text-sm transition-all disabled:opacity-30 disabled:cursor-not-allowed text-gray-400 hover:text-white hover:bg-white/[0.06]"}," Next ",8,st)])])):Z("",!0)])}const dt=Oe(qe,[["render",it]]);export{dt as default}; diff --git a/dist/client/_astro/_plugin-vue_export-helper.DlAUqK2U.js b/dist/client/_astro/_plugin-vue_export-helper.DlAUqK2U.js deleted file mode 100644 index 718edd3..0000000 --- a/dist/client/_astro/_plugin-vue_export-helper.DlAUqK2U.js +++ /dev/null @@ -1 +0,0 @@ -const s=(t,r)=>{const o=t.__vccOpts||t;for(const[c,e]of r)o[c]=e;return o};export{s as _}; diff --git a/dist/client/_astro/_slug_.DRpcPMTm.css b/dist/client/_astro/_slug_.DRpcPMTm.css deleted file mode 100644 index 5b41fda..0000000 --- a/dist/client/_astro/_slug_.DRpcPMTm.css +++ /dev/null @@ -1 +0,0 @@ -/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:"Inter",ui-sans-serif,system-ui,sans-serif;--font-mono:"JetBrains Mono",ui-monospace,monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-xl:36rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-tight:-.025em;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--animate-spin:spin 1s linear infinite;--blur-sm:8px;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-accent-400:#fb923c;--color-accent-500:#f97316;--color-accent-600:#ea580c;--color-surface-50:#0a0a0f;--color-surface-100:#12121a;--color-surface-200:#1a1a25}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing)*0)}.-top-40{top:calc(var(--spacing)*-40)}.top-1\/2{top:50%}.top-4{top:calc(var(--spacing)*4)}.right-4{right:calc(var(--spacing)*4)}.left-1\/2{left:50%}.left-3{left:calc(var(--spacing)*3)}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-16{height:calc(var(--spacing)*16)}.h-80{height:calc(var(--spacing)*80)}.max-h-40{max-height:calc(var(--spacing)*40)}.max-h-48{max-height:calc(var(--spacing)*48)}.min-h-\[20rem\]{min-height:20rem}.min-h-\[42px\]{min-height:42px}.min-h-screen{min-height:100vh}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-16{width:calc(var(--spacing)*16)}.w-\[600px\]{width:600px}.w-\[calc\(50\%-6px\)\]{width:calc(50% - 6px)}.w-full{width:100%}.max-w-6xl{max-width:var(--container-6xl)}.max-w-md{max-width:var(--container-md)}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-\[80px\]{min-width:80px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.resize-y{resize:vertical}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-white\/\[0\.04\]>:not(:last-child)){border-color:#ffffff0a}@supports (color:color-mix(in lab,red,red)){:where(.divide-white\/\[0\.04\]>:not(:last-child)){border-color:color-mix(in oklab,var(--color-white)4%,transparent)}}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-\[var\(--color-accent-500\)\]\/20{border-color:#f9731633}@supports (color:color-mix(in lab,red,red)){.border-\[var\(--color-accent-500\)\]\/20{border-color:color-mix(in oklab,var(--color-accent-500)20%,transparent)}}.border-\[var\(--color-accent-500\)\]\/25{border-color:#f9731640}@supports (color:color-mix(in lab,red,red)){.border-\[var\(--color-accent-500\)\]\/25{border-color:color-mix(in oklab,var(--color-accent-500)25%,transparent)}}.border-amber-500\/20{border-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/20{border-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.border-red-500\/20{border-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.border-red-500\/20{border-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.border-white\/\[0\.06\]{border-color:#ffffff0f}@supports (color:color-mix(in lab,red,red)){.border-white\/\[0\.06\]{border-color:color-mix(in oklab,var(--color-white)6%,transparent)}}.border-white\/\[0\.08\]{border-color:#ffffff14}@supports (color:color-mix(in lab,red,red)){.border-white\/\[0\.08\]{border-color:color-mix(in oklab,var(--color-white)8%,transparent)}}.bg-\[var\(--color-accent-500\)\]{background-color:var(--color-accent-500)}.bg-\[var\(--color-accent-500\)\]\/5{background-color:#f973160d}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--color-accent-500\)\]\/5{background-color:color-mix(in oklab,var(--color-accent-500)5%,transparent)}}.bg-\[var\(--color-accent-500\)\]\/10{background-color:#f973161a}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--color-accent-500\)\]\/10{background-color:color-mix(in oklab,var(--color-accent-500)10%,transparent)}}.bg-\[var\(--color-accent-500\)\]\/15{background-color:#f9731626}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--color-accent-500\)\]\/15{background-color:color-mix(in oklab,var(--color-accent-500)15%,transparent)}}.bg-\[var\(--color-surface-100\)\]{background-color:var(--color-surface-100)}.bg-\[var\(--color-surface-200\)\]{background-color:var(--color-surface-200)}.bg-accent-500{background-color:var(--color-accent-500)}.bg-accent-500\/\[0\.07\]{background-color:#f9731612}@supports (color:color-mix(in lab,red,red)){.bg-accent-500\/\[0\.07\]{background-color:color-mix(in oklab,var(--color-accent-500)7%,transparent)}}.bg-amber-500\/5{background-color:#f99c000d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/5{background-color:color-mix(in oklab,var(--color-amber-500)5%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/5{background-color:#fb2c360d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/5{background-color:color-mix(in oklab,var(--color-red-500)5%,transparent)}}.bg-surface-50{background-color:var(--color-surface-50)}.bg-surface-50\/80{background-color:#0a0a0fcc}@supports (color:color-mix(in lab,red,red)){.bg-surface-50\/80{background-color:color-mix(in oklab,var(--color-surface-50)80%,transparent)}}.bg-surface-100{background-color:var(--color-surface-100)}.bg-surface-200{background-color:var(--color-surface-200)}.bg-transparent{background-color:#0000}.bg-white\/\[0\.04\]{background-color:#ffffff0a}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.04\]{background-color:color-mix(in oklab,var(--color-white)4%,transparent)}}.bg-white\/\[0\.06\]{background-color:#ffffff0f}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.06\]{background-color:color-mix(in oklab,var(--color-white)6%,transparent)}}.bg-white\/\[0\.08\]{background-color:#ffffff14}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.08\]{background-color:color-mix(in oklab,var(--color-white)8%,transparent)}}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-accent-500\/\[0\.03\]{--tw-gradient-from:#f9731608}@supports (color:color-mix(in lab,red,red)){.from-accent-500\/\[0\.03\]{--tw-gradient-from:color-mix(in oklab,var(--color-accent-500)3%,transparent)}}.from-accent-500\/\[0\.03\]{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-3\.5{padding-inline:calc(var(--spacing)*3.5)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-10{padding-block:calc(var(--spacing)*10)}.py-24{padding-block:calc(var(--spacing)*24)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pr-1\.5{padding-right:calc(var(--spacing)*1.5)}.pr-4{padding-right:calc(var(--spacing)*4)}.pb-5{padding-bottom:calc(var(--spacing)*5)}.pl-2\.5{padding-left:calc(var(--spacing)*2.5)}.pl-3{padding-left:calc(var(--spacing)*3)}.pl-10{padding-left:calc(var(--spacing)*10)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[11px\]{font-size:11px}.text-\[15px\]{font-size:15px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.whitespace-nowrap{white-space:nowrap}.text-\[var\(--color-accent-400\)\]{color:var(--color-accent-400)}.text-\[var\(--color-accent-500\)\]{color:var(--color-accent-500)}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-red-400{color:var(--color-red-400)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.placeholder-gray-600::placeholder{color:var(--color-gray-600)}.placeholder-gray-700::placeholder{color:var(--color-gray-700)}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-75{opacity:.75}.shadow-\[var\(--color-accent-500\)\]\/20{--tw-shadow-alpha:20%;--tw-shadow:var(--color-accent-500);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-accent-500\/20{--tw-shadow-color:#f9731633}@supports (color:color-mix(in lab,red,red)){.shadow-accent-500\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-accent-500)20%,transparent)var(--tw-shadow-alpha),transparent)}}.blur-\[120px\]{--tw-blur:blur(120px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}.group-open\:flex:is(:where(.group):is([open],:popover-open,:open) *){display:flex}.group-open\:rotate-180:is(:where(.group):is([open],:popover-open,:open) *){rotate:180deg}@media(hover:hover){.group-hover\:translate-x-0\.5:is(:where(.group):hover *){--tw-translate-x:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.group-hover\:text-accent-400:is(:where(.group):hover *){color:var(--color-accent-400)}.group-hover\:text-accent-500:is(:where(.group):hover *){color:var(--color-accent-500)}.group-hover\:text-gray-300:is(:where(.group):hover *){color:var(--color-gray-300)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.peer-checked\:border-\[var\(--color-accent-500\)\]:is(:where(.peer):checked~*){border-color:var(--color-accent-500)}.peer-checked\:bg-\[var\(--color-accent-500\)\]:is(:where(.peer):checked~*){background-color:var(--color-accent-500)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-0\.5:after{content:var(--tw-content);top:calc(var(--spacing)*.5)}.after\:left-0\.5:after{content:var(--tw-content);left:calc(var(--spacing)*.5)}.after\:h-4:after{content:var(--tw-content);height:calc(var(--spacing)*4)}.after\:w-4:after{content:var(--tw-content);width:calc(var(--spacing)*4)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:bg-gray-400:after{content:var(--tw-content);background-color:var(--color-gray-400)}.after\:transition-all:after{content:var(--tw-content);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}.peer-checked\:after\:translate-x-4:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:calc(var(--spacing)*4);translate:var(--tw-translate-x)var(--tw-translate-y)}.peer-checked\:after\:bg-white:is(:where(.peer):checked~*):after{content:var(--tw-content);background-color:var(--color-white)}.focus-within\:border-\[var\(--color-accent-500\)\]\/50:focus-within{border-color:#f9731680}@supports (color:color-mix(in lab,red,red)){.focus-within\:border-\[var\(--color-accent-500\)\]\/50:focus-within{border-color:color-mix(in oklab,var(--color-accent-500)50%,transparent)}}.focus-within\:ring-1:focus-within{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-within\:ring-\[var\(--color-accent-500\)\]\/20:focus-within{--tw-ring-color:#f9731633}@supports (color:color-mix(in lab,red,red)){.focus-within\:ring-\[var\(--color-accent-500\)\]\/20:focus-within{--tw-ring-color:color-mix(in oklab,var(--color-accent-500)20%,transparent)}}@media(hover:hover){.hover\:border-accent-500\/30:hover{border-color:#f973164d}@supports (color:color-mix(in lab,red,red)){.hover\:border-accent-500\/30:hover{border-color:color-mix(in oklab,var(--color-accent-500)30%,transparent)}}.hover\:border-red-500\/30:hover{border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.hover\:border-red-500\/30:hover{border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.hover\:border-white\/\[0\.15\]:hover{border-color:#ffffff26}@supports (color:color-mix(in lab,red,red)){.hover\:border-white\/\[0\.15\]:hover{border-color:color-mix(in oklab,var(--color-white)15%,transparent)}}.hover\:bg-\[var\(--color-accent-500\)\]\/30:hover{background-color:#f973164d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-\[var\(--color-accent-500\)\]\/30:hover{background-color:color-mix(in oklab,var(--color-accent-500)30%,transparent)}}.hover\:bg-\[var\(--color-accent-600\)\]:hover,.hover\:bg-accent-600:hover{background-color:var(--color-accent-600)}.hover\:bg-red-500\/10:hover{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/10:hover{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-surface-100:hover{background-color:var(--color-surface-100)}.hover\:bg-surface-200\/80:hover{background-color:#1a1a25cc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-surface-200\/80:hover{background-color:color-mix(in oklab,var(--color-surface-200)80%,transparent)}}.hover\:bg-white\/\[0\.1\]:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/\[0\.1\]:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\:bg-white\/\[0\.03\]:hover{background-color:#ffffff08}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/\[0\.03\]:hover{background-color:color-mix(in oklab,var(--color-white)3%,transparent)}}.hover\:bg-white\/\[0\.06\]:hover{background-color:#ffffff0f}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/\[0\.06\]:hover{background-color:color-mix(in oklab,var(--color-white)6%,transparent)}}.hover\:bg-white\/\[0\.08\]:hover{background-color:#ffffff14}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/\[0\.08\]:hover{background-color:color-mix(in oklab,var(--color-white)8%,transparent)}}.hover\:text-\[var\(--color-accent-300\)\]:hover{color:var(--color-accent-300)}.hover\:text-\[var\(--color-accent-400\)\]:hover,.hover\:text-accent-400:hover{color:var(--color-accent-400)}.hover\:text-gray-300:hover{color:var(--color-gray-300)}.hover\:text-gray-400:hover{color:var(--color-gray-400)}.hover\:text-white:hover{color:var(--color-white)}.hover\:shadow-\[var\(--color-accent-500\)\]\/30:hover{--tw-shadow-alpha:30%;--tw-shadow:var(--color-accent-500);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-accent-500\/30:hover{--tw-shadow-color:#f973164d}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-accent-500\/30:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-accent-500)30%,transparent)var(--tw-shadow-alpha),transparent)}}}.focus\:border-\[var\(--color-accent-500\)\]\/50:focus{border-color:#f9731680}@supports (color:color-mix(in lab,red,red)){.focus\:border-\[var\(--color-accent-500\)\]\/50:focus{border-color:color-mix(in oklab,var(--color-accent-500)50%,transparent)}}.focus\:border-amber-500\/50:focus{border-color:#f99c0080}@supports (color:color-mix(in lab,red,red)){.focus\:border-amber-500\/50:focus{border-color:color-mix(in oklab,var(--color-amber-500)50%,transparent)}}.focus\:border-red-500\/50:focus{border-color:#fb2c3680}@supports (color:color-mix(in lab,red,red)){.focus\:border-red-500\/50:focus{border-color:color-mix(in oklab,var(--color-red-500)50%,transparent)}}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-\[var\(--color-accent-500\)\]\/20:focus{--tw-ring-color:#f9731633}@supports (color:color-mix(in lab,red,red)){.focus\:ring-\[var\(--color-accent-500\)\]\/20:focus{--tw-ring-color:color-mix(in oklab,var(--color-accent-500)20%,transparent)}}.focus\:ring-amber-500\/20:focus{--tw-ring-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.focus\:ring-amber-500\/20:focus{--tw-ring-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.focus\:ring-red-500\/20:focus{--tw-ring-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.focus\:ring-red-500\/20:focus{--tw-ring-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-\[0\.97\]:active{scale:.97}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:w-auto{width:auto}.sm\:min-w-\[130px\]{min-width:130px}.sm\:min-w-\[160px\]{min-width:160px}.sm\:min-w-\[180px\]{min-width:180px}.sm\:flex-1{flex:1}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:items-start{align-items:flex-start}}}body{background-color:var(--color-surface-50);font-feature-settings:"cv02","cv03","cv04","cv11"}::selection{background-color:#f973164d}.skill-prose h1{color:#fff;margin-bottom:.75rem;font-size:1.5rem;font-weight:700}.skill-prose h2{color:#e5e5e5;margin-top:1.5rem;margin-bottom:.5rem;font-size:1.2rem;font-weight:600}.skill-prose h3{color:#d4d4d4;margin-top:1.25rem;margin-bottom:.5rem;font-size:1.05rem;font-weight:600}.skill-prose p{color:#a3a3a3;margin-bottom:.75rem;line-height:1.7}.skill-prose ul,.skill-prose ol{color:#a3a3a3;margin-bottom:.75rem;padding-left:1.5rem}.skill-prose li{margin-bottom:.25rem;line-height:1.6}.skill-prose code{color:#fb923c;background:#ffffff0f;border-radius:.25rem;padding:.15rem .4rem;font-size:.85em}.skill-prose pre{background:#0006;border:1px solid #ffffff0f;border-radius:.5rem;margin-bottom:1rem;padding:1rem;overflow-x:auto}.skill-prose pre code{color:#d4d4d4;background:0 0;padding:0}.skill-prose a{color:#fb923c;text-underline-offset:2px;text-decoration:underline}.skill-prose blockquote{color:#737373;border-left:3px solid #f97316;padding-left:1rem;font-style:italic}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}} diff --git a/dist/client/_astro/client.BnTlSu1B.js b/dist/client/_astro/client.BnTlSu1B.js deleted file mode 100644 index fa0c350..0000000 --- a/dist/client/_astro/client.BnTlSu1B.js +++ /dev/null @@ -1 +0,0 @@ -import{h as m,s as r,u as y,x as v,S}from"./runtime-dom.esm-bundler.A7MyAQcw.js";const g=()=>{},h=m({props:{value:String,name:String,hydrate:{type:Boolean,default:!0}},setup({name:t,value:s,hydrate:o}){if(!s)return()=>null;let c=o?"astro-slot":"astro-static-slot";return()=>r(c,{name:t,innerHTML:s})}});var A=h;let p=new WeakMap;var H=t=>async(s,o,c,{client:l})=>{if(!t.hasAttribute("ssr"))return;const f=s.name?`${s.name} Host`:void 0,u={};for(const[n,a]of Object.entries(c))u[n]=()=>r(A,{value:a,name:n==="default"?void 0:n});const i=l!=="only",d=i?y:v;let e=p.get(t);if(e)e.props=o,e.slots=u,e.component.$forceUpdate();else{e={props:o,slots:u};const n=d({name:f,render(){let a=r(s,e.props,e.slots);return e.component=this,b(s.setup)&&(a=r(S,null,a)),a}});n.config.idPrefix=t.getAttribute("prefix")??void 0,await g(),n.mount(t,i),p.set(t,e),t.addEventListener("astro:unmount",()=>n.unmount(),{once:!0})}};function b(t){const s=t?.constructor;return s&&s.name==="AsyncFunction"}export{H as default}; diff --git a/dist/client/_astro/runtime-dom.esm-bundler.A7MyAQcw.js b/dist/client/_astro/runtime-dom.esm-bundler.A7MyAQcw.js deleted file mode 100644 index 17b065a..0000000 --- a/dist/client/_astro/runtime-dom.esm-bundler.A7MyAQcw.js +++ /dev/null @@ -1,19 +0,0 @@ -/** -* @vue/shared v3.5.28 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function zs(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const ee={},at=[],De=()=>{},fi=()=>!1,$t=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),en=e=>e.startsWith("onUpdate:"),ce=Object.assign,tn=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},Er=Object.prototype.hasOwnProperty,Z=(e,t)=>Er.call(e,t),V=Array.isArray,ht=e=>Kt(e)==="[object Map]",vt=e=>Kt(e)==="[object Set]",An=e=>Kt(e)==="[object Date]",K=e=>typeof e=="function",ie=e=>typeof e=="string",Ne=e=>typeof e=="symbol",z=e=>e!==null&&typeof e=="object",ui=e=>(z(e)||K(e))&&K(e.then)&&K(e.catch),ai=Object.prototype.toString,Kt=e=>ai.call(e),Mr=e=>Kt(e).slice(8,-1),hi=e=>Kt(e)==="[object Object]",sn=e=>ie(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,it=zs(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),gs=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},Fr=/-\w/g,ze=gs(e=>e.replace(Fr,t=>t.slice(1).toUpperCase())),Or=/\B([A-Z])/g,et=gs(e=>e.replace(Or,"-$1").toLowerCase()),di=gs(e=>e.charAt(0).toUpperCase()+e.slice(1)),As=gs(e=>e?`on${di(e)}`:""),Ze=(e,t)=>!Object.is(e,t),ts=(e,...t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},ms=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Pr=e=>{const t=ie(e)?Number(e):NaN;return isNaN(t)?e:t};let En;const _s=()=>En||(En=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function nn(e){if(V(e)){const t={};for(let s=0;s{if(s){const n=s.split(Ir);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function rn(e){let t="";if(ie(e))t=e;else if(V(e))for(let s=0;swt(s,t))}const mi=e=>!!(e&&e.__v_isRef===!0),jr=e=>ie(e)?e:e==null?"":V(e)||z(e)&&(e.toString===ai||!K(e.toString))?mi(e)?jr(e.value):JSON.stringify(e,_i,2):String(e),_i=(e,t)=>mi(t)?_i(e,t.value):ht(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],r)=>(s[Es(n,r)+" =>"]=i,s),{})}:vt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Es(s))}:Ne(t)?Es(t):z(t)&&!V(t)&&!hi(t)?String(t):t,Es=(e,t="")=>{var s;return Ne(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/** -* @vue/reactivity v3.5.28 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let _e;class Vr{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.__v_skip=!0,this.parent=_e,!t&&_e&&(this.index=(_e.scopes||(_e.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t0&&--this._on===0&&(_e=this.prevScope,this.prevScope=void 0)}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s0)return;if(Ft){let t=Ft;for(Ft=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Mt;){let t=Mt;for(Mt=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Ti(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function vi(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),fn(n),Kr(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function Bs(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(wi(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function wi(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Dt)||(e.globalVersion=Dt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Bs(e))))return;e.flags|=2;const t=e.dep,s=se,n=Ee;se=e,Ee=!0;try{Ti(e);const i=e.fn(e._value);(t.version===0||Ze(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{se=s,Ee=n,vi(e),e.flags&=-3}}function fn(e,t=!1){const{dep:s,prevSub:n,nextSub:i}=e;if(n&&(n.nextSub=i,e.prevSub=void 0),i&&(i.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let r=s.computed.deps;r;r=r.nextDep)fn(r,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function Kr(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Ee=!0;const Si=[];function Ue(){Si.push(Ee),Ee=!1}function We(){const e=Si.pop();Ee=e===void 0?!0:e}function Mn(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=se;se=void 0;try{t()}finally{se=s}}}let Dt=0;class Ur{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class un{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!se||!Ee||se===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==se)s=this.activeLink=new Ur(se,this),se.deps?(s.prevDep=se.depsTail,se.depsTail.nextDep=s,se.depsTail=s):se.deps=se.depsTail=s,Ci(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=se.depsTail,s.nextDep=void 0,se.depsTail.nextDep=s,se.depsTail=s,se.deps===s&&(se.deps=n)}return s}trigger(t){this.version++,Dt++,this.notify(t)}notify(t){on();try{for(let s=this.subs;s;s=s.prevSub)s.sub.notify()&&s.sub.dep.notify()}finally{cn()}}}function Ci(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let n=t.deps;n;n=n.nextDep)Ci(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const Ls=new WeakMap,rt=Symbol(""),js=Symbol(""),Nt=Symbol("");function ue(e,t,s){if(Ee&&se){let n=Ls.get(e);n||Ls.set(e,n=new Map);let i=n.get(s);i||(n.set(s,i=new un),i.map=n,i.key=s),i.track()}}function Ve(e,t,s,n,i,r){const l=Ls.get(e);if(!l){Dt++;return}const o=c=>{c&&c.trigger()};if(on(),t==="clear")l.forEach(o);else{const c=V(e),d=c&&sn(s);if(c&&s==="length"){const a=Number(n);l.forEach((h,b)=>{(b==="length"||b===Nt||!Ne(b)&&b>=a)&&o(h)})}else switch((s!==void 0||l.has(void 0))&&o(l.get(s)),d&&o(l.get(Nt)),t){case"add":c?d&&o(l.get("length")):(o(l.get(rt)),ht(e)&&o(l.get(js)));break;case"delete":c||(o(l.get(rt)),ht(e)&&o(l.get(js)));break;case"set":ht(e)&&o(l.get(rt));break}}cn()}function ct(e){const t=X(e);return t===e?t:(ue(t,"iterate",Nt),Se(e)?t:t.map(Me))}function bs(e){return ue(e=X(e),"iterate",Nt),e}function Ge(e,t){return ke(e)?bt(Qe(e)?Me(t):t):Me(t)}const Wr={__proto__:null,[Symbol.iterator](){return Fs(this,Symbol.iterator,e=>Ge(this,e))},concat(...e){return ct(this).concat(...e.map(t=>V(t)?ct(t):t))},entries(){return Fs(this,"entries",e=>(e[1]=Ge(this,e[1]),e))},every(e,t){return Be(this,"every",e,t,void 0,arguments)},filter(e,t){return Be(this,"filter",e,t,s=>s.map(n=>Ge(this,n)),arguments)},find(e,t){return Be(this,"find",e,t,s=>Ge(this,s),arguments)},findIndex(e,t){return Be(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Be(this,"findLast",e,t,s=>Ge(this,s),arguments)},findLastIndex(e,t){return Be(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Be(this,"forEach",e,t,void 0,arguments)},includes(...e){return Os(this,"includes",e)},indexOf(...e){return Os(this,"indexOf",e)},join(e){return ct(this).join(e)},lastIndexOf(...e){return Os(this,"lastIndexOf",e)},map(e,t){return Be(this,"map",e,t,void 0,arguments)},pop(){return At(this,"pop")},push(...e){return At(this,"push",e)},reduce(e,...t){return Fn(this,"reduce",e,t)},reduceRight(e,...t){return Fn(this,"reduceRight",e,t)},shift(){return At(this,"shift")},some(e,t){return Be(this,"some",e,t,void 0,arguments)},splice(...e){return At(this,"splice",e)},toReversed(){return ct(this).toReversed()},toSorted(e){return ct(this).toSorted(e)},toSpliced(...e){return ct(this).toSpliced(...e)},unshift(...e){return At(this,"unshift",e)},values(){return Fs(this,"values",e=>Ge(this,e))}};function Fs(e,t,s){const n=bs(e),i=n[t]();return n!==e&&!Se(e)&&(i._next=i.next,i.next=()=>{const r=i._next();return r.done||(r.value=s(r.value)),r}),i}const kr=Array.prototype;function Be(e,t,s,n,i,r){const l=bs(e),o=l!==e&&!Se(e),c=l[t];if(c!==kr[t]){const h=c.apply(e,r);return o?Me(h):h}let d=s;l!==e&&(o?d=function(h,b){return s.call(this,Ge(e,h),b,e)}:s.length>2&&(d=function(h,b){return s.call(this,h,b,e)}));const a=c.call(l,d,n);return o&&i?i(a):a}function Fn(e,t,s,n){const i=bs(e);let r=s;return i!==e&&(Se(e)?s.length>3&&(r=function(l,o,c){return s.call(this,l,o,c,e)}):r=function(l,o,c){return s.call(this,l,Ge(e,o),c,e)}),i[t](r,...n)}function Os(e,t,s){const n=X(e);ue(n,"iterate",Nt);const i=n[t](...s);return(i===-1||i===!1)&&pn(s[0])?(s[0]=X(s[0]),n[t](...s)):i}function At(e,t,s=[]){Ue(),on();const n=X(e)[t].apply(e,s);return cn(),We(),n}const qr=zs("__proto__,__v_isRef,__isVue"),Ai=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Ne));function Gr(e){Ne(e)||(e=String(e));const t=X(this);return ue(t,"has",e),t.hasOwnProperty(e)}class Ei{constructor(t=!1,s=!1){this._isReadonly=t,this._isShallow=s}get(t,s,n){if(s==="__v_skip")return t.__v_skip;const i=this._isReadonly,r=this._isShallow;if(s==="__v_isReactive")return!i;if(s==="__v_isReadonly")return i;if(s==="__v_isShallow")return r;if(s==="__v_raw")return n===(i?r?nl:Pi:r?Oi:Fi).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const l=V(t);if(!i){let c;if(l&&(c=Wr[s]))return c;if(s==="hasOwnProperty")return Gr}const o=Reflect.get(t,s,he(t)?t:n);if((Ne(s)?Ai.has(s):qr(s))||(i||ue(t,"get",s),r))return o;if(he(o)){const c=l&&sn(s)?o:o.value;return i&&z(c)?$s(c):c}return z(o)?i?$s(o):hn(o):o}}class Mi extends Ei{constructor(t=!1){super(!1,t)}set(t,s,n,i){let r=t[s];const l=V(t)&&sn(s);if(!this._isShallow){const d=ke(r);if(!Se(n)&&!ke(n)&&(r=X(r),n=X(n)),!l&&he(r)&&!he(n))return d||(r.value=n),!0}const o=l?Number(s)e,Jt=e=>Reflect.getPrototypeOf(e);function Qr(e,t,s){return function(...n){const i=this.__v_raw,r=X(i),l=ht(r),o=e==="entries"||e===Symbol.iterator&&l,c=e==="keys"&&l,d=i[e](...n),a=s?Vs:t?bt:Me;return!t&&ue(r,"iterate",c?js:rt),ce(Object.create(d),{next(){const{value:h,done:b}=d.next();return b?{value:h,done:b}:{value:o?[a(h[0]),a(h[1])]:a(h),done:b}}})}}function Yt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function zr(e,t){const s={get(i){const r=this.__v_raw,l=X(r),o=X(i);e||(Ze(i,o)&&ue(l,"get",i),ue(l,"get",o));const{has:c}=Jt(l),d=t?Vs:e?bt:Me;if(c.call(l,i))return d(r.get(i));if(c.call(l,o))return d(r.get(o));r!==l&&r.get(i)},get size(){const i=this.__v_raw;return!e&&ue(X(i),"iterate",rt),i.size},has(i){const r=this.__v_raw,l=X(r),o=X(i);return e||(Ze(i,o)&&ue(l,"has",i),ue(l,"has",o)),i===o?r.has(i):r.has(i)||r.has(o)},forEach(i,r){const l=this,o=l.__v_raw,c=X(o),d=t?Vs:e?bt:Me;return!e&&ue(c,"iterate",rt),o.forEach((a,h)=>i.call(r,d(a),d(h),l))}};return ce(s,e?{add:Yt("add"),set:Yt("set"),delete:Yt("delete"),clear:Yt("clear")}:{add(i){!t&&!Se(i)&&!ke(i)&&(i=X(i));const r=X(this);return Jt(r).has.call(r,i)||(r.add(i),Ve(r,"add",i,i)),this},set(i,r){!t&&!Se(r)&&!ke(r)&&(r=X(r));const l=X(this),{has:o,get:c}=Jt(l);let d=o.call(l,i);d||(i=X(i),d=o.call(l,i));const a=c.call(l,i);return l.set(i,r),d?Ze(r,a)&&Ve(l,"set",i,r):Ve(l,"add",i,r),this},delete(i){const r=X(this),{has:l,get:o}=Jt(r);let c=l.call(r,i);c||(i=X(i),c=l.call(r,i)),o&&o.call(r,i);const d=r.delete(i);return c&&Ve(r,"delete",i,void 0),d},clear(){const i=X(this),r=i.size!==0,l=i.clear();return r&&Ve(i,"clear",void 0,void 0),l}}),["keys","values","entries",Symbol.iterator].forEach(i=>{s[i]=Qr(i,e,t)}),s}function an(e,t){const s=zr(e,t);return(n,i,r)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(Z(s,i)&&i in n?s:n,i,r)}const el={get:an(!1,!1)},tl={get:an(!1,!0)},sl={get:an(!0,!1)};const Fi=new WeakMap,Oi=new WeakMap,Pi=new WeakMap,nl=new WeakMap;function il(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function rl(e){return e.__v_skip||!Object.isExtensible(e)?0:il(Mr(e))}function hn(e){return ke(e)?e:dn(e,!1,Yr,el,Fi)}function ll(e){return dn(e,!1,Zr,tl,Oi)}function $s(e){return dn(e,!0,Xr,sl,Pi)}function dn(e,t,s,n,i){if(!z(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const r=rl(e);if(r===0)return e;const l=i.get(e);if(l)return l;const o=new Proxy(e,r===2?n:s);return i.set(e,o),o}function Qe(e){return ke(e)?Qe(e.__v_raw):!!(e&&e.__v_isReactive)}function ke(e){return!!(e&&e.__v_isReadonly)}function Se(e){return!!(e&&e.__v_isShallow)}function pn(e){return e?!!e.__v_raw:!1}function X(e){const t=e&&e.__v_raw;return t?X(t):e}function ol(e){return!Z(e,"__v_skip")&&Object.isExtensible(e)&&pi(e,"__v_skip",!0),e}const Me=e=>z(e)?hn(e):e,bt=e=>z(e)?$s(e):e;function he(e){return e?e.__v_isRef===!0:!1}function lc(e){return cl(e,!1)}function cl(e,t){return he(e)?e:new fl(e,t)}class fl{constructor(t,s){this.dep=new un,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=s?t:X(t),this._value=s?t:Me(t),this.__v_isShallow=s}get value(){return this.dep.track(),this._value}set value(t){const s=this._rawValue,n=this.__v_isShallow||Se(t)||ke(t);t=n?t:X(t),Ze(t,s)&&(this._rawValue=t,this._value=n?t:Me(t),this.dep.trigger())}}function ul(e){return he(e)?e.value:e}const al={get:(e,t,s)=>t==="__v_raw"?e:ul(Reflect.get(e,t,s)),set:(e,t,s,n)=>{const i=e[t];return he(i)&&!he(s)?(i.value=s,!0):Reflect.set(e,t,s,n)}};function Ri(e){return Qe(e)?e:new Proxy(e,al)}class hl{constructor(t,s,n){this.fn=t,this.setter=s,this._value=void 0,this.dep=new un(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Dt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!s,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&se!==this)return xi(this,!0),!0}get value(){const t=this.dep.track();return wi(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function dl(e,t,s=!1){let n,i;return K(e)?n=e:(n=e.get,i=e.set),new hl(n,i,s)}const Xt={},os=new WeakMap;let nt;function pl(e,t=!1,s=nt){if(s){let n=os.get(s);n||os.set(s,n=[]),n.push(e)}}function gl(e,t,s=ee){const{immediate:n,deep:i,once:r,scheduler:l,augmentJob:o,call:c}=s,d=m=>i?m:Se(m)||i===!1||i===0?$e(m,1):$e(m);let a,h,b,S,O=!1,F=!1;if(he(e)?(h=()=>e.value,O=Se(e)):Qe(e)?(h=()=>d(e),O=!0):V(e)?(F=!0,O=e.some(m=>Qe(m)||Se(m)),h=()=>e.map(m=>{if(he(m))return m.value;if(Qe(m))return d(m);if(K(m))return c?c(m,2):m()})):K(e)?t?h=c?()=>c(e,2):e:h=()=>{if(b){Ue();try{b()}finally{We()}}const m=nt;nt=a;try{return c?c(e,3,[S]):e(S)}finally{nt=m}}:h=De,t&&i){const m=h,T=i===!0?1/0:i;h=()=>$e(m(),T)}const k=$r(),U=()=>{a.stop(),k&&k.active&&tn(k.effects,a)};if(r&&t){const m=t;t=(...T)=>{m(...T),U()}}let D=F?new Array(e.length).fill(Xt):Xt;const p=m=>{if(!(!(a.flags&1)||!a.dirty&&!m))if(t){const T=a.run();if(i||O||(F?T.some((M,B)=>Ze(M,D[B])):Ze(T,D))){b&&b();const M=nt;nt=a;try{const B=[T,D===Xt?void 0:F&&D[0]===Xt?[]:D,S];D=T,c?c(t,3,B):t(...B)}finally{nt=M}}}else a.run()};return o&&o(p),a=new bi(h),a.scheduler=l?()=>l(p,!1):p,S=m=>pl(m,!1,a),b=a.onStop=()=>{const m=os.get(a);if(m){if(c)c(m,4);else for(const T of m)T();os.delete(a)}},t?n?p(!0):D=a.run():l?l(p.bind(null,!0),!0):a.run(),U.pause=a.pause.bind(a),U.resume=a.resume.bind(a),U.stop=U,U}function $e(e,t=1/0,s){if(t<=0||!z(e)||e.__v_skip||(s=s||new Map,(s.get(e)||0)>=t))return e;if(s.set(e,t),t--,he(e))$e(e.value,t,s);else if(V(e))for(let n=0;n{$e(n,t,s)});else if(hi(e)){for(const n in e)$e(e[n],t,s);for(const n of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,n)&&$e(e[n],t,s)}return e}/** -* @vue/runtime-core v3.5.28 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Ut(e,t,s,n){try{return n?e(...n):e()}catch(i){Wt(i,t,s)}}function He(e,t,s,n){if(K(e)){const i=Ut(e,t,s,n);return i&&ui(i)&&i.catch(r=>{Wt(r,t,s)}),i}if(V(e)){const i=[];for(let r=0;r>>1,i=pe[n],r=Ht(i);r=Ht(s)?pe.push(e):pe.splice(_l(t),0,e),e.flags|=1,Ni()}}function Ni(){cs||(cs=Ii.then(Hi))}function Ks(e){V(e)?dt.push(...e):Je&&e.id===-1?Je.splice(ut+1,0,e):e.flags&1||(dt.push(e),e.flags|=1),Ni()}function On(e,t,s=Re+1){for(;sHt(s)-Ht(n));if(dt.length=0,Je){Je.push(...t);return}for(Je=t,ut=0;ute.id==null?e.flags&2?-1:1/0:e.id;function Hi(e){try{for(Re=0;Re{n._d&&ds(-1);const r=us(t);let l;try{l=e(...i)}finally{us(r),n._d&&ds(1)}return l};return n._n=!0,n._c=!0,n._d=!0,n}function oc(e,t){if(we===null)return e;const s=vs(we),n=e.dirs||(e.dirs=[]);for(let i=0;i1)return s&&K(t)?t.call(n&&n.proxy):t}}const xl=Symbol.for("v-scx"),Tl=()=>ss(xl);function Ps(e,t,s){return Li(e,t,s)}function Li(e,t,s=ee){const{immediate:n,deep:i,flush:r,once:l}=s,o=ce({},s),c=t&&n||!t&&r!=="post";let d;if(jt){if(r==="sync"){const S=Tl();d=S.__watcherHandles||(S.__watcherHandles=[])}else if(!c){const S=()=>{};return S.stop=De,S.resume=De,S.pause=De,S}}const a=ge;o.call=(S,O,F)=>He(S,a,O,F);let h=!1;r==="post"?o.scheduler=S=>{oe(S,a&&a.suspense)}:r!=="sync"&&(h=!0,o.scheduler=(S,O)=>{O?S():gn(S)}),o.augmentJob=S=>{t&&(S.flags|=4),h&&(S.flags|=2,a&&(S.id=a.uid,S.i=a))};const b=gl(e,t,o);return jt&&(d?d.push(b):c&&b()),b}function vl(e,t,s){const n=this.proxy,i=ie(e)?e.includes(".")?ji(n,e):()=>n[e]:e.bind(n,n);let r;K(t)?r=t:(r=t.handler,s=t);const l=kt(this),o=Li(i,r.bind(n),s);return l(),o}function ji(e,t){const s=t.split(".");return()=>{let n=e;for(let i=0;ie.__isTeleport,Ot=e=>e&&(e.disabled||e.disabled===""),Pn=e=>e&&(e.defer||e.defer===""),Rn=e=>typeof SVGElement<"u"&&e instanceof SVGElement,In=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Us=(e,t)=>{const s=e&&e.to;return ie(s)?t?t(s):null:s},$i={name:"Teleport",__isTeleport:!0,process(e,t,s,n,i,r,l,o,c,d){const{mc:a,pc:h,pbc:b,o:{insert:S,querySelector:O,createText:F,createComment:k}}=d,U=Ot(t.props);let{shapeFlag:D,children:p,dynamicChildren:m}=t;if(e==null){const T=t.el=F(""),M=t.anchor=F("");S(T,s,n),S(M,s,n);const B=(H,P)=>{D&16&&a(p,H,P,i,r,l,o,c)},L=()=>{const H=t.target=Us(t.props,O),P=Ws(H,t,F,S);H&&(l!=="svg"&&Rn(H)?l="svg":l!=="mathml"&&In(H)&&(l="mathml"),i&&i.isCE&&(i.ce._teleportTargets||(i.ce._teleportTargets=new Set)).add(H),U||(B(H,P),ns(t,!1)))};U&&(B(s,M),ns(t,!0)),Pn(t.props)?(t.el.__isMounted=!1,oe(()=>{L(),delete t.el.__isMounted},r)):L()}else{if(Pn(t.props)&&e.el.__isMounted===!1){oe(()=>{$i.process(e,t,s,n,i,r,l,o,c,d)},r);return}t.el=e.el,t.targetStart=e.targetStart;const T=t.anchor=e.anchor,M=t.target=e.target,B=t.targetAnchor=e.targetAnchor,L=Ot(e.props),H=L?s:M,P=L?T:B;if(l==="svg"||Rn(M)?l="svg":(l==="mathml"||In(M))&&(l="mathml"),m?(b(e.dynamicChildren,m,H,i,r,l,o),yn(e,t,!0)):c||h(e,t,H,P,i,r,l,o,!1),U)L?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):Zt(t,s,T,d,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const q=t.target=Us(t.props,O);q&&Zt(t,q,null,d,0)}else L&&Zt(t,M,B,d,1);ns(t,U)}},remove(e,t,s,{um:n,o:{remove:i}},r){const{shapeFlag:l,children:o,anchor:c,targetStart:d,targetAnchor:a,target:h,props:b}=e;if(h&&(i(d),i(a)),r&&i(c),l&16){const S=r||!Ot(b);for(let O=0;Opt(F,t&&(V(t)?t[k]:t),s,n,i));return}if(gt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&pt(e,t,s,n.component.subTree);return}const r=n.shapeFlag&4?vs(n.component):n.el,l=i?null:r,{i:o,r:c}=e,d=t&&t.r,a=o.refs===ee?o.refs={}:o.refs,h=o.setupState,b=X(h),S=h===ee?fi:F=>Dn(a,F)?!1:Z(b,F),O=(F,k)=>!(k&&Dn(a,k));if(d!=null&&d!==c){if(Nn(t),ie(d))a[d]=null,S(d)&&(h[d]=null);else if(he(d)){const F=t;O(d,F.k)&&(d.value=null),F.k&&(a[F.k]=null)}}if(K(c))Ut(c,o,12,[l,a]);else{const F=ie(c),k=he(c);if(F||k){const U=()=>{if(e.f){const D=F?S(c)?h[c]:a[c]:O()||!e.k?c.value:a[e.k];if(i)V(D)&&tn(D,r);else if(V(D))D.includes(r)||D.push(r);else if(F)a[c]=[r],S(c)&&(h[c]=a[c]);else{const p=[r];O(c,e.k)&&(c.value=p),e.k&&(a[e.k]=p)}}else F?(a[c]=l,S(c)&&(h[c]=l)):k&&(O(c,e.k)&&(c.value=l),e.k&&(a[e.k]=l))};if(l){const D=()=>{U(),as.delete(e)};D.id=-1,as.set(e,D),oe(D,s)}else Nn(e),U()}}}function Nn(e){const t=as.get(e);t&&(t.flags|=8,as.delete(e))}let Hn=!1;const ft=()=>{Hn||(console.error("Hydration completed but contains mismatches."),Hn=!0)},Al=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",El=e=>e.namespaceURI.includes("MathML"),Qt=e=>{if(e.nodeType===1){if(Al(e))return"svg";if(El(e))return"mathml"}},zt=e=>e.nodeType===8;function Ml(e){const{mt:t,p:s,o:{patchProp:n,createText:i,nextSibling:r,parentNode:l,remove:o,insert:c,createComment:d}}=e,a=(p,m)=>{if(!m.hasChildNodes()){s(null,p,m),fs(),m._vnode=p;return}h(m.firstChild,p,null,null,null),fs(),m._vnode=p},h=(p,m,T,M,B,L=!1)=>{L=L||!!m.dynamicChildren;const H=zt(p)&&p.data==="[",P=()=>F(p,m,T,M,B,H),{type:q,ref:J,shapeFlag:Y,patchFlag:re}=m;let le=p.nodeType;m.el=p,re===-2&&(L=!1,m.dynamicChildren=null);let N=null;switch(q){case lt:le!==3?m.children===""?(c(m.el=i(""),l(p),p),N=p):N=P():(p.data!==m.children&&(ft(),p.data=m.children),N=r(p));break;case Fe:D(p)?(N=r(p),U(m.el=p.content.firstChild,p,T)):le!==8||H?N=P():N=r(p);break;case is:if(H&&(p=r(p),le=p.nodeType),le===1||le===3){N=p;const W=!m.children.length;for(let R=0;R{L=L||!!m.dynamicChildren;const{type:H,props:P,patchFlag:q,shapeFlag:J,dirs:Y,transition:re}=m,le=H==="input"||H==="option";if(le||q!==-1){Y&&Ie(m,null,T,"created");let N=!1;if(D(p)){N=lr(null,re)&&T&&T.vnode.props&&T.vnode.props.appear;const R=p.content.firstChild;if(N){const ne=R.getAttribute("class");ne&&(R.$cls=ne),re.beforeEnter(R)}U(R,p,T),m.el=p=R}if(J&16&&!(P&&(P.innerHTML||P.textContent))){let R=S(p.firstChild,m,p,T,M,B,L);for(;R;){es(p,1)||ft();const ne=R;R=R.nextSibling,o(ne)}}else if(J&8){let R=m.children;R[0]===` -`&&(p.tagName==="PRE"||p.tagName==="TEXTAREA")&&(R=R.slice(1));const{textContent:ne}=p;ne!==R&&ne!==R.replace(/\r\n|\r/g,` -`)&&(es(p,0)||ft(),p.textContent=m.children)}if(P){if(le||!L||q&48){const R=p.tagName.includes("-");for(const ne in P)(le&&(ne.endsWith("value")||ne==="indeterminate")||$t(ne)&&!it(ne)||ne[0]==="."||R&&!it(ne))&&n(p,ne,null,P[ne],void 0,T)}else if(P.onClick)n(p,"onClick",null,P.onClick,void 0,T);else if(q&4&&Qe(P.style))for(const R in P.style)P.style[R]}let W;(W=P&&P.onVnodeBeforeMount)&&ve(W,T,m),Y&&Ie(m,null,T,"beforeMount"),((W=P&&P.onVnodeMounted)||Y||N)&&ar(()=>{W&&ve(W,T,m),N&&re.enter(p),Y&&Ie(m,null,T,"mounted")},M)}return p.nextSibling},S=(p,m,T,M,B,L,H)=>{H=H||!!m.dynamicChildren;const P=m.children,q=P.length;for(let J=0;J{const{slotScopeIds:H}=m;H&&(B=B?B.concat(H):H);const P=l(p),q=S(r(p),m,P,T,M,B,L);return q&&zt(q)&&q.data==="]"?r(m.anchor=q):(ft(),c(m.anchor=d("]"),P,q),q)},F=(p,m,T,M,B,L)=>{if(es(p.parentElement,1)||ft(),m.el=null,L){const q=k(p);for(;;){const J=r(p);if(J&&J!==q)o(J);else break}}const H=r(p),P=l(p);return o(p),s(null,m,P,H,T,M,Qt(P),B),T&&(T.vnode.el=m.el,Ts(T,m.el)),H},k=(p,m="[",T="]")=>{let M=0;for(;p;)if(p=r(p),p&&zt(p)&&(p.data===m&&M++,p.data===T)){if(M===0)return r(p);M--}return p},U=(p,m,T)=>{const M=m.parentNode;M&&M.replaceChild(p,m);let B=T;for(;B;)B.vnode.el===m&&(B.vnode.el=B.subTree.el=p),B=B.parent},D=p=>p.nodeType===1&&p.tagName==="TEMPLATE";return[a,h]}const Bn="data-allow-mismatch",Fl={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function es(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(Bn);)e=e.parentElement;const s=e&&e.getAttribute(Bn);if(s==null)return!1;if(s==="")return!0;{const n=s.split(",");return t===0&&n.includes("children")?!0:n.includes(Fl[t])}}_s().requestIdleCallback;_s().cancelIdleCallback;const gt=e=>!!e.type.__asyncLoader,Ui=e=>e.type.__isKeepAlive;function Ol(e,t){Wi(e,"a",t)}function Pl(e,t){Wi(e,"da",t)}function Wi(e,t,s=ge){const n=e.__wdc||(e.__wdc=()=>{let i=s;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(ys(t,n,s),s){let i=s.parent;for(;i&&i.parent;)Ui(i.parent.vnode)&&Rl(n,t,s,i),i=i.parent}}function Rl(e,t,s,n){const i=ys(t,e,n,!0);ki(()=>{tn(n[t],i)},s)}function ys(e,t,s=ge,n=!1){if(s){const i=s[e]||(s[e]=[]),r=t.__weh||(t.__weh=(...l)=>{Ue();const o=kt(s),c=He(t,s,e,l);return o(),We(),c});return n?i.unshift(r):i.push(r),r}}const qe=e=>(t,s=ge)=>{(!jt||e==="sp")&&ys(e,(...n)=>t(...n),s)},Il=qe("bm"),Dl=qe("m"),Nl=qe("bu"),Hl=qe("u"),Bl=qe("bum"),ki=qe("um"),Ll=qe("sp"),jl=qe("rtg"),Vl=qe("rtc");function $l(e,t=ge){ys("ec",e,t)}const Kl=Symbol.for("v-ndc");function uc(e,t,s,n){let i;const r=s,l=V(e);if(l||ie(e)){const o=l&&Qe(e);let c=!1,d=!1;o&&(c=!Se(e),d=ke(e),e=bs(e)),i=new Array(e.length);for(let a=0,h=e.length;at(o,c,void 0,r));else{const o=Object.keys(e);i=new Array(o.length);for(let c=0,d=o.length;ce?br(e)?vs(e):ks(e.parent):null,Pt=ce(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>ks(e.parent),$root:e=>ks(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Gi(e),$forceUpdate:e=>e.f||(e.f=()=>{gn(e.update)}),$nextTick:e=>e.n||(e.n=Di.bind(e.proxy)),$watch:e=>vl.bind(e)}),Rs=(e,t)=>e!==ee&&!e.__isScriptSetup&&Z(e,t),Ul={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:s,setupState:n,data:i,props:r,accessCache:l,type:o,appContext:c}=e;if(t[0]!=="$"){const b=l[t];if(b!==void 0)switch(b){case 1:return n[t];case 2:return i[t];case 4:return s[t];case 3:return r[t]}else{if(Rs(n,t))return l[t]=1,n[t];if(i!==ee&&Z(i,t))return l[t]=2,i[t];if(Z(r,t))return l[t]=3,r[t];if(s!==ee&&Z(s,t))return l[t]=4,s[t];qs&&(l[t]=0)}}const d=Pt[t];let a,h;if(d)return t==="$attrs"&&ue(e.attrs,"get",""),d(e);if((a=o.__cssModules)&&(a=a[t]))return a;if(s!==ee&&Z(s,t))return l[t]=4,s[t];if(h=c.config.globalProperties,Z(h,t))return h[t]},set({_:e},t,s){const{data:n,setupState:i,ctx:r}=e;return Rs(i,t)?(i[t]=s,!0):n!==ee&&Z(n,t)?(n[t]=s,!0):Z(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(r[t]=s,!0)},has({_:{data:e,setupState:t,accessCache:s,ctx:n,appContext:i,props:r,type:l}},o){let c;return!!(s[o]||e!==ee&&o[0]!=="$"&&Z(e,o)||Rs(t,o)||Z(r,o)||Z(n,o)||Z(Pt,o)||Z(i.config.globalProperties,o)||(c=l.__cssModules)&&c[o])},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:Z(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function Ln(e){return V(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let qs=!0;function Wl(e){const t=Gi(e),s=e.proxy,n=e.ctx;qs=!1,t.beforeCreate&&jn(t.beforeCreate,e,"bc");const{data:i,computed:r,methods:l,watch:o,provide:c,inject:d,created:a,beforeMount:h,mounted:b,beforeUpdate:S,updated:O,activated:F,deactivated:k,beforeDestroy:U,beforeUnmount:D,destroyed:p,unmounted:m,render:T,renderTracked:M,renderTriggered:B,errorCaptured:L,serverPrefetch:H,expose:P,inheritAttrs:q,components:J,directives:Y,filters:re}=t;if(d&&kl(d,n,null),l)for(const W in l){const R=l[W];K(R)&&(n[W]=R.bind(s))}if(i){const W=i.call(s,s);z(W)&&(e.data=hn(W))}if(qs=!0,r)for(const W in r){const R=r[W],ne=K(R)?R.bind(s,s):K(R.get)?R.get.bind(s,s):De,qt=!K(R)&&K(R.set)?R.set.bind(s):De,tt=Io({get:ne,set:qt});Object.defineProperty(n,W,{enumerable:!0,configurable:!0,get:()=>tt.value,set:Oe=>tt.value=Oe})}if(o)for(const W in o)qi(o[W],n,s,W);if(c){const W=K(c)?c.call(s):c;Reflect.ownKeys(W).forEach(R=>{yl(R,W[R])})}a&&jn(a,e,"c");function N(W,R){V(R)?R.forEach(ne=>W(ne.bind(s))):R&&W(R.bind(s))}if(N(Il,h),N(Dl,b),N(Nl,S),N(Hl,O),N(Ol,F),N(Pl,k),N($l,L),N(Vl,M),N(jl,B),N(Bl,D),N(ki,m),N(Ll,H),V(P))if(P.length){const W=e.exposed||(e.exposed={});P.forEach(R=>{Object.defineProperty(W,R,{get:()=>s[R],set:ne=>s[R]=ne,enumerable:!0})})}else e.exposed||(e.exposed={});T&&e.render===De&&(e.render=T),q!=null&&(e.inheritAttrs=q),J&&(e.components=J),Y&&(e.directives=Y),H&&Ki(e)}function kl(e,t,s=De){V(e)&&(e=Gs(e));for(const n in e){const i=e[n];let r;z(i)?"default"in i?r=ss(i.from||n,i.default,!0):r=ss(i.from||n):r=ss(i),he(r)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>r.value,set:l=>r.value=l}):t[n]=r}}function jn(e,t,s){He(V(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,s)}function qi(e,t,s,n){let i=n.includes(".")?ji(s,n):()=>s[n];if(ie(e)){const r=t[e];K(r)&&Ps(i,r)}else if(K(e))Ps(i,e.bind(s));else if(z(e))if(V(e))e.forEach(r=>qi(r,t,s,n));else{const r=K(e.handler)?e.handler.bind(s):t[e.handler];K(r)&&Ps(i,r,e)}}function Gi(e){const t=e.type,{mixins:s,extends:n}=t,{mixins:i,optionsCache:r,config:{optionMergeStrategies:l}}=e.appContext,o=r.get(t);let c;return o?c=o:!i.length&&!s&&!n?c=t:(c={},i.length&&i.forEach(d=>hs(c,d,l,!0)),hs(c,t,l)),z(t)&&r.set(t,c),c}function hs(e,t,s,n=!1){const{mixins:i,extends:r}=t;r&&hs(e,r,s,!0),i&&i.forEach(l=>hs(e,l,s,!0));for(const l in t)if(!(n&&l==="expose")){const o=ql[l]||s&&s[l];e[l]=o?o(e[l],t[l]):t[l]}return e}const ql={data:Vn,props:$n,emits:$n,methods:Et,computed:Et,beforeCreate:de,created:de,beforeMount:de,mounted:de,beforeUpdate:de,updated:de,beforeDestroy:de,beforeUnmount:de,destroyed:de,unmounted:de,activated:de,deactivated:de,errorCaptured:de,serverPrefetch:de,components:Et,directives:Et,watch:Jl,provide:Vn,inject:Gl};function Vn(e,t){return t?e?function(){return ce(K(e)?e.call(this,this):e,K(t)?t.call(this,this):t)}:t:e}function Gl(e,t){return Et(Gs(e),Gs(t))}function Gs(e){if(V(e)){const t={};for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${ze(t)}Modifiers`]||e[`${et(t)}Modifiers`];function Ql(e,t,...s){if(e.isUnmounted)return;const n=e.vnode.props||ee;let i=s;const r=t.startsWith("update:"),l=r&&Zl(n,t.slice(7));l&&(l.trim&&(i=s.map(a=>ie(a)?a.trim():a)),l.number&&(i=s.map(ms)));let o,c=n[o=As(t)]||n[o=As(ze(t))];!c&&r&&(c=n[o=As(et(t))]),c&&He(c,e,6,i);const d=n[o+"Once"];if(d){if(!e.emitted)e.emitted={};else if(e.emitted[o])return;e.emitted[o]=!0,He(d,e,6,i)}}const zl=new WeakMap;function Yi(e,t,s=!1){const n=s?zl:t.emitsCache,i=n.get(e);if(i!==void 0)return i;const r=e.emits;let l={},o=!1;if(!K(e)){const c=d=>{const a=Yi(d,t,!0);a&&(o=!0,ce(l,a))};!s&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!r&&!o?(z(e)&&n.set(e,null),null):(V(r)?r.forEach(c=>l[c]=null):ce(l,r),z(e)&&n.set(e,l),l)}function xs(e,t){return!e||!$t(t)?!1:(t=t.slice(2).replace(/Once$/,""),Z(e,t[0].toLowerCase()+t.slice(1))||Z(e,et(t))||Z(e,t))}function Is(e){const{type:t,vnode:s,proxy:n,withProxy:i,propsOptions:[r],slots:l,attrs:o,emit:c,render:d,renderCache:a,props:h,data:b,setupState:S,ctx:O,inheritAttrs:F}=e,k=us(e);let U,D;try{if(s.shapeFlag&4){const m=i||n,T=m;U=Te(d.call(T,m,a,h,S,b,O)),D=o}else{const m=t;U=Te(m.length>1?m(h,{attrs:o,slots:l,emit:c}):m(h,null)),D=t.props?o:to(o)}}catch(m){Rt.length=0,Wt(m,e,1),U=ae(Fe)}let p=U;if(D&&F!==!1){const m=Object.keys(D),{shapeFlag:T}=p;m.length&&T&7&&(r&&m.some(en)&&(D=so(D,r)),p=xt(p,D,!1,!0))}return s.dirs&&(p=xt(p,null,!1,!0),p.dirs=p.dirs?p.dirs.concat(s.dirs):s.dirs),s.transition&&mn(p,s.transition),U=p,us(k),U}function eo(e,t=!0){let s;for(let n=0;n{let t;for(const s in e)(s==="class"||s==="style"||$t(s))&&((t||(t={}))[s]=e[s]);return t},so=(e,t)=>{const s={};for(const n in e)(!en(n)||!(n.slice(9)in t))&&(s[n]=e[n]);return s};function no(e,t,s){const{props:n,children:i,component:r}=e,{props:l,children:o,patchFlag:c}=t,d=r.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&c>=0){if(c&1024)return!0;if(c&16)return n?Kn(n,l,d):!!l;if(c&8){const a=t.dynamicProps;for(let h=0;hObject.create(Zi),zi=e=>Object.getPrototypeOf(e)===Zi;function io(e,t,s,n=!1){const i={},r=Qi();e.propsDefaults=Object.create(null),er(e,t,i,r);for(const l in e.propsOptions[0])l in i||(i[l]=void 0);s?e.props=n?i:ll(i):e.type.props?e.props=i:e.props=r,e.attrs=r}function ro(e,t,s,n){const{props:i,attrs:r,vnode:{patchFlag:l}}=e,o=X(i),[c]=e.propsOptions;let d=!1;if((n||l>0)&&!(l&16)){if(l&8){const a=e.vnode.dynamicProps;for(let h=0;h{c=!0;const[b,S]=tr(h,t,!0);ce(l,b),S&&o.push(...S)};!s&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}if(!r&&!c)return z(e)&&n.set(e,at),at;if(V(r))for(let a=0;ae==="_"||e==="_ctx"||e==="$stable",bn=e=>V(e)?e.map(Te):[Te(e)],oo=(e,t,s)=>{if(t._n)return t;const n=bl((...i)=>bn(t(...i)),s);return n._c=!1,n},sr=(e,t,s)=>{const n=e._ctx;for(const i in e){if(_n(i))continue;const r=e[i];if(K(r))t[i]=oo(i,r,n);else if(r!=null){const l=bn(r);t[i]=()=>l}}},nr=(e,t)=>{const s=bn(t);e.slots.default=()=>s},ir=(e,t,s)=>{for(const n in t)(s||!_n(n))&&(e[n]=t[n])},co=(e,t,s)=>{const n=e.slots=Qi();if(e.vnode.shapeFlag&32){const i=t._;i?(ir(n,t,s),s&&pi(n,"_",i,!0)):sr(t,n)}else t&&nr(e,t)},fo=(e,t,s)=>{const{vnode:n,slots:i}=e;let r=!0,l=ee;if(n.shapeFlag&32){const o=t._;o?s&&o===1?r=!1:ir(i,t,s):(r=!t.$stable,sr(t,i)),l=t}else t&&(nr(e,t),l={default:1});if(r)for(const o in i)!_n(o)&&l[o]==null&&delete i[o]},oe=ar;function uo(e){return rr(e)}function ao(e){return rr(e,Ml)}function rr(e,t){const s=_s();s.__VUE__=!0;const{insert:n,remove:i,patchProp:r,createElement:l,createText:o,createComment:c,setText:d,setElementText:a,parentNode:h,nextSibling:b,setScopeId:S=De,insertStaticContent:O}=e,F=(f,u,g,v=null,_=null,y=null,A=void 0,C=null,w=!!u.dynamicChildren)=>{if(f===u)return;f&&!Ye(f,u)&&(v=Gt(f),Oe(f,_,y,!0),f=null),u.patchFlag===-2&&(w=!1,u.dynamicChildren=null);const{type:x,ref:j,shapeFlag:E}=u;switch(x){case lt:k(f,u,g,v);break;case Fe:U(f,u,g,v);break;case is:f==null&&D(u,g,v,A);break;case Ae:J(f,u,g,v,_,y,A,C,w);break;default:E&1?T(f,u,g,v,_,y,A,C,w):E&6?Y(f,u,g,v,_,y,A,C,w):(E&64||E&128)&&x.process(f,u,g,v,_,y,A,C,w,ot)}j!=null&&_?pt(j,f&&f.ref,y,u||f,!u):j==null&&f&&f.ref!=null&&pt(f.ref,null,y,f,!0)},k=(f,u,g,v)=>{if(f==null)n(u.el=o(u.children),g,v);else{const _=u.el=f.el;u.children!==f.children&&d(_,u.children)}},U=(f,u,g,v)=>{f==null?n(u.el=c(u.children||""),g,v):u.el=f.el},D=(f,u,g,v)=>{[f.el,f.anchor]=O(f.children,u,g,v,f.el,f.anchor)},p=({el:f,anchor:u},g,v)=>{let _;for(;f&&f!==u;)_=b(f),n(f,g,v),f=_;n(u,g,v)},m=({el:f,anchor:u})=>{let g;for(;f&&f!==u;)g=b(f),i(f),f=g;i(u)},T=(f,u,g,v,_,y,A,C,w)=>{if(u.type==="svg"?A="svg":u.type==="math"&&(A="mathml"),f==null)M(u,g,v,_,y,A,C,w);else{const x=f.el&&f.el._isVueCE?f.el:null;try{x&&x._beginPatch(),H(f,u,_,y,A,C,w)}finally{x&&x._endPatch()}}},M=(f,u,g,v,_,y,A,C)=>{let w,x;const{props:j,shapeFlag:E,transition:I,dirs:$}=f;if(w=f.el=l(f.type,y,j&&j.is,j),E&8?a(w,f.children):E&16&&L(f.children,w,null,v,_,Ds(f,y),A,C),$&&Ie(f,null,v,"created"),B(w,f,f.scopeId,A,v),j){for(const te in j)te!=="value"&&!it(te)&&r(w,te,null,j[te],y,v);"value"in j&&r(w,"value",null,j.value,y),(x=j.onVnodeBeforeMount)&&ve(x,v,f)}$&&Ie(f,null,v,"beforeMount");const G=lr(_,I);G&&I.beforeEnter(w),n(w,u,g),((x=j&&j.onVnodeMounted)||G||$)&&oe(()=>{x&&ve(x,v,f),G&&I.enter(w),$&&Ie(f,null,v,"mounted")},_)},B=(f,u,g,v,_)=>{if(g&&S(f,g),v)for(let y=0;y{for(let x=w;x{const C=u.el=f.el;let{patchFlag:w,dynamicChildren:x,dirs:j}=u;w|=f.patchFlag&16;const E=f.props||ee,I=u.props||ee;let $;if(g&&st(g,!1),($=I.onVnodeBeforeUpdate)&&ve($,g,u,f),j&&Ie(u,f,g,"beforeUpdate"),g&&st(g,!0),(E.innerHTML&&I.innerHTML==null||E.textContent&&I.textContent==null)&&a(C,""),x?P(f.dynamicChildren,x,C,g,v,Ds(u,_),y):A||R(f,u,C,null,g,v,Ds(u,_),y,!1),w>0){if(w&16)q(C,E,I,g,_);else if(w&2&&E.class!==I.class&&r(C,"class",null,I.class,_),w&4&&r(C,"style",E.style,I.style,_),w&8){const G=u.dynamicProps;for(let te=0;te{$&&ve($,g,u,f),j&&Ie(u,f,g,"updated")},v)},P=(f,u,g,v,_,y,A)=>{for(let C=0;C{if(u!==g){if(u!==ee)for(const y in u)!it(y)&&!(y in g)&&r(f,y,u[y],null,_,v);for(const y in g){if(it(y))continue;const A=g[y],C=u[y];A!==C&&y!=="value"&&r(f,y,C,A,_,v)}"value"in g&&r(f,"value",u.value,g.value,_)}},J=(f,u,g,v,_,y,A,C,w)=>{const x=u.el=f?f.el:o(""),j=u.anchor=f?f.anchor:o("");let{patchFlag:E,dynamicChildren:I,slotScopeIds:$}=u;$&&(C=C?C.concat($):$),f==null?(n(x,g,v),n(j,g,v),L(u.children||[],g,j,_,y,A,C,w)):E>0&&E&64&&I&&f.dynamicChildren&&f.dynamicChildren.length===I.length?(P(f.dynamicChildren,I,g,_,y,A,C),(u.key!=null||_&&u===_.subTree)&&yn(f,u,!0)):R(f,u,g,j,_,y,A,C,w)},Y=(f,u,g,v,_,y,A,C,w)=>{u.slotScopeIds=C,f==null?u.shapeFlag&512?_.ctx.activate(u,g,v,A,w):re(u,g,v,_,y,A,w):le(f,u,w)},re=(f,u,g,v,_,y,A)=>{const C=f.component=Ao(f,v,_);if(Ui(f)&&(C.ctx.renderer=ot),Mo(C,!1,A),C.asyncDep){if(_&&_.registerDep(C,N,A),!f.el){const w=C.subTree=ae(Fe);U(null,w,u,g),f.placeholder=w.el}}else N(C,f,u,g,_,y,A)},le=(f,u,g)=>{const v=u.component=f.component;if(no(f,u,g))if(v.asyncDep&&!v.asyncResolved){W(v,u,g);return}else v.next=u,v.update();else u.el=f.el,v.vnode=u},N=(f,u,g,v,_,y,A)=>{const C=()=>{if(f.isMounted){let{next:E,bu:I,u:$,parent:G,vnode:te}=f;{const ye=or(f);if(ye){E&&(E.el=te.el,W(f,E,A)),ye.asyncDep.then(()=>{oe(()=>{f.isUnmounted||x()},_)});return}}let Q=E,me;st(f,!1),E?(E.el=te.el,W(f,E,A)):E=te,I&&ts(I),(me=E.props&&E.props.onVnodeBeforeUpdate)&&ve(me,G,E,te),st(f,!0);const fe=Is(f),Ce=f.subTree;f.subTree=fe,F(Ce,fe,h(Ce.el),Gt(Ce),f,_,y),E.el=fe.el,Q===null&&Ts(f,fe.el),$&&oe($,_),(me=E.props&&E.props.onVnodeUpdated)&&oe(()=>ve(me,G,E,te),_)}else{let E;const{el:I,props:$}=u,{bm:G,m:te,parent:Q,root:me,type:fe}=f,Ce=gt(u);if(st(f,!1),G&&ts(G),!Ce&&(E=$&&$.onVnodeBeforeMount)&&ve(E,Q,u),st(f,!0),I&&Cs){const ye=()=>{f.subTree=Is(f),Cs(I,f.subTree,f,_,null)};Ce&&fe.__asyncHydrate?fe.__asyncHydrate(I,f,ye):ye()}else{me.ce&&me.ce._hasShadowRoot()&&me.ce._injectChildStyle(fe);const ye=f.subTree=Is(f);F(null,ye,g,v,f,_,y),u.el=ye.el}if(te&&oe(te,_),!Ce&&(E=$&&$.onVnodeMounted)){const ye=u;oe(()=>ve(E,Q,ye),_)}(u.shapeFlag&256||Q&>(Q.vnode)&&Q.vnode.shapeFlag&256)&&f.a&&oe(f.a,_),f.isMounted=!0,u=g=v=null}};f.scope.on();const w=f.effect=new bi(C);f.scope.off();const x=f.update=w.run.bind(w),j=f.job=w.runIfDirty.bind(w);j.i=f,j.id=f.uid,w.scheduler=()=>gn(j),st(f,!0),x()},W=(f,u,g)=>{u.component=f;const v=f.vnode.props;f.vnode=u,f.next=null,ro(f,u.props,v,g),fo(f,u.children,g),Ue(),On(f),We()},R=(f,u,g,v,_,y,A,C,w=!1)=>{const x=f&&f.children,j=f?f.shapeFlag:0,E=u.children,{patchFlag:I,shapeFlag:$}=u;if(I>0){if(I&128){qt(x,E,g,v,_,y,A,C,w);return}else if(I&256){ne(x,E,g,v,_,y,A,C,w);return}}$&8?(j&16&&St(x,_,y),E!==x&&a(g,E)):j&16?$&16?qt(x,E,g,v,_,y,A,C,w):St(x,_,y,!0):(j&8&&a(g,""),$&16&&L(E,g,v,_,y,A,C,w))},ne=(f,u,g,v,_,y,A,C,w)=>{f=f||at,u=u||at;const x=f.length,j=u.length,E=Math.min(x,j);let I;for(I=0;Ij?St(f,_,y,!0,!1,E):L(u,g,v,_,y,A,C,w,E)},qt=(f,u,g,v,_,y,A,C,w)=>{let x=0;const j=u.length;let E=f.length-1,I=j-1;for(;x<=E&&x<=I;){const $=f[x],G=u[x]=w?je(u[x]):Te(u[x]);if(Ye($,G))F($,G,g,null,_,y,A,C,w);else break;x++}for(;x<=E&&x<=I;){const $=f[E],G=u[I]=w?je(u[I]):Te(u[I]);if(Ye($,G))F($,G,g,null,_,y,A,C,w);else break;E--,I--}if(x>E){if(x<=I){const $=I+1,G=$I)for(;x<=E;)Oe(f[x],_,y,!0),x++;else{const $=x,G=x,te=new Map;for(x=G;x<=I;x++){const xe=u[x]=w?je(u[x]):Te(u[x]);xe.key!=null&&te.set(xe.key,x)}let Q,me=0;const fe=I-G+1;let Ce=!1,ye=0;const Ct=new Array(fe);for(x=0;x=fe){Oe(xe,_,y,!0);continue}let Pe;if(xe.key!=null)Pe=te.get(xe.key);else for(Q=G;Q<=I;Q++)if(Ct[Q-G]===0&&Ye(xe,u[Q])){Pe=Q;break}Pe===void 0?Oe(xe,_,y,!0):(Ct[Pe-G]=x+1,Pe>=ye?ye=Pe:Ce=!0,F(xe,u[Pe],g,null,_,y,A,C,w),me++)}const wn=Ce?ho(Ct):at;for(Q=wn.length-1,x=fe-1;x>=0;x--){const xe=G+x,Pe=u[xe],Sn=u[xe+1],Cn=xe+1{const{el:y,type:A,transition:C,children:w,shapeFlag:x}=f;if(x&6){tt(f.component.subTree,u,g,v);return}if(x&128){f.suspense.move(u,g,v);return}if(x&64){A.move(f,u,g,ot);return}if(A===Ae){n(y,u,g);for(let E=0;EC.enter(y),_);else{const{leave:E,delayLeave:I,afterLeave:$}=C,G=()=>{f.ctx.isUnmounted?i(y):n(y,u,g)},te=()=>{y._isLeaving&&y[Cl](!0),E(y,()=>{G(),$&&$()})};I?I(y,G,te):te()}else n(y,u,g)},Oe=(f,u,g,v=!1,_=!1)=>{const{type:y,props:A,ref:C,children:w,dynamicChildren:x,shapeFlag:j,patchFlag:E,dirs:I,cacheIndex:$}=f;if(E===-2&&(_=!1),C!=null&&(Ue(),pt(C,null,g,f,!0),We()),$!=null&&(u.renderCache[$]=void 0),j&256){u.ctx.deactivate(f);return}const G=j&1&&I,te=!gt(f);let Q;if(te&&(Q=A&&A.onVnodeBeforeUnmount)&&ve(Q,u,f),j&6)Ar(f.component,g,v);else{if(j&128){f.suspense.unmount(g,v);return}G&&Ie(f,null,u,"beforeUnmount"),j&64?f.type.remove(f,u,g,ot,v):x&&!x.hasOnce&&(y!==Ae||E>0&&E&64)?St(x,u,g,!1,!0):(y===Ae&&E&384||!_&&j&16)&&St(w,u,g),v&&Tn(f)}(te&&(Q=A&&A.onVnodeUnmounted)||G)&&oe(()=>{Q&&ve(Q,u,f),G&&Ie(f,null,u,"unmounted")},g)},Tn=f=>{const{type:u,el:g,anchor:v,transition:_}=f;if(u===Ae){Cr(g,v);return}if(u===is){m(f);return}const y=()=>{i(g),_&&!_.persisted&&_.afterLeave&&_.afterLeave()};if(f.shapeFlag&1&&_&&!_.persisted){const{leave:A,delayLeave:C}=_,w=()=>A(g,y);C?C(f.el,y,w):w()}else y()},Cr=(f,u)=>{let g;for(;f!==u;)g=b(f),i(f),f=g;i(u)},Ar=(f,u,g)=>{const{bum:v,scope:_,job:y,subTree:A,um:C,m:w,a:x}=f;Wn(w),Wn(x),v&&ts(v),_.stop(),y&&(y.flags|=8,Oe(A,f,u,g)),C&&oe(C,u),oe(()=>{f.isUnmounted=!0},u)},St=(f,u,g,v=!1,_=!1,y=0)=>{for(let A=y;A{if(f.shapeFlag&6)return Gt(f.component.subTree);if(f.shapeFlag&128)return f.suspense.next();const u=b(f.anchor||f.el),g=u&&u[Vi];return g?b(g):u};let ws=!1;const vn=(f,u,g)=>{let v;f==null?u._vnode&&(Oe(u._vnode,null,null,!0),v=u._vnode.component):F(u._vnode||null,f,u,null,null,null,g),u._vnode=f,ws||(ws=!0,On(v),fs(),ws=!1)},ot={p:F,um:Oe,m:tt,r:Tn,mt:re,mc:L,pc:R,pbc:P,n:Gt,o:e};let Ss,Cs;return t&&([Ss,Cs]=t(ot)),{render:vn,hydrate:Ss,createApp:Xl(vn,Ss)}}function Ds({type:e,props:t},s){return s==="svg"&&e==="foreignObject"||s==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:s}function st({effect:e,job:t},s){s?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function lr(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function yn(e,t,s=!1){const n=e.children,i=t.children;if(V(n)&&V(i))for(let r=0;r>1,e[s[o]]0&&(t[n]=s[r-1]),s[r]=n)}}for(r=s.length,l=s[r-1];r-- >0;)s[r]=l,l=t[l];return s}function or(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:or(t)}function Wn(e){if(e)for(let t=0;te.__isSuspense;let Ys=0;const po={name:"Suspense",__isSuspense:!0,process(e,t,s,n,i,r,l,o,c,d){if(e==null)go(t,s,n,i,r,l,o,c,d);else{if(r&&r.deps>0&&!e.suspense.isInFallback){t.suspense=e.suspense,t.suspense.vnode=t,t.el=e.el;return}mo(e,t,s,n,i,l,o,c,d)}},hydrate:_o,normalize:bo},ac=po;function Bt(e,t){const s=e.props&&e.props[t];K(s)&&s()}function go(e,t,s,n,i,r,l,o,c){const{p:d,o:{createElement:a}}=c,h=a("div"),b=e.suspense=ur(e,i,n,t,h,s,r,l,o,c);d(null,b.pendingBranch=e.ssContent,h,null,n,b,r,l),b.deps>0?(Bt(e,"onPending"),Bt(e,"onFallback"),d(null,e.ssFallback,t,s,n,null,r,l),_t(b,e.ssFallback)):b.resolve(!1,!0)}function mo(e,t,s,n,i,r,l,o,{p:c,um:d,o:{createElement:a}}){const h=t.suspense=e.suspense;h.vnode=t,t.el=e.el;const b=t.ssContent,S=t.ssFallback,{activeBranch:O,pendingBranch:F,isInFallback:k,isHydrating:U}=h;if(F)h.pendingBranch=b,Ye(F,b)?(c(F,b,h.hiddenContainer,null,i,h,r,l,o),h.deps<=0?h.resolve():k&&(U||(c(O,S,s,n,i,null,r,l,o),_t(h,S)))):(h.pendingId=Ys++,U?(h.isHydrating=!1,h.activeBranch=F):d(F,i,h),h.deps=0,h.effects.length=0,h.hiddenContainer=a("div"),k?(c(null,b,h.hiddenContainer,null,i,h,r,l,o),h.deps<=0?h.resolve():(c(O,S,s,n,i,null,r,l,o),_t(h,S))):O&&Ye(O,b)?(c(O,b,s,n,i,h,r,l,o),h.resolve(!0)):(c(null,b,h.hiddenContainer,null,i,h,r,l,o),h.deps<=0&&h.resolve()));else if(O&&Ye(O,b))c(O,b,s,n,i,h,r,l,o),_t(h,b);else if(Bt(t,"onPending"),h.pendingBranch=b,b.shapeFlag&512?h.pendingId=b.component.suspenseId:h.pendingId=Ys++,c(null,b,h.hiddenContainer,null,i,h,r,l,o),h.deps<=0)h.resolve();else{const{timeout:D,pendingId:p}=h;D>0?setTimeout(()=>{h.pendingId===p&&h.fallback(S)},D):D===0&&h.fallback(S)}}function ur(e,t,s,n,i,r,l,o,c,d,a=!1){const{p:h,m:b,um:S,n:O,o:{parentNode:F,remove:k}}=d;let U;const D=yo(e);D&&t&&t.pendingBranch&&(U=t.pendingId,t.deps++);const p=e.props?Pr(e.props.timeout):void 0,m=r,T={vnode:e,parent:t,parentComponent:s,namespace:l,container:n,hiddenContainer:i,deps:0,pendingId:Ys++,timeout:typeof p=="number"?p:-1,activeBranch:null,pendingBranch:null,isInFallback:!a,isHydrating:a,isUnmounted:!1,effects:[],resolve(M=!1,B=!1){const{vnode:L,activeBranch:H,pendingBranch:P,pendingId:q,effects:J,parentComponent:Y,container:re,isInFallback:le}=T;let N=!1;T.isHydrating?T.isHydrating=!1:M||(N=H&&P.transition&&P.transition.mode==="out-in",N&&(H.transition.afterLeave=()=>{q===T.pendingId&&(b(P,re,r===m?O(H):r,0),Ks(J),le&&L.ssFallback&&(L.ssFallback.el=null))}),H&&(F(H.el)===re&&(r=O(H)),S(H,Y,T,!0),!N&&le&&L.ssFallback&&oe(()=>L.ssFallback.el=null,T)),N||b(P,re,r,0)),_t(T,P),T.pendingBranch=null,T.isInFallback=!1;let W=T.parent,R=!1;for(;W;){if(W.pendingBranch){W.effects.push(...J),R=!0;break}W=W.parent}!R&&!N&&Ks(J),T.effects=[],D&&t&&t.pendingBranch&&U===t.pendingId&&(t.deps--,t.deps===0&&!B&&t.resolve()),Bt(L,"onResolve")},fallback(M){if(!T.pendingBranch)return;const{vnode:B,activeBranch:L,parentComponent:H,container:P,namespace:q}=T;Bt(B,"onFallback");const J=O(L),Y=()=>{T.isInFallback&&(h(null,M,P,J,H,null,q,o,c),_t(T,M))},re=M.transition&&M.transition.mode==="out-in";re&&(L.transition.afterLeave=Y),T.isInFallback=!0,S(L,H,null,!0),re||Y()},move(M,B,L){T.activeBranch&&b(T.activeBranch,M,B,L),T.container=M},next(){return T.activeBranch&&O(T.activeBranch)},registerDep(M,B,L){const H=!!T.pendingBranch;H&&T.deps++;const P=M.vnode.el;M.asyncDep.catch(q=>{Wt(q,M,0)}).then(q=>{if(M.isUnmounted||T.isUnmounted||T.pendingId!==M.suspenseId)return;M.asyncResolved=!0;const{vnode:J}=M;Zs(M,q),P&&(J.el=P);const Y=!P&&M.subTree.el;B(M,J,F(P||M.subTree.el),P?null:O(M.subTree),T,l,L),Y&&(J.placeholder=null,k(Y)),Ts(M,J.el),H&&--T.deps===0&&T.resolve()})},unmount(M,B){T.isUnmounted=!0,T.activeBranch&&S(T.activeBranch,s,M,B),T.pendingBranch&&S(T.pendingBranch,s,M,B)}};return T}function _o(e,t,s,n,i,r,l,o,c){const d=t.suspense=ur(t,n,s,e.parentNode,document.createElement("div"),null,i,r,l,o,!0),a=c(e,d.pendingBranch=t.ssContent,s,d,r,l);return d.deps===0&&d.resolve(!1,!0),a}function bo(e){const{shapeFlag:t,children:s}=e,n=t&32;e.ssContent=kn(n?s.default:s),e.ssFallback=n?kn(s.fallback):ae(Fe)}function kn(e){let t;if(K(e)){const s=yt&&e._c;s&&(e._d=!1,hr()),e=e(),s&&(e._d=!0,t=be,dr())}return V(e)&&(e=eo(e)),e=Te(e),t&&!e.dynamicChildren&&(e.dynamicChildren=t.filter(s=>s!==e)),e}function ar(e,t){t&&t.pendingBranch?V(e)?t.effects.push(...e):t.effects.push(e):Ks(e)}function _t(e,t){e.activeBranch=t;const{vnode:s,parentComponent:n}=e;let i=t.el;for(;!i&&t.component;)t=t.component.subTree,i=t.el;s.el=i,n&&n.subTree===s&&(n.vnode.el=i,Ts(n,i))}function yo(e){const t=e.props&&e.props.suspensible;return t!=null&&t!==!1}const Ae=Symbol.for("v-fgt"),lt=Symbol.for("v-txt"),Fe=Symbol.for("v-cmt"),is=Symbol.for("v-stc"),Rt=[];let be=null;function hr(e=!1){Rt.push(be=e?null:[])}function dr(){Rt.pop(),be=Rt[Rt.length-1]||null}let yt=1;function ds(e,t=!1){yt+=e,e<0&&be&&t&&(be.hasOnce=!0)}function pr(e){return e.dynamicChildren=yt>0?be||at:null,dr(),yt>0&&be&&be.push(e),e}function hc(e,t,s,n,i,r){return pr(mr(e,t,s,n,i,r,!0))}function xo(e,t,s,n,i){return pr(ae(e,t,s,n,i,!0))}function Lt(e){return e?e.__v_isVNode===!0:!1}function Ye(e,t){return e.type===t.type&&e.key===t.key}const gr=({key:e})=>e??null,rs=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?ie(e)||he(e)||K(e)?{i:we,r:e,k:t,f:!!s}:e:null);function mr(e,t=null,s=null,n=0,i=null,r=e===Ae?0:1,l=!1,o=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&gr(t),ref:t&&rs(t),scopeId:Bi,slotScopeIds:null,children:s,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:r,patchFlag:n,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:we};return o?(xn(c,s),r&128&&e.normalize(c)):s&&(c.shapeFlag|=ie(s)?8:16),yt>0&&!l&&be&&(c.patchFlag>0||r&6)&&c.patchFlag!==32&&be.push(c),c}const ae=To;function To(e,t=null,s=null,n=0,i=null,r=!1){if((!e||e===Kl)&&(e=Fe),Lt(e)){const o=xt(e,t,!0);return s&&xn(o,s),yt>0&&!r&&be&&(o.shapeFlag&6?be[be.indexOf(e)]=o:be.push(o)),o.patchFlag=-2,o}if(Ro(e)&&(e=e.__vccOpts),t){t=vo(t);let{class:o,style:c}=t;o&&!ie(o)&&(t.class=rn(o)),z(c)&&(pn(c)&&!V(c)&&(c=ce({},c)),t.style=nn(c))}const l=ie(e)?1:fr(e)?128:wl(e)?64:z(e)?4:K(e)?2:0;return mr(e,t,s,n,i,l,r,!0)}function vo(e){return e?pn(e)||zi(e)?ce({},e):e:null}function xt(e,t,s=!1,n=!1){const{props:i,ref:r,patchFlag:l,children:o,transition:c}=e,d=t?wo(i||{},t):i,a={__v_isVNode:!0,__v_skip:!0,type:e.type,props:d,key:d&&gr(d),ref:t&&t.ref?s&&r?V(r)?r.concat(rs(t)):[r,rs(t)]:rs(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:o,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Ae?l===-1?16:l|16:l,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&xt(e.ssContent),ssFallback:e.ssFallback&&xt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&n&&mn(a,c.clone(a)),a}function _r(e=" ",t=0){return ae(lt,null,e,t)}function dc(e="",t=!1){return t?(hr(),xo(Fe,null,e)):ae(Fe,null,e)}function Te(e){return e==null||typeof e=="boolean"?ae(Fe):V(e)?ae(Ae,null,e.slice()):Lt(e)?je(e):ae(lt,null,String(e))}function je(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:xt(e)}function xn(e,t){let s=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(V(t))s=16;else if(typeof t=="object")if(n&65){const i=t.default;i&&(i._c&&(i._d=!1),xn(e,i()),i._c&&(i._d=!0));return}else{s=32;const i=t._;!i&&!zi(t)?t._ctx=we:i===3&&we&&(we.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else K(t)?(t={default:t,_ctx:we},s=32):(t=String(t),n&64?(s=16,t=[_r(t)]):s=8);e.children=t,e.shapeFlag|=s}function wo(...e){const t={};for(let s=0;sge||we;let ps,Xs;{const e=_s(),t=(s,n)=>{let i;return(i=e[s])||(i=e[s]=[]),i.push(n),r=>{i.length>1?i.forEach(l=>l(r)):i[0](r)}};ps=t("__VUE_INSTANCE_SETTERS__",s=>ge=s),Xs=t("__VUE_SSR_SETTERS__",s=>jt=s)}const kt=e=>{const t=ge;return ps(e),e.scope.on(),()=>{e.scope.off(),ps(t)}},qn=()=>{ge&&ge.scope.off(),ps(null)};function br(e){return e.vnode.shapeFlag&4}let jt=!1;function Mo(e,t=!1,s=!1){t&&Xs(t);const{props:n,children:i}=e.vnode,r=br(e);io(e,n,r,t),co(e,i,s||t);const l=r?Fo(e,t):void 0;return t&&Xs(!1),l}function Fo(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Ul);const{setup:n}=s;if(n){Ue();const i=e.setupContext=n.length>1?Po(e):null,r=kt(e),l=Ut(n,e,0,[e.props,i]),o=ui(l);if(We(),r(),(o||e.sp)&&!gt(e)&&Ki(e),o){if(l.then(qn,qn),t)return l.then(c=>{Zs(e,c)}).catch(c=>{Wt(c,e,0)});e.asyncDep=l}else Zs(e,l)}else yr(e)}function Zs(e,t,s){K(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:z(t)&&(e.setupState=Ri(t)),yr(e)}function yr(e,t,s){const n=e.type;e.render||(e.render=n.render||De);{const i=kt(e);Ue();try{Wl(e)}finally{We(),i()}}}const Oo={get(e,t){return ue(e,"get",""),e[t]}};function Po(e){const t=s=>{e.exposed=s||{}};return{attrs:new Proxy(e.attrs,Oo),slots:e.slots,emit:e.emit,expose:t}}function vs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Ri(ol(e.exposed)),{get(t,s){if(s in t)return t[s];if(s in Pt)return Pt[s](e)},has(t,s){return s in t||s in Pt}})):e.proxy}function Ro(e){return K(e)&&"__vccOpts"in e}const Io=(e,t)=>dl(e,t,jt);function pc(e,t,s){try{ds(-1);const n=arguments.length;return n===2?z(t)&&!V(t)?Lt(t)?ae(e,null,[t]):ae(e,t):ae(e,null,t):(n>3?s=Array.prototype.slice.call(arguments,2):n===3&&Lt(s)&&(s=[s]),ae(e,t,s))}finally{ds(1)}}const Do="3.5.28";/** -* @vue/runtime-dom v3.5.28 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Qs;const Gn=typeof window<"u"&&window.trustedTypes;if(Gn)try{Qs=Gn.createPolicy("vue",{createHTML:e=>e})}catch{}const xr=Qs?e=>Qs.createHTML(e):e=>e,No="http://www.w3.org/2000/svg",Ho="http://www.w3.org/1998/Math/MathML",Le=typeof document<"u"?document:null,Jn=Le&&Le.createElement("template"),Bo={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const i=t==="svg"?Le.createElementNS(No,e):t==="mathml"?Le.createElementNS(Ho,e):s?Le.createElement(e,{is:s}):Le.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>Le.createTextNode(e),createComment:e=>Le.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Le.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,i,r){const l=s?s.previousSibling:t.lastChild;if(i&&(i===r||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),s),!(i===r||!(i=i.nextSibling)););else{Jn.innerHTML=xr(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const o=Jn.content;if(n==="svg"||n==="mathml"){const c=o.firstChild;for(;c.firstChild;)o.appendChild(c.firstChild);o.removeChild(c)}t.insertBefore(o,s)}return[l?l.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Lo=Symbol("_vtc");function jo(e,t,s){const n=e[Lo];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const Yn=Symbol("_vod"),Vo=Symbol("_vsh"),$o=Symbol(""),Ko=/(?:^|;)\s*display\s*:/;function Uo(e,t,s){const n=e.style,i=ie(s);let r=!1;if(s&&!i){if(t)if(ie(t))for(const l of t.split(";")){const o=l.slice(0,l.indexOf(":")).trim();s[o]==null&&ls(n,o,"")}else for(const l in t)s[l]==null&&ls(n,l,"");for(const l in s)l==="display"&&(r=!0),ls(n,l,s[l])}else if(i){if(t!==s){const l=n[$o];l&&(s+=";"+l),n.cssText=s,r=Ko.test(s)}}else t&&e.removeAttribute("style");Yn in e&&(e[Yn]=r?n.display:"",e[Vo]&&(n.display="none"))}const Xn=/\s*!important$/;function ls(e,t,s){if(V(s))s.forEach(n=>ls(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Wo(e,t);Xn.test(s)?e.setProperty(et(n),s.replace(Xn,""),"important"):e[n]=s}}const Zn=["Webkit","Moz","ms"],Ns={};function Wo(e,t){const s=Ns[t];if(s)return s;let n=ze(t);if(n!=="filter"&&n in e)return Ns[t]=n;n=di(n);for(let i=0;iHs||(Jo.then(()=>Hs=0),Hs=Date.now());function Xo(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;He(Zo(n,s.value),t,5,[n])};return s.value=e,s.attached=Yo(),s}function Zo(e,t){if(V(t)){const s=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{s.call(e),e._stopped=!0},t.map(n=>i=>!i._stopped&&n&&n(i))}else return t}const ni=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Qo=(e,t,s,n,i,r)=>{const l=i==="svg";t==="class"?jo(e,n,l):t==="style"?Uo(e,s,n):$t(t)?en(t)||qo(e,t,s,n,r):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):zo(e,t,n,l))?(ei(e,t,n),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&zn(e,t,n,l,r,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!ie(n))?ei(e,ze(t),n,r,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),zn(e,t,n,l))};function zo(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&ni(t)&&K(s));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const i=e.tagName;if(i==="IMG"||i==="VIDEO"||i==="CANVAS"||i==="SOURCE")return!1}return ni(t)&&ie(s)?!1:t in e}const Tt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return V(t)?s=>ts(t,s):t};function ec(e){e.target.composing=!0}function ii(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ke=Symbol("_assign");function ri(e,t,s){return t&&(e=e.trim()),s&&(e=ms(e)),e}const gc={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Ke]=Tt(i);const r=n||i.props&&i.props.type==="number";Xe(e,t?"change":"input",l=>{l.target.composing||e[Ke](ri(e.value,s,r))}),(s||r)&&Xe(e,"change",()=>{e.value=ri(e.value,s,r)}),t||(Xe(e,"compositionstart",ec),Xe(e,"compositionend",ii),Xe(e,"change",ii))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:r}},l){if(e[Ke]=Tt(l),e.composing)return;const o=(r||e.type==="number")&&!/^0\d/.test(e.value)?ms(e.value):e.value,c=t??"";o!==c&&(document.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===c)||(e.value=c))}},mc={deep:!0,created(e,t,s){e[Ke]=Tt(s),Xe(e,"change",()=>{const n=e._modelValue,i=Vt(e),r=e.checked,l=e[Ke];if(V(n)){const o=ln(n,i),c=o!==-1;if(r&&!c)l(n.concat(i));else if(!r&&c){const d=[...n];d.splice(o,1),l(d)}}else if(vt(n)){const o=new Set(n);r?o.add(i):o.delete(i),l(o)}else l(Tr(e,r))})},mounted:li,beforeUpdate(e,t,s){e[Ke]=Tt(s),li(e,t,s)}};function li(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(V(t))i=ln(t,n.props.value)>-1;else if(vt(t))i=t.has(n.props.value);else{if(t===s)return;i=wt(t,Tr(e,!0))}e.checked!==i&&(e.checked=i)}const _c={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=vt(t);Xe(e,"change",()=>{const r=Array.prototype.filter.call(e.options,l=>l.selected).map(l=>s?ms(Vt(l)):Vt(l));e[Ke](e.multiple?i?new Set(r):r:r[0]),e._assigning=!0,Di(()=>{e._assigning=!1})}),e[Ke]=Tt(n)},mounted(e,{value:t}){oi(e,t)},beforeUpdate(e,t,s){e[Ke]=Tt(s)},updated(e,{value:t}){e._assigning||oi(e,t)}};function oi(e,t){const s=e.multiple,n=V(t);if(!(s&&!n&&!vt(t))){for(let i=0,r=e.options.length;iString(d)===String(o)):l.selected=ln(t,o)>-1}else l.selected=t.has(o);else if(wt(Vt(l),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Vt(e){return"_value"in e?e._value:e.value}function Tr(e,t){const s=t?"_trueValue":"_falseValue";return s in e?e[s]:t}const tc=["ctrl","shift","alt","meta"],sc={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>tc.some(s=>e[`${s}Key`]&&!t.includes(s))},bc=(e,t)=>{if(!e)return e;const s=e._withMods||(e._withMods={}),n=t.join(".");return s[n]||(s[n]=((i,...r)=>{for(let l=0;l{const s=e._withKeys||(e._withKeys={}),n=t.join(".");return s[n]||(s[n]=(i=>{if(!("key"in i))return;const r=et(i.key);if(t.some(l=>l===r||nc[l]===r))return e(i)}))},vr=ce({patchProp:Qo},Bo);let It,ci=!1;function ic(){return It||(It=uo(vr))}function rc(){return It=ci?It:ao(vr),ci=!0,It}const xc=((...e)=>{const t=ic().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=Sr(n);if(!i)return;const r=t._component;!K(r)&&!r.render&&!r.template&&(r.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const l=s(i,!1,wr(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),l},t}),Tc=((...e)=>{const t=rc().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=Sr(n);if(i)return s(i,!0,wr(i))},t});function wr(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Sr(e){return ie(e)?document.querySelector(e):e}export{Ae as F,ac as S,cc as T,mr as a,dc as b,hc as c,_r as d,_c as e,mc as f,bc as g,fc as h,lc as i,Ps as j,Io as k,xo as l,Di as m,rn as n,hr as o,yc as p,Dl as q,uc as r,pc as s,jr as t,Tc as u,gc as v,oc as w,xc as x}; diff --git a/dist/client/favicon.svg b/dist/client/favicon.svg deleted file mode 100644 index 1726c13..0000000 --- a/dist/client/favicon.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - diff --git a/dist/server/_@astrojs-ssr-adapter.mjs b/dist/server/_@astrojs-ssr-adapter.mjs deleted file mode 100644 index e53f9f6..0000000 --- a/dist/server/_@astrojs-ssr-adapter.mjs +++ /dev/null @@ -1 +0,0 @@ -export { c as createExports, a as start } from './chunks/_@astrojs-ssr-adapter_BeL8VyJ8.mjs'; diff --git a/dist/server/_noop-middleware.mjs b/dist/server/_noop-middleware.mjs deleted file mode 100644 index 84424b0..0000000 --- a/dist/server/_noop-middleware.mjs +++ /dev/null @@ -1,3 +0,0 @@ -const onRequest = (_, next) => next(); - -export { onRequest }; diff --git a/dist/server/chunks/_@astrojs-ssr-adapter_BeL8VyJ8.mjs b/dist/server/chunks/_@astrojs-ssr-adapter_BeL8VyJ8.mjs deleted file mode 100644 index 2db951c..0000000 --- a/dist/server/chunks/_@astrojs-ssr-adapter_BeL8VyJ8.mjs +++ /dev/null @@ -1,4412 +0,0 @@ -import { q as decryptString, v as createSlotValueFromString, w as isAstroComponentFactory, k as renderComponent, r as renderTemplate, R as ROUTE_TYPE_HEADER, x as REROUTE_DIRECTIVE_HEADER, A as AstroError, y as i18nNoLocaleFoundInPath, z as ResponseSentError, B as ActionNotFoundError, C as MiddlewareNoDataOrNextCalled, D as MiddlewareNotAResponse, G as originPathnameSymbol, H as RewriteWithBodyUsed, J as GetStaticPathsRequired, K as InvalidGetStaticPathsReturn, O as InvalidGetStaticPathsEntry, P as GetStaticPathsExpectedParams, Q as GetStaticPathsInvalidRouteParam, S as PageNumberParamNotFound, T as DEFAULT_404_COMPONENT, V as NoMatchingStaticPathFound, W as PrerenderDynamicEndpointPathCollide, X as ReservedSlotName, Y as renderSlotToString, Z as renderJSX, _ as chunkToString, $ as isRenderInstruction, a0 as ForbiddenRewrite, a1 as SessionStorageInitError, a2 as SessionStorageSaveError, a3 as ASTRO_VERSION, a4 as CspNotEnabled, a5 as LocalsReassigned, a6 as generateCspDigest, a7 as PrerenderClientAddressNotAvailable, a8 as clientAddressSymbol, a9 as ClientAddressNotAvailable, aa as StaticClientAddressNotAvailable, ab as AstroResponseHeadersReassigned, ac as responseSentSymbol$1, ad as renderPage, ae as REWRITE_DIRECTIVE_HEADER_KEY, af as REWRITE_DIRECTIVE_HEADER_VALUE, ag as renderEndpoint, ah as LocalsNotAnObject, ai as FailedToFindPageMapSSR, aj as REROUTABLE_STATUS_CODES, ak as nodeRequestAbortControllerCleanupSymbol } from './astro/server_CF97kUu8.mjs'; -import colors from 'piccolore'; -import 'clsx'; -import { A as ActionError, d as deserializeActionResult, s as serializeActionResult, a as ACTION_RPC_ROUTE_PATTERN, b as ACTION_QUERY_PARAMS, g as getActionQueryString, D as DEFAULT_404_ROUTE, c as default404Instance, N as NOOP_MIDDLEWARE_FN, e as ensure404Route } from './astro-designed-error-pages_DSexancP.mjs'; -import 'es-module-lexer'; -import buffer from 'node:buffer'; -import crypto$1 from 'node:crypto'; -import fs, { existsSync, readFileSync } from 'node:fs'; -import { Http2ServerResponse } from 'node:http2'; -import { c as appendForwardSlash$1, j as joinPaths, f as fileExtension, s as slash, p as prependForwardSlash$1, d as removeTrailingForwardSlash, t as trimSlashes, m as matchPattern, e as isInternalPath, g as collapseDuplicateTrailingSlashes, h as hasFileExtension } from './remote_B3W5fv4r.mjs'; -import { serialize, parse } from 'cookie'; -import { unflatten as unflatten$1, stringify as stringify$1 } from 'devalue'; -import { createStorage, builtinDrivers } from 'unstorage'; -import { AsyncLocalStorage } from 'node:async_hooks'; -import http from 'node:http'; -import https from 'node:https'; -import enableDestroy from 'server-destroy'; -import os from 'node:os'; -import path from 'node:path'; -import url from 'node:url'; -import send from 'send'; - -function shouldAppendForwardSlash(trailingSlash, buildFormat) { - switch (trailingSlash) { - case "always": - return true; - case "never": - return false; - case "ignore": { - switch (buildFormat) { - case "directory": - return true; - case "preserve": - case "file": - return false; - } - } - } -} - -function redirectIsExternal(redirect) { - if (typeof redirect === "string") { - return redirect.startsWith("http://") || redirect.startsWith("https://"); - } else { - return redirect.destination.startsWith("http://") || redirect.destination.startsWith("https://"); - } -} -async function renderRedirect(renderContext) { - const { - request: { method }, - routeData - } = renderContext; - const { redirect, redirectRoute } = routeData; - const status = redirectRoute && typeof redirect === "object" ? redirect.status : method === "GET" ? 301 : 308; - const headers = { location: encodeURI(redirectRouteGenerate(renderContext)) }; - if (redirect && redirectIsExternal(redirect)) { - if (typeof redirect === "string") { - return Response.redirect(redirect, status); - } else { - return Response.redirect(redirect.destination, status); - } - } - return new Response(null, { status, headers }); -} -function redirectRouteGenerate(renderContext) { - const { - params, - routeData: { redirect, redirectRoute } - } = renderContext; - if (typeof redirectRoute !== "undefined") { - return redirectRoute?.generate(params) || redirectRoute?.pathname || "/"; - } else if (typeof redirect === "string") { - if (redirectIsExternal(redirect)) { - return redirect; - } else { - let target = redirect; - for (const param of Object.keys(params)) { - const paramValue = params[param]; - target = target.replace(`[${param}]`, paramValue).replace(`[...${param}]`, paramValue); - } - return target; - } - } else if (typeof redirect === "undefined") { - return "/"; - } - return redirect.destination; -} - -const SERVER_ISLAND_ROUTE = "/_server-islands/[name]"; -const SERVER_ISLAND_COMPONENT = "_server-islands.astro"; -const SERVER_ISLAND_BASE_PREFIX = "_server-islands"; -function badRequest(reason) { - return new Response(null, { - status: 400, - statusText: "Bad request: " + reason - }); -} -async function getRequestData(request) { - switch (request.method) { - case "GET": { - const url = new URL(request.url); - const params = url.searchParams; - if (!params.has("s") || !params.has("e") || !params.has("p")) { - return badRequest("Missing required query parameters."); - } - const encryptedSlots = params.get("s"); - return { - encryptedComponentExport: params.get("e"), - encryptedProps: params.get("p"), - encryptedSlots - }; - } - case "POST": { - try { - const raw = await request.text(); - const data = JSON.parse(raw); - if ("slots" in data && typeof data.slots === "object") { - return badRequest("Plaintext slots are not allowed. Slots must be encrypted."); - } - if ("componentExport" in data && typeof data.componentExport === "string") { - return badRequest( - "Plaintext componentExport is not allowed. componentExport must be encrypted." - ); - } - return data; - } catch (e) { - if (e instanceof SyntaxError) { - return badRequest("Request format is invalid."); - } - throw e; - } - } - default: { - return new Response(null, { status: 405 }); - } - } -} -function createEndpoint(manifest) { - const page = async (result) => { - const params = result.params; - if (!params.name) { - return new Response(null, { - status: 400, - statusText: "Bad request" - }); - } - const componentId = params.name; - const data = await getRequestData(result.request); - if (data instanceof Response) { - return data; - } - const imp = manifest.serverIslandMap?.get(componentId); - if (!imp) { - return new Response(null, { - status: 404, - statusText: "Not found" - }); - } - const key = await manifest.key; - let componentExport; - try { - componentExport = await decryptString(key, data.encryptedComponentExport); - } catch (_e) { - return badRequest("Encrypted componentExport value is invalid."); - } - const encryptedProps = data.encryptedProps; - let props = {}; - if (encryptedProps !== "") { - try { - const propString = await decryptString(key, encryptedProps); - props = JSON.parse(propString); - } catch (_e) { - return badRequest("Encrypted props value is invalid."); - } - } - let decryptedSlots = {}; - const encryptedSlots = data.encryptedSlots; - if (encryptedSlots !== "") { - try { - const slotsString = await decryptString(key, encryptedSlots); - decryptedSlots = JSON.parse(slotsString); - } catch (_e) { - return badRequest("Encrypted slots value is invalid."); - } - } - const componentModule = await imp(); - let Component = componentModule[componentExport]; - const slots = {}; - for (const prop in decryptedSlots) { - slots[prop] = createSlotValueFromString(decryptedSlots[prop]); - } - result.response.headers.set("X-Robots-Tag", "noindex"); - if (isAstroComponentFactory(Component)) { - const ServerIsland = Component; - Component = function(...args) { - return ServerIsland.apply(this, args); - }; - Object.assign(Component, ServerIsland); - Component.propagation = "self"; - } - return renderTemplate`${renderComponent(result, "Component", Component, props, slots)}`; - }; - page.isAstroComponentFactory = true; - const instance = { - default: page, - partial: true - }; - return instance; -} - -function matchRoute(pathname, manifest) { - return manifest.routes.find((route) => { - return route.pattern.test(pathname) || route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(pathname)); - }); -} -const ROUTE404_RE = /^\/404\/?$/; -const ROUTE500_RE = /^\/500\/?$/; -function isRoute404(route) { - return ROUTE404_RE.test(route); -} -function isRoute500(route) { - return ROUTE500_RE.test(route); -} -function isRoute404or500(route) { - return isRoute404(route.route) || isRoute500(route.route); -} -function isRouteServerIsland(route) { - return route.component === SERVER_ISLAND_COMPONENT; -} -function isRequestServerIsland(request, base = "") { - const url = new URL(request.url); - const pathname = base === "/" ? url.pathname.slice(base.length) : url.pathname.slice(base.length + 1); - return pathname.startsWith(SERVER_ISLAND_BASE_PREFIX); -} -function requestIs404Or500(request, base = "") { - const url = new URL(request.url); - const pathname = url.pathname.slice(base.length); - return isRoute404(pathname) || isRoute500(pathname); -} -function isRouteExternalRedirect(route) { - return !!(route.type === "redirect" && route.redirect && redirectIsExternal(route.redirect)); -} - -function createI18nMiddleware(i18n, base, trailingSlash, format) { - if (!i18n) return (_, next) => next(); - const payload = { - ...i18n, - trailingSlash, - base, - format}; - const _redirectToDefaultLocale = redirectToDefaultLocale(payload); - const _noFoundForNonLocaleRoute = notFound(payload); - const _requestHasLocale = requestHasLocale(payload.locales); - const _redirectToFallback = redirectToFallback(payload); - const prefixAlways = (context, response) => { - const url = context.url; - if (url.pathname === base + "/" || url.pathname === base) { - return _redirectToDefaultLocale(context); - } else if (!_requestHasLocale(context)) { - return _noFoundForNonLocaleRoute(context, response); - } - return void 0; - }; - const prefixOtherLocales = (context, response) => { - let pathnameContainsDefaultLocale = false; - const url = context.url; - for (const segment of url.pathname.split("/")) { - if (normalizeTheLocale(segment) === normalizeTheLocale(i18n.defaultLocale)) { - pathnameContainsDefaultLocale = true; - break; - } - } - if (pathnameContainsDefaultLocale) { - const newLocation = url.pathname.replace(`/${i18n.defaultLocale}`, ""); - response.headers.set("Location", newLocation); - return _noFoundForNonLocaleRoute(context); - } - return void 0; - }; - return async (context, next) => { - const response = await next(); - const type = response.headers.get(ROUTE_TYPE_HEADER); - const isReroute = response.headers.get(REROUTE_DIRECTIVE_HEADER); - if (isReroute === "no" && typeof i18n.fallback === "undefined") { - return response; - } - if (type !== "page" && type !== "fallback") { - return response; - } - if (requestIs404Or500(context.request, base)) { - return response; - } - if (isRequestServerIsland(context.request, base)) { - return response; - } - const { currentLocale } = context; - switch (i18n.strategy) { - // NOTE: theoretically, we should never hit this code path - case "manual": { - return response; - } - case "domains-prefix-other-locales": { - if (localeHasntDomain(i18n, currentLocale)) { - const result = prefixOtherLocales(context, response); - if (result) { - return result; - } - } - break; - } - case "pathname-prefix-other-locales": { - const result = prefixOtherLocales(context, response); - if (result) { - return result; - } - break; - } - case "domains-prefix-always-no-redirect": { - if (localeHasntDomain(i18n, currentLocale)) { - const result = _noFoundForNonLocaleRoute(context, response); - if (result) { - return result; - } - } - break; - } - case "pathname-prefix-always-no-redirect": { - const result = _noFoundForNonLocaleRoute(context, response); - if (result) { - return result; - } - break; - } - case "pathname-prefix-always": { - const result = prefixAlways(context, response); - if (result) { - return result; - } - break; - } - case "domains-prefix-always": { - if (localeHasntDomain(i18n, currentLocale)) { - const result = prefixAlways(context, response); - if (result) { - return result; - } - } - break; - } - } - return _redirectToFallback(context, response); - }; -} -function localeHasntDomain(i18n, currentLocale) { - for (const domainLocale of Object.values(i18n.domainLookupTable)) { - if (domainLocale === currentLocale) { - return false; - } - } - return true; -} - -function requestHasLocale(locales) { - return function(context) { - return pathHasLocale(context.url.pathname, locales); - }; -} -function pathHasLocale(path, locales) { - const segments = path.split("/").map(normalizeThePath); - for (const segment of segments) { - for (const locale of locales) { - if (typeof locale === "string") { - if (normalizeTheLocale(segment) === normalizeTheLocale(locale)) { - return true; - } - } else if (segment === locale.path) { - return true; - } - } - } - return false; -} -function getPathByLocale(locale, locales) { - for (const loopLocale of locales) { - if (typeof loopLocale === "string") { - if (loopLocale === locale) { - return loopLocale; - } - } else { - for (const code of loopLocale.codes) { - if (code === locale) { - return loopLocale.path; - } - } - } - } - throw new AstroError(i18nNoLocaleFoundInPath); -} -function normalizeTheLocale(locale) { - return locale.replaceAll("_", "-").toLowerCase(); -} -function normalizeThePath(path) { - return path.endsWith(".html") ? path.slice(0, -5) : path; -} -function getAllCodes(locales) { - const result = []; - for (const loopLocale of locales) { - if (typeof loopLocale === "string") { - result.push(loopLocale); - } else { - result.push(...loopLocale.codes); - } - } - return result; -} -function redirectToDefaultLocale({ - trailingSlash, - format, - base, - defaultLocale -}) { - return function(context, statusCode) { - if (shouldAppendForwardSlash(trailingSlash, format)) { - return context.redirect(`${appendForwardSlash$1(joinPaths(base, defaultLocale))}`, statusCode); - } else { - return context.redirect(`${joinPaths(base, defaultLocale)}`, statusCode); - } - }; -} -function notFound({ base, locales, fallback }) { - return function(context, response) { - if (response?.headers.get(REROUTE_DIRECTIVE_HEADER) === "no" && typeof fallback === "undefined") { - return response; - } - const url = context.url; - const isRoot = url.pathname === base + "/" || url.pathname === base; - if (!(isRoot || pathHasLocale(url.pathname, locales))) { - if (response) { - response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); - return new Response(response.body, { - status: 404, - headers: response.headers - }); - } else { - return new Response(null, { - status: 404, - headers: { - [REROUTE_DIRECTIVE_HEADER]: "no" - } - }); - } - } - return void 0; - }; -} -function redirectToFallback({ - fallback, - locales, - defaultLocale, - strategy, - base, - fallbackType -}) { - return async function(context, response) { - if (response.status >= 300 && fallback) { - const fallbackKeys = fallback ? Object.keys(fallback) : []; - const segments = context.url.pathname.split("/"); - const urlLocale = segments.find((segment) => { - for (const locale of locales) { - if (typeof locale === "string") { - if (locale === segment) { - return true; - } - } else if (locale.path === segment) { - return true; - } - } - return false; - }); - if (urlLocale && fallbackKeys.includes(urlLocale)) { - const fallbackLocale = fallback[urlLocale]; - const pathFallbackLocale = getPathByLocale(fallbackLocale, locales); - let newPathname; - if (pathFallbackLocale === defaultLocale && strategy === "pathname-prefix-other-locales") { - if (context.url.pathname.includes(`${base}`)) { - newPathname = context.url.pathname.replace(`/${urlLocale}`, ``); - if (newPathname === "") { - newPathname = "/"; - } - } else { - newPathname = context.url.pathname.replace(`/${urlLocale}`, `/`); - } - } else { - newPathname = context.url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`); - } - if (fallbackType === "rewrite") { - return await context.rewrite(newPathname + context.url.search); - } else { - return context.redirect(newPathname + context.url.search); - } - } - } - return response; - }; -} - -const DELETED_EXPIRATION = /* @__PURE__ */ new Date(0); -const DELETED_VALUE = "deleted"; -const responseSentSymbol = Symbol.for("astro.responseSent"); -const identity = (value) => value; -class AstroCookie { - constructor(value) { - this.value = value; - } - json() { - if (this.value === void 0) { - throw new Error(`Cannot convert undefined to an object.`); - } - return JSON.parse(this.value); - } - number() { - return Number(this.value); - } - boolean() { - if (this.value === "false") return false; - if (this.value === "0") return false; - return Boolean(this.value); - } -} -class AstroCookies { - #request; - #requestValues; - #outgoing; - #consumed; - constructor(request) { - this.#request = request; - this.#requestValues = null; - this.#outgoing = null; - this.#consumed = false; - } - /** - * Astro.cookies.delete(key) is used to delete a cookie. Using this method will result - * in a Set-Cookie header added to the response. - * @param key The cookie to delete - * @param options Options related to this deletion, such as the path of the cookie. - */ - delete(key, options) { - const { - // @ts-expect-error - maxAge: _ignoredMaxAge, - // @ts-expect-error - expires: _ignoredExpires, - ...sanitizedOptions - } = options || {}; - const serializeOptions = { - expires: DELETED_EXPIRATION, - ...sanitizedOptions - }; - this.#ensureOutgoingMap().set(key, [ - DELETED_VALUE, - serialize(key, DELETED_VALUE, serializeOptions), - false - ]); - } - /** - * Astro.cookies.get(key) is used to get a cookie value. The cookie value is read from the - * request. If you have set a cookie via Astro.cookies.set(key, value), the value will be taken - * from that set call, overriding any values already part of the request. - * @param key The cookie to get. - * @returns An object containing the cookie value as well as convenience methods for converting its value. - */ - get(key, options = void 0) { - if (this.#outgoing?.has(key)) { - let [serializedValue, , isSetValue] = this.#outgoing.get(key); - if (isSetValue) { - return new AstroCookie(serializedValue); - } else { - return void 0; - } - } - const decode = options?.decode ?? decodeURIComponent; - const values = this.#ensureParsed(); - if (key in values) { - const value = values[key]; - if (value) { - let decodedValue; - try { - decodedValue = decode(value); - } catch (_error) { - decodedValue = value; - } - return new AstroCookie(decodedValue); - } - } - } - /** - * Astro.cookies.has(key) returns a boolean indicating whether this cookie is either - * part of the initial request or set via Astro.cookies.set(key) - * @param key The cookie to check for. - * @param _options This parameter is no longer used. - * @returns - */ - has(key, _options) { - if (this.#outgoing?.has(key)) { - let [, , isSetValue] = this.#outgoing.get(key); - return isSetValue; - } - const values = this.#ensureParsed(); - return values[key] !== void 0; - } - /** - * Astro.cookies.set(key, value) is used to set a cookie's value. If provided - * an object it will be stringified via JSON.stringify(value). Additionally you - * can provide options customizing how this cookie will be set, such as setting httpOnly - * in order to prevent the cookie from being read in client-side JavaScript. - * @param key The name of the cookie to set. - * @param value A value, either a string or other primitive or an object. - * @param options Options for the cookie, such as the path and security settings. - */ - set(key, value, options) { - if (this.#consumed) { - const warning = new Error( - "Astro.cookies.set() was called after the cookies had already been sent to the browser.\nThis may have happened if this method was called in an imported component.\nPlease make sure that Astro.cookies.set() is only called in the frontmatter of the main page." - ); - warning.name = "Warning"; - console.warn(warning); - } - let serializedValue; - if (typeof value === "string") { - serializedValue = value; - } else { - let toStringValue = value.toString(); - if (toStringValue === Object.prototype.toString.call(value)) { - serializedValue = JSON.stringify(value); - } else { - serializedValue = toStringValue; - } - } - const serializeOptions = {}; - if (options) { - Object.assign(serializeOptions, options); - } - this.#ensureOutgoingMap().set(key, [ - serializedValue, - serialize(key, serializedValue, serializeOptions), - true - ]); - if (this.#request[responseSentSymbol]) { - throw new AstroError({ - ...ResponseSentError - }); - } - } - /** - * Merges a new AstroCookies instance into the current instance. Any new cookies - * will be added to the current instance, overwriting any existing cookies with the same name. - */ - merge(cookies) { - const outgoing = cookies.#outgoing; - if (outgoing) { - for (const [key, value] of outgoing) { - this.#ensureOutgoingMap().set(key, value); - } - } - } - /** - * Astro.cookies.header() returns an iterator for the cookies that have previously - * been set by either Astro.cookies.set() or Astro.cookies.delete(). - * This method is primarily used by adapters to set the header on outgoing responses. - * @returns - */ - *headers() { - if (this.#outgoing == null) return; - for (const [, value] of this.#outgoing) { - yield value[1]; - } - } - /** - * Behaves the same as AstroCookies.prototype.headers(), - * but allows a warning when cookies are set after the instance is consumed. - */ - static consume(cookies) { - cookies.#consumed = true; - return cookies.headers(); - } - #ensureParsed() { - if (!this.#requestValues) { - this.#parse(); - } - if (!this.#requestValues) { - this.#requestValues = {}; - } - return this.#requestValues; - } - #ensureOutgoingMap() { - if (!this.#outgoing) { - this.#outgoing = /* @__PURE__ */ new Map(); - } - return this.#outgoing; - } - #parse() { - const raw = this.#request.headers.get("cookie"); - if (!raw) { - return; - } - this.#requestValues = parse(raw, { decode: identity }); - } -} - -const astroCookiesSymbol = Symbol.for("astro.cookies"); -function attachCookiesToResponse(response, cookies) { - Reflect.set(response, astroCookiesSymbol, cookies); -} -function getCookiesFromResponse(response) { - let cookies = Reflect.get(response, astroCookiesSymbol); - if (cookies != null) { - return cookies; - } else { - return void 0; - } -} -function* getSetCookiesFromResponse(response) { - const cookies = getCookiesFromResponse(response); - if (!cookies) { - return []; - } - for (const headerValue of AstroCookies.consume(cookies)) { - yield headerValue; - } - return []; -} - -const dateTimeFormat = new Intl.DateTimeFormat([], { - hour: "2-digit", - minute: "2-digit", - second: "2-digit", - hour12: false -}); -const levels = { - debug: 20, - info: 30, - warn: 40, - error: 50, - silent: 90 -}; -function log(opts, level, label, message, newLine = true) { - const logLevel = opts.level; - const dest = opts.dest; - const event = { - label, - level, - message, - newLine - }; - if (!isLogLevelEnabled(logLevel, level)) { - return; - } - dest.write(event); -} -function isLogLevelEnabled(configuredLogLevel, level) { - return levels[configuredLogLevel] <= levels[level]; -} -function info(opts, label, message, newLine = true) { - return log(opts, "info", label, message, newLine); -} -function warn(opts, label, message, newLine = true) { - return log(opts, "warn", label, message, newLine); -} -function error(opts, label, message, newLine = true) { - return log(opts, "error", label, message, newLine); -} -function debug(...args) { - if ("_astroGlobalDebug" in globalThis) { - globalThis._astroGlobalDebug(...args); - } -} -function getEventPrefix({ level, label }) { - const timestamp = `${dateTimeFormat.format(/* @__PURE__ */ new Date())}`; - const prefix = []; - if (level === "error" || level === "warn") { - prefix.push(colors.bold(timestamp)); - prefix.push(`[${level.toUpperCase()}]`); - } else { - prefix.push(timestamp); - } - if (label) { - prefix.push(`[${label}]`); - } - if (level === "error") { - return colors.red(prefix.join(" ")); - } - if (level === "warn") { - return colors.yellow(prefix.join(" ")); - } - if (prefix.length === 1) { - return colors.dim(prefix[0]); - } - return colors.dim(prefix[0]) + " " + colors.blue(prefix.splice(1).join(" ")); -} -class Logger { - options; - constructor(options) { - this.options = options; - } - info(label, message, newLine = true) { - info(this.options, label, message, newLine); - } - warn(label, message, newLine = true) { - warn(this.options, label, message, newLine); - } - error(label, message, newLine = true) { - error(this.options, label, message, newLine); - } - debug(label, ...messages) { - debug(label, ...messages); - } - level() { - return this.options.level; - } - forkIntegrationLogger(label) { - return new AstroIntegrationLogger(this.options, label); - } -} -class AstroIntegrationLogger { - options; - label; - constructor(logging, label) { - this.options = logging; - this.label = label; - } - /** - * Creates a new logger instance with a new label, but the same log options. - */ - fork(label) { - return new AstroIntegrationLogger(this.options, label); - } - info(message) { - info(this.options, this.label, message); - } - warn(message) { - warn(this.options, this.label, message); - } - error(message) { - error(this.options, this.label, message); - } - debug(message) { - debug(this.label, message); - } -} - -const consoleLogDestination = { - write(event) { - let dest = console.error; - if (levels[event.level] < levels["error"]) { - dest = console.info; - } - if (event.label === "SKIP_FORMAT") { - dest(event.message); - } else { - dest(getEventPrefix(event) + " " + event.message); - } - return true; - } -}; - -function getAssetsPrefix(fileExtension, assetsPrefix) { - let prefix = ""; - if (!assetsPrefix) { - prefix = ""; - } else if (typeof assetsPrefix === "string") { - prefix = assetsPrefix; - } else { - const dotLessFileExtension = fileExtension.slice(1); - prefix = assetsPrefix[dotLessFileExtension] || assetsPrefix.fallback; - } - return prefix; -} - -function createAssetLink(href, base, assetsPrefix, queryParams) { - let url = ""; - if (assetsPrefix) { - const pf = getAssetsPrefix(fileExtension(href), assetsPrefix); - url = joinPaths(pf, slash(href)); - } else if (base) { - url = prependForwardSlash$1(joinPaths(base, slash(href))); - } else { - url = href; - } - return url; -} -function createStylesheetElement(stylesheet, base, assetsPrefix, queryParams) { - if (stylesheet.type === "inline") { - return { - props: {}, - children: stylesheet.content - }; - } else { - return { - props: { - rel: "stylesheet", - href: createAssetLink(stylesheet.src, base, assetsPrefix) - }, - children: "" - }; - } -} -function createStylesheetElementSet(stylesheets, base, assetsPrefix, queryParams) { - return new Set( - stylesheets.map((s) => createStylesheetElement(s, base, assetsPrefix)) - ); -} -function createModuleScriptElement(script, base, assetsPrefix, queryParams) { - if (script.type === "external") { - return createModuleScriptElementWithSrc(script.value, base, assetsPrefix); - } else { - return { - props: { - type: "module" - }, - children: script.value - }; - } -} -function createModuleScriptElementWithSrc(src, base, assetsPrefix, queryParams) { - return { - props: { - type: "module", - src: createAssetLink(src, base, assetsPrefix) - }, - children: "" - }; -} - -const ACTION_API_CONTEXT_SYMBOL = Symbol.for("astro.actionAPIContext"); -const formContentTypes = ["application/x-www-form-urlencoded", "multipart/form-data"]; -function hasContentType(contentType, expected) { - const type = contentType.split(";")[0].toLowerCase(); - return expected.some((t) => type === t); -} - -function getActionContext(context) { - const callerInfo = getCallerInfo(context); - const actionResultAlreadySet = Boolean(context.locals._actionPayload); - let action = void 0; - if (callerInfo && context.request.method === "POST" && !actionResultAlreadySet) { - action = { - calledFrom: callerInfo.from, - name: callerInfo.name, - handler: async () => { - const pipeline = Reflect.get(context, apiContextRoutesSymbol); - const callerInfoName = shouldAppendForwardSlash( - pipeline.manifest.trailingSlash, - pipeline.manifest.buildFormat - ) ? removeTrailingForwardSlash(callerInfo.name) : callerInfo.name; - let baseAction; - try { - baseAction = await pipeline.getAction(callerInfoName); - } catch (error) { - if (error instanceof Error && "name" in error && typeof error.name === "string" && error.name === ActionNotFoundError.name) { - return { data: void 0, error: new ActionError({ code: "NOT_FOUND" }) }; - } - throw error; - } - let input; - try { - input = await parseRequestBody(context.request); - } catch (e) { - if (e instanceof TypeError) { - return { data: void 0, error: new ActionError({ code: "UNSUPPORTED_MEDIA_TYPE" }) }; - } - throw e; - } - const omitKeys = ["props", "getActionResult", "callAction", "redirect"]; - const actionAPIContext = Object.create( - Object.getPrototypeOf(context), - Object.fromEntries( - Object.entries(Object.getOwnPropertyDescriptors(context)).filter( - ([key]) => !omitKeys.includes(key) - ) - ) - ); - Reflect.set(actionAPIContext, ACTION_API_CONTEXT_SYMBOL, true); - const handler = baseAction.bind(actionAPIContext); - return handler(input); - } - }; - } - function setActionResult(actionName, actionResult) { - context.locals._actionPayload = { - actionResult, - actionName - }; - } - return { - action, - setActionResult, - serializeActionResult, - deserializeActionResult - }; -} -function getCallerInfo(ctx) { - if (ctx.routePattern === ACTION_RPC_ROUTE_PATTERN) { - return { from: "rpc", name: ctx.url.pathname.replace(/^.*\/_actions\//, "") }; - } - const queryParam = ctx.url.searchParams.get(ACTION_QUERY_PARAMS.actionName); - if (queryParam) { - return { from: "form", name: queryParam }; - } - return void 0; -} -async function parseRequestBody(request) { - const contentType = request.headers.get("content-type"); - const contentLength = request.headers.get("Content-Length"); - if (!contentType) return void 0; - if (hasContentType(contentType, formContentTypes)) { - return await request.clone().formData(); - } - if (hasContentType(contentType, ["application/json"])) { - return contentLength === "0" ? void 0 : await request.clone().json(); - } - throw new TypeError("Unsupported content type"); -} - -function hasActionPayload(locals) { - return "_actionPayload" in locals; -} -function createGetActionResult(locals) { - return (actionFn) => { - if (!hasActionPayload(locals) || actionFn.toString() !== getActionQueryString(locals._actionPayload.actionName)) { - return void 0; - } - return deserializeActionResult(locals._actionPayload.actionResult); - }; -} -function createCallAction(context) { - return (baseAction, input) => { - Reflect.set(context, ACTION_API_CONTEXT_SYMBOL, true); - const action = baseAction.bind(context); - return action(input); - }; -} - -function parseLocale(header) { - if (header === "*") { - return [{ locale: header, qualityValue: void 0 }]; - } - const result = []; - const localeValues = header.split(",").map((str) => str.trim()); - for (const localeValue of localeValues) { - const split = localeValue.split(";").map((str) => str.trim()); - const localeName = split[0]; - const qualityValue = split[1]; - if (!split) { - continue; - } - if (qualityValue && qualityValue.startsWith("q=")) { - const qualityValueAsFloat = Number.parseFloat(qualityValue.slice("q=".length)); - if (Number.isNaN(qualityValueAsFloat) || qualityValueAsFloat > 1) { - result.push({ - locale: localeName, - qualityValue: void 0 - }); - } else { - result.push({ - locale: localeName, - qualityValue: qualityValueAsFloat - }); - } - } else { - result.push({ - locale: localeName, - qualityValue: void 0 - }); - } - } - return result; -} -function sortAndFilterLocales(browserLocaleList, locales) { - const normalizedLocales = getAllCodes(locales).map(normalizeTheLocale); - return browserLocaleList.filter((browserLocale) => { - if (browserLocale.locale !== "*") { - return normalizedLocales.includes(normalizeTheLocale(browserLocale.locale)); - } - return true; - }).sort((a, b) => { - if (a.qualityValue && b.qualityValue) { - return Math.sign(b.qualityValue - a.qualityValue); - } - return 0; - }); -} -function computePreferredLocale(request, locales) { - const acceptHeader = request.headers.get("Accept-Language"); - let result = void 0; - if (acceptHeader) { - const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); - const firstResult = browserLocaleList.at(0); - if (firstResult && firstResult.locale !== "*") { - for (const currentLocale of locales) { - if (typeof currentLocale === "string") { - if (normalizeTheLocale(currentLocale) === normalizeTheLocale(firstResult.locale)) { - result = currentLocale; - break; - } - } else { - for (const currentCode of currentLocale.codes) { - if (normalizeTheLocale(currentCode) === normalizeTheLocale(firstResult.locale)) { - result = currentCode; - break; - } - } - } - } - } - } - return result; -} -function computePreferredLocaleList(request, locales) { - const acceptHeader = request.headers.get("Accept-Language"); - let result = []; - if (acceptHeader) { - const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales); - if (browserLocaleList.length === 1 && browserLocaleList.at(0).locale === "*") { - return getAllCodes(locales); - } else if (browserLocaleList.length > 0) { - for (const browserLocale of browserLocaleList) { - for (const loopLocale of locales) { - if (typeof loopLocale === "string") { - if (normalizeTheLocale(loopLocale) === normalizeTheLocale(browserLocale.locale)) { - result.push(loopLocale); - } - } else { - for (const code of loopLocale.codes) { - if (code === browserLocale.locale) { - result.push(code); - } - } - } - } - } - } - } - return result; -} -function computeCurrentLocale(pathname, locales, defaultLocale) { - for (const segment of pathname.split("/").map(normalizeThePath)) { - for (const locale of locales) { - if (typeof locale === "string") { - if (!segment.includes(locale)) continue; - if (normalizeTheLocale(locale) === normalizeTheLocale(segment)) { - return locale; - } - } else { - if (locale.path === segment) { - return locale.codes.at(0); - } else { - for (const code of locale.codes) { - if (normalizeTheLocale(code) === normalizeTheLocale(segment)) { - return code; - } - } - } - } - } - } - for (const locale of locales) { - if (typeof locale === "string") { - if (locale === defaultLocale) { - return locale; - } - } else { - if (locale.path === defaultLocale) { - return locale.codes.at(0); - } - } - } -} - -function deduplicateDirectiveValues(existingDirective, newDirective) { - const [directiveName, ...existingValues] = existingDirective.split(/\s+/).filter(Boolean); - const [newDirectiveName, ...newValues] = newDirective.split(/\s+/).filter(Boolean); - if (directiveName !== newDirectiveName) { - return void 0; - } - const finalDirectives = Array.from(/* @__PURE__ */ new Set([...existingValues, ...newValues])); - return `${directiveName} ${finalDirectives.join(" ")}`; -} -function pushDirective(directives, newDirective) { - let deduplicated = false; - if (directives.length === 0) { - return [newDirective]; - } - const finalDirectives = []; - for (const directive of directives) { - if (deduplicated) { - finalDirectives.push(directive); - continue; - } - const result = deduplicateDirectiveValues(directive, newDirective); - if (result) { - finalDirectives.push(result); - deduplicated = true; - } else { - finalDirectives.push(directive); - finalDirectives.push(newDirective); - } - } - return finalDirectives; -} - -async function callMiddleware(onRequest, apiContext, responseFunction) { - let nextCalled = false; - let responseFunctionPromise = void 0; - const next = async (payload) => { - nextCalled = true; - responseFunctionPromise = responseFunction(apiContext, payload); - return responseFunctionPromise; - }; - let middlewarePromise = onRequest(apiContext, next); - return await Promise.resolve(middlewarePromise).then(async (value) => { - if (nextCalled) { - if (typeof value !== "undefined") { - if (value instanceof Response === false) { - throw new AstroError(MiddlewareNotAResponse); - } - return value; - } else { - if (responseFunctionPromise) { - return responseFunctionPromise; - } else { - throw new AstroError(MiddlewareNotAResponse); - } - } - } else if (typeof value === "undefined") { - throw new AstroError(MiddlewareNoDataOrNextCalled); - } else if (value instanceof Response === false) { - throw new AstroError(MiddlewareNotAResponse); - } else { - return value; - } - }); -} - -function createRequest({ - url, - headers, - method = "GET", - body = void 0, - logger, - isPrerendered = false, - routePattern, - init -}) { - const headersObj = isPrerendered ? void 0 : headers instanceof Headers ? headers : new Headers( - // Filter out HTTP/2 pseudo-headers. These are internally-generated headers added to all HTTP/2 requests with trusted metadata about the request. - // Examples include `:method`, `:scheme`, `:authority`, and `:path`. - // They are always prefixed with a colon to distinguish them from other headers, and it is an error to add the to a Headers object manually. - // See https://httpwg.org/specs/rfc7540.html#HttpRequest - Object.entries(headers).filter(([name]) => !name.startsWith(":")) - ); - if (typeof url === "string") url = new URL(url); - if (isPrerendered) { - url.search = ""; - } - const request = new Request(url, { - method, - headers: headersObj, - // body is made available only if the request is for a page that will be on-demand rendered - body: isPrerendered ? null : body, - ...init - }); - if (isPrerendered) { - let _headers = request.headers; - const { value, writable, ...headersDesc } = Object.getOwnPropertyDescriptor(request, "headers") || {}; - Object.defineProperty(request, "headers", { - ...headersDesc, - get() { - logger.warn( - null, - `\`Astro.request.headers\` was used when rendering the route \`${routePattern}'\`. \`Astro.request.headers\` is not available on prerendered pages. If you need access to request headers, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default.` - ); - return _headers; - }, - set(newHeaders) { - _headers = newHeaders; - } - }); - } - return request; -} - -function findRouteToRewrite({ - payload, - routes, - request, - trailingSlash, - buildFormat, - base, - outDir -}) { - let newUrl = void 0; - if (payload instanceof URL) { - newUrl = payload; - } else if (payload instanceof Request) { - newUrl = new URL(payload.url); - } else { - newUrl = new URL(payload, new URL(request.url).origin); - } - let pathname = newUrl.pathname; - const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat); - if (base !== "/") { - const isBasePathRequest = newUrl.pathname === base || newUrl.pathname === removeTrailingForwardSlash(base); - if (isBasePathRequest) { - pathname = shouldAppendSlash ? "/" : ""; - } else if (newUrl.pathname.startsWith(base)) { - pathname = shouldAppendSlash ? appendForwardSlash$1(newUrl.pathname) : removeTrailingForwardSlash(newUrl.pathname); - pathname = pathname.slice(base.length); - } - } - if (!pathname.startsWith("/") && shouldAppendSlash && newUrl.pathname.endsWith("/")) { - pathname = prependForwardSlash$1(pathname); - } - if (pathname === "/" && base !== "/" && !shouldAppendSlash) { - pathname = ""; - } - if (buildFormat === "file") { - pathname = pathname.replace(/\.html$/, ""); - } - if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) { - newUrl.pathname = removeTrailingForwardSlash(base); - } else { - newUrl.pathname = joinPaths(...[base, pathname].filter(Boolean)); - } - const decodedPathname = decodeURI(pathname); - let foundRoute; - for (const route of routes) { - if (route.pattern.test(decodedPathname)) { - if (route.params && route.params.length !== 0 && route.distURL && route.distURL.length !== 0) { - if (!route.distURL.find( - (url) => url.href.replace(outDir.toString(), "").replace(/(?:\/index\.html|\.html)$/, "") == trimSlashes(decodedPathname) - )) { - continue; - } - } - foundRoute = route; - break; - } - } - if (foundRoute) { - return { - routeData: foundRoute, - newUrl, - pathname: decodedPathname - }; - } else { - const custom404 = routes.find((route) => route.route === "/404"); - if (custom404) { - return { routeData: custom404, newUrl, pathname }; - } else { - return { routeData: DEFAULT_404_ROUTE, newUrl, pathname }; - } - } -} -function copyRequest(newUrl, oldRequest, isPrerendered, logger, routePattern) { - if (oldRequest.bodyUsed) { - throw new AstroError(RewriteWithBodyUsed); - } - return createRequest({ - url: newUrl, - method: oldRequest.method, - body: oldRequest.body, - isPrerendered, - logger, - headers: isPrerendered ? {} : oldRequest.headers, - routePattern, - init: { - referrer: oldRequest.referrer, - referrerPolicy: oldRequest.referrerPolicy, - mode: oldRequest.mode, - credentials: oldRequest.credentials, - cache: oldRequest.cache, - redirect: oldRequest.redirect, - integrity: oldRequest.integrity, - signal: oldRequest.signal, - keepalive: oldRequest.keepalive, - // https://fetch.spec.whatwg.org/#dom-request-duplex - // @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request - duplex: "half" - } - }); -} -function setOriginPathname(request, pathname, trailingSlash, buildFormat) { - if (!pathname) { - pathname = "/"; - } - const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat); - let finalPathname; - if (pathname === "/") { - finalPathname = "/"; - } else if (shouldAppendSlash) { - finalPathname = appendForwardSlash$1(pathname); - } else { - finalPathname = removeTrailingForwardSlash(pathname); - } - Reflect.set(request, originPathnameSymbol, encodeURIComponent(finalPathname)); -} -function getOriginPathname(request) { - const origin = Reflect.get(request, originPathnameSymbol); - if (origin) { - return decodeURIComponent(origin); - } - return new URL(request.url).pathname; -} - -const NOOP_ACTIONS_MOD = { - server: {} -}; - -const FORM_CONTENT_TYPES = [ - "application/x-www-form-urlencoded", - "multipart/form-data", - "text/plain" -]; -const SAFE_METHODS = ["GET", "HEAD", "OPTIONS"]; -function createOriginCheckMiddleware() { - return defineMiddleware((context, next) => { - const { request, url, isPrerendered } = context; - if (isPrerendered) { - return next(); - } - if (SAFE_METHODS.includes(request.method)) { - return next(); - } - const isSameOrigin = request.headers.get("origin") === url.origin; - const hasContentType = request.headers.has("content-type"); - if (hasContentType) { - const formLikeHeader = hasFormLikeHeader(request.headers.get("content-type")); - if (formLikeHeader && !isSameOrigin) { - return new Response(`Cross-site ${request.method} form submissions are forbidden`, { - status: 403 - }); - } - } else { - if (!isSameOrigin) { - return new Response(`Cross-site ${request.method} form submissions are forbidden`, { - status: 403 - }); - } - } - return next(); - }); -} -function hasFormLikeHeader(contentType) { - if (contentType) { - for (const FORM_CONTENT_TYPE of FORM_CONTENT_TYPES) { - if (contentType.toLowerCase().includes(FORM_CONTENT_TYPE)) { - return true; - } - } - } - return false; -} - -const VALID_PARAM_TYPES = ["string", "number", "undefined"]; -function validateGetStaticPathsParameter([key, value], route) { - if (!VALID_PARAM_TYPES.includes(typeof value)) { - throw new AstroError({ - ...GetStaticPathsInvalidRouteParam, - message: GetStaticPathsInvalidRouteParam.message(key, value, typeof value), - location: { - file: route - } - }); - } -} -function validateDynamicRouteModule(mod, { - ssr, - route -}) { - if ((!ssr || route.prerender) && !mod.getStaticPaths) { - throw new AstroError({ - ...GetStaticPathsRequired, - location: { file: route.component } - }); - } -} -function validateGetStaticPathsResult(result, logger, route) { - if (!Array.isArray(result)) { - throw new AstroError({ - ...InvalidGetStaticPathsReturn, - message: InvalidGetStaticPathsReturn.message(typeof result), - location: { - file: route.component - } - }); - } - result.forEach((pathObject) => { - if (typeof pathObject === "object" && Array.isArray(pathObject) || pathObject === null) { - throw new AstroError({ - ...InvalidGetStaticPathsEntry, - message: InvalidGetStaticPathsEntry.message( - Array.isArray(pathObject) ? "array" : typeof pathObject - ) - }); - } - if (pathObject.params === void 0 || pathObject.params === null || pathObject.params && Object.keys(pathObject.params).length === 0) { - throw new AstroError({ - ...GetStaticPathsExpectedParams, - location: { - file: route.component - } - }); - } - for (const [key, val] of Object.entries(pathObject.params)) { - if (!(typeof val === "undefined" || typeof val === "string" || typeof val === "number")) { - logger.warn( - "router", - `getStaticPaths() returned an invalid path param: "${key}". A string, number or undefined value was expected, but got \`${JSON.stringify( - val - )}\`.` - ); - } - if (typeof val === "string" && val === "") { - logger.warn( - "router", - `getStaticPaths() returned an invalid path param: "${key}". \`undefined\` expected for an optional param, but got empty string.` - ); - } - } - }); -} - -function stringifyParams(params, route) { - const validatedParams = Object.entries(params).reduce((acc, next) => { - validateGetStaticPathsParameter(next, route.component); - const [key, value] = next; - if (value !== void 0) { - acc[key] = typeof value === "string" ? trimSlashes(value) : value.toString(); - } - return acc; - }, {}); - return route.generate(validatedParams); -} - -function generatePaginateFunction(routeMatch, base) { - return function paginateUtility(data, args = {}) { - let { pageSize: _pageSize, params: _params, props: _props } = args; - const pageSize = _pageSize || 10; - const paramName = "page"; - const additionalParams = _params || {}; - const additionalProps = _props || {}; - let includesFirstPageNumber; - if (routeMatch.params.includes(`...${paramName}`)) { - includesFirstPageNumber = false; - } else if (routeMatch.params.includes(`${paramName}`)) { - includesFirstPageNumber = true; - } else { - throw new AstroError({ - ...PageNumberParamNotFound, - message: PageNumberParamNotFound.message(paramName) - }); - } - const lastPage = Math.max(1, Math.ceil(data.length / pageSize)); - const result = [...Array(lastPage).keys()].map((num) => { - const pageNum = num + 1; - const start = pageSize === Infinity ? 0 : (pageNum - 1) * pageSize; - const end = Math.min(start + pageSize, data.length); - const params = { - ...additionalParams, - [paramName]: includesFirstPageNumber || pageNum > 1 ? String(pageNum) : void 0 - }; - const current = addRouteBase(routeMatch.generate({ ...params }), base); - const next = pageNum === lastPage ? void 0 : addRouteBase(routeMatch.generate({ ...params, page: String(pageNum + 1) }), base); - const prev = pageNum === 1 ? void 0 : addRouteBase( - routeMatch.generate({ - ...params, - page: !includesFirstPageNumber && pageNum - 1 === 1 ? void 0 : String(pageNum - 1) - }), - base - ); - const first = pageNum === 1 ? void 0 : addRouteBase( - routeMatch.generate({ - ...params, - page: includesFirstPageNumber ? "1" : void 0 - }), - base - ); - const last = pageNum === lastPage ? void 0 : addRouteBase(routeMatch.generate({ ...params, page: String(lastPage) }), base); - return { - params, - props: { - ...additionalProps, - page: { - data: data.slice(start, end), - start, - end: end - 1, - size: pageSize, - total: data.length, - currentPage: pageNum, - lastPage, - url: { current, next, prev, first, last } - } - } - }; - }); - return result; - }; -} -function addRouteBase(route, base) { - let routeWithBase = joinPaths(base, route); - if (routeWithBase === "") routeWithBase = "/"; - return routeWithBase; -} - -async function callGetStaticPaths({ - mod, - route, - routeCache, - logger, - ssr, - base -}) { - const cached = routeCache.get(route); - if (!mod) { - throw new Error("This is an error caused by Astro and not your code. Please file an issue."); - } - if (cached?.staticPaths) { - return cached.staticPaths; - } - validateDynamicRouteModule(mod, { ssr, route }); - if (ssr && !route.prerender) { - const entry = Object.assign([], { keyed: /* @__PURE__ */ new Map() }); - routeCache.set(route, { ...cached, staticPaths: entry }); - return entry; - } - let staticPaths = []; - if (!mod.getStaticPaths) { - throw new Error("Unexpected Error."); - } - staticPaths = await mod.getStaticPaths({ - // Q: Why the cast? - // A: So users downstream can have nicer typings, we have to make some sacrifice in our internal typings, which necessitate a cast here - paginate: generatePaginateFunction(route, base), - routePattern: route.route - }); - validateGetStaticPathsResult(staticPaths, logger, route); - const keyedStaticPaths = staticPaths; - keyedStaticPaths.keyed = /* @__PURE__ */ new Map(); - for (const sp of keyedStaticPaths) { - const paramsKey = stringifyParams(sp.params, route); - keyedStaticPaths.keyed.set(paramsKey, sp); - } - routeCache.set(route, { ...cached, staticPaths: keyedStaticPaths }); - return keyedStaticPaths; -} -class RouteCache { - logger; - cache = {}; - runtimeMode; - constructor(logger, runtimeMode = "production") { - this.logger = logger; - this.runtimeMode = runtimeMode; - } - /** Clear the cache. */ - clearAll() { - this.cache = {}; - } - set(route, entry) { - const key = this.key(route); - if (this.runtimeMode === "production" && this.cache[key]?.staticPaths) { - this.logger.warn(null, `Internal Warning: route cache overwritten. (${key})`); - } - this.cache[key] = entry; - } - get(route) { - return this.cache[this.key(route)]; - } - key(route) { - return `${route.route}_${route.component}`; - } -} -function findPathItemByKey(staticPaths, params, route, logger) { - const paramsKey = stringifyParams(params, route); - const matchedStaticPath = staticPaths.keyed.get(paramsKey); - if (matchedStaticPath) { - return matchedStaticPath; - } - logger.debug("router", `findPathItemByKey() - Unexpected cache miss looking for ${paramsKey}`); -} - -function createDefaultRoutes(manifest) { - const root = new URL(manifest.hrefRoot); - return [ - { - instance: default404Instance, - matchesComponent: (filePath) => filePath.href === new URL(DEFAULT_404_COMPONENT, root).href, - route: DEFAULT_404_ROUTE.route, - component: DEFAULT_404_COMPONENT - }, - { - instance: createEndpoint(manifest), - matchesComponent: (filePath) => filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href, - route: SERVER_ISLAND_ROUTE, - component: SERVER_ISLAND_COMPONENT - } - ]; -} - -class Pipeline { - constructor(logger, manifest, runtimeMode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, runtimeMode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest), actions = manifest.actions) { - this.logger = logger; - this.manifest = manifest; - this.runtimeMode = runtimeMode; - this.renderers = renderers; - this.resolve = resolve; - this.serverLike = serverLike; - this.streaming = streaming; - this.adapterName = adapterName; - this.clientDirectives = clientDirectives; - this.inlinedScripts = inlinedScripts; - this.compressHTML = compressHTML; - this.i18n = i18n; - this.middleware = middleware; - this.routeCache = routeCache; - this.site = site; - this.defaultRoutes = defaultRoutes; - this.actions = actions; - this.internalMiddleware = []; - if (i18n?.strategy !== "manual") { - this.internalMiddleware.push( - createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat) - ); - } - } - internalMiddleware; - resolvedMiddleware = void 0; - resolvedActions = void 0; - /** - * Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there, - * it returns a no-op function - */ - async getMiddleware() { - if (this.resolvedMiddleware) { - return this.resolvedMiddleware; - } else if (this.middleware) { - const middlewareInstance = await this.middleware(); - const onRequest = middlewareInstance.onRequest ?? NOOP_MIDDLEWARE_FN; - const internalMiddlewares = [onRequest]; - if (this.manifest.checkOrigin) { - internalMiddlewares.unshift(createOriginCheckMiddleware()); - } - this.resolvedMiddleware = sequence(...internalMiddlewares); - return this.resolvedMiddleware; - } else { - this.resolvedMiddleware = NOOP_MIDDLEWARE_FN; - return this.resolvedMiddleware; - } - } - setActions(actions) { - this.resolvedActions = actions; - } - async getActions() { - if (this.resolvedActions) { - return this.resolvedActions; - } else if (this.actions) { - return await this.actions(); - } - return NOOP_ACTIONS_MOD; - } - async getAction(path) { - const pathKeys = path.split(".").map((key) => decodeURIComponent(key)); - let { server } = await this.getActions(); - if (!server || !(typeof server === "object")) { - throw new TypeError( - `Expected \`server\` export in actions file to be an object. Received ${typeof server}.` - ); - } - for (const key of pathKeys) { - if (!(key in server)) { - throw new AstroError({ - ...ActionNotFoundError, - message: ActionNotFoundError.message(pathKeys.join(".")) - }); - } - server = server[key]; - } - if (typeof server !== "function") { - throw new TypeError( - `Expected handler for action ${pathKeys.join(".")} to be a function. Received ${typeof server}.` - ); - } - return server; - } -} - -function routeIsRedirect(route) { - return route?.type === "redirect"; -} -function routeIsFallback(route) { - return route?.type === "fallback"; -} - -const RedirectComponentInstance = { - default() { - return new Response(null, { - status: 301 - }); - } -}; -const RedirectSinglePageBuiltModule = { - page: () => Promise.resolve(RedirectComponentInstance), - onRequest: (_, next) => next(), - renderers: [] -}; - -async function getProps(opts) { - const { logger, mod, routeData: route, routeCache, pathname, serverLike, base } = opts; - if (!route || route.pathname) { - return {}; - } - if (routeIsRedirect(route) || routeIsFallback(route) || route.component === DEFAULT_404_COMPONENT) { - return {}; - } - const staticPaths = await callGetStaticPaths({ - mod, - route, - routeCache, - logger, - ssr: serverLike, - base - }); - const params = getParams(route, pathname); - const matchedStaticPath = findPathItemByKey(staticPaths, params, route, logger); - if (!matchedStaticPath && (serverLike ? route.prerender : true)) { - throw new AstroError({ - ...NoMatchingStaticPathFound, - message: NoMatchingStaticPathFound.message(pathname), - hint: NoMatchingStaticPathFound.hint([route.component]) - }); - } - if (mod) { - validatePrerenderEndpointCollision(route, mod, params); - } - const props = matchedStaticPath?.props ? { ...matchedStaticPath.props } : {}; - return props; -} -function getParams(route, pathname) { - if (!route.params.length) return {}; - const paramsMatch = route.pattern.exec(pathname) || route.fallbackRoutes.map((fallbackRoute) => fallbackRoute.pattern.exec(pathname)).find((x) => x); - if (!paramsMatch) return {}; - const params = {}; - route.params.forEach((key, i) => { - if (key.startsWith("...")) { - params[key.slice(3)] = paramsMatch[i + 1] ? paramsMatch[i + 1] : void 0; - } else { - params[key] = paramsMatch[i + 1]; - } - }); - return params; -} -function validatePrerenderEndpointCollision(route, mod, params) { - if (route.type === "endpoint" && mod.getStaticPaths) { - const lastSegment = route.segments[route.segments.length - 1]; - const paramValues = Object.values(params); - const lastParam = paramValues[paramValues.length - 1]; - if (lastSegment.length === 1 && lastSegment[0].dynamic && lastParam === void 0) { - throw new AstroError({ - ...PrerenderDynamicEndpointPathCollide, - message: PrerenderDynamicEndpointPathCollide.message(route.route), - hint: PrerenderDynamicEndpointPathCollide.hint(route.component), - location: { - file: route.component - } - }); - } - } -} - -function getFunctionExpression(slot) { - if (!slot) return; - const expressions = slot?.expressions?.filter((e) => isRenderInstruction(e) === false); - if (expressions?.length !== 1) return; - return expressions[0]; -} -class Slots { - #result; - #slots; - #logger; - constructor(result, slots, logger) { - this.#result = result; - this.#slots = slots; - this.#logger = logger; - if (slots) { - for (const key of Object.keys(slots)) { - if (this[key] !== void 0) { - throw new AstroError({ - ...ReservedSlotName, - message: ReservedSlotName.message(key) - }); - } - Object.defineProperty(this, key, { - get() { - return true; - }, - enumerable: true - }); - } - } - } - has(name) { - if (!this.#slots) return false; - return Boolean(this.#slots[name]); - } - async render(name, args = []) { - if (!this.#slots || !this.has(name)) return; - const result = this.#result; - if (!Array.isArray(args)) { - this.#logger.warn( - null, - `Expected second parameter to be an array, received a ${typeof args}. If you're trying to pass an array as a single argument and getting unexpected results, make sure you're passing your array as a item of an array. Ex: Astro.slots.render('default', [["Hello", "World"]])` - ); - } else if (args.length > 0) { - const slotValue = this.#slots[name]; - const component = typeof slotValue === "function" ? await slotValue(result) : await slotValue; - const expression = getFunctionExpression(component); - if (expression) { - const slot = async () => typeof expression === "function" ? expression(...args) : expression; - return await renderSlotToString(result, slot).then((res) => { - return res; - }); - } - if (typeof component === "function") { - return await renderJSX(result, component(...args)).then( - (res) => res != null ? String(res) : res - ); - } - } - const content = await renderSlotToString(result, this.#slots[name]); - const outHTML = chunkToString(result, content); - return outHTML; - } -} - -function sequence(...handlers) { - const filtered = handlers.filter((h) => !!h); - const length = filtered.length; - if (!length) { - return defineMiddleware((_context, next) => { - return next(); - }); - } - return defineMiddleware((context, next) => { - let carriedPayload = void 0; - return applyHandle(0, context); - function applyHandle(i, handleContext) { - const handle = filtered[i]; - const result = handle(handleContext, async (payload) => { - if (i < length - 1) { - if (payload) { - let newRequest; - if (payload instanceof Request) { - newRequest = payload; - } else if (payload instanceof URL) { - newRequest = new Request(payload, handleContext.request.clone()); - } else { - newRequest = new Request( - new URL(payload, handleContext.url.origin), - handleContext.request.clone() - ); - } - const oldPathname = handleContext.url.pathname; - const pipeline = Reflect.get(handleContext, apiContextRoutesSymbol); - const { routeData, pathname } = await pipeline.tryRewrite( - payload, - handleContext.request - ); - if (pipeline.serverLike === true && handleContext.isPrerendered === false && routeData.prerender === true) { - throw new AstroError({ - ...ForbiddenRewrite, - message: ForbiddenRewrite.message( - handleContext.url.pathname, - pathname, - routeData.component - ), - hint: ForbiddenRewrite.hint(routeData.component) - }); - } - carriedPayload = payload; - handleContext.request = newRequest; - handleContext.url = new URL(newRequest.url); - handleContext.params = getParams(routeData, pathname); - handleContext.routePattern = routeData.route; - setOriginPathname( - handleContext.request, - oldPathname, - pipeline.manifest.trailingSlash, - pipeline.manifest.buildFormat - ); - } - return applyHandle(i + 1, handleContext); - } else { - return next(payload ?? carriedPayload); - } - }); - return result; - } - }); -} - -function defineMiddleware(fn) { - return fn; -} - -const PERSIST_SYMBOL = Symbol(); -const DEFAULT_COOKIE_NAME = "astro-session"; -const VALID_COOKIE_REGEX = /^[\w-]+$/; -const unflatten = (parsed, _) => { - return unflatten$1(parsed, { - URL: (href) => new URL(href) - }); -}; -const stringify = (data, _) => { - return stringify$1(data, { - // Support URL objects - URL: (val) => val instanceof URL && val.href - }); -}; -class AstroSession { - // The cookies object. - #cookies; - // The session configuration. - #config; - // The cookie config - #cookieConfig; - // The cookie name - #cookieName; - // The unstorage object for the session driver. - #storage; - #data; - // The session ID. A v4 UUID. - #sessionID; - // Sessions to destroy. Needed because we won't have the old session ID after it's destroyed locally. - #toDestroy = /* @__PURE__ */ new Set(); - // Session keys to delete. Used for partial data sets to avoid overwriting the deleted value. - #toDelete = /* @__PURE__ */ new Set(); - // Whether the session is dirty and needs to be saved. - #dirty = false; - // Whether the session cookie has been set. - #cookieSet = false; - // The local data is "partial" if it has not been loaded from storage yet and only - // contains values that have been set or deleted in-memory locally. - // We do this to avoid the need to block on loading data when it is only being set. - // When we load the data from storage, we need to merge it with the local partial data, - // preserving in-memory changes and deletions. - #partial = true; - static #sharedStorage = /* @__PURE__ */ new Map(); - constructor(cookies, { - cookie: cookieConfig = DEFAULT_COOKIE_NAME, - ...config - }, runtimeMode) { - const { driver } = config; - if (!driver) { - throw new AstroError({ - ...SessionStorageInitError, - message: SessionStorageInitError.message( - "No driver was defined in the session configuration and the adapter did not provide a default driver." - ) - }); - } - this.#cookies = cookies; - let cookieConfigObject; - if (typeof cookieConfig === "object") { - const { name = DEFAULT_COOKIE_NAME, ...rest } = cookieConfig; - this.#cookieName = name; - cookieConfigObject = rest; - } else { - this.#cookieName = cookieConfig || DEFAULT_COOKIE_NAME; - } - this.#cookieConfig = { - sameSite: "lax", - secure: runtimeMode === "production", - path: "/", - ...cookieConfigObject, - httpOnly: true - }; - this.#config = { ...config, driver }; - } - /** - * Gets a session value. Returns `undefined` if the session or value does not exist. - */ - async get(key) { - return (await this.#ensureData()).get(key)?.data; - } - /** - * Checks if a session value exists. - */ - async has(key) { - return (await this.#ensureData()).has(key); - } - /** - * Gets all session values. - */ - async keys() { - return (await this.#ensureData()).keys(); - } - /** - * Gets all session values. - */ - async values() { - return [...(await this.#ensureData()).values()].map((entry) => entry.data); - } - /** - * Gets all session entries. - */ - async entries() { - return [...(await this.#ensureData()).entries()].map(([key, entry]) => [key, entry.data]); - } - /** - * Deletes a session value. - */ - delete(key) { - this.#data?.delete(key); - if (this.#partial) { - this.#toDelete.add(key); - } - this.#dirty = true; - } - /** - * Sets a session value. The session is created if it does not exist. - */ - set(key, value, { ttl } = {}) { - if (!key) { - throw new AstroError({ - ...SessionStorageSaveError, - message: "The session key was not provided." - }); - } - let cloned; - try { - cloned = unflatten(JSON.parse(stringify(value))); - } catch (err) { - throw new AstroError( - { - ...SessionStorageSaveError, - message: `The session data for ${key} could not be serialized.`, - hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue" - }, - { cause: err } - ); - } - if (!this.#cookieSet) { - this.#setCookie(); - this.#cookieSet = true; - } - this.#data ??= /* @__PURE__ */ new Map(); - const lifetime = ttl ?? this.#config.ttl; - const expires = typeof lifetime === "number" ? Date.now() + lifetime * 1e3 : lifetime; - this.#data.set(key, { - data: cloned, - expires - }); - this.#dirty = true; - } - /** - * Destroys the session, clearing the cookie and storage if it exists. - */ - destroy() { - const sessionId = this.#sessionID ?? this.#cookies.get(this.#cookieName)?.value; - if (sessionId) { - this.#toDestroy.add(sessionId); - } - this.#cookies.delete(this.#cookieName, this.#cookieConfig); - this.#sessionID = void 0; - this.#data = void 0; - this.#dirty = true; - } - /** - * Regenerates the session, creating a new session ID. The existing session data is preserved. - */ - async regenerate() { - let data = /* @__PURE__ */ new Map(); - try { - data = await this.#ensureData(); - } catch (err) { - console.error("Failed to load session data during regeneration:", err); - } - const oldSessionId = this.#sessionID; - this.#sessionID = crypto.randomUUID(); - this.#data = data; - await this.#setCookie(); - if (oldSessionId && this.#storage) { - this.#storage.removeItem(oldSessionId).catch((err) => { - console.error("Failed to remove old session data:", err); - }); - } - } - // Persists the session data to storage. - // This is called automatically at the end of the request. - // Uses a symbol to prevent users from calling it directly. - async [PERSIST_SYMBOL]() { - if (!this.#dirty && !this.#toDestroy.size) { - return; - } - const storage = await this.#ensureStorage(); - if (this.#dirty && this.#data) { - const data = await this.#ensureData(); - this.#toDelete.forEach((key2) => data.delete(key2)); - const key = this.#ensureSessionID(); - let serialized; - try { - serialized = stringify(data); - } catch (err) { - throw new AstroError( - { - ...SessionStorageSaveError, - message: SessionStorageSaveError.message( - "The session data could not be serialized.", - this.#config.driver - ) - }, - { cause: err } - ); - } - await storage.setItem(key, serialized); - this.#dirty = false; - } - if (this.#toDestroy.size > 0) { - const cleanupPromises = [...this.#toDestroy].map( - (sessionId) => storage.removeItem(sessionId).catch((err) => { - console.error(`Failed to clean up session ${sessionId}:`, err); - }) - ); - await Promise.all(cleanupPromises); - this.#toDestroy.clear(); - } - } - get sessionID() { - return this.#sessionID; - } - /** - * Loads a session from storage with the given ID, and replaces the current session. - * Any changes made to the current session will be lost. - * This is not normally needed, as the session is automatically loaded using the cookie. - * However it can be used to restore a session where the ID has been recorded somewhere - * else (e.g. in a database). - */ - async load(sessionID) { - this.#sessionID = sessionID; - this.#data = void 0; - await this.#setCookie(); - await this.#ensureData(); - } - /** - * Sets the session cookie. - */ - async #setCookie() { - if (!VALID_COOKIE_REGEX.test(this.#cookieName)) { - throw new AstroError({ - ...SessionStorageSaveError, - message: "Invalid cookie name. Cookie names can only contain letters, numbers, and dashes." - }); - } - const value = this.#ensureSessionID(); - this.#cookies.set(this.#cookieName, value, this.#cookieConfig); - } - /** - * Attempts to load the session data from storage, or creates a new data object if none exists. - * If there is existing partial data, it will be merged into the new data object. - */ - async #ensureData() { - const storage = await this.#ensureStorage(); - if (this.#data && !this.#partial) { - return this.#data; - } - this.#data ??= /* @__PURE__ */ new Map(); - const raw = await storage.get(this.#ensureSessionID()); - if (!raw) { - return this.#data; - } - try { - const storedMap = unflatten(raw); - if (!(storedMap instanceof Map)) { - await this.destroy(); - throw new AstroError({ - ...SessionStorageInitError, - message: SessionStorageInitError.message( - "The session data was an invalid type.", - this.#config.driver - ) - }); - } - const now = Date.now(); - for (const [key, value] of storedMap) { - const expired = typeof value.expires === "number" && value.expires < now; - if (!this.#data.has(key) && !this.#toDelete.has(key) && !expired) { - this.#data.set(key, value); - } - } - this.#partial = false; - return this.#data; - } catch (err) { - await this.destroy(); - if (err instanceof AstroError) { - throw err; - } - throw new AstroError( - { - ...SessionStorageInitError, - message: SessionStorageInitError.message( - "The session data could not be parsed.", - this.#config.driver - ) - }, - { cause: err } - ); - } - } - /** - * Returns the session ID, generating a new one if it does not exist. - */ - #ensureSessionID() { - this.#sessionID ??= this.#cookies.get(this.#cookieName)?.value ?? crypto.randomUUID(); - return this.#sessionID; - } - /** - * Ensures the storage is initialized. - * This is called automatically when a storage operation is needed. - */ - async #ensureStorage() { - if (this.#storage) { - return this.#storage; - } - if (AstroSession.#sharedStorage.has(this.#config.driver)) { - this.#storage = AstroSession.#sharedStorage.get(this.#config.driver); - return this.#storage; - } - if (this.#config.driver === "test") { - this.#storage = this.#config.options.mockStorage; - return this.#storage; - } - if (this.#config.driver === "fs" || this.#config.driver === "fsLite" || this.#config.driver === "fs-lite") { - this.#config.options ??= {}; - this.#config.driver = "fs-lite"; - this.#config.options.base ??= ".astro/session"; - } - let driver = null; - try { - if (this.#config.driverModule) { - driver = (await this.#config.driverModule()).default; - } else if (this.#config.driver) { - const driverName = resolveSessionDriverName(this.#config.driver); - if (driverName) { - driver = (await import(driverName)).default; - } - } - } catch (err) { - if (err.code === "ERR_MODULE_NOT_FOUND") { - throw new AstroError( - { - ...SessionStorageInitError, - message: SessionStorageInitError.message( - err.message.includes(`Cannot find package`) ? "The driver module could not be found." : err.message, - this.#config.driver - ) - }, - { cause: err } - ); - } - throw err; - } - if (!driver) { - throw new AstroError({ - ...SessionStorageInitError, - message: SessionStorageInitError.message( - "The module did not export a driver.", - this.#config.driver - ) - }); - } - try { - this.#storage = createStorage({ - driver: driver(this.#config.options) - }); - AstroSession.#sharedStorage.set(this.#config.driver, this.#storage); - return this.#storage; - } catch (err) { - throw new AstroError( - { - ...SessionStorageInitError, - message: SessionStorageInitError.message("Unknown error", this.#config.driver) - }, - { cause: err } - ); - } - } -} -function resolveSessionDriverName(driver) { - if (!driver) { - return null; - } - try { - if (driver === "fs") { - return builtinDrivers.fsLite; - } - if (driver in builtinDrivers) { - return builtinDrivers[driver]; - } - } catch { - return null; - } - return driver; -} - -function validateAndDecodePathname(pathname) { - let decoded; - try { - decoded = decodeURI(pathname); - } catch (_e) { - throw new Error("Invalid URL encoding"); - } - const hasDecoding = decoded !== pathname; - const decodedStillHasEncoding = /%[0-9a-fA-F]{2}/.test(decoded); - if (hasDecoding && decodedStillHasEncoding) { - throw new Error("Multi-level URL encoding is not allowed"); - } - return decoded; -} - -const apiContextRoutesSymbol = Symbol.for("context.routes"); -class RenderContext { - constructor(pipeline, locals, middleware, actions, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = RenderContext.#createNormalizedUrl(request.url), props = {}, partial = void 0, shouldInjectCspMetaTags = !!pipeline.manifest.csp, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig, pipeline.runtimeMode) : void 0) { - this.pipeline = pipeline; - this.locals = locals; - this.middleware = middleware; - this.actions = actions; - this.pathname = pathname; - this.request = request; - this.routeData = routeData; - this.status = status; - this.clientAddress = clientAddress; - this.cookies = cookies; - this.params = params; - this.url = url; - this.props = props; - this.partial = partial; - this.shouldInjectCspMetaTags = shouldInjectCspMetaTags; - this.session = session; - } - static #createNormalizedUrl(requestUrl) { - const url = new URL(requestUrl); - try { - url.pathname = validateAndDecodePathname(url.pathname); - } catch { - try { - url.pathname = decodeURI(url.pathname); - } catch { - } - } - return url; - } - /** - * A flag that tells the render content if the rewriting was triggered - */ - isRewriting = false; - /** - * A safety net in case of loops - */ - counter = 0; - result = void 0; - static async create({ - locals = {}, - middleware, - pathname, - pipeline, - request, - routeData, - clientAddress, - status = 200, - props, - partial = void 0, - actions, - shouldInjectCspMetaTags - }) { - const pipelineMiddleware = await pipeline.getMiddleware(); - const pipelineActions = actions ?? await pipeline.getActions(); - setOriginPathname( - request, - pathname, - pipeline.manifest.trailingSlash, - pipeline.manifest.buildFormat - ); - return new RenderContext( - pipeline, - locals, - sequence(...pipeline.internalMiddleware, middleware ?? pipelineMiddleware), - pipelineActions, - pathname, - request, - routeData, - status, - clientAddress, - void 0, - void 0, - void 0, - props, - partial, - shouldInjectCspMetaTags ?? !!pipeline.manifest.csp - ); - } - /** - * The main function of the RenderContext. - * - * Use this function to render any route known to Astro. - * It attempts to render a route. A route can be a: - * - * - page - * - redirect - * - endpoint - * - fallback - */ - async render(componentInstance, slots = {}) { - const { middleware, pipeline } = this; - const { logger, serverLike, streaming, manifest } = pipeline; - const props = Object.keys(this.props).length > 0 ? this.props : await getProps({ - mod: componentInstance, - routeData: this.routeData, - routeCache: this.pipeline.routeCache, - pathname: this.pathname, - logger, - serverLike, - base: manifest.base - }); - const actionApiContext = this.createActionAPIContext(); - const apiContext = this.createAPIContext(props, actionApiContext); - this.counter++; - if (this.counter === 4) { - return new Response("Loop Detected", { - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508 - status: 508, - statusText: "Astro detected a loop where you tried to call the rewriting logic more than four times." - }); - } - const lastNext = async (ctx, payload) => { - if (payload) { - const oldPathname = this.pathname; - pipeline.logger.debug("router", "Called rewriting to:", payload); - const { - routeData, - componentInstance: newComponent, - pathname, - newUrl - } = await pipeline.tryRewrite(payload, this.request); - if (this.pipeline.serverLike === true && this.routeData.prerender === false && routeData.prerender === true) { - throw new AstroError({ - ...ForbiddenRewrite, - message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component), - hint: ForbiddenRewrite.hint(routeData.component) - }); - } - this.routeData = routeData; - componentInstance = newComponent; - if (payload instanceof Request) { - this.request = payload; - } else { - this.request = copyRequest( - newUrl, - this.request, - // need to send the flag of the previous routeData - routeData.prerender, - this.pipeline.logger, - this.routeData.route - ); - } - this.isRewriting = true; - this.url = RenderContext.#createNormalizedUrl(this.request.url); - this.params = getParams(routeData, pathname); - this.pathname = pathname; - this.status = 200; - setOriginPathname( - this.request, - oldPathname, - this.pipeline.manifest.trailingSlash, - this.pipeline.manifest.buildFormat - ); - } - let response2; - if (!ctx.isPrerendered) { - const { action, setActionResult, serializeActionResult } = getActionContext(ctx); - if (action?.calledFrom === "form") { - const actionResult = await action.handler(); - setActionResult(action.name, serializeActionResult(actionResult)); - } - } - switch (this.routeData.type) { - case "endpoint": { - response2 = await renderEndpoint( - componentInstance, - ctx, - this.routeData.prerender, - logger - ); - break; - } - case "redirect": - return renderRedirect(this); - case "page": { - this.result = await this.createResult(componentInstance, actionApiContext); - try { - response2 = await renderPage( - this.result, - componentInstance?.default, - props, - slots, - streaming, - this.routeData - ); - } catch (e) { - this.result.cancelled = true; - throw e; - } - response2.headers.set(ROUTE_TYPE_HEADER, "page"); - if (this.routeData.route === "/404" || this.routeData.route === "/500") { - response2.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); - } - if (this.isRewriting) { - response2.headers.set(REWRITE_DIRECTIVE_HEADER_KEY, REWRITE_DIRECTIVE_HEADER_VALUE); - } - break; - } - case "fallback": { - return new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } }); - } - } - const responseCookies = getCookiesFromResponse(response2); - if (responseCookies) { - this.cookies.merge(responseCookies); - } - return response2; - }; - if (isRouteExternalRedirect(this.routeData)) { - return renderRedirect(this); - } - const response = await callMiddleware(middleware, apiContext, lastNext); - if (response.headers.get(ROUTE_TYPE_HEADER)) { - response.headers.delete(ROUTE_TYPE_HEADER); - } - attachCookiesToResponse(response, this.cookies); - return response; - } - createAPIContext(props, context) { - const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } }); - Reflect.set(context, apiContextRoutesSymbol, this.pipeline); - return Object.assign(context, { - props, - redirect, - getActionResult: createGetActionResult(context.locals), - callAction: createCallAction(context) - }); - } - async #executeRewrite(reroutePayload) { - this.pipeline.logger.debug("router", "Calling rewrite: ", reroutePayload); - const oldPathname = this.pathname; - const { routeData, componentInstance, newUrl, pathname } = await this.pipeline.tryRewrite( - reroutePayload, - this.request - ); - const isI18nFallback = routeData.fallbackRoutes && routeData.fallbackRoutes.length > 0; - if (this.pipeline.serverLike && !this.routeData.prerender && routeData.prerender && !isI18nFallback) { - throw new AstroError({ - ...ForbiddenRewrite, - message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component), - hint: ForbiddenRewrite.hint(routeData.component) - }); - } - this.routeData = routeData; - if (reroutePayload instanceof Request) { - this.request = reroutePayload; - } else { - this.request = copyRequest( - newUrl, - this.request, - // need to send the flag of the previous routeData - routeData.prerender, - this.pipeline.logger, - this.routeData.route - ); - } - this.url = RenderContext.#createNormalizedUrl(this.request.url); - const newCookies = new AstroCookies(this.request); - if (this.cookies) { - newCookies.merge(this.cookies); - } - this.cookies = newCookies; - this.params = getParams(routeData, pathname); - this.pathname = pathname; - this.isRewriting = true; - this.status = 200; - setOriginPathname( - this.request, - oldPathname, - this.pipeline.manifest.trailingSlash, - this.pipeline.manifest.buildFormat - ); - return await this.render(componentInstance); - } - createActionAPIContext() { - const renderContext = this; - const { params, pipeline, url } = this; - const generator = `Astro v${ASTRO_VERSION}`; - const rewrite = async (reroutePayload) => { - return await this.#executeRewrite(reroutePayload); - }; - return { - // Don't allow reassignment of cookies because it doesn't work - get cookies() { - return renderContext.cookies; - }, - routePattern: this.routeData.route, - isPrerendered: this.routeData.prerender, - get clientAddress() { - return renderContext.getClientAddress(); - }, - get currentLocale() { - return renderContext.computeCurrentLocale(); - }, - generator, - get locals() { - return renderContext.locals; - }, - set locals(_) { - throw new AstroError(LocalsReassigned); - }, - params, - get preferredLocale() { - return renderContext.computePreferredLocale(); - }, - get preferredLocaleList() { - return renderContext.computePreferredLocaleList(); - }, - rewrite, - request: this.request, - site: pipeline.site, - url, - get originPathname() { - return getOriginPathname(renderContext.request); - }, - get session() { - if (this.isPrerendered) { - pipeline.logger.warn( - "session", - `context.session was used when rendering the route ${colors.green(this.routePattern)}, but it is not available on prerendered routes. If you need access to sessions, make sure that the route is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your routes server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/` - ); - return void 0; - } - if (!renderContext.session) { - pipeline.logger.warn( - "session", - `context.session was used when rendering the route ${colors.green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/` - ); - return void 0; - } - return renderContext.session; - }, - get csp() { - return { - insertDirective(payload) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - if (renderContext?.result?.directives) { - renderContext.result.directives = pushDirective( - renderContext.result.directives, - payload - ); - } else { - renderContext?.result?.directives.push(payload); - } - }, - insertScriptResource(resource) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.scriptResources.push(resource); - }, - insertStyleResource(resource) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.styleResources.push(resource); - }, - insertStyleHash(hash) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.styleHashes.push(hash); - }, - insertScriptHash(hash) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.scriptHashes.push(hash); - } - }; - } - }; - } - async createResult(mod, ctx) { - const { cookies, pathname, pipeline, routeData, status } = this; - const { clientDirectives, inlinedScripts, compressHTML, manifest, renderers, resolve } = pipeline; - const { links, scripts, styles } = await pipeline.headElements(routeData); - const extraStyleHashes = []; - const extraScriptHashes = []; - const shouldInjectCspMetaTags = this.shouldInjectCspMetaTags; - const cspAlgorithm = manifest.csp?.algorithm ?? "SHA-256"; - if (shouldInjectCspMetaTags) { - for (const style of styles) { - extraStyleHashes.push(await generateCspDigest(style.children, cspAlgorithm)); - } - for (const script of scripts) { - extraScriptHashes.push(await generateCspDigest(script.children, cspAlgorithm)); - } - } - const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata; - const headers = new Headers({ "Content-Type": "text/html" }); - const partial = typeof this.partial === "boolean" ? this.partial : Boolean(mod.partial); - const actionResult = hasActionPayload(this.locals) ? deserializeActionResult(this.locals._actionPayload.actionResult) : void 0; - const response = { - status: actionResult?.error ? actionResult?.error.status : status, - statusText: actionResult?.error ? actionResult?.error.type : "OK", - get headers() { - return headers; - }, - // Disallow `Astro.response.headers = new Headers` - set headers(_) { - throw new AstroError(AstroResponseHeadersReassigned); - } - }; - const result = { - base: manifest.base, - userAssetsBase: manifest.userAssetsBase, - cancelled: false, - clientDirectives, - inlinedScripts, - componentMetadata, - compressHTML, - cookies, - /** This function returns the `Astro` faux-global */ - createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots, ctx), - links, - params: this.params, - partial, - pathname, - renderers, - resolve, - response, - request: this.request, - scripts, - styles, - actionResult, - serverIslandNameMap: manifest.serverIslandNameMap ?? /* @__PURE__ */ new Map(), - key: manifest.key, - trailingSlash: manifest.trailingSlash, - _metadata: { - hasHydrationScript: false, - rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(), - hasRenderedHead: false, - renderedScripts: /* @__PURE__ */ new Set(), - hasDirectives: /* @__PURE__ */ new Set(), - hasRenderedServerIslandRuntime: false, - headInTree: false, - extraHead: [], - extraStyleHashes, - extraScriptHashes, - propagators: /* @__PURE__ */ new Set() - }, - cspDestination: manifest.csp?.cspDestination ?? (routeData.prerender ? "meta" : "header"), - shouldInjectCspMetaTags, - cspAlgorithm, - // The following arrays must be cloned, otherwise they become mutable across routes. - scriptHashes: manifest.csp?.scriptHashes ? [...manifest.csp.scriptHashes] : [], - scriptResources: manifest.csp?.scriptResources ? [...manifest.csp.scriptResources] : [], - styleHashes: manifest.csp?.styleHashes ? [...manifest.csp.styleHashes] : [], - styleResources: manifest.csp?.styleResources ? [...manifest.csp.styleResources] : [], - directives: manifest.csp?.directives ? [...manifest.csp.directives] : [], - isStrictDynamic: manifest.csp?.isStrictDynamic ?? false, - internalFetchHeaders: manifest.internalFetchHeaders - }; - return result; - } - #astroPagePartial; - /** - * The Astro global is sourced in 3 different phases: - * - **Static**: `.generator` and `.glob` is printed by the compiler, instantiated once per process per astro file - * - **Page-level**: `.request`, `.cookies`, `.locals` etc. These remain the same for the duration of the request. - * - **Component-level**: `.props`, `.slots`, and `.self` are unique to each _use_ of each component. - * - * The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component. - */ - createAstro(result, astroStaticPartial, props, slotValues, apiContext) { - let astroPagePartial; - if (this.isRewriting) { - astroPagePartial = this.#astroPagePartial = this.createAstroPagePartial( - result, - astroStaticPartial, - apiContext - ); - } else { - astroPagePartial = this.#astroPagePartial ??= this.createAstroPagePartial( - result, - astroStaticPartial, - apiContext - ); - } - const astroComponentPartial = { props, self: null }; - const Astro = Object.assign( - Object.create(astroPagePartial), - astroComponentPartial - ); - let _slots; - Object.defineProperty(Astro, "slots", { - get: () => { - if (!_slots) { - _slots = new Slots( - result, - slotValues, - this.pipeline.logger - ); - } - return _slots; - } - }); - return Astro; - } - createAstroPagePartial(result, astroStaticPartial, apiContext) { - const renderContext = this; - const { cookies, locals, params, pipeline, url } = this; - const { response } = result; - const redirect = (path, status = 302) => { - if (this.request[responseSentSymbol$1]) { - throw new AstroError({ - ...ResponseSentError - }); - } - return new Response(null, { status, headers: { Location: path } }); - }; - const rewrite = async (reroutePayload) => { - return await this.#executeRewrite(reroutePayload); - }; - const callAction = createCallAction(apiContext); - return { - generator: astroStaticPartial.generator, - glob: astroStaticPartial.glob, - routePattern: this.routeData.route, - isPrerendered: this.routeData.prerender, - cookies, - get session() { - if (this.isPrerendered) { - pipeline.logger.warn( - "session", - `Astro.session was used when rendering the route ${colors.green(this.routePattern)}, but it is not available on prerendered pages. If you need access to sessions, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/` - ); - return void 0; - } - if (!renderContext.session) { - pipeline.logger.warn( - "session", - `Astro.session was used when rendering the route ${colors.green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/` - ); - return void 0; - } - return renderContext.session; - }, - get clientAddress() { - return renderContext.getClientAddress(); - }, - get currentLocale() { - return renderContext.computeCurrentLocale(); - }, - params, - get preferredLocale() { - return renderContext.computePreferredLocale(); - }, - get preferredLocaleList() { - return renderContext.computePreferredLocaleList(); - }, - locals, - redirect, - rewrite, - request: this.request, - response, - site: pipeline.site, - getActionResult: createGetActionResult(locals), - get callAction() { - return callAction; - }, - url, - get originPathname() { - return getOriginPathname(renderContext.request); - }, - get csp() { - return { - insertDirective(payload) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - if (renderContext?.result?.directives) { - renderContext.result.directives = pushDirective( - renderContext.result.directives, - payload - ); - } else { - renderContext?.result?.directives.push(payload); - } - }, - insertScriptResource(resource) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.scriptResources.push(resource); - }, - insertStyleResource(resource) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.styleResources.push(resource); - }, - insertStyleHash(hash) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.styleHashes.push(hash); - }, - insertScriptHash(hash) { - if (!pipeline.manifest.csp) { - throw new AstroError(CspNotEnabled); - } - renderContext.result?.scriptHashes.push(hash); - } - }; - } - }; - } - getClientAddress() { - const { pipeline, request, routeData, clientAddress } = this; - if (routeData.prerender) { - throw new AstroError({ - ...PrerenderClientAddressNotAvailable, - message: PrerenderClientAddressNotAvailable.message(routeData.component) - }); - } - if (clientAddress) { - return clientAddress; - } - if (clientAddressSymbol in request) { - return Reflect.get(request, clientAddressSymbol); - } - if (pipeline.adapterName) { - throw new AstroError({ - ...ClientAddressNotAvailable, - message: ClientAddressNotAvailable.message(pipeline.adapterName) - }); - } - throw new AstroError(StaticClientAddressNotAvailable); - } - /** - * API Context may be created multiple times per request, i18n data needs to be computed only once. - * So, it is computed and saved here on creation of the first APIContext and reused for later ones. - */ - #currentLocale; - computeCurrentLocale() { - const { - url, - pipeline: { i18n }, - routeData - } = this; - if (!i18n) return; - const { defaultLocale, locales, strategy } = i18n; - const fallbackTo = strategy === "pathname-prefix-other-locales" || strategy === "domains-prefix-other-locales" ? defaultLocale : void 0; - if (this.#currentLocale) { - return this.#currentLocale; - } - let computedLocale; - if (isRouteServerIsland(routeData)) { - let referer = this.request.headers.get("referer"); - if (referer) { - if (URL.canParse(referer)) { - referer = new URL(referer).pathname; - } - computedLocale = computeCurrentLocale(referer, locales, defaultLocale); - } - } else { - let pathname = routeData.pathname; - if (!routeData.pattern.test(url.pathname)) { - for (const fallbackRoute of routeData.fallbackRoutes) { - if (fallbackRoute.pattern.test(url.pathname)) { - pathname = fallbackRoute.pathname; - break; - } - } - } - pathname = pathname && !isRoute404or500(routeData) ? pathname : url.pathname; - computedLocale = computeCurrentLocale(pathname, locales, defaultLocale); - } - this.#currentLocale = computedLocale ?? fallbackTo; - return this.#currentLocale; - } - #preferredLocale; - computePreferredLocale() { - const { - pipeline: { i18n }, - request - } = this; - if (!i18n) return; - return this.#preferredLocale ??= computePreferredLocale(request, i18n.locales); - } - #preferredLocaleList; - computePreferredLocaleList() { - const { - pipeline: { i18n }, - request - } = this; - if (!i18n) return; - return this.#preferredLocaleList ??= computePreferredLocaleList(request, i18n.locales); - } -} - -function redirectTemplate({ - status, - absoluteLocation, - relativeLocation, - from -}) { - const delay = status === 302 ? 2 : 0; - return ` -Redirecting to: ${relativeLocation} - - - - -
    Redirecting ${from ? `from ${from} ` : ""}to ${relativeLocation} -`; -} - -class AppPipeline extends Pipeline { - static create({ - logger, - manifest, - runtimeMode, - renderers, - resolve, - serverLike, - streaming, - defaultRoutes - }) { - const pipeline = new AppPipeline( - logger, - manifest, - runtimeMode, - renderers, - resolve, - serverLike, - streaming, - void 0, - void 0, - void 0, - void 0, - void 0, - void 0, - void 0, - void 0, - defaultRoutes - ); - return pipeline; - } - headElements(routeData) { - const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData); - const links = /* @__PURE__ */ new Set(); - const scripts = /* @__PURE__ */ new Set(); - const styles = createStylesheetElementSet(routeInfo?.styles ?? []); - for (const script of routeInfo?.scripts ?? []) { - if ("stage" in script) { - if (script.stage === "head-inline") { - scripts.add({ - props: {}, - children: script.children - }); - } - } else { - scripts.add(createModuleScriptElement(script)); - } - } - return { links, styles, scripts }; - } - componentMetadata() { - } - async getComponentByRoute(routeData) { - const module = await this.getModuleForRoute(routeData); - return module.page(); - } - async tryRewrite(payload, request) { - const { newUrl, pathname, routeData } = findRouteToRewrite({ - payload, - request, - routes: this.manifest?.routes.map((r) => r.routeData), - trailingSlash: this.manifest.trailingSlash, - buildFormat: this.manifest.buildFormat, - base: this.manifest.base, - outDir: this.serverLike ? this.manifest.buildClientDir : this.manifest.outDir - }); - const componentInstance = await this.getComponentByRoute(routeData); - return { newUrl, pathname, componentInstance, routeData }; - } - async getModuleForRoute(route) { - for (const defaultRoute of this.defaultRoutes) { - if (route.component === defaultRoute.component) { - return { - page: () => Promise.resolve(defaultRoute.instance), - renderers: [] - }; - } - } - if (route.type === "redirect") { - return RedirectSinglePageBuiltModule; - } else { - if (this.manifest.pageMap) { - const importComponentInstance = this.manifest.pageMap.get(route.component); - if (!importComponentInstance) { - throw new Error( - `Unexpectedly unable to find a component instance for route ${route.route}` - ); - } - return await importComponentInstance(); - } else if (this.manifest.pageModule) { - return this.manifest.pageModule; - } - throw new Error( - "Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error, please file an issue." - ); - } - } -} - -class App { - #manifest; - #manifestData; - #logger = new Logger({ - dest: consoleLogDestination, - level: "info" - }); - #baseWithoutTrailingSlash; - #pipeline; - #adapterLogger; - constructor(manifest, streaming = true) { - this.#manifest = manifest; - this.#manifestData = { - routes: manifest.routes.map((route) => route.routeData) - }; - ensure404Route(this.#manifestData); - this.#baseWithoutTrailingSlash = removeTrailingForwardSlash(this.#manifest.base); - this.#pipeline = this.#createPipeline(streaming); - this.#adapterLogger = new AstroIntegrationLogger( - this.#logger.options, - this.#manifest.adapterName - ); - } - getAdapterLogger() { - return this.#adapterLogger; - } - getAllowedDomains() { - return this.#manifest.allowedDomains; - } - get manifest() { - return this.#manifest; - } - set manifest(value) { - this.#manifest = value; - } - matchesAllowedDomains(forwardedHost, protocol) { - return App.validateForwardedHost(forwardedHost, this.#manifest.allowedDomains, protocol); - } - static validateForwardedHost(forwardedHost, allowedDomains, protocol) { - if (!allowedDomains || allowedDomains.length === 0) { - return false; - } - try { - const testUrl = new URL(`${protocol || "https"}://${forwardedHost}`); - return allowedDomains.some((pattern) => { - return matchPattern(testUrl, pattern); - }); - } catch { - return false; - } - } - /** - * Validate a hostname by rejecting any with path separators. - * Prevents path injection attacks. Invalid hostnames return undefined. - */ - static sanitizeHost(hostname) { - if (!hostname) return void 0; - if (/[/\\]/.test(hostname)) return void 0; - return hostname; - } - /** - * Validate forwarded headers (proto, host, port) against allowedDomains. - * Returns validated values or undefined for rejected headers. - * Uses strict defaults: http/https only for proto, rejects port if not in allowedDomains. - */ - static validateForwardedHeaders(forwardedProtocol, forwardedHost, forwardedPort, allowedDomains) { - const result = {}; - if (forwardedProtocol) { - if (allowedDomains && allowedDomains.length > 0) { - const hasProtocolPatterns = allowedDomains.some( - (pattern) => pattern.protocol !== void 0 - ); - if (hasProtocolPatterns) { - try { - const testUrl = new URL(`${forwardedProtocol}://example.com`); - const isAllowed = allowedDomains.some((pattern) => matchPattern(testUrl, pattern)); - if (isAllowed) { - result.protocol = forwardedProtocol; - } - } catch { - } - } else if (/^https?$/.test(forwardedProtocol)) { - result.protocol = forwardedProtocol; - } - } else if (/^https?$/.test(forwardedProtocol)) { - result.protocol = forwardedProtocol; - } - } - if (forwardedPort && allowedDomains && allowedDomains.length > 0) { - const hasPortPatterns = allowedDomains.some((pattern) => pattern.port !== void 0); - if (hasPortPatterns) { - const isAllowed = allowedDomains.some((pattern) => pattern.port === forwardedPort); - if (isAllowed) { - result.port = forwardedPort; - } - } - } - if (forwardedHost && forwardedHost.length > 0 && allowedDomains && allowedDomains.length > 0) { - const protoForValidation = result.protocol || "https"; - const sanitized = App.sanitizeHost(forwardedHost); - if (sanitized) { - try { - const hostnameOnly = sanitized.split(":")[0]; - const portFromHost = sanitized.includes(":") ? sanitized.split(":")[1] : void 0; - const portForValidation = result.port || portFromHost; - const hostWithPort = portForValidation ? `${hostnameOnly}:${portForValidation}` : hostnameOnly; - const testUrl = new URL(`${protoForValidation}://${hostWithPort}`); - const isAllowed = allowedDomains.some((pattern) => matchPattern(testUrl, pattern)); - if (isAllowed) { - result.host = sanitized; - } - } catch { - } - } - } - return result; - } - /** - * Creates a pipeline by reading the stored manifest - * - * @param streaming - * @private - */ - #createPipeline(streaming = false) { - return AppPipeline.create({ - logger: this.#logger, - manifest: this.#manifest, - runtimeMode: "production", - renderers: this.#manifest.renderers, - defaultRoutes: createDefaultRoutes(this.#manifest), - resolve: async (specifier) => { - if (!(specifier in this.#manifest.entryModules)) { - throw new Error(`Unable to resolve [${specifier}]`); - } - const bundlePath = this.#manifest.entryModules[specifier]; - if (bundlePath.startsWith("data:") || bundlePath.length === 0) { - return bundlePath; - } else { - return createAssetLink(bundlePath, this.#manifest.base, this.#manifest.assetsPrefix); - } - }, - serverLike: true, - streaming - }); - } - set setManifestData(newManifestData) { - this.#manifestData = newManifestData; - } - removeBase(pathname) { - if (pathname.startsWith(this.#manifest.base)) { - return pathname.slice(this.#baseWithoutTrailingSlash.length + 1); - } - return pathname; - } - /** - * It removes the base from the request URL, prepends it with a forward slash and attempts to decoded it. - * - * If the decoding fails, it logs the error and return the pathname as is. - * @param request - * @private - */ - #getPathnameFromRequest(request) { - const url = new URL(request.url); - const pathname = prependForwardSlash$1(this.removeBase(url.pathname)); - try { - return validateAndDecodePathname(pathname); - } catch (e) { - this.getAdapterLogger().error(e.toString()); - return pathname; - } - } - /** - * Given a `Request`, it returns the `RouteData` that matches its `pathname`. By default, prerendered - * routes aren't returned, even if they are matched. - * - * When `allowPrerenderedRoutes` is `true`, the function returns matched prerendered routes too. - * @param request - * @param allowPrerenderedRoutes - */ - match(request, allowPrerenderedRoutes = false) { - const url = new URL(request.url); - if (this.#manifest.assets.has(url.pathname)) return void 0; - let pathname = this.#computePathnameFromDomain(request); - if (!pathname) { - pathname = prependForwardSlash$1(this.removeBase(url.pathname)); - } - try { - pathname = validateAndDecodePathname(pathname); - } catch { - return void 0; - } - let routeData = matchRoute(pathname, this.#manifestData); - if (!routeData) return void 0; - if (allowPrerenderedRoutes) { - return routeData; - } else if (routeData.prerender) { - return void 0; - } - return routeData; - } - #computePathnameFromDomain(request) { - let pathname = void 0; - const url = new URL(request.url); - if (this.#manifest.i18n && (this.#manifest.i18n.strategy === "domains-prefix-always" || this.#manifest.i18n.strategy === "domains-prefix-other-locales" || this.#manifest.i18n.strategy === "domains-prefix-always-no-redirect")) { - const validated = App.validateForwardedHeaders( - request.headers.get("X-Forwarded-Proto") ?? void 0, - request.headers.get("X-Forwarded-Host") ?? void 0, - request.headers.get("X-Forwarded-Port") ?? void 0, - this.#manifest.allowedDomains - ); - let protocol = validated.protocol ? validated.protocol + ":" : url.protocol; - let host = validated.host ?? request.headers.get("Host"); - if (host && protocol) { - host = host.split(":")[0]; - try { - let locale; - const hostAsUrl = new URL(`${protocol}//${host}`); - for (const [domainKey, localeValue] of Object.entries( - this.#manifest.i18n.domainLookupTable - )) { - const domainKeyAsUrl = new URL(domainKey); - if (hostAsUrl.host === domainKeyAsUrl.host && hostAsUrl.protocol === domainKeyAsUrl.protocol) { - locale = localeValue; - break; - } - } - if (locale) { - pathname = prependForwardSlash$1( - joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname)) - ); - if (url.pathname.endsWith("/")) { - pathname = appendForwardSlash$1(pathname); - } - } - } catch (e) { - this.#logger.error( - "router", - `Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.` - ); - this.#logger.error("router", `Error: ${e}`); - } - } - } - return pathname; - } - #redirectTrailingSlash(pathname) { - const { trailingSlash } = this.#manifest; - if (pathname === "/" || isInternalPath(pathname)) { - return pathname; - } - const path = collapseDuplicateTrailingSlashes(pathname, trailingSlash !== "never"); - if (path !== pathname) { - return path; - } - if (trailingSlash === "ignore") { - return pathname; - } - if (trailingSlash === "always" && !hasFileExtension(pathname)) { - return appendForwardSlash$1(pathname); - } - if (trailingSlash === "never") { - return removeTrailingForwardSlash(pathname); - } - return pathname; - } - async render(request, renderOptions) { - let routeData; - let locals; - let clientAddress; - let addCookieHeader; - const url = new URL(request.url); - const redirect = this.#redirectTrailingSlash(url.pathname); - const prerenderedErrorPageFetch = renderOptions?.prerenderedErrorPageFetch ?? fetch; - if (redirect !== url.pathname) { - const status = request.method === "GET" ? 301 : 308; - return new Response( - redirectTemplate({ - status, - relativeLocation: url.pathname, - absoluteLocation: redirect, - from: request.url - }), - { - status, - headers: { - location: redirect + url.search - } - } - ); - } - addCookieHeader = renderOptions?.addCookieHeader; - clientAddress = renderOptions?.clientAddress ?? Reflect.get(request, clientAddressSymbol); - routeData = renderOptions?.routeData; - locals = renderOptions?.locals; - if (routeData) { - this.#logger.debug( - "router", - "The adapter " + this.#manifest.adapterName + " provided a custom RouteData for ", - request.url - ); - this.#logger.debug("router", "RouteData:\n" + routeData); - } - if (locals) { - if (typeof locals !== "object") { - const error = new AstroError(LocalsNotAnObject); - this.#logger.error(null, error.stack); - return this.#renderError(request, { - status: 500, - error, - clientAddress, - prerenderedErrorPageFetch - }); - } - } - if (!routeData) { - routeData = this.match(request); - this.#logger.debug("router", "Astro matched the following route for " + request.url); - this.#logger.debug("router", "RouteData:\n" + routeData); - } - if (!routeData) { - routeData = this.#manifestData.routes.find( - (route) => route.component === "404.astro" || route.component === DEFAULT_404_COMPONENT - ); - } - if (!routeData) { - this.#logger.debug("router", "Astro hasn't found routes that match " + request.url); - this.#logger.debug("router", "Here's the available routes:\n", this.#manifestData); - return this.#renderError(request, { - locals, - status: 404, - clientAddress, - prerenderedErrorPageFetch - }); - } - const pathname = this.#getPathnameFromRequest(request); - const defaultStatus = this.#getDefaultStatusCode(routeData, pathname); - let response; - let session; - try { - const mod = await this.#pipeline.getModuleForRoute(routeData); - if (!mod || typeof mod.page !== "function") { - throw new AstroError({ - ...FailedToFindPageMapSSR, - message: `The module for route "${routeData.route}" does not have a valid page function. This may occur when using static output mode with an SSR adapter.` - }); - } - const renderContext = await RenderContext.create({ - pipeline: this.#pipeline, - locals, - pathname, - request, - routeData, - status: defaultStatus, - clientAddress - }); - session = renderContext.session; - response = await renderContext.render(await mod.page()); - } catch (err) { - this.#logger.error("router", "Error while trying to render the route " + routeData.route); - this.#logger.error(null, err.stack || err.message || String(err)); - return this.#renderError(request, { - locals, - status: 500, - error: err, - clientAddress, - prerenderedErrorPageFetch - }); - } finally { - await session?.[PERSIST_SYMBOL](); - } - if (REROUTABLE_STATUS_CODES.includes(response.status) && // If the body isn't null, that means the user sets the 404 status - // but uses the current route to handle the 404 - response.body === null && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") { - return this.#renderError(request, { - locals, - response, - status: response.status, - // We don't have an error to report here. Passing null means we pass nothing intentionally - // while undefined means there's no error - error: response.status === 500 ? null : void 0, - clientAddress, - prerenderedErrorPageFetch - }); - } - if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) { - response.headers.delete(REROUTE_DIRECTIVE_HEADER); - } - if (addCookieHeader) { - for (const setCookieHeaderValue of App.getSetCookieFromResponse(response)) { - response.headers.append("set-cookie", setCookieHeaderValue); - } - } - Reflect.set(response, responseSentSymbol$1, true); - return response; - } - setCookieHeaders(response) { - return getSetCookiesFromResponse(response); - } - /** - * Reads all the cookies written by `Astro.cookie.set()` onto the passed response. - * For example, - * ```ts - * for (const cookie_ of App.getSetCookieFromResponse(response)) { - * const cookie: string = cookie_ - * } - * ``` - * @param response The response to read cookies from. - * @returns An iterator that yields key-value pairs as equal-sign-separated strings. - */ - static getSetCookieFromResponse = getSetCookiesFromResponse; - /** - * If it is a known error code, try sending the according page (e.g. 404.astro / 500.astro). - * This also handles pre-rendered /404 or /500 routes - */ - async #renderError(request, { - locals, - status, - response: originalResponse, - skipMiddleware = false, - error, - clientAddress, - prerenderedErrorPageFetch - }) { - const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? "/" : ""}`; - const errorRouteData = matchRoute(errorRoutePath, this.#manifestData); - const url = new URL(request.url); - if (errorRouteData) { - if (errorRouteData.prerender) { - const maybeDotHtml = errorRouteData.route.endsWith(`/${status}`) ? ".html" : ""; - const statusURL = new URL( - `${this.#baseWithoutTrailingSlash}/${status}${maybeDotHtml}`, - url - ); - if (statusURL.toString() !== request.url) { - const response2 = await prerenderedErrorPageFetch(statusURL.toString()); - const override = { status, removeContentEncodingHeaders: true }; - return this.#mergeResponses(response2, originalResponse, override); - } - } - const mod = await this.#pipeline.getModuleForRoute(errorRouteData); - if (!mod || typeof mod.page !== "function") { - const response2 = this.#mergeResponses(new Response(null, { status }), originalResponse); - Reflect.set(response2, responseSentSymbol$1, true); - return response2; - } - let session; - try { - const renderContext = await RenderContext.create({ - locals, - pipeline: this.#pipeline, - middleware: skipMiddleware ? NOOP_MIDDLEWARE_FN : void 0, - pathname: this.#getPathnameFromRequest(request), - request, - routeData: errorRouteData, - status, - props: { error }, - clientAddress - }); - session = renderContext.session; - const response2 = await renderContext.render(await mod.page()); - return this.#mergeResponses(response2, originalResponse); - } catch { - if (skipMiddleware === false) { - return this.#renderError(request, { - locals, - status, - response: originalResponse, - skipMiddleware: true, - clientAddress, - prerenderedErrorPageFetch - }); - } - } finally { - await session?.[PERSIST_SYMBOL](); - } - } - const response = this.#mergeResponses(new Response(null, { status }), originalResponse); - Reflect.set(response, responseSentSymbol$1, true); - return response; - } - #mergeResponses(newResponse, originalResponse, override) { - let newResponseHeaders = newResponse.headers; - if (override?.removeContentEncodingHeaders) { - newResponseHeaders = new Headers(newResponseHeaders); - newResponseHeaders.delete("Content-Encoding"); - newResponseHeaders.delete("Content-Length"); - } - if (!originalResponse) { - if (override !== void 0) { - return new Response(newResponse.body, { - status: override.status, - statusText: newResponse.statusText, - headers: newResponseHeaders - }); - } - return newResponse; - } - const status = override?.status ? override.status : originalResponse.status === 200 ? newResponse.status : originalResponse.status; - try { - originalResponse.headers.delete("Content-type"); - } catch { - } - const mergedHeaders = new Map([ - ...Array.from(newResponseHeaders), - ...Array.from(originalResponse.headers) - ]); - const newHeaders = new Headers(); - for (const [name, value] of mergedHeaders) { - newHeaders.set(name, value); - } - return new Response(newResponse.body, { - status, - statusText: status === 200 ? newResponse.statusText : originalResponse.statusText, - // If you're looking at here for possible bugs, it means that it's not a bug. - // With the middleware, users can meddle with headers, and we should pass to the 404/500. - // If users see something weird, it's because they are setting some headers they should not. - // - // Although, we don't want it to replace the content-type, because the error page must return `text/html` - headers: newHeaders - }); - } - #getDefaultStatusCode(routeData, pathname) { - if (!routeData.pattern.test(pathname)) { - for (const fallbackRoute of routeData.fallbackRoutes) { - if (fallbackRoute.pattern.test(pathname)) { - return 302; - } - } - } - const route = removeTrailingForwardSlash(routeData.route); - if (route.endsWith("/404")) return 404; - if (route.endsWith("/500")) return 500; - return 200; - } -} - -const createOutgoingHttpHeaders = (headers) => { - if (!headers) { - return void 0; - } - const nodeHeaders = Object.fromEntries(headers.entries()); - if (Object.keys(nodeHeaders).length === 0) { - return void 0; - } - if (headers.has("set-cookie")) { - const cookieHeaders = headers.getSetCookie(); - if (cookieHeaders.length > 1) { - nodeHeaders["set-cookie"] = cookieHeaders; - } - } - return nodeHeaders; -}; - -function apply() { - if (!globalThis.crypto) { - Object.defineProperty(globalThis, "crypto", { - value: crypto$1.webcrypto - }); - } - if (!globalThis.File) { - Object.defineProperty(globalThis, "File", { - value: buffer.File - }); - } -} - -class NodeApp extends App { - headersMap = void 0; - setHeadersMap(headers) { - this.headersMap = headers; - } - match(req, allowPrerenderedRoutes = false) { - if (!(req instanceof Request)) { - req = NodeApp.createRequest(req, { - skipBody: true, - allowedDomains: this.manifest.allowedDomains - }); - } - return super.match(req, allowPrerenderedRoutes); - } - render(req, routeDataOrOptions, maybeLocals) { - if (!(req instanceof Request)) { - req = NodeApp.createRequest(req, { - allowedDomains: this.manifest.allowedDomains - }); - } - return super.render(req, routeDataOrOptions, maybeLocals); - } - /** - * Converts a NodeJS IncomingMessage into a web standard Request. - * ```js - * import { NodeApp } from 'astro/app/node'; - * import { createServer } from 'node:http'; - * - * const server = createServer(async (req, res) => { - * const request = NodeApp.createRequest(req); - * const response = await app.render(request); - * await NodeApp.writeResponse(response, res); - * }) - * ``` - */ - static createRequest(req, { - skipBody = false, - allowedDomains = [] - } = {}) { - const controller = new AbortController(); - const isEncrypted = "encrypted" in req.socket && req.socket.encrypted; - const getFirstForwardedValue = (multiValueHeader) => { - return multiValueHeader?.toString()?.split(",").map((e) => e.trim())?.[0]; - }; - const providedProtocol = isEncrypted ? "https" : "http"; - const providedHostname = req.headers.host ?? req.headers[":authority"]; - const validated = App.validateForwardedHeaders( - getFirstForwardedValue(req.headers["x-forwarded-proto"]), - getFirstForwardedValue(req.headers["x-forwarded-host"]), - getFirstForwardedValue(req.headers["x-forwarded-port"]), - allowedDomains - ); - const protocol = validated.protocol ?? providedProtocol; - const sanitizedProvidedHostname = App.sanitizeHost( - typeof providedHostname === "string" ? providedHostname : void 0 - ); - const hostname = validated.host ?? sanitizedProvidedHostname; - const port = validated.port; - let url; - try { - const hostnamePort = getHostnamePort(hostname, port); - url = new URL(`${protocol}://${hostnamePort}${req.url}`); - } catch { - const hostnamePort = getHostnamePort(providedHostname, port); - url = new URL(`${providedProtocol}://${hostnamePort}`); - } - const options = { - method: req.method || "GET", - headers: makeRequestHeaders(req), - signal: controller.signal - }; - const bodyAllowed = options.method !== "HEAD" && options.method !== "GET" && skipBody === false; - if (bodyAllowed) { - Object.assign(options, makeRequestBody(req)); - } - const request = new Request(url, options); - const socket = getRequestSocket(req); - if (socket && typeof socket.on === "function") { - const existingCleanup = getAbortControllerCleanup(req); - if (existingCleanup) { - existingCleanup(); - } - let cleanedUp = false; - const removeSocketListener = () => { - if (typeof socket.off === "function") { - socket.off("close", onSocketClose); - } else if (typeof socket.removeListener === "function") { - socket.removeListener("close", onSocketClose); - } - }; - const cleanup = () => { - if (cleanedUp) return; - cleanedUp = true; - removeSocketListener(); - controller.signal.removeEventListener("abort", cleanup); - Reflect.deleteProperty(req, nodeRequestAbortControllerCleanupSymbol); - }; - const onSocketClose = () => { - cleanup(); - if (!controller.signal.aborted) { - controller.abort(); - } - }; - socket.on("close", onSocketClose); - controller.signal.addEventListener("abort", cleanup, { once: true }); - Reflect.set(req, nodeRequestAbortControllerCleanupSymbol, cleanup); - if (socket.destroyed) { - onSocketClose(); - } - } - const forwardedClientIp = getFirstForwardedValue(req.headers["x-forwarded-for"]); - const clientIp = forwardedClientIp || req.socket?.remoteAddress; - if (clientIp) { - Reflect.set(request, clientAddressSymbol, clientIp); - } - return request; - } - /** - * Streams a web-standard Response into a NodeJS Server Response. - * ```js - * import { NodeApp } from 'astro/app/node'; - * import { createServer } from 'node:http'; - * - * const server = createServer(async (req, res) => { - * const request = NodeApp.createRequest(req); - * const response = await app.render(request); - * await NodeApp.writeResponse(response, res); - * }) - * ``` - * @param source WhatWG Response - * @param destination NodeJS ServerResponse - */ - static async writeResponse(source, destination) { - const { status, headers, body, statusText } = source; - if (!(destination instanceof Http2ServerResponse)) { - destination.statusMessage = statusText; - } - destination.writeHead(status, createOutgoingHttpHeaders(headers)); - const cleanupAbortFromDestination = getAbortControllerCleanup( - destination.req ?? void 0 - ); - if (cleanupAbortFromDestination) { - const runCleanup = () => { - cleanupAbortFromDestination(); - if (typeof destination.off === "function") { - destination.off("finish", runCleanup); - destination.off("close", runCleanup); - } else { - destination.removeListener?.("finish", runCleanup); - destination.removeListener?.("close", runCleanup); - } - }; - destination.on("finish", runCleanup); - destination.on("close", runCleanup); - } - if (!body) return destination.end(); - try { - const reader = body.getReader(); - destination.on("close", () => { - reader.cancel().catch((err) => { - console.error( - `There was an uncaught error in the middle of the stream while rendering ${destination.req.url}.`, - err - ); - }); - }); - let result = await reader.read(); - while (!result.done) { - destination.write(result.value); - result = await reader.read(); - } - destination.end(); - } catch (err) { - destination.write("Internal server error", () => { - err instanceof Error ? destination.destroy(err) : destination.destroy(); - }); - } - } -} -function getHostnamePort(hostname, port) { - const portInHostname = typeof hostname === "string" && /:\d+$/.test(hostname); - const hostnamePort = portInHostname ? hostname : `${hostname}${port ? `:${port}` : ""}`; - return hostnamePort; -} -function makeRequestHeaders(req) { - const headers = new Headers(); - for (const [name, value] of Object.entries(req.headers)) { - if (value === void 0) { - continue; - } - if (Array.isArray(value)) { - for (const item of value) { - headers.append(name, item); - } - } else { - headers.append(name, value); - } - } - return headers; -} -function makeRequestBody(req) { - if (req.body !== void 0) { - if (typeof req.body === "string" && req.body.length > 0) { - return { body: Buffer.from(req.body) }; - } - if (typeof req.body === "object" && req.body !== null && Object.keys(req.body).length > 0) { - return { body: Buffer.from(JSON.stringify(req.body)) }; - } - if (typeof req.body === "object" && req.body !== null && typeof req.body[Symbol.asyncIterator] !== "undefined") { - return asyncIterableToBodyProps(req.body); - } - } - return asyncIterableToBodyProps(req); -} -function asyncIterableToBodyProps(iterable) { - return { - // Node uses undici for the Request implementation. Undici accepts - // a non-standard async iterable for the body. - // @ts-expect-error - body: iterable, - // The duplex property is required when using a ReadableStream or async - // iterable for the body. The type definitions do not include the duplex - // property because they are not up-to-date. - duplex: "half" - }; -} -function getAbortControllerCleanup(req) { - if (!req) return void 0; - const cleanup = Reflect.get(req, nodeRequestAbortControllerCleanupSymbol); - return typeof cleanup === "function" ? cleanup : void 0; -} -function getRequestSocket(req) { - if (req.socket && typeof req.socket.on === "function") { - return req.socket; - } - const http2Socket = req.stream?.session?.socket; - if (http2Socket && typeof http2Socket.on === "function") { - return http2Socket; - } - return void 0; -} - -apply(); - -function createAppHandler(app, options) { - const als = new AsyncLocalStorage(); - const logger = app.getAdapterLogger(); - process.on("unhandledRejection", (reason) => { - const requestUrl = als.getStore(); - logger.error(`Unhandled rejection while rendering ${requestUrl}`); - console.error(reason); - }); - const originUrl = options.experimentalErrorPageHost ? new URL(options.experimentalErrorPageHost) : void 0; - const prerenderedErrorPageFetch = originUrl ? (url) => { - const errorPageUrl = new URL(url); - errorPageUrl.protocol = originUrl.protocol; - errorPageUrl.host = originUrl.host; - return fetch(errorPageUrl); - } : void 0; - return async (req, res, next, locals) => { - let request; - try { - request = NodeApp.createRequest(req, { - allowedDomains: app.getAllowedDomains?.() ?? [] - }); - } catch (err) { - logger.error(`Could not render ${req.url}`); - console.error(err); - res.statusCode = 500; - res.end("Internal Server Error"); - return; - } - const routeData = app.match(request, true); - if (routeData) { - const response = await als.run( - request.url, - () => app.render(request, { - addCookieHeader: true, - locals, - routeData, - prerenderedErrorPageFetch - }) - ); - await NodeApp.writeResponse(response, res); - } else if (next) { - return next(); - } else { - const response = await app.render(req, { addCookieHeader: true, prerenderedErrorPageFetch }); - await NodeApp.writeResponse(response, res); - } - }; -} - -function createMiddleware(app, options) { - const handler = createAppHandler(app, options); - const logger = app.getAdapterLogger(); - return async (...args) => { - const [req, res, next, locals] = args; - if (req instanceof Error) { - const error = req; - if (next) { - return next(error); - } else { - throw error; - } - } - try { - await handler(req, res, next, locals); - } catch (err) { - logger.error(`Could not render ${req.url}`); - console.error(err); - if (!res.headersSent) { - res.writeHead(500, `Server error`); - res.end(); - } - } - }; -} - -const STATIC_HEADERS_FILE = "_experimentalHeaders.json"; - -const wildcardHosts = /* @__PURE__ */ new Set(["0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"]); -async function logListeningOn(logger, server, configuredHost) { - await new Promise((resolve) => server.once("listening", resolve)); - const protocol = server instanceof https.Server ? "https" : "http"; - const host = getResolvedHostForHttpServer(configuredHost); - const { port } = server.address(); - const address = getNetworkAddress(protocol, host, port); - if (host === void 0 || wildcardHosts.has(host)) { - logger.info( - `Server listening on - local: ${address.local[0]} - network: ${address.network[0]} -` - ); - } else { - logger.info(`Server listening on ${address.local[0]}`); - } -} -function getResolvedHostForHttpServer(host) { - if (host === false) { - return "localhost"; - } else if (host === true) { - return void 0; - } else { - return host; - } -} -function getNetworkAddress(protocol = "http", hostname, port, base) { - const NetworkAddress = { - local: [], - network: [] - }; - Object.values(os.networkInterfaces()).flatMap((nInterface) => nInterface ?? []).filter( - (detail) => detail && detail.address && (detail.family === "IPv4" || // @ts-expect-error Node 18.0 - 18.3 returns number - detail.family === 4) - ).forEach((detail) => { - let host = detail.address.replace( - "127.0.0.1", - hostname === void 0 || wildcardHosts.has(hostname) ? "localhost" : hostname - ); - if (host.includes(":")) { - host = `[${host}]`; - } - const url = `${protocol}://${host}:${port}${""}`; - if (detail.address.includes("127.0.0.1")) { - NetworkAddress.local.push(url); - } else { - NetworkAddress.network.push(url); - } - }); - return NetworkAddress; -} - -function createStaticHandler(app, options) { - const client = resolveClientDir(options); - return (req, res, ssr) => { - if (req.url) { - let fullUrl = req.url; - if (req.url.includes("#")) { - fullUrl = fullUrl.slice(0, req.url.indexOf("#")); - } - const [urlPath, urlQuery] = fullUrl.split("?"); - const filePath = path.join(client, app.removeBase(urlPath)); - let isDirectory = false; - try { - isDirectory = fs.lstatSync(filePath).isDirectory(); - } catch { - } - const { trailingSlash = "ignore" } = options; - const hasSlash = urlPath.endsWith("/"); - let pathname = urlPath; - if (app.headersMap && app.headersMap.length > 0) { - const routeData = app.match(req, true); - if (routeData && routeData.prerender) { - const matchedRoute = app.headersMap.find((header) => header.pathname.includes(pathname)); - if (matchedRoute) { - for (const header of matchedRoute.headers) { - res.setHeader(header.key, header.value); - } - } - } - } - switch (trailingSlash) { - case "never": { - if (isDirectory && urlPath !== "/" && hasSlash) { - pathname = urlPath.slice(0, -1) + (urlQuery ? "?" + urlQuery : ""); - res.statusCode = 301; - res.setHeader("Location", pathname); - return res.end(); - } - if (isDirectory && !hasSlash) { - pathname = `${urlPath}/index.html`; - } - break; - } - case "ignore": { - if (isDirectory && !hasSlash) { - pathname = `${urlPath}/index.html`; - } - break; - } - case "always": { - if (!hasSlash && !hasFileExtension(urlPath) && !isInternalPath(urlPath)) { - pathname = urlPath + "/" + (urlQuery ? "?" + urlQuery : ""); - res.statusCode = 301; - res.setHeader("Location", pathname); - return res.end(); - } - break; - } - } - pathname = prependForwardSlash(app.removeBase(pathname)); - const stream = send(req, pathname, { - root: client, - dotfiles: pathname.startsWith("/.well-known/") ? "allow" : "deny" - }); - let forwardError = false; - stream.on("error", (err) => { - if (forwardError) { - console.error(err.toString()); - res.writeHead(500); - res.end("Internal server error"); - return; - } - ssr(); - }); - stream.on("headers", (_res) => { - if (pathname.startsWith(`/${options.assets}/`)) { - _res.setHeader("Cache-Control", "public, max-age=31536000, immutable"); - } - }); - stream.on("file", () => { - forwardError = true; - }); - stream.pipe(res); - } else { - ssr(); - } - }; -} -function resolveClientDir(options) { - const clientURLRaw = new URL(options.client); - const serverURLRaw = new URL(options.server); - const rel = path.relative(url.fileURLToPath(serverURLRaw), url.fileURLToPath(clientURLRaw)); - const serverFolder = path.basename(options.server); - let serverEntryFolderURL = path.dirname(import.meta.url); - while (!serverEntryFolderURL.endsWith(serverFolder)) { - serverEntryFolderURL = path.dirname(serverEntryFolderURL); - } - const serverEntryURL = serverEntryFolderURL + "/entry.mjs"; - const clientURL = new URL(appendForwardSlash(rel), serverEntryURL); - const client = url.fileURLToPath(clientURL); - return client; -} -function prependForwardSlash(pth) { - return pth.startsWith("/") ? pth : "/" + pth; -} -function appendForwardSlash(pth) { - return pth.endsWith("/") ? pth : pth + "/"; -} - -const hostOptions = (host) => { - if (typeof host === "boolean") { - return host ? "0.0.0.0" : "localhost"; - } - return host; -}; -function standalone(app, options) { - const port = process.env.PORT ? Number(process.env.PORT) : options.port ?? 8080; - const host = process.env.HOST ?? hostOptions(options.host); - const handler = createStandaloneHandler(app, options); - const server = createServer(handler, host, port); - server.server.listen(port, host); - if (process.env.ASTRO_NODE_LOGGING !== "disabled") { - logListeningOn(app.getAdapterLogger(), server.server, host); - } - return { - server, - done: server.closed() - }; -} -function createStandaloneHandler(app, options) { - const appHandler = createAppHandler(app, options); - const staticHandler = createStaticHandler(app, options); - return (req, res) => { - try { - decodeURI(req.url); - } catch { - res.writeHead(400); - res.end("Bad request."); - return; - } - staticHandler(req, res, () => appHandler(req, res)); - }; -} -function createServer(listener, host, port) { - let httpServer; - if (process.env.SERVER_CERT_PATH && process.env.SERVER_KEY_PATH) { - httpServer = https.createServer( - { - key: fs.readFileSync(process.env.SERVER_KEY_PATH), - cert: fs.readFileSync(process.env.SERVER_CERT_PATH) - }, - listener - ); - } else { - httpServer = http.createServer(listener); - } - enableDestroy(httpServer); - const closed = new Promise((resolve, reject) => { - httpServer.addListener("close", resolve); - httpServer.addListener("error", reject); - }); - const previewable = { - host, - port, - closed() { - return closed; - }, - async stop() { - await new Promise((resolve, reject) => { - httpServer.destroy((err) => err ? reject(err) : resolve(void 0)); - }); - } - }; - return { - server: httpServer, - ...previewable - }; -} - -function createExports(manifest, options) { - const app = new NodeApp(manifest, !options.experimentalDisableStreaming); - let headersMap = void 0; - if (options.experimentalStaticHeaders) { - headersMap = readHeadersJson(manifest.outDir); - } - if (headersMap) { - app.setHeadersMap(headersMap); - } - options.trailingSlash = manifest.trailingSlash; - return { - options, - handler: options.mode === "middleware" ? createMiddleware(app, options) : createStandaloneHandler(app, options), - startServer: () => standalone(app, options) - }; -} -function start(manifest, options) { - if (options.mode !== "standalone" || process.env.ASTRO_NODE_AUTOSTART === "disabled") { - return; - } - let headersMap = void 0; - if (options.experimentalStaticHeaders) { - headersMap = readHeadersJson(manifest.outDir); - } - const app = new NodeApp(manifest, !options.experimentalDisableStreaming); - if (headersMap) { - app.setHeadersMap(headersMap); - } - standalone(app, options); -} -function readHeadersJson(outDir) { - let headersMap = void 0; - const headersUrl = new URL(STATIC_HEADERS_FILE, outDir); - if (existsSync(headersUrl)) { - const content = readFileSync(headersUrl, "utf-8"); - try { - headersMap = JSON.parse(content); - } catch (e) { - console.error("[@astrojs/node] Error parsing _headers.json: " + e.message); - console.error("[@astrojs/node] Please make sure your _headers.json is valid JSON."); - } - } - return headersMap; -} - -const serverEntrypointModule = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - createExports, - start -}, Symbol.toStringTag, { value: 'Module' })); - -export { start as a, createExports as c, serverEntrypointModule as s }; diff --git a/dist/server/chunks/_plugin-vue_export-helper_CEgY73aA.mjs b/dist/server/chunks/_plugin-vue_export-helper_CEgY73aA.mjs deleted file mode 100644 index cd4a30a..0000000 --- a/dist/server/chunks/_plugin-vue_export-helper_CEgY73aA.mjs +++ /dev/null @@ -1,24 +0,0 @@ -import { e as createAstro, f as createComponent, n as renderHead, o as renderSlot, r as renderTemplate } from './astro/server_CF97kUu8.mjs'; -import 'piccolore'; -import 'clsx'; -/* empty css */ - -const $$Astro = createAstro("https://skills.here.run.place"); -const $$Base = createComponent(($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); - Astro2.self = $$Base; - const { title = "Skills Here" } = Astro2.props; - return renderTemplate` ${title}${renderHead()}
    ${renderSlot($$result, $$slots["default"])}
    `; -}, "/Users/alex/projects/skillit/src/layouts/Base.astro", void 0); - -const _export_sfc = (sfc, props) => { - const target = sfc.__vccOpts || sfc; - for (const [key, val] of props) { - target[key] = val; - } - return target; -}; - -export { $$Base as $, _export_sfc as _ }; diff --git a/dist/server/chunks/astro-designed-error-pages_DSexancP.mjs b/dist/server/chunks/astro-designed-error-pages_DSexancP.mjs deleted file mode 100644 index 24fd071..0000000 --- a/dist/server/chunks/astro-designed-error-pages_DSexancP.mjs +++ /dev/null @@ -1,364 +0,0 @@ -import { al as NOOP_MIDDLEWARE_HEADER, am as REDIRECT_STATUS_CODES, A as AstroError, an as ActionsReturnedInvalidDataError, T as DEFAULT_404_COMPONENT } from './astro/server_CF97kUu8.mjs'; -import { parse, stringify } from 'devalue'; -import { escape } from 'html-escaper'; - -const NOOP_MIDDLEWARE_FN = async (_ctx, next) => { - const response = await next(); - response.headers.set(NOOP_MIDDLEWARE_HEADER, "true"); - return response; -}; - -const ACTION_QUERY_PARAMS$1 = { - actionName: "_action"}; -const ACTION_RPC_ROUTE_PATTERN = "/_actions/[...path]"; - -const __vite_import_meta_env__ = {"ASSETS_PREFIX": undefined, "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SITE": "https://skills.here.run.place", "SSR": true}; -const ACTION_QUERY_PARAMS = ACTION_QUERY_PARAMS$1; -const codeToStatusMap = { - // Implemented from IANA HTTP Status Code Registry - // https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml - BAD_REQUEST: 400, - UNAUTHORIZED: 401, - PAYMENT_REQUIRED: 402, - FORBIDDEN: 403, - NOT_FOUND: 404, - METHOD_NOT_ALLOWED: 405, - NOT_ACCEPTABLE: 406, - PROXY_AUTHENTICATION_REQUIRED: 407, - REQUEST_TIMEOUT: 408, - CONFLICT: 409, - GONE: 410, - LENGTH_REQUIRED: 411, - PRECONDITION_FAILED: 412, - CONTENT_TOO_LARGE: 413, - URI_TOO_LONG: 414, - UNSUPPORTED_MEDIA_TYPE: 415, - RANGE_NOT_SATISFIABLE: 416, - EXPECTATION_FAILED: 417, - MISDIRECTED_REQUEST: 421, - UNPROCESSABLE_CONTENT: 422, - LOCKED: 423, - FAILED_DEPENDENCY: 424, - TOO_EARLY: 425, - UPGRADE_REQUIRED: 426, - PRECONDITION_REQUIRED: 428, - TOO_MANY_REQUESTS: 429, - REQUEST_HEADER_FIELDS_TOO_LARGE: 431, - UNAVAILABLE_FOR_LEGAL_REASONS: 451, - INTERNAL_SERVER_ERROR: 500, - NOT_IMPLEMENTED: 501, - BAD_GATEWAY: 502, - SERVICE_UNAVAILABLE: 503, - GATEWAY_TIMEOUT: 504, - HTTP_VERSION_NOT_SUPPORTED: 505, - VARIANT_ALSO_NEGOTIATES: 506, - INSUFFICIENT_STORAGE: 507, - LOOP_DETECTED: 508, - NETWORK_AUTHENTICATION_REQUIRED: 511 -}; -const statusToCodeMap = Object.entries(codeToStatusMap).reduce( - // reverse the key-value pairs - (acc, [key, value]) => ({ ...acc, [value]: key }), - {} -); -class ActionError extends Error { - type = "AstroActionError"; - code = "INTERNAL_SERVER_ERROR"; - status = 500; - constructor(params) { - super(params.message); - this.code = params.code; - this.status = ActionError.codeToStatus(params.code); - if (params.stack) { - this.stack = params.stack; - } - } - static codeToStatus(code) { - return codeToStatusMap[code]; - } - static statusToCode(status) { - return statusToCodeMap[status] ?? "INTERNAL_SERVER_ERROR"; - } - static fromJson(body) { - if (isInputError(body)) { - return new ActionInputError(body.issues); - } - if (isActionError(body)) { - return new ActionError(body); - } - return new ActionError({ - code: "INTERNAL_SERVER_ERROR" - }); - } -} -function isActionError(error) { - return typeof error === "object" && error != null && "type" in error && error.type === "AstroActionError"; -} -function isInputError(error) { - return typeof error === "object" && error != null && "type" in error && error.type === "AstroActionInputError" && "issues" in error && Array.isArray(error.issues); -} -class ActionInputError extends ActionError { - type = "AstroActionInputError"; - // We don't expose all ZodError properties. - // Not all properties will serialize from server to client, - // and we don't want to import the full ZodError object into the client. - issues; - fields; - constructor(issues) { - super({ - message: `Failed to validate: ${JSON.stringify(issues, null, 2)}`, - code: "BAD_REQUEST" - }); - this.issues = issues; - this.fields = {}; - for (const issue of issues) { - if (issue.path.length > 0) { - const key = issue.path[0].toString(); - this.fields[key] ??= []; - this.fields[key]?.push(issue.message); - } - } - } -} -function getActionQueryString(name) { - const searchParams = new URLSearchParams({ [ACTION_QUERY_PARAMS$1.actionName]: name }); - return `?${searchParams.toString()}`; -} -function serializeActionResult(res) { - if (res.error) { - if (Object.assign(__vite_import_meta_env__, { _: process.env._ })?.DEV) { - actionResultErrorStack.set(res.error.stack); - } - let body2; - if (res.error instanceof ActionInputError) { - body2 = { - type: res.error.type, - issues: res.error.issues, - fields: res.error.fields - }; - } else { - body2 = { - ...res.error, - message: res.error.message - }; - } - return { - type: "error", - status: res.error.status, - contentType: "application/json", - body: JSON.stringify(body2) - }; - } - if (res.data === void 0) { - return { - type: "empty", - status: 204 - }; - } - let body; - try { - body = stringify(res.data, { - // Add support for URL objects - URL: (value) => value instanceof URL && value.href - }); - } catch (e) { - let hint = ActionsReturnedInvalidDataError.hint; - if (res.data instanceof Response) { - hint = REDIRECT_STATUS_CODES.includes(res.data.status) ? "If you need to redirect when the action succeeds, trigger a redirect where the action is called. See the Actions guide for server and client redirect examples: https://docs.astro.build/en/guides/actions." : "If you need to return a Response object, try using a server endpoint instead. See https://docs.astro.build/en/guides/endpoints/#server-endpoints-api-routes"; - } - throw new AstroError({ - ...ActionsReturnedInvalidDataError, - message: ActionsReturnedInvalidDataError.message(String(e)), - hint - }); - } - return { - type: "data", - status: 200, - contentType: "application/json+devalue", - body - }; -} -function deserializeActionResult(res) { - if (res.type === "error") { - let json; - try { - json = JSON.parse(res.body); - } catch { - return { - data: void 0, - error: new ActionError({ - message: res.body, - code: "INTERNAL_SERVER_ERROR" - }) - }; - } - if (Object.assign(__vite_import_meta_env__, { _: process.env._ })?.PROD) { - return { error: ActionError.fromJson(json), data: void 0 }; - } else { - const error = ActionError.fromJson(json); - error.stack = actionResultErrorStack.get(); - return { - error, - data: void 0 - }; - } - } - if (res.type === "empty") { - return { data: void 0, error: void 0 }; - } - return { - data: parse(res.body, { - URL: (href) => new URL(href) - }), - error: void 0 - }; -} -const actionResultErrorStack = /* @__PURE__ */ (function actionResultErrorStackFn() { - let errorStack; - return { - set(stack) { - errorStack = stack; - }, - get() { - return errorStack; - } - }; -})(); - -function template({ - title, - pathname, - statusCode = 404, - tabTitle, - body -}) { - return ` - - - - ${tabTitle} - - - -
    - -

    ${statusCode ? `${statusCode}: ` : ""}${title}

    - ${body || ` -
    Path: ${escape(pathname)}
    - `} -
    - -`; -} - -const DEFAULT_404_ROUTE = { - component: DEFAULT_404_COMPONENT, - generate: () => "", - params: [], - pattern: /^\/404\/?$/, - prerender: false, - pathname: "/404", - segments: [[{ content: "404", dynamic: false, spread: false }]], - type: "page", - route: "/404", - fallbackRoutes: [], - isIndex: false, - origin: "internal" -}; -function ensure404Route(manifest) { - if (!manifest.routes.some((route) => route.route === "/404")) { - manifest.routes.push(DEFAULT_404_ROUTE); - } - return manifest; -} -async function default404Page({ pathname }) { - return new Response( - template({ - statusCode: 404, - title: "Not found", - tabTitle: "404: Not Found", - pathname - }), - { status: 404, headers: { "Content-Type": "text/html" } } - ); -} -default404Page.isAstroComponentFactory = true; -const default404Instance = { - default: default404Page -}; - -export { ActionError as A, DEFAULT_404_ROUTE as D, NOOP_MIDDLEWARE_FN as N, ACTION_RPC_ROUTE_PATTERN as a, ACTION_QUERY_PARAMS as b, default404Instance as c, deserializeActionResult as d, ensure404Route as e, getActionQueryString as g, serializeActionResult as s }; diff --git a/dist/server/chunks/astro/server_CF97kUu8.mjs b/dist/server/chunks/astro/server_CF97kUu8.mjs deleted file mode 100644 index 6104092..0000000 --- a/dist/server/chunks/astro/server_CF97kUu8.mjs +++ /dev/null @@ -1,2840 +0,0 @@ -import colors from 'piccolore'; -import { clsx } from 'clsx'; -import { escape } from 'html-escaper'; -import { decodeBase64, encodeBase64, encodeHexUpperCase, decodeHex } from '@oslojs/encoding'; -import { z } from 'zod'; -import 'cssesc'; - -const ASTRO_VERSION = "5.17.1"; -const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute"; -const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite"; -const REWRITE_DIRECTIVE_HEADER_VALUE = "yes"; -const NOOP_MIDDLEWARE_HEADER = "X-Astro-Noop"; -const ROUTE_TYPE_HEADER = "X-Astro-Route-Type"; -const DEFAULT_404_COMPONENT = "astro-default-404.astro"; -const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308, 300, 304]; -const REROUTABLE_STATUS_CODES = [404, 500]; -const clientAddressSymbol = Symbol.for("astro.clientAddress"); -const originPathnameSymbol = Symbol.for("astro.originPathname"); -const nodeRequestAbortControllerCleanupSymbol = Symbol.for( - "astro.nodeRequestAbortControllerCleanup" -); -const responseSentSymbol = Symbol.for("astro.responseSent"); - -const ClientAddressNotAvailable = { - name: "ClientAddressNotAvailable", - title: "`Astro.clientAddress` is not available in current adapter.", - message: (adapterName) => `\`Astro.clientAddress\` is not available in the \`${adapterName}\` adapter. File an issue with the adapter to add support.` -}; -const PrerenderClientAddressNotAvailable = { - name: "PrerenderClientAddressNotAvailable", - title: "`Astro.clientAddress` cannot be used inside prerendered routes.", - message: (name) => `\`Astro.clientAddress\` cannot be used inside prerendered route ${name}` -}; -const StaticClientAddressNotAvailable = { - name: "StaticClientAddressNotAvailable", - title: "`Astro.clientAddress` is not available in prerendered pages.", - message: "`Astro.clientAddress` is only available on pages that are server-rendered.", - hint: "See https://docs.astro.build/en/guides/on-demand-rendering/ for more information on how to enable SSR." -}; -const NoMatchingStaticPathFound = { - name: "NoMatchingStaticPathFound", - title: "No static path found for requested path.", - message: (pathName) => `A \`getStaticPaths()\` route pattern was matched, but no matching static path was found for requested path \`${pathName}\`.`, - hint: (possibleRoutes) => `Possible dynamic routes being matched: ${possibleRoutes.join(", ")}.` -}; -const OnlyResponseCanBeReturned = { - name: "OnlyResponseCanBeReturned", - title: "Invalid type returned by Astro page.", - message: (route, returnedValue) => `Route \`${route ? route : ""}\` returned a \`${returnedValue}\`. Only a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) can be returned from Astro files.`, - hint: "See https://docs.astro.build/en/guides/on-demand-rendering/#response for more information." -}; -const MissingMediaQueryDirective = { - name: "MissingMediaQueryDirective", - title: "Missing value for `client:media` directive.", - message: 'Media query not provided for `client:media` directive. A media query similar to `client:media="(max-width: 600px)"` must be provided' -}; -const NoMatchingRenderer = { - name: "NoMatchingRenderer", - title: "No matching renderer found.", - message: (componentName, componentExtension, plural, validRenderersCount) => `Unable to render \`${componentName}\`. - -${validRenderersCount > 0 ? `There ${plural ? "are" : "is"} ${validRenderersCount} renderer${plural ? "s" : ""} configured in your \`astro.config.mjs\` file, -but ${plural ? "none were" : "it was not"} able to server-side render \`${componentName}\`.` : `No valid renderer was found ${componentExtension ? `for the \`.${componentExtension}\` file extension.` : `for this file extension.`}`}`, - hint: (probableRenderers) => `Did you mean to enable the ${probableRenderers} integration? - -See https://docs.astro.build/en/guides/framework-components/ for more information on how to install and configure integrations.` -}; -const NoClientOnlyHint = { - name: "NoClientOnlyHint", - title: "Missing hint on client:only directive.", - message: (componentName) => `Unable to render \`${componentName}\`. When using the \`client:only\` hydration strategy, Astro needs a hint to use the correct renderer.`, - hint: (probableRenderers) => `Did you mean to pass \`client:only="${probableRenderers}"\`? See https://docs.astro.build/en/reference/directives-reference/#clientonly for more information on client:only` -}; -const InvalidGetStaticPathsEntry = { - name: "InvalidGetStaticPathsEntry", - title: "Invalid entry inside getStaticPath's return value", - message: (entryType) => `Invalid entry returned by getStaticPaths. Expected an object, got \`${entryType}\``, - hint: "If you're using a `.map` call, you might be looking for `.flatMap()` instead. See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." -}; -const InvalidGetStaticPathsReturn = { - name: "InvalidGetStaticPathsReturn", - title: "Invalid value returned by getStaticPaths.", - message: (returnType) => `Invalid type returned by \`getStaticPaths\`. Expected an \`array\`, got \`${returnType}\``, - hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." -}; -const GetStaticPathsExpectedParams = { - name: "GetStaticPathsExpectedParams", - title: "Missing params property on `getStaticPaths` route.", - message: "Missing or empty required `params` property on `getStaticPaths` route.", - hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." -}; -const GetStaticPathsInvalidRouteParam = { - name: "GetStaticPathsInvalidRouteParam", - title: "Invalid value for `getStaticPaths` route parameter.", - message: (key, value, valueType) => `Invalid getStaticPaths route parameter for \`${key}\`. Expected undefined, a string or a number, received \`${valueType}\` (\`${value}\`)`, - hint: "See https://docs.astro.build/en/reference/routing-reference/#getstaticpaths for more information on getStaticPaths." -}; -const GetStaticPathsRequired = { - name: "GetStaticPathsRequired", - title: "`getStaticPaths()` function required for dynamic routes.", - message: "`getStaticPaths()` function is required for dynamic routes. Make sure that you `export` a `getStaticPaths` function from your dynamic route.", - hint: `See https://docs.astro.build/en/guides/routing/#dynamic-routes for more information on dynamic routes. - - If you meant for this route to be server-rendered, set \`export const prerender = false;\` in the page.` -}; -const ReservedSlotName = { - name: "ReservedSlotName", - title: "Invalid slot name.", - message: (slotName) => `Unable to create a slot named \`${slotName}\`. \`${slotName}\` is a reserved slot name. Please update the name of this slot.` -}; -const NoMatchingImport = { - name: "NoMatchingImport", - title: "No import found for component.", - message: (componentName) => `Could not render \`${componentName}\`. No matching import has been found for \`${componentName}\`.`, - hint: "Please make sure the component is properly imported." -}; -const InvalidComponentArgs = { - name: "InvalidComponentArgs", - title: "Invalid component arguments.", - message: (name) => `Invalid arguments passed to${name ? ` <${name}>` : ""} component.`, - hint: "Astro components cannot be rendered directly via function call, such as `Component()` or `{items.map(Component)}`." -}; -const PageNumberParamNotFound = { - name: "PageNumberParamNotFound", - title: "Page number param not found.", - message: (paramName) => `[paginate()] page number param \`${paramName}\` not found in your filepath.`, - hint: "Rename your file to `[page].astro` or `[...page].astro`." -}; -const ImageMissingAlt = { - name: "ImageMissingAlt", - title: 'Image missing required "alt" property.', - message: 'Image missing "alt" property. "alt" text is required to describe important images on the page.', - hint: 'Use an empty string ("") for decorative images.' -}; -const InvalidImageService = { - name: "InvalidImageService", - title: "Error while loading image service.", - message: "There was an error loading the configured image service. Please see the stack trace for more information." -}; -const MissingImageDimension = { - name: "MissingImageDimension", - title: "Missing image dimensions", - message: (missingDimension, imageURL) => `Missing ${missingDimension === "both" ? "width and height attributes" : `${missingDimension} attribute`} for ${imageURL}. When using remote images, both dimensions are required in order to avoid CLS.`, - hint: "If your image is inside your `src` folder, you probably meant to import it instead. See [the Imports guide for more information](https://docs.astro.build/en/guides/imports/#other-assets). You can also use `inferSize={true}` for remote images to get the original dimensions." -}; -const FailedToFetchRemoteImageDimensions = { - name: "FailedToFetchRemoteImageDimensions", - title: "Failed to retrieve remote image dimensions", - message: (imageURL) => `Failed to get the dimensions for ${imageURL}.`, - hint: "Verify your remote image URL is accurate, and that you are not using `inferSize` with a file located in your `public/` folder." -}; -const UnsupportedImageFormat = { - name: "UnsupportedImageFormat", - title: "Unsupported image format", - message: (format, imagePath, supportedFormats) => `Received unsupported format \`${format}\` from \`${imagePath}\`. Currently only ${supportedFormats.join( - ", " - )} are supported by our image services.`, - hint: "Using an `img` tag directly instead of the `Image` component might be what you're looking for." -}; -const UnsupportedImageConversion = { - name: "UnsupportedImageConversion", - title: "Unsupported image conversion", - message: "Converting between vector (such as SVGs) and raster (such as PNGs and JPEGs) images is not currently supported." -}; -const PrerenderDynamicEndpointPathCollide = { - name: "PrerenderDynamicEndpointPathCollide", - title: "Prerendered dynamic endpoint has path collision.", - message: (pathname) => `Could not render \`${pathname}\` with an \`undefined\` param as the generated path will collide during prerendering. Prevent passing \`undefined\` as \`params\` for the endpoint's \`getStaticPaths()\` function, or add an additional extension to the endpoint's filename.`, - hint: (filename) => `Rename \`${filename}\` to \`${filename.replace(/\.(?:js|ts)/, (m) => `.json` + m)}\`` -}; -const ExpectedImage = { - name: "ExpectedImage", - title: "Expected src to be an image.", - message: (src, typeofOptions, fullOptions) => `Expected \`src\` property for \`getImage\` or \`\` to be either an ESM imported image or a string with the path of a remote image. Received \`${src}\` (type: \`${typeofOptions}\`). - -Full serialized options received: \`${fullOptions}\`.`, - hint: "This error can often happen because of a wrong path. Make sure the path to your image is correct. If you're passing an async function, make sure to call and await it." -}; -const ExpectedImageOptions = { - name: "ExpectedImageOptions", - title: "Expected image options.", - message: (options) => `Expected getImage() parameter to be an object. Received \`${options}\`.` -}; -const ExpectedNotESMImage = { - name: "ExpectedNotESMImage", - title: "Expected image options, not an ESM-imported image.", - message: "An ESM-imported image cannot be passed directly to `getImage()`. Instead, pass an object with the image in the `src` property.", - hint: "Try changing `getImage(myImage)` to `getImage({ src: myImage })`" -}; -const IncompatibleDescriptorOptions = { - name: "IncompatibleDescriptorOptions", - title: "Cannot set both `densities` and `widths`", - message: "Only one of `densities` or `widths` can be specified. In most cases, you'll probably want to use only `widths` if you require specific widths.", - hint: "Those attributes are used to construct a `srcset` attribute, which cannot have both `x` and `w` descriptors." -}; -const NoImageMetadata = { - name: "NoImageMetadata", - title: "Could not process image metadata.", - message: (imagePath) => `Could not process image metadata${imagePath ? ` for \`${imagePath}\`` : ""}.`, - hint: "This is often caused by a corrupted or malformed image. Re-exporting the image from your image editor may fix this issue." -}; -const ResponseSentError = { - name: "ResponseSentError", - title: "Unable to set response.", - message: "The response has already been sent to the browser and cannot be altered." -}; -const MiddlewareNoDataOrNextCalled = { - name: "MiddlewareNoDataOrNextCalled", - title: "The middleware didn't return a `Response`.", - message: "Make sure your middleware returns a `Response` object, either directly or by returning the `Response` from calling the `next` function." -}; -const MiddlewareNotAResponse = { - name: "MiddlewareNotAResponse", - title: "The middleware returned something that is not a `Response` object.", - message: "Any data returned from middleware must be a valid `Response` object." -}; -const EndpointDidNotReturnAResponse = { - name: "EndpointDidNotReturnAResponse", - title: "The endpoint did not return a `Response`.", - message: "An endpoint must return either a `Response`, or a `Promise` that resolves with a `Response`." -}; -const LocalsNotAnObject = { - name: "LocalsNotAnObject", - title: "Value assigned to `locals` is not accepted.", - message: "`locals` can only be assigned to an object. Other values like numbers, strings, etc. are not accepted.", - hint: "If you tried to remove some information from the `locals` object, try to use `delete` or set the property to `undefined`." -}; -const LocalsReassigned = { - name: "LocalsReassigned", - title: "`locals` must not be reassigned.", - message: "`locals` can not be assigned directly.", - hint: "Set a `locals` property instead." -}; -const AstroResponseHeadersReassigned = { - name: "AstroResponseHeadersReassigned", - title: "`Astro.response.headers` must not be reassigned.", - message: "Individual headers can be added to and removed from `Astro.response.headers`, but it must not be replaced with another instance of `Headers` altogether.", - hint: "Consider using `Astro.response.headers.add()`, and `Astro.response.headers.delete()`." -}; -const LocalImageUsedWrongly = { - name: "LocalImageUsedWrongly", - title: "Local images must be imported.", - message: (imageFilePath) => `\`Image\`'s and \`getImage\`'s \`src\` parameter must be an imported image or an URL, it cannot be a string filepath. Received \`${imageFilePath}\`.`, - hint: "If you want to use an image from your `src` folder, you need to either import it or if the image is coming from a content collection, use the [image() schema helper](https://docs.astro.build/en/guides/images/#images-in-content-collections). See https://docs.astro.build/en/guides/images/#src-required for more information on the `src` property." -}; -const AstroGlobUsedOutside = { - name: "AstroGlobUsedOutside", - title: "Astro.glob() used outside of an Astro file.", - message: (globStr) => `\`Astro.glob(${globStr})\` can only be used in \`.astro\` files. \`import.meta.glob(${globStr})\` can be used instead to achieve a similar result.`, - hint: "See Vite's documentation on `import.meta.glob` for more information: https://vite.dev/guide/features.html#glob-import" -}; -const AstroGlobNoMatch = { - name: "AstroGlobNoMatch", - title: "Astro.glob() did not match any files.", - message: (globStr) => `\`Astro.glob(${globStr})\` did not return any matching files.`, - hint: "Check the pattern for typos." -}; -const MissingSharp = { - name: "MissingSharp", - title: "Could not find Sharp.", - message: "Could not find Sharp. Please install Sharp (`sharp`) manually into your project or migrate to another image service.", - hint: "See Sharp's installation instructions for more information: https://sharp.pixelplumbing.com/install. If you are not relying on `astro:assets` to optimize, transform, or process any images, you can configure a passthrough image service instead of installing Sharp. See https://docs.astro.build/en/reference/errors/missing-sharp for more information.\n\nSee https://docs.astro.build/en/guides/images/#default-image-service for more information on how to migrate to another image service." -}; -const FailedToFindPageMapSSR = { - name: "FailedToFindPageMapSSR", - title: "Astro couldn't find the correct page to render", - message: "Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error. Please file an issue." -}; -const i18nNoLocaleFoundInPath = { - name: "i18nNoLocaleFoundInPath", - title: "The path doesn't contain any locale", - message: "You tried to use an i18n utility on a path that doesn't contain any locale. You can use `pathHasLocale` first to determine if the path has a locale." -}; -const RewriteWithBodyUsed = { - name: "RewriteWithBodyUsed", - title: "Cannot use Astro.rewrite after the request body has been read", - message: "Astro.rewrite() cannot be used if the request body has already been read. If you need to read the body, first clone the request." -}; -const ForbiddenRewrite = { - name: "ForbiddenRewrite", - title: "Forbidden rewrite to a static route.", - message: (from, to, component) => `You tried to rewrite the on-demand route '${from}' with the static route '${to}', when using the 'server' output. - -The static route '${to}' is rendered by the component -'${component}', which is marked as prerendered. This is a forbidden operation because during the build the component '${component}' is compiled to an -HTML file, which can't be retrieved at runtime by Astro.`, - hint: (component) => `Add \`export const prerender = false\` to the component '${component}', or use a Astro.redirect().` -}; -const ExperimentalFontsNotEnabled = { - name: "ExperimentalFontsNotEnabled", - title: "Experimental fonts are not enabled", - message: "The Font component is used but experimental fonts have not been registered in the config.", - hint: "Check that you have enabled experimental fonts and also configured your preferred fonts." -}; -const FontFamilyNotFound = { - name: "FontFamilyNotFound", - title: "Font family not found", - message: (family) => `No data was found for the \`"${family}"\` family passed to the \`\` component.`, - hint: "This is often caused by a typo. Check that the `` component is using a `cssVariable` specified in your config." -}; -const CspNotEnabled = { - name: "CspNotEnabled", - title: "CSP feature isn't enabled", - message: "The `experimental.csp` configuration isn't enabled." -}; -const ActionsReturnedInvalidDataError = { - name: "ActionsReturnedInvalidDataError", - title: "Action handler returned invalid data.", - message: (error) => `Action handler returned invalid data. Handlers should return serializable data types like objects, arrays, strings, and numbers. Parse error: ${error}`, - hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue" -}; -const ActionNotFoundError = { - name: "ActionNotFoundError", - title: "Action not found.", - message: (actionName) => `The server received a request for an action named \`${actionName}\` but could not find a match. If you renamed an action, check that you've updated your \`actions/index\` file and your calling code to match.`, - hint: "You can run `astro check` to detect type errors caused by mismatched action names." -}; -const SessionStorageInitError = { - name: "SessionStorageInitError", - title: "Session storage could not be initialized.", - message: (error, driver) => `Error when initializing session storage${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``, - hint: "For more information, see https://docs.astro.build/en/guides/sessions/" -}; -const SessionStorageSaveError = { - name: "SessionStorageSaveError", - title: "Session data could not be saved.", - message: (error, driver) => `Error when saving session data${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``, - hint: "For more information, see https://docs.astro.build/en/guides/sessions/" -}; - -function normalizeLF(code) { - return code.replace(/\r\n|\r(?!\n)|\n/g, "\n"); -} - -function codeFrame(src, loc) { - if (!loc || loc.line === void 0 || loc.column === void 0) { - return ""; - } - const lines = normalizeLF(src).split("\n").map((ln) => ln.replace(/\t/g, " ")); - const visibleLines = []; - for (let n = -2; n <= 2; n++) { - if (lines[loc.line + n]) visibleLines.push(loc.line + n); - } - let gutterWidth = 0; - for (const lineNo of visibleLines) { - let w = `> ${lineNo}`; - if (w.length > gutterWidth) gutterWidth = w.length; - } - let output = ""; - for (const lineNo of visibleLines) { - const isFocusedLine = lineNo === loc.line - 1; - output += isFocusedLine ? "> " : " "; - output += `${lineNo + 1} | ${lines[lineNo]} -`; - if (isFocusedLine) - output += `${Array.from({ length: gutterWidth }).join(" ")} | ${Array.from({ - length: loc.column - }).join(" ")}^ -`; - } - return output; -} - -class AstroError extends Error { - loc; - title; - hint; - frame; - type = "AstroError"; - constructor(props, options) { - const { name, title, message, stack, location, hint, frame } = props; - super(message, options); - this.title = title; - this.name = name; - if (message) this.message = message; - this.stack = stack ? stack : this.stack; - this.loc = location; - this.hint = hint; - this.frame = frame; - } - setLocation(location) { - this.loc = location; - } - setName(name) { - this.name = name; - } - setMessage(message) { - this.message = message; - } - setHint(hint) { - this.hint = hint; - } - setFrame(source, location) { - this.frame = codeFrame(source, location); - } - static is(err) { - return err?.type === "AstroError"; - } -} - -function validateArgs(args) { - if (args.length !== 3) return false; - if (!args[0] || typeof args[0] !== "object") return false; - return true; -} -function baseCreateComponent(cb, moduleId, propagation) { - const name = moduleId?.split("/").pop()?.replace(".astro", "") ?? ""; - const fn = (...args) => { - if (!validateArgs(args)) { - throw new AstroError({ - ...InvalidComponentArgs, - message: InvalidComponentArgs.message(name) - }); - } - return cb(...args); - }; - Object.defineProperty(fn, "name", { value: name, writable: false }); - fn.isAstroComponentFactory = true; - fn.moduleId = moduleId; - fn.propagation = propagation; - return fn; -} -function createComponentWithOptions(opts) { - const cb = baseCreateComponent(opts.factory, opts.moduleId, opts.propagation); - return cb; -} -function createComponent(arg1, moduleId, propagation) { - if (typeof arg1 === "function") { - return baseCreateComponent(arg1, moduleId, propagation); - } else { - return createComponentWithOptions(arg1); - } -} - -function createAstroGlobFn() { - const globHandler = (importMetaGlobResult) => { - console.warn(`Astro.glob is deprecated and will be removed in a future major version of Astro. -Use import.meta.glob instead: https://vitejs.dev/guide/features.html#glob-import`); - if (typeof importMetaGlobResult === "string") { - throw new AstroError({ - ...AstroGlobUsedOutside, - message: AstroGlobUsedOutside.message(JSON.stringify(importMetaGlobResult)) - }); - } - let allEntries = [...Object.values(importMetaGlobResult)]; - if (allEntries.length === 0) { - throw new AstroError({ - ...AstroGlobNoMatch, - message: AstroGlobNoMatch.message(JSON.stringify(importMetaGlobResult)) - }); - } - return Promise.all(allEntries.map((fn) => fn())); - }; - return globHandler; -} -function createAstro(site) { - return { - site: new URL(site) , - generator: `Astro v${ASTRO_VERSION}`, - glob: createAstroGlobFn() - }; -} - -async function renderEndpoint(mod, context, isPrerendered, logger) { - const { request, url } = context; - const method = request.method.toUpperCase(); - let handler = mod[method] ?? mod["ALL"]; - if (!handler && method === "HEAD" && mod["GET"]) { - handler = mod["GET"]; - } - if (isPrerendered && !["GET", "HEAD"].includes(method)) { - logger.warn( - "router", - `${url.pathname} ${colors.bold( - method - )} requests are not available in static endpoints. Mark this page as server-rendered (\`export const prerender = false;\`) or update your config to \`output: 'server'\` to make all your pages server-rendered by default.` - ); - } - if (handler === void 0) { - logger.warn( - "router", - `No API Route handler exists for the method "${method}" for the route "${url.pathname}". -Found handlers: ${Object.keys(mod).map((exp) => JSON.stringify(exp)).join(", ")} -` + ("all" in mod ? `One of the exported handlers is "all" (lowercase), did you mean to export 'ALL'? -` : "") - ); - return new Response(null, { status: 404 }); - } - if (typeof handler !== "function") { - logger.error( - "router", - `The route "${url.pathname}" exports a value for the method "${method}", but it is of the type ${typeof handler} instead of a function.` - ); - return new Response(null, { status: 500 }); - } - let response = await handler.call(mod, context); - if (!response || response instanceof Response === false) { - throw new AstroError(EndpointDidNotReturnAResponse); - } - if (REROUTABLE_STATUS_CODES.includes(response.status)) { - try { - response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); - } catch (err) { - if (err.message?.includes("immutable")) { - response = new Response(response.body, response); - response.headers.set(REROUTE_DIRECTIVE_HEADER, "no"); - } else { - throw err; - } - } - } - if (method === "HEAD") { - return new Response(null, response); - } - return response; -} - -function isPromise(value) { - return !!value && typeof value === "object" && "then" in value && typeof value.then === "function"; -} -async function* streamAsyncIterator(stream) { - const reader = stream.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - if (done) return; - yield value; - } - } finally { - reader.releaseLock(); - } -} - -const escapeHTML = escape; -class HTMLBytes extends Uint8Array { -} -Object.defineProperty(HTMLBytes.prototype, Symbol.toStringTag, { - get() { - return "HTMLBytes"; - } -}); -class HTMLString extends String { - get [Symbol.toStringTag]() { - return "HTMLString"; - } -} -const markHTMLString = (value) => { - if (value instanceof HTMLString) { - return value; - } - if (typeof value === "string") { - return new HTMLString(value); - } - return value; -}; -function isHTMLString(value) { - return Object.prototype.toString.call(value) === "[object HTMLString]"; -} -function markHTMLBytes(bytes) { - return new HTMLBytes(bytes); -} -function hasGetReader(obj) { - return typeof obj.getReader === "function"; -} -async function* unescapeChunksAsync(iterable) { - if (hasGetReader(iterable)) { - for await (const chunk of streamAsyncIterator(iterable)) { - yield unescapeHTML(chunk); - } - } else { - for await (const chunk of iterable) { - yield unescapeHTML(chunk); - } - } -} -function* unescapeChunks(iterable) { - for (const chunk of iterable) { - yield unescapeHTML(chunk); - } -} -function unescapeHTML(str) { - if (!!str && typeof str === "object") { - if (str instanceof Uint8Array) { - return markHTMLBytes(str); - } else if (str instanceof Response && str.body) { - const body = str.body; - return unescapeChunksAsync(body); - } else if (typeof str.then === "function") { - return Promise.resolve(str).then((value) => { - return unescapeHTML(value); - }); - } else if (str[Symbol.for("astro:slot-string")]) { - return str; - } else if (Symbol.iterator in str) { - return unescapeChunks(str); - } else if (Symbol.asyncIterator in str || hasGetReader(str)) { - return unescapeChunksAsync(str); - } - } - return markHTMLString(str); -} - -const AstroJSX = "astro:jsx"; -function isVNode(vnode) { - return vnode && typeof vnode === "object" && vnode[AstroJSX]; -} - -function isAstroComponentFactory(obj) { - return obj == null ? false : obj.isAstroComponentFactory === true; -} -function isAPropagatingComponent(result, factory) { - const hint = getPropagationHint(result, factory); - return hint === "in-tree" || hint === "self"; -} -function getPropagationHint(result, factory) { - let hint = factory.propagation || "none"; - if (factory.moduleId && result.componentMetadata.has(factory.moduleId) && hint === "none") { - hint = result.componentMetadata.get(factory.moduleId).propagation; - } - return hint; -} - -const PROP_TYPE = { - Value: 0, - JSON: 1, - // Actually means Array - RegExp: 2, - Date: 3, - Map: 4, - Set: 5, - BigInt: 6, - URL: 7, - Uint8Array: 8, - Uint16Array: 9, - Uint32Array: 10, - Infinity: 11 -}; -function serializeArray(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { - if (parents.has(value)) { - throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>! - -Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`); - } - parents.add(value); - const serialized = value.map((v) => { - return convertToSerializedForm(v, metadata, parents); - }); - parents.delete(value); - return serialized; -} -function serializeObject(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { - if (parents.has(value)) { - throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>! - -Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`); - } - parents.add(value); - const serialized = Object.fromEntries( - Object.entries(value).map(([k, v]) => { - return [k, convertToSerializedForm(v, metadata, parents)]; - }) - ); - parents.delete(value); - return serialized; -} -function convertToSerializedForm(value, metadata = {}, parents = /* @__PURE__ */ new WeakSet()) { - const tag = Object.prototype.toString.call(value); - switch (tag) { - case "[object Date]": { - return [PROP_TYPE.Date, value.toISOString()]; - } - case "[object RegExp]": { - return [PROP_TYPE.RegExp, value.source]; - } - case "[object Map]": { - return [PROP_TYPE.Map, serializeArray(Array.from(value), metadata, parents)]; - } - case "[object Set]": { - return [PROP_TYPE.Set, serializeArray(Array.from(value), metadata, parents)]; - } - case "[object BigInt]": { - return [PROP_TYPE.BigInt, value.toString()]; - } - case "[object URL]": { - return [PROP_TYPE.URL, value.toString()]; - } - case "[object Array]": { - return [PROP_TYPE.JSON, serializeArray(value, metadata, parents)]; - } - case "[object Uint8Array]": { - return [PROP_TYPE.Uint8Array, Array.from(value)]; - } - case "[object Uint16Array]": { - return [PROP_TYPE.Uint16Array, Array.from(value)]; - } - case "[object Uint32Array]": { - return [PROP_TYPE.Uint32Array, Array.from(value)]; - } - default: { - if (value !== null && typeof value === "object") { - return [PROP_TYPE.Value, serializeObject(value, metadata, parents)]; - } - if (value === Infinity) { - return [PROP_TYPE.Infinity, 1]; - } - if (value === -Infinity) { - return [PROP_TYPE.Infinity, -1]; - } - if (value === void 0) { - return [PROP_TYPE.Value]; - } - return [PROP_TYPE.Value, value]; - } - } -} -function serializeProps(props, metadata) { - const serialized = JSON.stringify(serializeObject(props, metadata)); - return serialized; -} - -const transitionDirectivesToCopyOnIsland = Object.freeze([ - "data-astro-transition-scope", - "data-astro-transition-persist", - "data-astro-transition-persist-props" -]); -function extractDirectives(inputProps, clientDirectives) { - let extracted = { - isPage: false, - hydration: null, - props: {}, - propsWithoutTransitionAttributes: {} - }; - for (const [key, value] of Object.entries(inputProps)) { - if (key.startsWith("server:")) { - if (key === "server:root") { - extracted.isPage = true; - } - } - if (key.startsWith("client:")) { - if (!extracted.hydration) { - extracted.hydration = { - directive: "", - value: "", - componentUrl: "", - componentExport: { value: "" } - }; - } - switch (key) { - case "client:component-path": { - extracted.hydration.componentUrl = value; - break; - } - case "client:component-export": { - extracted.hydration.componentExport.value = value; - break; - } - // This is a special prop added to prove that the client hydration method - // was added statically. - case "client:component-hydration": { - break; - } - case "client:display-name": { - break; - } - default: { - extracted.hydration.directive = key.split(":")[1]; - extracted.hydration.value = value; - if (!clientDirectives.has(extracted.hydration.directive)) { - const hydrationMethods = Array.from(clientDirectives.keys()).map((d) => `client:${d}`).join(", "); - throw new Error( - `Error: invalid hydration directive "${key}". Supported hydration methods: ${hydrationMethods}` - ); - } - if (extracted.hydration.directive === "media" && typeof extracted.hydration.value !== "string") { - throw new AstroError(MissingMediaQueryDirective); - } - break; - } - } - } else { - extracted.props[key] = value; - if (!transitionDirectivesToCopyOnIsland.includes(key)) { - extracted.propsWithoutTransitionAttributes[key] = value; - } - } - } - for (const sym of Object.getOwnPropertySymbols(inputProps)) { - extracted.props[sym] = inputProps[sym]; - extracted.propsWithoutTransitionAttributes[sym] = inputProps[sym]; - } - return extracted; -} -async function generateHydrateScript(scriptOptions, metadata) { - const { renderer, result, astroId, props, attrs } = scriptOptions; - const { hydrate, componentUrl, componentExport } = metadata; - if (!componentExport.value) { - throw new AstroError({ - ...NoMatchingImport, - message: NoMatchingImport.message(metadata.displayName) - }); - } - const island = { - children: "", - props: { - // This is for HMR, probably can avoid it in prod - uid: astroId - } - }; - if (attrs) { - for (const [key, value] of Object.entries(attrs)) { - island.props[key] = escapeHTML(value); - } - } - island.props["component-url"] = await result.resolve(decodeURI(componentUrl)); - if (renderer.clientEntrypoint) { - island.props["component-export"] = componentExport.value; - island.props["renderer-url"] = await result.resolve( - decodeURI(renderer.clientEntrypoint.toString()) - ); - island.props["props"] = escapeHTML(serializeProps(props, metadata)); - } - island.props["ssr"] = ""; - island.props["client"] = hydrate; - let beforeHydrationUrl = await result.resolve("astro:scripts/before-hydration.js"); - if (beforeHydrationUrl.length) { - island.props["before-hydration-url"] = beforeHydrationUrl; - } - island.props["opts"] = escapeHTML( - JSON.stringify({ - name: metadata.displayName, - value: metadata.hydrateArgs || "" - }) - ); - transitionDirectivesToCopyOnIsland.forEach((name) => { - if (typeof props[name] !== "undefined") { - island.props[name] = props[name]; - } - }); - return island; -} - -/** - * shortdash - https://github.com/bibig/node-shorthash - * - * @license - * - * (The MIT License) - * - * Copyright (c) 2013 Bibig - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -const dictionary = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"; -const binary = dictionary.length; -function bitwise(str) { - let hash = 0; - if (str.length === 0) return hash; - for (let i = 0; i < str.length; i++) { - const ch = str.charCodeAt(i); - hash = (hash << 5) - hash + ch; - hash = hash & hash; - } - return hash; -} -function shorthash(text) { - let num; - let result = ""; - let integer = bitwise(text); - const sign = integer < 0 ? "Z" : ""; - integer = Math.abs(integer); - while (integer >= binary) { - num = integer % binary; - integer = Math.floor(integer / binary); - result = dictionary[num] + result; - } - if (integer > 0) { - result = dictionary[integer] + result; - } - return sign + result; -} - -const headAndContentSym = Symbol.for("astro.headAndContent"); -function isHeadAndContent(obj) { - return typeof obj === "object" && obj !== null && !!obj[headAndContentSym]; -} -function createThinHead() { - return { - [headAndContentSym]: true - }; -} - -var astro_island_prebuilt_default = `(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[l,e]=t;return l in i?i[l](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([l,e])=>[l,o(e)]));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template[data-astro-template]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"",v=this.getAttribute("component-export");throw v&&(s+=\` (export \${v})\`),console.error(\`[hydrate] Error parsing props for component \${s}\`,this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(\`astro:\${c}\`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h[u];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component[f]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",y)}})();`; - -var astro_island_prebuilt_dev_default = `(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var l=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>y(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[h,e]=t;return h in i?i[h](e):void 0},a=t=>t.map(o),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([h,e])=>[h,o(e)]));class f extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},p=this.querySelectorAll("template[data-astro-template]");for(let r of p){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let u;try{u=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"",v=this.getAttribute("component-export");throw v&&(s+=\` (export \${v})\`),console.error(\`[hydrate] Error parsing props for component \${s}\`,this.getAttribute("props"),r),r}let d,m=this.hydrator(this);d=performance.now(),await m(this.Component,u,n,{client:this.getAttribute("client")}),d&&this.setAttribute("client-render-time",(performance.now()-d).toString()),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(\`astro:\${c}\`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[p,{default:u}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),d=this.getAttribute("component-export")||"default";if(!d.includes("."))this.Component=p[d];else{this.Component=p;for(let m of d.split("."))this.Component=this.Component[m]}return this.hydrator=u,this.hydrate},e,this)}catch(n){console.error(\`[astro-island] Error hydrating \${this.getAttribute("component-url")}\`,n)}}attributeChangedCallback(){this.hydrate()}}l(f,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",f)}})();`; - -const ISLAND_STYLES = "astro-island,astro-slot,astro-static-slot{display:contents}"; - -function determineIfNeedsHydrationScript(result) { - if (result._metadata.hasHydrationScript) { - return false; - } - return result._metadata.hasHydrationScript = true; -} -function determinesIfNeedsDirectiveScript(result, directive) { - if (result._metadata.hasDirectives.has(directive)) { - return false; - } - result._metadata.hasDirectives.add(directive); - return true; -} -function getDirectiveScriptText(result, directive) { - const clientDirectives = result.clientDirectives; - const clientDirective = clientDirectives.get(directive); - if (!clientDirective) { - throw new Error(`Unknown directive: ${directive}`); - } - return clientDirective; -} -function getPrescripts(result, type, directive) { - switch (type) { - case "both": - return ``; - case "directive": - return ``; - } -} - -function renderCspContent(result) { - const finalScriptHashes = /* @__PURE__ */ new Set(); - const finalStyleHashes = /* @__PURE__ */ new Set(); - for (const scriptHash of result.scriptHashes) { - finalScriptHashes.add(`'${scriptHash}'`); - } - for (const styleHash of result.styleHashes) { - finalStyleHashes.add(`'${styleHash}'`); - } - for (const styleHash of result._metadata.extraStyleHashes) { - finalStyleHashes.add(`'${styleHash}'`); - } - for (const scriptHash of result._metadata.extraScriptHashes) { - finalScriptHashes.add(`'${scriptHash}'`); - } - let directives; - if (result.directives.length > 0) { - directives = result.directives.join(";") + ";"; - } - let scriptResources = "'self'"; - if (result.scriptResources.length > 0) { - scriptResources = result.scriptResources.map((r) => `${r}`).join(" "); - } - let styleResources = "'self'"; - if (result.styleResources.length > 0) { - styleResources = result.styleResources.map((r) => `${r}`).join(" "); - } - const strictDynamic = result.isStrictDynamic ? ` 'strict-dynamic'` : ""; - const scriptSrc = `script-src ${scriptResources} ${Array.from(finalScriptHashes).join(" ")}${strictDynamic};`; - const styleSrc = `style-src ${styleResources} ${Array.from(finalStyleHashes).join(" ")};`; - return [directives, scriptSrc, styleSrc].filter(Boolean).join(" "); -} - -const RenderInstructionSymbol = Symbol.for("astro:render"); -function createRenderInstruction(instruction) { - return Object.defineProperty(instruction, RenderInstructionSymbol, { - value: true - }); -} -function isRenderInstruction(chunk) { - return chunk && typeof chunk === "object" && chunk[RenderInstructionSymbol]; -} - -const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i; -const htmlBooleanAttributes = /^(?:allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|inert|loop|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|selected|itemscope)$/i; -const AMPERSAND_REGEX = /&/g; -const DOUBLE_QUOTE_REGEX = /"/g; -const STATIC_DIRECTIVES = /* @__PURE__ */ new Set(["set:html", "set:text"]); -const toIdent = (k) => k.trim().replace(/(?!^)\b\w|\s+|\W+/g, (match, index) => { - if (/\W/.test(match)) return ""; - return index === 0 ? match : match.toUpperCase(); -}); -const toAttributeString = (value, shouldEscape = true) => shouldEscape ? String(value).replace(AMPERSAND_REGEX, "&").replace(DOUBLE_QUOTE_REGEX, """) : value; -const kebab = (k) => k.toLowerCase() === k ? k : k.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`); -const toStyleString = (obj) => Object.entries(obj).filter(([_, v]) => typeof v === "string" && v.trim() || typeof v === "number").map(([k, v]) => { - if (k[0] !== "-" && k[1] !== "-") return `${kebab(k)}:${v}`; - return `${k}:${v}`; -}).join(";"); -function defineScriptVars(vars) { - let output = ""; - for (const [key, value] of Object.entries(vars)) { - output += `const ${toIdent(key)} = ${JSON.stringify(value)?.replace( - /<\/script>/g, - "\\x3C/script>" - )}; -`; - } - return markHTMLString(output); -} -function formatList(values) { - if (values.length === 1) { - return values[0]; - } - return `${values.slice(0, -1).join(", ")} or ${values[values.length - 1]}`; -} -function isCustomElement(tagName) { - return tagName.includes("-"); -} -function handleBooleanAttribute(key, value, shouldEscape, tagName) { - if (tagName && isCustomElement(tagName)) { - return markHTMLString(` ${key}="${toAttributeString(value, shouldEscape)}"`); - } - return markHTMLString(value ? ` ${key}` : ""); -} -function addAttribute(value, key, shouldEscape = true, tagName = "") { - if (value == null) { - return ""; - } - if (STATIC_DIRECTIVES.has(key)) { - console.warn(`[astro] The "${key}" directive cannot be applied dynamically at runtime. It will not be rendered as an attribute. - -Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the dynamic spread syntax (\`{...{ "${key}": value }}\`).`); - return ""; - } - if (key === "class:list") { - const listValue = toAttributeString(clsx(value), shouldEscape); - if (listValue === "") { - return ""; - } - return markHTMLString(` ${key.slice(0, -5)}="${listValue}"`); - } - if (key === "style" && !(value instanceof HTMLString)) { - if (Array.isArray(value) && value.length === 2) { - return markHTMLString( - ` ${key}="${toAttributeString(`${toStyleString(value[0])};${value[1]}`, shouldEscape)}"` - ); - } - if (typeof value === "object") { - return markHTMLString(` ${key}="${toAttributeString(toStyleString(value), shouldEscape)}"`); - } - } - if (key === "className") { - return markHTMLString(` class="${toAttributeString(value, shouldEscape)}"`); - } - if (typeof value === "string" && value.includes("&") && isHttpUrl(value)) { - return markHTMLString(` ${key}="${toAttributeString(value, false)}"`); - } - if (htmlBooleanAttributes.test(key)) { - return handleBooleanAttribute(key, value, shouldEscape, tagName); - } - if (value === "") { - return markHTMLString(` ${key}`); - } - if (key === "popover" && typeof value === "boolean") { - return handleBooleanAttribute(key, value, shouldEscape, tagName); - } - if (key === "download" && typeof value === "boolean") { - return handleBooleanAttribute(key, value, shouldEscape, tagName); - } - return markHTMLString(` ${key}="${toAttributeString(value, shouldEscape)}"`); -} -function internalSpreadAttributes(values, shouldEscape = true, tagName) { - let output = ""; - for (const [key, value] of Object.entries(values)) { - output += addAttribute(value, key, shouldEscape, tagName); - } - return markHTMLString(output); -} -function renderElement$1(name, { props: _props, children = "" }, shouldEscape = true) { - const { lang: _, "data-astro-id": astroId, "define:vars": defineVars, ...props } = _props; - if (defineVars) { - if (name === "style") { - delete props["is:global"]; - delete props["is:scoped"]; - } - if (name === "script") { - delete props.hoist; - children = defineScriptVars(defineVars) + "\n" + children; - } - } - if ((children == null || children == "") && voidElementNames.test(name)) { - return `<${name}${internalSpreadAttributes(props, shouldEscape, name)}>`; - } - return `<${name}${internalSpreadAttributes(props, shouldEscape, name)}>${children}`; -} -const noop = () => { -}; -class BufferedRenderer { - chunks = []; - renderPromise; - destination; - /** - * Determines whether buffer has been flushed - * to the final destination. - */ - flushed = false; - constructor(destination, renderFunction) { - this.destination = destination; - this.renderPromise = renderFunction(this); - if (isPromise(this.renderPromise)) { - Promise.resolve(this.renderPromise).catch(noop); - } - } - write(chunk) { - if (this.flushed) { - this.destination.write(chunk); - } else { - this.chunks.push(chunk); - } - } - flush() { - if (this.flushed) { - throw new Error("The render buffer has already been flushed."); - } - this.flushed = true; - for (const chunk of this.chunks) { - this.destination.write(chunk); - } - return this.renderPromise; - } -} -function createBufferedRenderer(destination, renderFunction) { - return new BufferedRenderer(destination, renderFunction); -} -const isNode = typeof process !== "undefined" && Object.prototype.toString.call(process) === "[object process]"; -const isDeno = typeof Deno !== "undefined"; -function promiseWithResolvers() { - let resolve, reject; - const promise = new Promise((_resolve, _reject) => { - resolve = _resolve; - reject = _reject; - }); - return { - promise, - resolve, - reject - }; -} -const VALID_PROTOCOLS = ["http:", "https:"]; -function isHttpUrl(url) { - try { - const parsedUrl = new URL(url); - return VALID_PROTOCOLS.includes(parsedUrl.protocol); - } catch { - return false; - } -} - -const uniqueElements = (item, index, all) => { - const props = JSON.stringify(item.props); - const children = item.children; - return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children); -}; -function renderAllHeadContent(result) { - result._metadata.hasRenderedHead = true; - let content = ""; - if (result.shouldInjectCspMetaTags && result.cspDestination === "meta") { - content += renderElement$1( - "meta", - { - props: { - "http-equiv": "content-security-policy", - content: renderCspContent(result) - }, - children: "" - }, - false - ); - } - const styles = Array.from(result.styles).filter(uniqueElements).map( - (style) => style.props.rel === "stylesheet" ? renderElement$1("link", style) : renderElement$1("style", style) - ); - result.styles.clear(); - const scripts = Array.from(result.scripts).filter(uniqueElements).map((script) => { - if (result.userAssetsBase) { - script.props.src = (result.base === "/" ? "" : result.base) + result.userAssetsBase + script.props.src; - } - return renderElement$1("script", script, false); - }); - const links = Array.from(result.links).filter(uniqueElements).map((link) => renderElement$1("link", link, false)); - content += styles.join("\n") + links.join("\n") + scripts.join("\n"); - if (result._metadata.extraHead.length > 0) { - for (const part of result._metadata.extraHead) { - content += part; - } - } - return markHTMLString(content); -} -function renderHead() { - return createRenderInstruction({ type: "head" }); -} -function maybeRenderHead() { - return createRenderInstruction({ type: "maybe-head" }); -} - -const ALGORITHMS = { - "SHA-256": "sha256-", - "SHA-384": "sha384-", - "SHA-512": "sha512-" -}; -const ALGORITHM_VALUES = Object.values(ALGORITHMS); -z.enum(Object.keys(ALGORITHMS)).optional().default("SHA-256"); -z.custom((value) => { - if (typeof value !== "string") { - return false; - } - return ALGORITHM_VALUES.some((allowedValue) => { - return value.startsWith(allowedValue); - }); -}); -const ALLOWED_DIRECTIVES = [ - "base-uri", - "child-src", - "connect-src", - "default-src", - "fenced-frame-src", - "font-src", - "form-action", - "frame-ancestors", - "frame-src", - "img-src", - "manifest-src", - "media-src", - "object-src", - "referrer", - "report-to", - "report-uri", - "require-trusted-types-for", - "sandbox", - "trusted-types", - "upgrade-insecure-requests", - "worker-src" -]; -z.custom((value) => { - if (typeof value !== "string") { - return false; - } - return ALLOWED_DIRECTIVES.some((allowedValue) => { - return value.startsWith(allowedValue); - }); -}); - -const ALGORITHM = "AES-GCM"; -async function decodeKey(encoded) { - const bytes = decodeBase64(encoded); - return crypto.subtle.importKey("raw", bytes.buffer, ALGORITHM, true, [ - "encrypt", - "decrypt" - ]); -} -const encoder$1 = new TextEncoder(); -const decoder$1 = new TextDecoder(); -const IV_LENGTH = 24; -async function encryptString(key, raw) { - const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH / 2)); - const data = encoder$1.encode(raw); - const buffer = await crypto.subtle.encrypt( - { - name: ALGORITHM, - iv - }, - key, - data - ); - return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer)); -} -async function decryptString(key, encoded) { - const iv = decodeHex(encoded.slice(0, IV_LENGTH)); - const dataArray = decodeBase64(encoded.slice(IV_LENGTH)); - const decryptedBuffer = await crypto.subtle.decrypt( - { - name: ALGORITHM, - iv - }, - key, - dataArray - ); - const decryptedString = decoder$1.decode(decryptedBuffer); - return decryptedString; -} -async function generateCspDigest(data, algorithm) { - const hashBuffer = await crypto.subtle.digest(algorithm, encoder$1.encode(data)); - const hash = encodeBase64(new Uint8Array(hashBuffer)); - return `${ALGORITHMS[algorithm]}${hash}`; -} - -const renderTemplateResultSym = Symbol.for("astro.renderTemplateResult"); -class RenderTemplateResult { - [renderTemplateResultSym] = true; - htmlParts; - expressions; - error; - constructor(htmlParts, expressions) { - this.htmlParts = htmlParts; - this.error = void 0; - this.expressions = expressions.map((expression) => { - if (isPromise(expression)) { - return Promise.resolve(expression).catch((err) => { - if (!this.error) { - this.error = err; - throw err; - } - }); - } - return expression; - }); - } - render(destination) { - const flushers = this.expressions.map((exp) => { - return createBufferedRenderer(destination, (bufferDestination) => { - if (exp || exp === 0) { - return renderChild(bufferDestination, exp); - } - }); - }); - let i = 0; - const iterate = () => { - while (i < this.htmlParts.length) { - const html = this.htmlParts[i]; - const flusher = flushers[i]; - i++; - if (html) { - destination.write(markHTMLString(html)); - } - if (flusher) { - const result = flusher.flush(); - if (isPromise(result)) { - return result.then(iterate); - } - } - } - }; - return iterate(); - } -} -function isRenderTemplateResult(obj) { - return typeof obj === "object" && obj !== null && !!obj[renderTemplateResultSym]; -} -function renderTemplate(htmlParts, ...expressions) { - return new RenderTemplateResult(htmlParts, expressions); -} - -const slotString = Symbol.for("astro:slot-string"); -class SlotString extends HTMLString { - instructions; - [slotString]; - constructor(content, instructions) { - super(content); - this.instructions = instructions; - this[slotString] = true; - } -} -function isSlotString(str) { - return !!str[slotString]; -} -function mergeSlotInstructions(target, source) { - if (source.instructions?.length) { - target ??= []; - target.push(...source.instructions); - } - return target; -} -function renderSlot(result, slotted, fallback) { - if (!slotted && fallback) { - return renderSlot(result, fallback); - } - return { - async render(destination) { - await renderChild(destination, typeof slotted === "function" ? slotted(result) : slotted); - } - }; -} -async function renderSlotToString(result, slotted, fallback) { - let content = ""; - let instructions = null; - const temporaryDestination = { - write(chunk) { - if (chunk instanceof SlotString) { - content += chunk; - instructions = mergeSlotInstructions(instructions, chunk); - } else if (chunk instanceof Response) return; - else if (typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string") { - if (instructions === null) { - instructions = []; - } - instructions.push(chunk); - } else { - content += chunkToString(result, chunk); - } - } - }; - const renderInstance = renderSlot(result, slotted, fallback); - await renderInstance.render(temporaryDestination); - return markHTMLString(new SlotString(content, instructions)); -} -async function renderSlots(result, slots = {}) { - let slotInstructions = null; - let children = {}; - if (slots) { - await Promise.all( - Object.entries(slots).map( - ([key, value]) => renderSlotToString(result, value).then((output) => { - if (output.instructions) { - if (slotInstructions === null) { - slotInstructions = []; - } - slotInstructions.push(...output.instructions); - } - children[key] = output; - }) - ) - ); - } - return { slotInstructions, children }; -} -function createSlotValueFromString(content) { - return function() { - return renderTemplate`${unescapeHTML(content)}`; - }; -} - -const internalProps = /* @__PURE__ */ new Set([ - "server:component-path", - "server:component-export", - "server:component-directive", - "server:defer" -]); -function containsServerDirective(props) { - return "server:component-directive" in props; -} -const SCRIPT_RE = /<\/script/giu; -const COMMENT_RE = /"); - for (const name in this.slots) { - if (name === "fallback") { - await renderChild(destination, this.slots.fallback(this.result)); - } - } - destination.write( - `` - ); - } - getComponentPath() { - if (this.componentPath) { - return this.componentPath; - } - const componentPath = this.props["server:component-path"]; - if (!componentPath) { - throw new Error(`Could not find server component path`); - } - this.componentPath = componentPath; - return componentPath; - } - getComponentExport() { - if (this.componentExport) { - return this.componentExport; - } - const componentExport = this.props["server:component-export"]; - if (!componentExport) { - throw new Error(`Could not find server component export`); - } - this.componentExport = componentExport; - return componentExport; - } - async getHostId() { - if (!this.hostId) { - this.hostId = await crypto.randomUUID(); - } - return this.hostId; - } - async getIslandContent() { - if (this.islandContent) { - return this.islandContent; - } - const componentPath = this.getComponentPath(); - const componentExport = this.getComponentExport(); - const componentId = this.result.serverIslandNameMap.get(componentPath); - if (!componentId) { - throw new Error(`Could not find server component name`); - } - for (const key2 of Object.keys(this.props)) { - if (internalProps.has(key2)) { - delete this.props[key2]; - } - } - const renderedSlots = {}; - for (const name in this.slots) { - if (name !== "fallback") { - const content = await renderSlotToString(this.result, this.slots[name]); - renderedSlots[name] = content.toString(); - } - } - const key = await this.result.key; - const componentExportEncrypted = await encryptString(key, componentExport); - const propsEncrypted = Object.keys(this.props).length === 0 ? "" : await encryptString(key, JSON.stringify(this.props)); - const slotsEncrypted = Object.keys(renderedSlots).length === 0 ? "" : await encryptString(key, JSON.stringify(renderedSlots)); - const hostId = await this.getHostId(); - const slash = this.result.base.endsWith("/") ? "" : "/"; - let serverIslandUrl = `${this.result.base}${slash}_server-islands/${componentId}${this.result.trailingSlash === "always" ? "/" : ""}`; - const potentialSearchParams = createSearchParams( - componentExportEncrypted, - propsEncrypted, - slotsEncrypted - ); - const useGETRequest = isWithinURLLimit(serverIslandUrl, potentialSearchParams); - if (useGETRequest) { - serverIslandUrl += "?" + potentialSearchParams.toString(); - this.result._metadata.extraHead.push( - markHTMLString( - `` - ) - ); - } - const adapterHeaders = this.result.internalFetchHeaders || {}; - const headersJson = safeJsonStringify(adapterHeaders); - const method = useGETRequest ? ( - // GET request - `const headers = new Headers(${headersJson}); -let response = await fetch('${serverIslandUrl}', { headers });` - ) : ( - // POST request - `let data = { - encryptedComponentExport: ${safeJsonStringify(componentExportEncrypted)}, - encryptedProps: ${safeJsonStringify(propsEncrypted)}, - encryptedSlots: ${safeJsonStringify(slotsEncrypted)}, -}; -const headers = new Headers({ 'Content-Type': 'application/json', ...${headersJson} }); -let response = await fetch('${serverIslandUrl}', { - method: 'POST', - body: JSON.stringify(data), - headers, -});` - ); - this.islandContent = `${method}replaceServerIsland('${hostId}', response);`; - return this.islandContent; - } -} -const renderServerIslandRuntime = () => { - return ``; -}; -const SERVER_ISLAND_REPLACER = markHTMLString( - `async function replaceServerIsland(id, r) { - let s = document.querySelector(\`script[data-island-id="\${id}"]\`); - // If there's no matching script, or the request fails then return - if (!s || r.status !== 200 || r.headers.get('content-type')?.split(';')[0].trim() !== 'text/html') return; - // Load the HTML before modifying the DOM in case of errors - let html = await r.text(); - // Remove any placeholder content before the island script - while (s.previousSibling && s.previousSibling.nodeType !== 8 && s.previousSibling.data !== '[if astro]>server-island-start line.trim()).filter((line) => line && !line.startsWith("//")).join(" ") -); - -const Fragment = Symbol.for("astro:fragment"); -const Renderer = Symbol.for("astro:renderer"); -const encoder = new TextEncoder(); -const decoder = new TextDecoder(); -function stringifyChunk(result, chunk) { - if (isRenderInstruction(chunk)) { - const instruction = chunk; - switch (instruction.type) { - case "directive": { - const { hydration } = instruction; - let needsHydrationScript = hydration && determineIfNeedsHydrationScript(result); - let needsDirectiveScript = hydration && determinesIfNeedsDirectiveScript(result, hydration.directive); - if (needsHydrationScript) { - let prescripts = getPrescripts(result, "both", hydration.directive); - return markHTMLString(prescripts); - } else if (needsDirectiveScript) { - let prescripts = getPrescripts(result, "directive", hydration.directive); - return markHTMLString(prescripts); - } else { - return ""; - } - } - case "head": { - if (result._metadata.hasRenderedHead || result.partial) { - return ""; - } - return renderAllHeadContent(result); - } - case "maybe-head": { - if (result._metadata.hasRenderedHead || result._metadata.headInTree || result.partial) { - return ""; - } - return renderAllHeadContent(result); - } - case "renderer-hydration-script": { - const { rendererSpecificHydrationScripts } = result._metadata; - const { rendererName } = instruction; - if (!rendererSpecificHydrationScripts.has(rendererName)) { - rendererSpecificHydrationScripts.add(rendererName); - return instruction.render(); - } - return ""; - } - case "server-island-runtime": { - if (result._metadata.hasRenderedServerIslandRuntime) { - return ""; - } - result._metadata.hasRenderedServerIslandRuntime = true; - return renderServerIslandRuntime(); - } - case "script": { - const { id, content } = instruction; - if (result._metadata.renderedScripts.has(id)) { - return ""; - } - result._metadata.renderedScripts.add(id); - return content; - } - default: { - throw new Error(`Unknown chunk type: ${chunk.type}`); - } - } - } else if (chunk instanceof Response) { - return ""; - } else if (isSlotString(chunk)) { - let out = ""; - const c = chunk; - if (c.instructions) { - for (const instr of c.instructions) { - out += stringifyChunk(result, instr); - } - } - out += chunk.toString(); - return out; - } - return chunk.toString(); -} -function chunkToString(result, chunk) { - if (ArrayBuffer.isView(chunk)) { - return decoder.decode(chunk); - } else { - return stringifyChunk(result, chunk); - } -} -function chunkToByteArray(result, chunk) { - if (ArrayBuffer.isView(chunk)) { - return chunk; - } else { - const stringified = stringifyChunk(result, chunk); - return encoder.encode(stringified.toString()); - } -} -function chunkToByteArrayOrString(result, chunk) { - if (ArrayBuffer.isView(chunk)) { - return chunk; - } else { - return stringifyChunk(result, chunk).toString(); - } -} -function isRenderInstance(obj) { - return !!obj && typeof obj === "object" && "render" in obj && typeof obj.render === "function"; -} - -function renderChild(destination, child) { - if (isPromise(child)) { - return child.then((x) => renderChild(destination, x)); - } - if (child instanceof SlotString) { - destination.write(child); - return; - } - if (isHTMLString(child)) { - destination.write(child); - return; - } - if (Array.isArray(child)) { - return renderArray(destination, child); - } - if (typeof child === "function") { - return renderChild(destination, child()); - } - if (!child && child !== 0) { - return; - } - if (typeof child === "string") { - destination.write(markHTMLString(escapeHTML(child))); - return; - } - if (isRenderInstance(child)) { - return child.render(destination); - } - if (isRenderTemplateResult(child)) { - return child.render(destination); - } - if (isAstroComponentInstance(child)) { - return child.render(destination); - } - if (ArrayBuffer.isView(child)) { - destination.write(child); - return; - } - if (typeof child === "object" && (Symbol.asyncIterator in child || Symbol.iterator in child)) { - if (Symbol.asyncIterator in child) { - return renderAsyncIterable(destination, child); - } - return renderIterable(destination, child); - } - destination.write(child); -} -function renderArray(destination, children) { - const flushers = children.map((c) => { - return createBufferedRenderer(destination, (bufferDestination) => { - return renderChild(bufferDestination, c); - }); - }); - const iterator = flushers[Symbol.iterator](); - const iterate = () => { - for (; ; ) { - const { value: flusher, done } = iterator.next(); - if (done) { - break; - } - const result = flusher.flush(); - if (isPromise(result)) { - return result.then(iterate); - } - } - }; - return iterate(); -} -function renderIterable(destination, children) { - const iterator = children[Symbol.iterator](); - const iterate = () => { - for (; ; ) { - const { value, done } = iterator.next(); - if (done) { - break; - } - const result = renderChild(destination, value); - if (isPromise(result)) { - return result.then(iterate); - } - } - }; - return iterate(); -} -async function renderAsyncIterable(destination, children) { - for await (const value of children) { - await renderChild(destination, value); - } -} - -const astroComponentInstanceSym = Symbol.for("astro.componentInstance"); -class AstroComponentInstance { - [astroComponentInstanceSym] = true; - result; - props; - slotValues; - factory; - returnValue; - constructor(result, props, slots, factory) { - this.result = result; - this.props = props; - this.factory = factory; - this.slotValues = {}; - for (const name in slots) { - let didRender = false; - let value = slots[name](result); - this.slotValues[name] = () => { - if (!didRender) { - didRender = true; - return value; - } - return slots[name](result); - }; - } - } - init(result) { - if (this.returnValue !== void 0) { - return this.returnValue; - } - this.returnValue = this.factory(result, this.props, this.slotValues); - if (isPromise(this.returnValue)) { - this.returnValue.then((resolved) => { - this.returnValue = resolved; - }).catch(() => { - }); - } - return this.returnValue; - } - render(destination) { - const returnValue = this.init(this.result); - if (isPromise(returnValue)) { - return returnValue.then((x) => this.renderImpl(destination, x)); - } - return this.renderImpl(destination, returnValue); - } - renderImpl(destination, returnValue) { - if (isHeadAndContent(returnValue)) { - return returnValue.content.render(destination); - } else { - return renderChild(destination, returnValue); - } - } -} -function validateComponentProps(props, clientDirectives, displayName) { - if (props != null) { - const directives = [...clientDirectives.keys()].map((directive) => `client:${directive}`); - for (const prop of Object.keys(props)) { - if (directives.includes(prop)) { - console.warn( - `You are attempting to render <${displayName} ${prop} />, but ${displayName} is an Astro component. Astro components do not render in the client and should not have a hydration directive. Please use a framework component for client rendering.` - ); - } - } - } -} -function createAstroComponentInstance(result, displayName, factory, props, slots = {}) { - validateComponentProps(props, result.clientDirectives, displayName); - const instance = new AstroComponentInstance(result, props, slots, factory); - if (isAPropagatingComponent(result, factory)) { - result._metadata.propagators.add(instance); - } - return instance; -} -function isAstroComponentInstance(obj) { - return typeof obj === "object" && obj !== null && !!obj[astroComponentInstanceSym]; -} - -const DOCTYPE_EXP = /" : "\n"; - str += doctype; - } - } - if (chunk instanceof Response) return; - str += chunkToString(result, chunk); - } - }; - await templateResult.render(destination); - return str; -} -async function renderToReadableStream(result, componentFactory, props, children, isPage = false, route) { - const templateResult = await callComponentAsTemplateResultOrResponse( - result, - componentFactory, - props, - children, - route - ); - if (templateResult instanceof Response) return templateResult; - let renderedFirstPageChunk = false; - if (isPage) { - await bufferHeadContent(result); - } - return new ReadableStream({ - start(controller) { - const destination = { - write(chunk) { - if (isPage && !renderedFirstPageChunk) { - renderedFirstPageChunk = true; - if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) { - const doctype = result.compressHTML ? "" : "\n"; - controller.enqueue(encoder.encode(doctype)); - } - } - if (chunk instanceof Response) { - throw new AstroError({ - ...ResponseSentError - }); - } - const bytes = chunkToByteArray(result, chunk); - controller.enqueue(bytes); - } - }; - (async () => { - try { - await templateResult.render(destination); - controller.close(); - } catch (e) { - if (AstroError.is(e) && !e.loc) { - e.setLocation({ - file: route?.component - }); - } - setTimeout(() => controller.error(e), 0); - } - })(); - }, - cancel() { - result.cancelled = true; - } - }); -} -async function callComponentAsTemplateResultOrResponse(result, componentFactory, props, children, route) { - const factoryResult = await componentFactory(result, props, children); - if (factoryResult instanceof Response) { - return factoryResult; - } else if (isHeadAndContent(factoryResult)) { - if (!isRenderTemplateResult(factoryResult.content)) { - throw new AstroError({ - ...OnlyResponseCanBeReturned, - message: OnlyResponseCanBeReturned.message( - route?.route, - typeof factoryResult - ), - location: { - file: route?.component - } - }); - } - return factoryResult.content; - } else if (!isRenderTemplateResult(factoryResult)) { - throw new AstroError({ - ...OnlyResponseCanBeReturned, - message: OnlyResponseCanBeReturned.message(route?.route, typeof factoryResult), - location: { - file: route?.component - } - }); - } - return factoryResult; -} -async function bufferHeadContent(result) { - const iterator = result._metadata.propagators.values(); - while (true) { - const { value, done } = iterator.next(); - if (done) { - break; - } - const returnValue = await value.init(result); - if (isHeadAndContent(returnValue) && returnValue.head) { - result._metadata.extraHead.push(returnValue.head); - } - } -} -async function renderToAsyncIterable(result, componentFactory, props, children, isPage = false, route) { - const templateResult = await callComponentAsTemplateResultOrResponse( - result, - componentFactory, - props, - children, - route - ); - if (templateResult instanceof Response) return templateResult; - let renderedFirstPageChunk = false; - if (isPage) { - await bufferHeadContent(result); - } - let error = null; - let next = null; - const buffer = []; - let renderingComplete = false; - const iterator = { - async next() { - if (result.cancelled) return { done: true, value: void 0 }; - if (next !== null) { - await next.promise; - } else if (!renderingComplete && !buffer.length) { - next = promiseWithResolvers(); - await next.promise; - } - if (!renderingComplete) { - next = promiseWithResolvers(); - } - if (error) { - throw error; - } - let length = 0; - let stringToEncode = ""; - for (let i = 0, len = buffer.length; i < len; i++) { - const bufferEntry = buffer[i]; - if (typeof bufferEntry === "string") { - const nextIsString = i + 1 < len && typeof buffer[i + 1] === "string"; - stringToEncode += bufferEntry; - if (!nextIsString) { - const encoded = encoder.encode(stringToEncode); - length += encoded.length; - stringToEncode = ""; - buffer[i] = encoded; - } else { - buffer[i] = ""; - } - } else { - length += bufferEntry.length; - } - } - let mergedArray = new Uint8Array(length); - let offset = 0; - for (let i = 0, len = buffer.length; i < len; i++) { - const item = buffer[i]; - if (item === "") { - continue; - } - mergedArray.set(item, offset); - offset += item.length; - } - buffer.length = 0; - const returnValue = { - // The iterator is done when rendering has finished - // and there are no more chunks to return. - done: length === 0 && renderingComplete, - value: mergedArray - }; - return returnValue; - }, - async return() { - result.cancelled = true; - return { done: true, value: void 0 }; - } - }; - const destination = { - write(chunk) { - if (isPage && !renderedFirstPageChunk) { - renderedFirstPageChunk = true; - if (!result.partial && !DOCTYPE_EXP.test(String(chunk))) { - const doctype = result.compressHTML ? "" : "\n"; - buffer.push(encoder.encode(doctype)); - } - } - if (chunk instanceof Response) { - throw new AstroError(ResponseSentError); - } - const bytes = chunkToByteArrayOrString(result, chunk); - if (bytes.length > 0) { - buffer.push(bytes); - next?.resolve(); - } else if (buffer.length > 0) { - next?.resolve(); - } - } - }; - const renderResult = toPromise(() => templateResult.render(destination)); - renderResult.catch((err) => { - error = err; - }).finally(() => { - renderingComplete = true; - next?.resolve(); - }); - return { - [Symbol.asyncIterator]() { - return iterator; - } - }; -} -function toPromise(fn) { - try { - const result = fn(); - return isPromise(result) ? result : Promise.resolve(result); - } catch (err) { - return Promise.reject(err); - } -} - -function componentIsHTMLElement(Component) { - return typeof HTMLElement !== "undefined" && HTMLElement.isPrototypeOf(Component); -} -async function renderHTMLElement(result, constructor, props, slots) { - const name = getHTMLElementName(constructor); - let attrHTML = ""; - for (const attr in props) { - attrHTML += ` ${attr}="${toAttributeString(await props[attr])}"`; - } - return markHTMLString( - `<${name}${attrHTML}>${await renderSlotToString(result, slots?.default)}` - ); -} -function getHTMLElementName(constructor) { - const definedName = customElements.getName(constructor); - if (definedName) return definedName; - const assignedName = constructor.name.replace(/^HTML|Element$/g, "").replace(/[A-Z]/g, "-$&").toLowerCase().replace(/^-/, "html-"); - return assignedName; -} - -const needsHeadRenderingSymbol = Symbol.for("astro.needsHeadRendering"); -const rendererAliases = /* @__PURE__ */ new Map([["solid", "solid-js"]]); -const clientOnlyValues = /* @__PURE__ */ new Set(["solid-js", "react", "preact", "vue", "svelte"]); -function guessRenderers(componentUrl) { - const extname = componentUrl?.split(".").pop(); - switch (extname) { - case "svelte": - return ["@astrojs/svelte"]; - case "vue": - return ["@astrojs/vue"]; - case "jsx": - case "tsx": - return ["@astrojs/react", "@astrojs/preact", "@astrojs/solid-js", "@astrojs/vue (jsx)"]; - case void 0: - default: - return [ - "@astrojs/react", - "@astrojs/preact", - "@astrojs/solid-js", - "@astrojs/vue", - "@astrojs/svelte" - ]; - } -} -function isFragmentComponent(Component) { - return Component === Fragment; -} -function isHTMLComponent(Component) { - return Component && Component["astro:html"] === true; -} -const ASTRO_SLOT_EXP = /<\/?astro-slot\b[^>]*>/g; -const ASTRO_STATIC_SLOT_EXP = /<\/?astro-static-slot\b[^>]*>/g; -function removeStaticAstroSlot(html, supportsAstroStaticSlot = true) { - const exp = supportsAstroStaticSlot ? ASTRO_STATIC_SLOT_EXP : ASTRO_SLOT_EXP; - return html.replace(exp, ""); -} -async function renderFrameworkComponent(result, displayName, Component, _props, slots = {}) { - if (!Component && "client:only" in _props === false) { - throw new Error( - `Unable to render ${displayName} because it is ${Component}! -Did you forget to import the component or is it possible there is a typo?` - ); - } - const { renderers, clientDirectives } = result; - const metadata = { - astroStaticSlot: true, - displayName - }; - const { hydration, isPage, props, propsWithoutTransitionAttributes } = extractDirectives( - _props, - clientDirectives - ); - let html = ""; - let attrs = void 0; - if (hydration) { - metadata.hydrate = hydration.directive; - metadata.hydrateArgs = hydration.value; - metadata.componentExport = hydration.componentExport; - metadata.componentUrl = hydration.componentUrl; - } - const probableRendererNames = guessRenderers(metadata.componentUrl); - const validRenderers = renderers.filter((r) => r.name !== "astro:jsx"); - const { children, slotInstructions } = await renderSlots(result, slots); - let renderer; - if (metadata.hydrate !== "only") { - let isTagged = false; - try { - isTagged = Component && Component[Renderer]; - } catch { - } - if (isTagged) { - const rendererName = Component[Renderer]; - renderer = renderers.find(({ name }) => name === rendererName); - } - if (!renderer) { - let error; - for (const r of renderers) { - try { - if (await r.ssr.check.call({ result }, Component, props, children)) { - renderer = r; - break; - } - } catch (e) { - error ??= e; - } - } - if (!renderer && error) { - throw error; - } - } - if (!renderer && typeof HTMLElement === "function" && componentIsHTMLElement(Component)) { - const output = await renderHTMLElement( - result, - Component, - _props, - slots - ); - return { - render(destination) { - destination.write(output); - } - }; - } - } else { - if (metadata.hydrateArgs) { - const rendererName = rendererAliases.has(metadata.hydrateArgs) ? rendererAliases.get(metadata.hydrateArgs) : metadata.hydrateArgs; - if (clientOnlyValues.has(rendererName)) { - renderer = renderers.find( - ({ name }) => name === `@astrojs/${rendererName}` || name === rendererName - ); - } - } - if (!renderer && validRenderers.length === 1) { - renderer = validRenderers[0]; - } - if (!renderer) { - const extname = metadata.componentUrl?.split(".").pop(); - renderer = renderers.find(({ name }) => name === `@astrojs/${extname}` || name === extname); - } - } - let componentServerRenderEndTime; - if (!renderer) { - if (metadata.hydrate === "only") { - const rendererName = rendererAliases.has(metadata.hydrateArgs) ? rendererAliases.get(metadata.hydrateArgs) : metadata.hydrateArgs; - if (clientOnlyValues.has(rendererName)) { - const plural = validRenderers.length > 1; - throw new AstroError({ - ...NoMatchingRenderer, - message: NoMatchingRenderer.message( - metadata.displayName, - metadata?.componentUrl?.split(".").pop(), - plural, - validRenderers.length - ), - hint: NoMatchingRenderer.hint( - formatList(probableRendererNames.map((r) => "`" + r + "`")) - ) - }); - } else { - throw new AstroError({ - ...NoClientOnlyHint, - message: NoClientOnlyHint.message(metadata.displayName), - hint: NoClientOnlyHint.hint( - probableRendererNames.map((r) => r.replace("@astrojs/", "")).join("|") - ) - }); - } - } else if (typeof Component !== "string") { - const matchingRenderers = validRenderers.filter( - (r) => probableRendererNames.includes(r.name) - ); - const plural = validRenderers.length > 1; - if (matchingRenderers.length === 0) { - throw new AstroError({ - ...NoMatchingRenderer, - message: NoMatchingRenderer.message( - metadata.displayName, - metadata?.componentUrl?.split(".").pop(), - plural, - validRenderers.length - ), - hint: NoMatchingRenderer.hint( - formatList(probableRendererNames.map((r) => "`" + r + "`")) - ) - }); - } else if (matchingRenderers.length === 1) { - renderer = matchingRenderers[0]; - ({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call( - { result }, - Component, - propsWithoutTransitionAttributes, - children, - metadata - )); - } else { - throw new Error(`Unable to render ${metadata.displayName}! - -This component likely uses ${formatList(probableRendererNames)}, -but Astro encountered an error during server-side rendering. - -Please ensure that ${metadata.displayName}: -1. Does not unconditionally access browser-specific globals like \`window\` or \`document\`. - If this is unavoidable, use the \`client:only\` hydration directive. -2. Does not conditionally return \`null\` or \`undefined\` when rendered on the server. - -If you're still stuck, please open an issue on GitHub or join us at https://astro.build/chat.`); - } - } - } else { - if (metadata.hydrate === "only") { - html = await renderSlotToString(result, slots?.fallback); - } else { - const componentRenderStartTime = performance.now(); - ({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call( - { result }, - Component, - propsWithoutTransitionAttributes, - children, - metadata - )); - if (process.env.NODE_ENV === "development") - componentServerRenderEndTime = performance.now() - componentRenderStartTime; - } - } - if (!html && typeof Component === "string") { - const Tag = sanitizeElementName(Component); - const childSlots = Object.values(children).join(""); - const renderTemplateResult = renderTemplate`<${Tag}${internalSpreadAttributes( - props, - true, - Tag - )}${markHTMLString( - childSlots === "" && voidElementNames.test(Tag) ? `/>` : `>${childSlots}` - )}`; - html = ""; - const destination = { - write(chunk) { - if (chunk instanceof Response) return; - html += chunkToString(result, chunk); - } - }; - await renderTemplateResult.render(destination); - } - if (!hydration) { - return { - render(destination) { - if (slotInstructions) { - for (const instruction of slotInstructions) { - destination.write(instruction); - } - } - if (isPage || renderer?.name === "astro:jsx") { - destination.write(html); - } else if (html && html.length > 0) { - destination.write( - markHTMLString(removeStaticAstroSlot(html, renderer?.ssr?.supportsAstroStaticSlot)) - ); - } - } - }; - } - const astroId = shorthash( - ` -${html} -${serializeProps( - props, - metadata - )}` - ); - const island = await generateHydrateScript( - { renderer, result, astroId, props, attrs }, - metadata - ); - if (componentServerRenderEndTime && process.env.NODE_ENV === "development") - island.props["server-render-time"] = componentServerRenderEndTime; - let unrenderedSlots = []; - if (html) { - if (Object.keys(children).length > 0) { - for (const key of Object.keys(children)) { - let tagName = renderer?.ssr?.supportsAstroStaticSlot ? !!metadata.hydrate ? "astro-slot" : "astro-static-slot" : "astro-slot"; - let expectedHTML = key === "default" ? `<${tagName}>` : `<${tagName} name="${key}">`; - if (!html.includes(expectedHTML)) { - unrenderedSlots.push(key); - } - } - } - } else { - unrenderedSlots = Object.keys(children); - } - const template = unrenderedSlots.length > 0 ? unrenderedSlots.map( - (key) => `` - ).join("") : ""; - island.children = `${html ?? ""}${template}`; - if (island.children) { - island.props["await-children"] = ""; - island.children += ``; - } - return { - render(destination) { - if (slotInstructions) { - for (const instruction of slotInstructions) { - destination.write(instruction); - } - } - destination.write(createRenderInstruction({ type: "directive", hydration })); - if (hydration.directive !== "only" && renderer?.ssr.renderHydrationScript) { - destination.write( - createRenderInstruction({ - type: "renderer-hydration-script", - rendererName: renderer.name, - render: renderer.ssr.renderHydrationScript - }) - ); - } - const renderedElement = renderElement$1("astro-island", island, false); - destination.write(markHTMLString(renderedElement)); - } - }; -} -function sanitizeElementName(tag) { - const unsafe = /[&<>'"\s]+/; - if (!unsafe.test(tag)) return tag; - return tag.trim().split(unsafe)[0].trim(); -} -async function renderFragmentComponent(result, slots = {}) { - const children = await renderSlotToString(result, slots?.default); - return { - render(destination) { - if (children == null) return; - destination.write(children); - } - }; -} -async function renderHTMLComponent(result, Component, _props, slots = {}) { - const { slotInstructions, children } = await renderSlots(result, slots); - const html = Component({ slots: children }); - const hydrationHtml = slotInstructions ? slotInstructions.map((instr) => chunkToString(result, instr)).join("") : ""; - return { - render(destination) { - destination.write(markHTMLString(hydrationHtml + html)); - } - }; -} -function renderAstroComponent(result, displayName, Component, props, slots = {}) { - if (containsServerDirective(props)) { - const serverIslandComponent = new ServerIslandComponent(result, props, slots, displayName); - result._metadata.propagators.add(serverIslandComponent); - return serverIslandComponent; - } - const instance = createAstroComponentInstance(result, displayName, Component, props, slots); - return { - render(destination) { - return instance.render(destination); - } - }; -} -function renderComponent(result, displayName, Component, props, slots = {}) { - if (isPromise(Component)) { - return Component.catch(handleCancellation).then((x) => { - return renderComponent(result, displayName, x, props, slots); - }); - } - if (isFragmentComponent(Component)) { - return renderFragmentComponent(result, slots).catch(handleCancellation); - } - props = normalizeProps(props); - if (isHTMLComponent(Component)) { - return renderHTMLComponent(result, Component, props, slots).catch(handleCancellation); - } - if (isAstroComponentFactory(Component)) { - return renderAstroComponent(result, displayName, Component, props, slots); - } - return renderFrameworkComponent(result, displayName, Component, props, slots).catch( - handleCancellation - ); - function handleCancellation(e) { - if (result.cancelled) - return { - render() { - } - }; - throw e; - } -} -function normalizeProps(props) { - if (props["class:list"] !== void 0) { - const value = props["class:list"]; - delete props["class:list"]; - props["class"] = clsx(props["class"], value); - if (props["class"] === "") { - delete props["class"]; - } - } - return props; -} -async function renderComponentToString(result, displayName, Component, props, slots = {}, isPage = false, route) { - let str = ""; - let renderedFirstPageChunk = false; - let head = ""; - if (isPage && !result.partial && nonAstroPageNeedsHeadInjection(Component)) { - head += chunkToString(result, maybeRenderHead()); - } - try { - const destination = { - write(chunk) { - if (isPage && !result.partial && !renderedFirstPageChunk) { - renderedFirstPageChunk = true; - if (!/" : "\n"; - str += doctype + head; - } - } - if (chunk instanceof Response) return; - str += chunkToString(result, chunk); - } - }; - const renderInstance = await renderComponent(result, displayName, Component, props, slots); - if (containsServerDirective(props)) { - await bufferHeadContent(result); - } - await renderInstance.render(destination); - } catch (e) { - if (AstroError.is(e) && !e.loc) { - e.setLocation({ - file: route?.component - }); - } - throw e; - } - return str; -} -function nonAstroPageNeedsHeadInjection(pageComponent) { - return !!pageComponent?.[needsHeadRenderingSymbol]; -} - -const ClientOnlyPlaceholder = "astro-client-only"; -const hasTriedRenderComponentSymbol = Symbol("hasTriedRenderComponent"); -async function renderJSX(result, vnode) { - switch (true) { - case vnode instanceof HTMLString: - if (vnode.toString().trim() === "") { - return ""; - } - return vnode; - case typeof vnode === "string": - return markHTMLString(escapeHTML(vnode)); - case typeof vnode === "function": - return vnode; - case (!vnode && vnode !== 0): - return ""; - case Array.isArray(vnode): { - const renderedItems = await Promise.all(vnode.map((v) => renderJSX(result, v))); - let instructions = null; - let content = ""; - for (const item of renderedItems) { - if (item instanceof SlotString) { - content += item; - instructions = mergeSlotInstructions(instructions, item); - } else { - content += item; - } - } - if (instructions) { - return markHTMLString(new SlotString(content, instructions)); - } - return markHTMLString(content); - } - } - return renderJSXVNode(result, vnode); -} -async function renderJSXVNode(result, vnode) { - if (isVNode(vnode)) { - switch (true) { - case !vnode.type: { - throw new Error(`Unable to render ${result.pathname} because it contains an undefined Component! -Did you forget to import the component or is it possible there is a typo?`); - } - case vnode.type === Symbol.for("astro:fragment"): - return renderJSX(result, vnode.props.children); - case isAstroComponentFactory(vnode.type): { - let props = {}; - let slots = {}; - for (const [key, value] of Object.entries(vnode.props ?? {})) { - if (key === "children" || value && typeof value === "object" && value["$$slot"]) { - slots[key === "children" ? "default" : key] = () => renderJSX(result, value); - } else { - props[key] = value; - } - } - const str = await renderComponentToString( - result, - vnode.type.name, - vnode.type, - props, - slots - ); - const html = markHTMLString(str); - return html; - } - case (!vnode.type && vnode.type !== 0): - return ""; - case (typeof vnode.type === "string" && vnode.type !== ClientOnlyPlaceholder): - return markHTMLString(await renderElement(result, vnode.type, vnode.props ?? {})); - } - if (vnode.type) { - let extractSlots2 = function(child) { - if (Array.isArray(child)) { - return child.map((c) => extractSlots2(c)); - } - if (!isVNode(child)) { - _slots.default.push(child); - return; - } - if ("slot" in child.props) { - _slots[child.props.slot] = [..._slots[child.props.slot] ?? [], child]; - delete child.props.slot; - return; - } - _slots.default.push(child); - }; - if (typeof vnode.type === "function" && vnode.props["server:root"]) { - const output2 = await vnode.type(vnode.props ?? {}); - return await renderJSX(result, output2); - } - if (typeof vnode.type === "function") { - if (vnode.props[hasTriedRenderComponentSymbol]) { - delete vnode.props[hasTriedRenderComponentSymbol]; - const output2 = await vnode.type(vnode.props ?? {}); - if (output2?.[AstroJSX] || !output2) { - return await renderJSXVNode(result, output2); - } else { - return; - } - } else { - vnode.props[hasTriedRenderComponentSymbol] = true; - } - } - const { children = null, ...props } = vnode.props ?? {}; - const _slots = { - default: [] - }; - extractSlots2(children); - for (const [key, value] of Object.entries(props)) { - if (value?.["$$slot"]) { - _slots[key] = value; - delete props[key]; - } - } - const slotPromises = []; - const slots = {}; - for (const [key, value] of Object.entries(_slots)) { - slotPromises.push( - renderJSX(result, value).then((output2) => { - if (output2.toString().trim().length === 0) return; - slots[key] = () => output2; - }) - ); - } - await Promise.all(slotPromises); - let output; - if (vnode.type === ClientOnlyPlaceholder && vnode.props["client:only"]) { - output = await renderComponentToString( - result, - vnode.props["client:display-name"] ?? "", - null, - props, - slots - ); - } else { - output = await renderComponentToString( - result, - typeof vnode.type === "function" ? vnode.type.name : vnode.type, - vnode.type, - props, - slots - ); - } - return markHTMLString(output); - } - } - return markHTMLString(`${vnode}`); -} -async function renderElement(result, tag, { children, ...props }) { - return markHTMLString( - `<${tag}${spreadAttributes(props)}${markHTMLString( - (children == null || children == "") && voidElementNames.test(tag) ? `/>` : `>${children == null ? "" : await renderJSX(result, prerenderElementChildren(tag, children))}` - )}` - ); -} -function prerenderElementChildren(tag, children) { - if (typeof children === "string" && (tag === "style" || tag === "script")) { - return markHTMLString(children); - } else { - return children; - } -} - -async function renderPage(result, componentFactory, props, children, streaming, route) { - if (!isAstroComponentFactory(componentFactory)) { - result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false; - const pageProps = { ...props ?? {}, "server:root": true }; - const str = await renderComponentToString( - result, - componentFactory.name, - componentFactory, - pageProps, - {}, - true, - route - ); - const bytes = encoder.encode(str); - const headers2 = new Headers([ - ["Content-Type", "text/html"], - ["Content-Length", bytes.byteLength.toString()] - ]); - if (result.shouldInjectCspMetaTags && (result.cspDestination === "header" || result.cspDestination === "adapter")) { - headers2.set("content-security-policy", renderCspContent(result)); - } - return new Response(bytes, { - headers: headers2 - }); - } - result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false; - let body; - if (streaming) { - if (isNode && !isDeno) { - const nodeBody = await renderToAsyncIterable( - result, - componentFactory, - props, - children, - true, - route - ); - body = nodeBody; - } else { - body = await renderToReadableStream(result, componentFactory, props, children, true, route); - } - } else { - body = await renderToString(result, componentFactory, props, children, true, route); - } - if (body instanceof Response) return body; - const init = result.response; - const headers = new Headers(init.headers); - if (result.shouldInjectCspMetaTags && result.cspDestination === "header" || result.cspDestination === "adapter") { - headers.set("content-security-policy", renderCspContent(result)); - } - if (!streaming && typeof body === "string") { - body = encoder.encode(body); - headers.set("Content-Length", body.byteLength.toString()); - } - let status = init.status; - let statusText = init.statusText; - if (route?.route === "/404") { - status = 404; - if (statusText === "OK") { - statusText = "Not Found"; - } - } else if (route?.route === "/500") { - status = 500; - if (statusText === "OK") { - statusText = "Internal Server Error"; - } - } - if (status) { - return new Response(body, { ...init, headers, status, statusText }); - } else { - return new Response(body, { ...init, headers }); - } -} - -async function renderScript(result, id) { - const inlined = result.inlinedScripts.get(id); - let content = ""; - if (inlined != null) { - if (inlined) { - content = ``; - } - } else { - const resolved = await result.resolve(id); - content = ``; - } - return createRenderInstruction({ type: "script", id, content }); -} - -"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_".split("").reduce((v, c) => (v[c.charCodeAt(0)] = c, v), []); -"-0123456789_".split("").reduce((v, c) => (v[c.charCodeAt(0)] = c, v), []); - -function spreadAttributes(values = {}, _name, { class: scopedClassName } = {}) { - let output = ""; - if (scopedClassName) { - if (typeof values.class !== "undefined") { - values.class += ` ${scopedClassName}`; - } else if (typeof values["class:list"] !== "undefined") { - values["class:list"] = [values["class:list"], scopedClassName]; - } else { - values.class = scopedClassName; - } - } - for (const [key, value] of Object.entries(values)) { - output += addAttribute(value, key, true, _name); - } - return markHTMLString(output); -} - -export { isRenderInstruction as $, AstroError as A, ActionNotFoundError as B, MiddlewareNoDataOrNextCalled as C, MiddlewareNotAResponse as D, ExpectedImage as E, FailedToFetchRemoteImageDimensions as F, originPathnameSymbol as G, RewriteWithBodyUsed as H, IncompatibleDescriptorOptions as I, GetStaticPathsRequired as J, InvalidGetStaticPathsReturn as K, LocalImageUsedWrongly as L, MissingImageDimension as M, NoImageMetadata as N, InvalidGetStaticPathsEntry as O, GetStaticPathsExpectedParams as P, GetStaticPathsInvalidRouteParam as Q, ROUTE_TYPE_HEADER as R, PageNumberParamNotFound as S, DEFAULT_404_COMPONENT as T, UnsupportedImageFormat as U, NoMatchingStaticPathFound as V, PrerenderDynamicEndpointPathCollide as W, ReservedSlotName as X, renderSlotToString as Y, renderJSX as Z, chunkToString as _, UnsupportedImageConversion as a, ForbiddenRewrite as a0, SessionStorageInitError as a1, SessionStorageSaveError as a2, ASTRO_VERSION as a3, CspNotEnabled as a4, LocalsReassigned as a5, generateCspDigest as a6, PrerenderClientAddressNotAvailable as a7, clientAddressSymbol as a8, ClientAddressNotAvailable as a9, StaticClientAddressNotAvailable as aa, AstroResponseHeadersReassigned as ab, responseSentSymbol as ac, renderPage as ad, REWRITE_DIRECTIVE_HEADER_KEY as ae, REWRITE_DIRECTIVE_HEADER_VALUE as af, renderEndpoint as ag, LocalsNotAnObject as ah, FailedToFindPageMapSSR as ai, REROUTABLE_STATUS_CODES as aj, nodeRequestAbortControllerCleanupSymbol as ak, NOOP_MIDDLEWARE_HEADER as al, REDIRECT_STATUS_CODES as am, ActionsReturnedInvalidDataError as an, MissingSharp as ao, ExpectedImageOptions as b, ExpectedNotESMImage as c, InvalidImageService as d, createAstro as e, createComponent as f, ImageMissingAlt as g, addAttribute as h, ExperimentalFontsNotEnabled as i, FontFamilyNotFound as j, renderComponent as k, renderScript as l, maybeRenderHead as m, renderHead as n, renderSlot as o, decodeKey as p, decryptString as q, renderTemplate as r, spreadAttributes as s, toStyleString as t, unescapeHTML as u, createSlotValueFromString as v, isAstroComponentFactory as w, REROUTE_DIRECTIVE_HEADER as x, i18nNoLocaleFoundInPath as y, ResponseSentError as z }; diff --git a/dist/server/chunks/fs-lite_COtHaKzy.mjs b/dist/server/chunks/fs-lite_COtHaKzy.mjs deleted file mode 100644 index 7dc736a..0000000 --- a/dist/server/chunks/fs-lite_COtHaKzy.mjs +++ /dev/null @@ -1,157 +0,0 @@ -import { promises, existsSync } from 'node:fs'; -import { resolve, dirname, join } from 'node:path'; - -function defineDriver(factory) { - return factory; -} -function createError(driver, message, opts) { - const err = new Error(`[unstorage] [${driver}] ${message}`, opts); - if (Error.captureStackTrace) { - Error.captureStackTrace(err, createError); - } - return err; -} -function createRequiredError(driver, name) { - if (Array.isArray(name)) { - return createError( - driver, - `Missing some of the required options ${name.map((n) => "`" + n + "`").join(", ")}` - ); - } - return createError(driver, `Missing required option \`${name}\`.`); -} - -function ignoreNotfound(err) { - return err.code === "ENOENT" || err.code === "EISDIR" ? null : err; -} -function ignoreExists(err) { - return err.code === "EEXIST" ? null : err; -} -async function writeFile(path, data, encoding) { - await ensuredir(dirname(path)); - return promises.writeFile(path, data, encoding); -} -function readFile(path, encoding) { - return promises.readFile(path, encoding).catch(ignoreNotfound); -} -function unlink(path) { - return promises.unlink(path).catch(ignoreNotfound); -} -function readdir(dir) { - return promises.readdir(dir, { withFileTypes: true }).catch(ignoreNotfound).then((r) => r || []); -} -async function ensuredir(dir) { - if (existsSync(dir)) { - return; - } - await ensuredir(dirname(dir)).catch(ignoreExists); - await promises.mkdir(dir).catch(ignoreExists); -} -async function readdirRecursive(dir, ignore, maxDepth) { - if (ignore && ignore(dir)) { - return []; - } - const entries = await readdir(dir); - const files = []; - await Promise.all( - entries.map(async (entry) => { - const entryPath = resolve(dir, entry.name); - if (entry.isDirectory()) { - if (maxDepth === void 0 || maxDepth > 0) { - const dirFiles = await readdirRecursive( - entryPath, - ignore, - maxDepth === void 0 ? void 0 : maxDepth - 1 - ); - files.push(...dirFiles.map((f) => entry.name + "/" + f)); - } - } else { - if (!(ignore && ignore(entry.name))) { - files.push(entry.name); - } - } - }) - ); - return files; -} -async function rmRecursive(dir) { - const entries = await readdir(dir); - await Promise.all( - entries.map((entry) => { - const entryPath = resolve(dir, entry.name); - if (entry.isDirectory()) { - return rmRecursive(entryPath).then(() => promises.rmdir(entryPath)); - } else { - return promises.unlink(entryPath); - } - }) - ); -} - -const PATH_TRAVERSE_RE = /\.\.:|\.\.$/; -const DRIVER_NAME = "fs-lite"; -const fsLite = defineDriver((opts = {}) => { - if (!opts.base) { - throw createRequiredError(DRIVER_NAME, "base"); - } - opts.base = resolve(opts.base); - const r = (key) => { - if (PATH_TRAVERSE_RE.test(key)) { - throw createError( - DRIVER_NAME, - `Invalid key: ${JSON.stringify(key)}. It should not contain .. segments` - ); - } - const resolved = join(opts.base, key.replace(/:/g, "/")); - return resolved; - }; - return { - name: DRIVER_NAME, - options: opts, - flags: { - maxDepth: true - }, - hasItem(key) { - return existsSync(r(key)); - }, - getItem(key) { - return readFile(r(key), "utf8"); - }, - getItemRaw(key) { - return readFile(r(key)); - }, - async getMeta(key) { - const { atime, mtime, size, birthtime, ctime } = await promises.stat(r(key)).catch(() => ({})); - return { atime, mtime, size, birthtime, ctime }; - }, - setItem(key, value) { - if (opts.readOnly) { - return; - } - return writeFile(r(key), value, "utf8"); - }, - setItemRaw(key, value) { - if (opts.readOnly) { - return; - } - return writeFile(r(key), value); - }, - removeItem(key) { - if (opts.readOnly) { - return; - } - return unlink(r(key)); - }, - getKeys(_base, topts) { - return readdirRecursive(r("."), opts.ignore, topts?.maxDepth); - }, - async clear() { - if (opts.readOnly || opts.noClear) { - return; - } - await rmRecursive(r(".")); - } - }; -}); - -export { fsLite as default }; diff --git a/dist/server/chunks/models_BK7lP4G3.mjs b/dist/server/chunks/models_BK7lP4G3.mjs deleted file mode 100644 index 8bceed6..0000000 --- a/dist/server/chunks/models_BK7lP4G3.mjs +++ /dev/null @@ -1,441 +0,0 @@ -import { useSSRContext, defineComponent, computed, ref, watch, mergeProps } from 'vue'; -import { marked } from 'marked'; -import { ssrRenderAttrs, ssrRenderAttr, ssrRenderClass, ssrInterpolate, ssrRenderList, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual } from 'vue/server-renderer'; -import { _ as _export_sfc } from './_plugin-vue_export-helper_CEgY73aA.mjs'; - -const _sfc_main = /* @__PURE__ */ defineComponent({ - __name: "SkillEditor", - props: { - mode: {}, - slug: {}, - forkOf: {}, - initialName: {}, - initialDescription: {}, - initialAllowedTools: {}, - initialArgumentHint: {}, - initialModel: {}, - initialUserInvocable: { type: Boolean }, - initialDisableModelInvocation: { type: Boolean }, - initialContext: {}, - initialAgent: {}, - initialHooks: {}, - initialBody: {}, - initialAuthor: {}, - initialAuthorEmail: {}, - initialTags: {}, - availableTools: {}, - availableModels: {}, - availableTags: {} - }, - setup(__props, { expose: __expose }) { - __expose(); - const props = __props; - const AVAILABLE_TOOLS = props.availableTools ?? [ - "Bash", - "Read", - "Write", - "Edit", - "Glob", - "Grep", - "WebFetch", - "WebSearch", - "Task", - "NotebookEdit" - ]; - const AVAILABLE_MODELS = props.availableModels ?? [ - { id: "claude-opus-4-6", display_name: "Claude Opus 4.6" }, - { id: "claude-sonnet-4-5-20250929", display_name: "Claude Sonnet 4.5" }, - { id: "claude-haiku-4-5-20251001", display_name: "Claude Haiku 4.5" } - ]; - const isFork = computed(() => Boolean(props.forkOf)); - const name = ref(props.initialName || ""); - const description = ref(props.initialDescription || ""); - const argumentHint = ref(props.initialArgumentHint || ""); - const model = ref(props.initialModel || ""); - const userInvocable = ref(props.initialUserInvocable ?? true); - const disableModelInvocation = ref(props.initialDisableModelInvocation ?? false); - const context = ref(props.initialContext || ""); - const agent = ref(props.initialAgent || ""); - const hooksJson = ref(props.initialHooks || ""); - const tags = ref( - props.initialTags ? props.initialTags.split(",").map((t) => t.trim()).filter(Boolean) : [] - ); - const tagQuery = ref(""); - const tagSuggestionsOpen = ref(false); - const tagInputEl = ref(); - const knownTags = props.availableTags ? props.availableTags.split(",").map((t) => t.trim()).filter(Boolean) : []; - const body = ref(props.initialBody || ""); - const saving = ref(false); - const error = ref(""); - const forkAuthorName = ref(""); - const forkAuthorEmail = ref(""); - const authorToken = ref( - typeof localStorage !== "undefined" ? localStorage.getItem("skillshere-token") || "" : "" - ); - const selectedTools = ref(new Set( - props.initialAllowedTools ? props.initialAllowedTools.split(",").map((t) => t.trim()).filter(Boolean) : [] - )); - function toggleTool(tool) { - if (selectedTools.value.has(tool)) { - selectedTools.value.delete(tool); - } else { - selectedTools.value.add(tool); - } - selectedTools.value = new Set(selectedTools.value); - } - const tagSuggestions = computed(() => { - const q = tagQuery.value.toLowerCase().trim(); - const current = new Set(tags.value.map((t) => t.toLowerCase())); - const matches = knownTags.filter((t) => !current.has(t.toLowerCase()) && (!q || t.toLowerCase().includes(q))); - if (q && !current.has(q) && !matches.some((m) => m.toLowerCase() === q)) { - matches.push(q); - } - return matches; - }); - const isNewTag = (tag) => !knownTags.some((t) => t.toLowerCase() === tag.toLowerCase()); - function addTag(tag) { - const normalized = tag.trim().toLowerCase(); - if (normalized && !tags.value.some((t) => t.toLowerCase() === normalized)) { - tags.value.push(normalized); - } - tagQuery.value = ""; - tagInputEl.value?.focus(); - } - function removeTag(idx) { - tags.value.splice(idx, 1); - } - function onTagKeydown(e) { - if (e.key === "Enter" || e.key === ",") { - e.preventDefault(); - if (tagQuery.value.trim()) { - addTag(tagQuery.value); - } - } else if (e.key === "Backspace" && !tagQuery.value && tags.value.length) { - tags.value.pop(); - } - } - let tagBlurTimer; - function onTagBlur() { - tagBlurTimer = setTimeout(() => { - tagSuggestionsOpen.value = false; - }, 200); - } - function onTagSuggestionClick(tag) { - clearTimeout(tagBlurTimer); - addTag(tag); - } - const computedSlug = computed(() => { - if (props.mode === "edit" && props.slug) return props.slug; - return name.value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "my-skill"; - }); - const slugMatchesOriginal = computed(() => { - if (!props.forkOf) return false; - return computedSlug.value === props.forkOf; - }); - const bodyLines = computed(() => body.value.split("\n").length); - let previewHtml = ref(""); - let debounceTimer; - watch(body, (val) => { - clearTimeout(debounceTimer); - debounceTimer = setTimeout(async () => { - previewHtml.value = await marked(val || ""); - }, 300); - }, { immediate: true }); - function buildContent() { - const tools = [...selectedTools.value]; - const lines = ["---"]; - lines.push(`name: ${name.value}`); - if (description.value) lines.push(`description: ${description.value}`); - if (isFork.value) { - if (forkAuthorName.value) lines.push(`author: ${forkAuthorName.value}`); - if (forkAuthorEmail.value) lines.push(`author-email: ${forkAuthorEmail.value}`); - lines.push(`fork-of: ${props.forkOf}`); - } else { - if (props.initialAuthor) lines.push(`author: ${props.initialAuthor}`); - if (props.initialAuthorEmail) lines.push(`author-email: ${props.initialAuthorEmail}`); - } - if (argumentHint.value) lines.push(`argument-hint: ${argumentHint.value}`); - if (tools.length > 0) lines.push(`allowed-tools: ${tools.join(", ")}`); - if (tags.value.length > 0) lines.push(`tags: ${tags.value.join(", ")}`); - if (model.value) lines.push(`model: ${model.value}`); - if (userInvocable.value === false) lines.push("user-invocable: false"); - if (disableModelInvocation.value) lines.push("disable-model-invocation: true"); - if (context.value) lines.push(`context: ${context.value}`); - if (agent.value) lines.push(`agent: ${agent.value}`); - if (hooksJson.value.trim()) { - try { - const parsed = JSON.parse(hooksJson.value.trim()); - lines.push(`hooks: ${JSON.stringify(parsed)}`); - } catch { - } - } - lines.push("---"); - return lines.join("\n") + "\n\n" + body.value.trim() + "\n"; - } - async function save() { - saving.value = true; - error.value = ""; - try { - const content = buildContent(); - const headers = { "Content-Type": "application/json" }; - if (!isFork.value && authorToken.value) { - headers["Authorization"] = `Bearer ${authorToken.value}`; - } - if (props.mode === "create") { - const res = await fetch("/api/skills", { - method: "POST", - headers, - body: JSON.stringify({ slug: computedSlug.value, content }) - }); - if (!res.ok) { - const data = await res.json(); - throw new Error(data.error || "Failed to create skill"); - } - window.location.href = `/${computedSlug.value}`; - } else { - const res = await fetch(`/api/skills/${props.slug}`, { - method: "PUT", - headers, - body: JSON.stringify({ content }) - }); - if (!res.ok) { - const data = await res.json(); - throw new Error(data.error || "Failed to update skill"); - } - window.location.href = `/${props.slug}`; - } - } catch (err) { - error.value = err instanceof Error ? err.message : "Something went wrong"; - } finally { - saving.value = false; - } - } - const __returned__ = { props, AVAILABLE_TOOLS, AVAILABLE_MODELS, isFork, name, description, argumentHint, model, userInvocable, disableModelInvocation, context, agent, hooksJson, tags, tagQuery, tagSuggestionsOpen, tagInputEl, knownTags, body, saving, error, forkAuthorName, forkAuthorEmail, authorToken, selectedTools, toggleTool, tagSuggestions, isNewTag, addTag, removeTag, onTagKeydown, get tagBlurTimer() { - return tagBlurTimer; - }, set tagBlurTimer(v) { - tagBlurTimer = v; - }, onTagBlur, onTagSuggestionClick, computedSlug, slugMatchesOriginal, bodyLines, get previewHtml() { - return previewHtml; - }, set previewHtml(v) { - previewHtml = v; - }, get debounceTimer() { - return debounceTimer; - }, set debounceTimer(v) { - debounceTimer = v; - }, buildContent, save }; - Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); - return __returned__; - } -}); -function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { - _push(``); - if ($setup.isFork) { - _push(`

    Claim this fork as yours. It will stay open for editing until you push from CLI, which registers a token and locks it to you.

    `); - } else { - _push(``); - } - if ($setup.isFork && $setup.slugMatchesOriginal) { - _push(`

    Change the name to generate a different slug. You can't save a fork with the same slug as the original.

    `); - } else { - _push(``); - } - _push(`

    Slug: ${ssrInterpolate($setup.computedSlug)}${ssrInterpolate($setup.name.length)}/64

    ${ssrInterpolate($setup.description.length)}/200

    `); - ssrRenderList($setup.tags, (tag, i) => { - _push(`${ssrInterpolate(tag)} `); - }); - _push(`
    `); - if ($setup.tagSuggestionsOpen && $setup.tagSuggestions.length > 0) { - _push(`
    `); - ssrRenderList($setup.tagSuggestions, (s) => { - _push(``); - }); - _push(`
    `); - } else { - _push(``); - } - _push(`

    Type and press Enter or comma. Click suggestions to add.

    `); - ssrRenderList($setup.AVAILABLE_TOOLS, (tool) => { - _push(``); - }); - _push(`

    Fork runs the skill in an isolated subagent context

    Hooks (advanced)

    JSON object. Leave empty to omit.

    Preview

    ${$setup.previewHtml ?? ""}
    Cancel`); - if ($setup.error) { - _push(`

    ${ssrInterpolate($setup.error)}

    `); - } else { - _push(``); - } - _push(`
    `); -} -const _sfc_setup = _sfc_main.setup; -_sfc_main.setup = (props, ctx) => { - const ssrContext = useSSRContext(); - (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("src/components/SkillEditor.vue"); - return _sfc_setup ? _sfc_setup(props, ctx) : void 0; -}; -const SkillEditor = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); - -const FALLBACK_TOOLS = [ - "Bash", - "Read", - "Write", - "Edit", - "MultiEdit", - "Glob", - "Grep", - "WebFetch", - "WebSearch", - "Task", - "NotebookEdit", - "NotebookRead", - "TodoRead", - "TodoWrite" -]; -const GIST_URL = "https://gist.githubusercontent.com/wong2/e0f34aac66caf890a332f7b6f9e2ba8f/raw"; -const IGNORED = /* @__PURE__ */ new Set(["LS", "exit_plan_mode", "Agent", "BashOutput", "KillShell", "SlashCommand", "ExitPlanMode"]); -let cached$1 = null; -let lastFetch$1 = 0; -const CACHE_TTL$1 = 1e3 * 60 * 60; -async function getAvailableTools() { - if (cached$1 && Date.now() - lastFetch$1 < CACHE_TTL$1) { - return cached$1; - } - try { - const res = await fetch(GIST_URL, { signal: AbortSignal.timeout(5e3) }); - if (!res.ok) throw new Error(`HTTP ${res.status}`); - const text = await res.text(); - const matches = text.matchAll(/"name":\s*"([A-Z][a-zA-Z]+)"/g); - const tools = /* @__PURE__ */ new Set(); - for (const m of matches) { - if (!IGNORED.has(m[1])) { - tools.add(m[1]); - } - } - if (tools.size >= 5) { - cached$1 = [...tools].sort(); - lastFetch$1 = Date.now(); - return cached$1; - } - } catch { - } - cached$1 = FALLBACK_TOOLS; - lastFetch$1 = Date.now(); - return cached$1; -} - -const FALLBACK_MODELS = [ - { id: "claude-opus-4-6", display_name: "Claude Opus 4.6" }, - { id: "claude-sonnet-4-5-20250929", display_name: "Claude Sonnet 4.5" }, - { id: "claude-haiku-4-5-20251001", display_name: "Claude Haiku 4.5" } -]; -const DOCS_URL = "https://platform.claude.com/docs/en/about-claude/models/overview"; -const MODEL_ID_RE = /claude-(?:opus|sonnet|haiku|3-\d+-(?:opus|sonnet|haiku)|3-(?:opus|sonnet|haiku))-[\w-]*\d+(?:-\d{8})?/g; -let cached = null; -let lastFetch = 0; -const CACHE_TTL = 1e3 * 60 * 60 * 24; -function displayName(id) { - const clean = id.replace(/-\d{8}$/, "").replace(/^claude-/, ""); - const parts = clean.split("-"); - const words = parts.map((p, i) => { - if (/^\d+$/.test(p) && i === parts.length - 1 && parts.length > 1) { - const prev = parts[i - 1]; - if (/^\d+$/.test(prev)) return null; - return p; - } - return p.charAt(0).toUpperCase() + p.slice(1); - }).filter(Boolean); - const result = []; - for (const w of words) { - if (/^\d+$/.test(w) && result.length > 0 && /^\d+$/.test(result[result.length - 1])) { - result[result.length - 1] += "." + w; - } else { - result.push(w); - } - } - return "Claude " + result.join(" "); -} -async function getAvailableModels() { - if (cached && Date.now() - lastFetch < CACHE_TTL) { - return cached; - } - const apiKey = process.env.ANTHROPIC_API_KEY; - if (apiKey) { - try { - const res = await fetch("https://api.anthropic.com/v1/models?limit=100", { - headers: { "x-api-key": apiKey, "anthropic-version": "2023-06-01" }, - signal: AbortSignal.timeout(5e3) - }); - if (res.ok) { - const body = await res.json(); - const models = body.data.filter((m) => m.id.startsWith("claude-")).map((m) => ({ id: m.id, display_name: m.display_name })); - if (models.length > 0) { - cached = models; - lastFetch = Date.now(); - return cached; - } - } - } catch { - } - } - try { - const res = await fetch(DOCS_URL, { signal: AbortSignal.timeout(5e3) }); - if (!res.ok) throw new Error(`HTTP ${res.status}`); - const html = await res.text(); - const seen = /* @__PURE__ */ new Set(); - const models = []; - for (const match of html.matchAll(MODEL_ID_RE)) { - const id = match[0]; - if (id.endsWith("-v1") || id.includes("-v1:")) continue; - if (seen.has(id)) continue; - seen.add(id); - models.push({ id, display_name: displayName(id) }); - } - const deduped = /* @__PURE__ */ new Map(); - for (const m of models) { - const base = m.id.replace(/-\d{8}$/, "").replace(/-0$/, ""); - if (!deduped.has(base) || m.id.length < deduped.get(base).id.length) { - deduped.set(base, m); - } - } - const result = [...deduped.values()]; - if (result.length > 0) { - cached = result; - lastFetch = Date.now(); - return cached; - } - } catch { - } - cached = FALLBACK_MODELS; - lastFetch = Date.now(); - return cached; -} - -export { SkillEditor as S, getAvailableModels as a, getAvailableTools as g }; diff --git a/dist/server/chunks/node_HH9e2ntY.mjs b/dist/server/chunks/node_HH9e2ntY.mjs deleted file mode 100644 index f645092..0000000 --- a/dist/server/chunks/node_HH9e2ntY.mjs +++ /dev/null @@ -1,1896 +0,0 @@ -import { i as isRemoteAllowed, j as joinPaths, a as isRemotePath, r as removeQueryString, b as isParentDirectory } from './remote_B3W5fv4r.mjs'; -import { A as AstroError, E as ExpectedImage, L as LocalImageUsedWrongly, M as MissingImageDimension, U as UnsupportedImageFormat, I as IncompatibleDescriptorOptions, a as UnsupportedImageConversion, t as toStyleString, N as NoImageMetadata, F as FailedToFetchRemoteImageDimensions, b as ExpectedImageOptions, c as ExpectedNotESMImage, d as InvalidImageService, e as createAstro, f as createComponent, g as ImageMissingAlt, m as maybeRenderHead, h as addAttribute, s as spreadAttributes, r as renderTemplate, i as ExperimentalFontsNotEnabled, j as FontFamilyNotFound, u as unescapeHTML } from './astro/server_CF97kUu8.mjs'; -import 'clsx'; -import * as mime from 'mrmime'; -import 'piccolore'; -import { readFile } from 'node:fs/promises'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; -import '../renderers.mjs'; - -const VALID_SUPPORTED_FORMATS = [ - "jpeg", - "jpg", - "png", - "tiff", - "webp", - "gif", - "svg", - "avif" -]; -const DEFAULT_OUTPUT_FORMAT = "webp"; -const DEFAULT_HASH_PROPS = [ - "src", - "width", - "height", - "format", - "quality", - "fit", - "position", - "background" -]; - -const DEFAULT_RESOLUTIONS = [ - 640, - // older and lower-end phones - 750, - // iPhone 6-8 - 828, - // iPhone XR/11 - 960, - // older horizontal phones - 1080, - // iPhone 6-8 Plus - 1280, - // 720p - 1668, - // Various iPads - 1920, - // 1080p - 2048, - // QXGA - 2560, - // WQXGA - 3200, - // QHD+ - 3840, - // 4K - 4480, - // 4.5K - 5120, - // 5K - 6016 - // 6K -]; -const LIMITED_RESOLUTIONS = [ - 640, - // older and lower-end phones - 750, - // iPhone 6-8 - 828, - // iPhone XR/11 - 1080, - // iPhone 6-8 Plus - 1280, - // 720p - 1668, - // Various iPads - 2048, - // QXGA - 2560 - // WQXGA -]; -const getWidths = ({ - width, - layout, - breakpoints = DEFAULT_RESOLUTIONS, - originalWidth -}) => { - const smallerThanOriginal = (w) => !originalWidth || w <= originalWidth; - if (layout === "full-width") { - return breakpoints.filter(smallerThanOriginal); - } - if (!width) { - return []; - } - const doubleWidth = width * 2; - const maxSize = originalWidth ? Math.min(doubleWidth, originalWidth) : doubleWidth; - if (layout === "fixed") { - return originalWidth && width > originalWidth ? [originalWidth] : [width, maxSize]; - } - if (layout === "constrained") { - return [ - // Always include the image at 1x and 2x the specified width - width, - doubleWidth, - ...breakpoints - ].filter((w) => w <= maxSize).sort((a, b) => a - b); - } - return []; -}; -const getSizesAttribute = ({ - width, - layout -}) => { - if (!width || !layout) { - return void 0; - } - switch (layout) { - // If screen is wider than the max size then image width is the max size, - // otherwise it's the width of the screen - case "constrained": - return `(min-width: ${width}px) ${width}px, 100vw`; - // Image is always the same width, whatever the size of the screen - case "fixed": - return `${width}px`; - // Image is always the width of the screen - case "full-width": - return `100vw`; - case "none": - default: - return void 0; - } -}; - -function isESMImportedImage(src) { - return typeof src === "object" || typeof src === "function" && "src" in src; -} -function isRemoteImage(src) { - return typeof src === "string"; -} -async function resolveSrc(src) { - if (typeof src === "object" && "then" in src) { - const resource = await src; - return resource.default ?? resource; - } - return src; -} - -function isLocalService(service) { - if (!service) { - return false; - } - return "transform" in service; -} -function parseQuality(quality) { - let result = parseInt(quality); - if (Number.isNaN(result)) { - return quality; - } - return result; -} -const sortNumeric = (a, b) => a - b; -function verifyOptions(options) { - if (!options.src || !isRemoteImage(options.src) && !isESMImportedImage(options.src)) { - throw new AstroError({ - ...ExpectedImage, - message: ExpectedImage.message( - JSON.stringify(options.src), - typeof options.src, - JSON.stringify(options, (_, v) => v === void 0 ? null : v) - ) - }); - } - if (!isESMImportedImage(options.src)) { - if (options.src.startsWith("/@fs/") || !isRemotePath(options.src) && !options.src.startsWith("/")) { - throw new AstroError({ - ...LocalImageUsedWrongly, - message: LocalImageUsedWrongly.message(options.src) - }); - } - let missingDimension; - if (!options.width && !options.height) { - missingDimension = "both"; - } else if (!options.width && options.height) { - missingDimension = "width"; - } else if (options.width && !options.height) { - missingDimension = "height"; - } - if (missingDimension) { - throw new AstroError({ - ...MissingImageDimension, - message: MissingImageDimension.message(missingDimension, options.src) - }); - } - } else { - if (!VALID_SUPPORTED_FORMATS.includes(options.src.format)) { - throw new AstroError({ - ...UnsupportedImageFormat, - message: UnsupportedImageFormat.message( - options.src.format, - options.src.src, - VALID_SUPPORTED_FORMATS - ) - }); - } - if (options.widths && options.densities) { - throw new AstroError(IncompatibleDescriptorOptions); - } - if (options.src.format === "svg" && options.format !== "svg" || options.src.format !== "svg" && options.format === "svg") { - throw new AstroError(UnsupportedImageConversion); - } - } -} -const baseService = { - validateOptions(options) { - if (isESMImportedImage(options.src) && options.src.format === "svg") { - options.format = "svg"; - } - verifyOptions(options); - if (!options.format) { - options.format = DEFAULT_OUTPUT_FORMAT; - } - if (options.width) options.width = Math.round(options.width); - if (options.height) options.height = Math.round(options.height); - if (options.layout && options.width && options.height) { - options.fit ??= "cover"; - delete options.layout; - } - if (options.fit === "none") { - delete options.fit; - } - return options; - }, - getHTMLAttributes(options) { - const { targetWidth, targetHeight } = getTargetDimensions(options); - const { - src, - width, - height, - format, - quality, - densities, - widths, - formats, - layout, - priority, - fit, - position, - background, - ...attributes - } = options; - return { - ...attributes, - width: targetWidth, - height: targetHeight, - loading: attributes.loading ?? "lazy", - decoding: attributes.decoding ?? "async" - }; - }, - getSrcSet(options) { - const { targetWidth, targetHeight } = getTargetDimensions(options); - const aspectRatio = targetWidth / targetHeight; - const { widths, densities } = options; - const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT; - let transformedWidths = (widths ?? []).sort(sortNumeric); - let imageWidth = options.width; - let maxWidth = Infinity; - if (isESMImportedImage(options.src)) { - imageWidth = options.src.width; - maxWidth = imageWidth; - if (transformedWidths.length > 0 && transformedWidths.at(-1) > maxWidth) { - transformedWidths = transformedWidths.filter((width) => width <= maxWidth); - transformedWidths.push(maxWidth); - } - } - transformedWidths = Array.from(new Set(transformedWidths)); - const { - width: transformWidth, - height: transformHeight, - ...transformWithoutDimensions - } = options; - let allWidths = []; - if (densities) { - const densityValues = densities.map((density) => { - if (typeof density === "number") { - return density; - } else { - return parseFloat(density); - } - }); - const densityWidths = densityValues.sort(sortNumeric).map((density) => Math.round(targetWidth * density)); - allWidths = densityWidths.map((width, index) => ({ - width, - descriptor: `${densityValues[index]}x` - })); - } else if (transformedWidths.length > 0) { - allWidths = transformedWidths.map((width) => ({ - width, - descriptor: `${width}w` - })); - } - return allWidths.map(({ width, descriptor }) => { - const height = Math.round(width / aspectRatio); - const transform = { ...transformWithoutDimensions, width, height }; - return { - transform, - descriptor, - attributes: { - type: `image/${targetFormat}` - } - }; - }); - }, - getURL(options, imageConfig) { - const searchParams = new URLSearchParams(); - if (isESMImportedImage(options.src)) { - searchParams.append("href", options.src.src); - } else if (isRemoteAllowed(options.src, imageConfig)) { - searchParams.append("href", options.src); - } else { - return options.src; - } - const params = { - w: "width", - h: "height", - q: "quality", - f: "format", - fit: "fit", - position: "position", - background: "background" - }; - Object.entries(params).forEach(([param, key]) => { - options[key] && searchParams.append(param, options[key].toString()); - }); - const imageEndpoint = joinPaths("/", imageConfig.endpoint.route); - let url = `${imageEndpoint}?${searchParams}`; - if (imageConfig.assetQueryParams) { - const assetQueryString = imageConfig.assetQueryParams.toString(); - if (assetQueryString) { - url += "&" + assetQueryString; - } - } - return url; - }, - parseURL(url) { - const params = url.searchParams; - if (!params.has("href")) { - return void 0; - } - const transform = { - src: params.get("href"), - width: params.has("w") ? parseInt(params.get("w")) : void 0, - height: params.has("h") ? parseInt(params.get("h")) : void 0, - format: params.get("f"), - quality: params.get("q"), - fit: params.get("fit"), - position: params.get("position") ?? void 0, - background: params.get("background") ?? void 0 - }; - return transform; - } -}; -function getTargetDimensions(options) { - let targetWidth = options.width; - let targetHeight = options.height; - if (isESMImportedImage(options.src)) { - const aspectRatio = options.src.width / options.src.height; - if (targetHeight && !targetWidth) { - targetWidth = Math.round(targetHeight * aspectRatio); - } else if (targetWidth && !targetHeight) { - targetHeight = Math.round(targetWidth / aspectRatio); - } else if (!targetWidth && !targetHeight) { - targetWidth = options.src.width; - targetHeight = options.src.height; - } - } - return { - targetWidth, - targetHeight - }; -} - -function isImageMetadata(src) { - return src.fsPath && !("fsPath" in src); -} - -const cssFitValues = ["fill", "contain", "cover", "scale-down"]; -function addCSSVarsToStyle(vars, styles) { - const cssVars = Object.entries(vars).filter(([_, value]) => value !== void 0 && value !== false).map(([key, value]) => `--${key}: ${value};`).join(" "); - if (!styles) { - return cssVars; - } - const style = typeof styles === "string" ? styles : toStyleString(styles); - return `${cssVars} ${style}`; -} - -const decoder = new TextDecoder(); -const toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end)); -const toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + `0${i.toString(16)}`.slice(-2), ""); -const getView = (input, offset) => new DataView(input.buffer, input.byteOffset + offset); -const readInt16LE = (input, offset = 0) => getView(input, offset).getInt16(0, true); -const readUInt16BE = (input, offset = 0) => getView(input, offset).getUint16(0, false); -const readUInt16LE = (input, offset = 0) => getView(input, offset).getUint16(0, true); -const readUInt24LE = (input, offset = 0) => { - const view = getView(input, offset); - return view.getUint16(0, true) + (view.getUint8(2) << 16); -}; -const readInt32LE = (input, offset = 0) => getView(input, offset).getInt32(0, true); -const readUInt32BE = (input, offset = 0) => getView(input, offset).getUint32(0, false); -const readUInt32LE = (input, offset = 0) => getView(input, offset).getUint32(0, true); -const readUInt64 = (input, offset, isBigEndian) => getView(input, offset).getBigUint64(0, !isBigEndian); -const methods = { - readUInt16BE, - readUInt16LE, - readUInt32BE, - readUInt32LE -}; -function readUInt(input, bits, offset = 0, isBigEndian = false) { - const endian = isBigEndian ? "BE" : "LE"; - const methodName = `readUInt${bits}${endian}`; - return methods[methodName](input, offset); -} -function readBox(input, offset) { - if (input.length - offset < 4) return; - const boxSize = readUInt32BE(input, offset); - if (input.length - offset < boxSize) return; - return { - name: toUTF8String(input, 4 + offset, 8 + offset), - offset, - size: boxSize - }; -} -function findBox(input, boxName, currentOffset) { - while (currentOffset < input.length) { - const box = readBox(input, currentOffset); - if (!box) break; - if (box.name === boxName) return box; - currentOffset += box.size > 0 ? box.size : 8; - } -} - -const BMP = { - validate: (input) => toUTF8String(input, 0, 2) === "BM", - calculate: (input) => ({ - height: Math.abs(readInt32LE(input, 22)), - width: readUInt32LE(input, 18) - }) -}; - -const TYPE_ICON = 1; -const SIZE_HEADER$1 = 2 + 2 + 2; -const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4; -function getSizeFromOffset(input, offset) { - const value = input[offset]; - return value === 0 ? 256 : value; -} -function getImageSize$1(input, imageIndex) { - const offset = SIZE_HEADER$1 + imageIndex * SIZE_IMAGE_ENTRY; - return { - height: getSizeFromOffset(input, offset + 1), - width: getSizeFromOffset(input, offset) - }; -} -const ICO = { - validate(input) { - const reserved = readUInt16LE(input, 0); - const imageCount = readUInt16LE(input, 4); - if (reserved !== 0 || imageCount === 0) return false; - const imageType = readUInt16LE(input, 2); - return imageType === TYPE_ICON; - }, - calculate(input) { - const nbImages = readUInt16LE(input, 4); - const imageSize = getImageSize$1(input, 0); - if (nbImages === 1) return imageSize; - const images = []; - for (let imageIndex = 0; imageIndex < nbImages; imageIndex += 1) { - images.push(getImageSize$1(input, imageIndex)); - } - return { - width: imageSize.width, - height: imageSize.height, - images - }; - } -}; - -const TYPE_CURSOR = 2; -const CUR = { - validate(input) { - const reserved = readUInt16LE(input, 0); - const imageCount = readUInt16LE(input, 4); - if (reserved !== 0 || imageCount === 0) return false; - const imageType = readUInt16LE(input, 2); - return imageType === TYPE_CURSOR; - }, - calculate: (input) => ICO.calculate(input) -}; - -const DDS = { - validate: (input) => readUInt32LE(input, 0) === 542327876, - calculate: (input) => ({ - height: readUInt32LE(input, 12), - width: readUInt32LE(input, 16) - }) -}; - -const gifRegexp = /^GIF8[79]a/; -const GIF = { - validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)), - calculate: (input) => ({ - height: readUInt16LE(input, 8), - width: readUInt16LE(input, 6) - }) -}; - -const brandMap = { - avif: "avif", - avis: "avif", - // avif-sequence - mif1: "heif", - msf1: "heif", - // heif-sequence - heic: "heic", - heix: "heic", - hevc: "heic", - // heic-sequence - hevx: "heic" - // heic-sequence -}; -function detectType(input, start, end) { - let hasAvif = false; - let hasHeic = false; - let hasHeif = false; - for (let i = start; i <= end; i += 4) { - const brand = toUTF8String(input, i, i + 4); - if (brand === "avif" || brand === "avis") hasAvif = true; - else if (brand === "heic" || brand === "heix" || brand === "hevc" || brand === "hevx") hasHeic = true; - else if (brand === "mif1" || brand === "msf1") hasHeif = true; - } - if (hasAvif) return "avif"; - if (hasHeic) return "heic"; - if (hasHeif) return "heif"; -} -const HEIF = { - validate(input) { - const boxType = toUTF8String(input, 4, 8); - if (boxType !== "ftyp") return false; - const ftypBox = findBox(input, "ftyp", 0); - if (!ftypBox) return false; - const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12); - return brand in brandMap; - }, - calculate(input) { - const metaBox = findBox(input, "meta", 0); - const iprpBox = metaBox && findBox(input, "iprp", metaBox.offset + 12); - const ipcoBox = iprpBox && findBox(input, "ipco", iprpBox.offset + 8); - if (!ipcoBox) { - throw new TypeError("Invalid HEIF, no ipco box found"); - } - const type = detectType(input, 8, metaBox.offset); - const images = []; - let currentOffset = ipcoBox.offset + 8; - while (currentOffset < ipcoBox.offset + ipcoBox.size) { - const ispeBox = findBox(input, "ispe", currentOffset); - if (!ispeBox) break; - const rawWidth = readUInt32BE(input, ispeBox.offset + 12); - const rawHeight = readUInt32BE(input, ispeBox.offset + 16); - const clapBox = findBox(input, "clap", currentOffset); - let width = rawWidth; - let height = rawHeight; - if (clapBox && clapBox.offset < ipcoBox.offset + ipcoBox.size) { - const cropRight = readUInt32BE(input, clapBox.offset + 12); - width = rawWidth - cropRight; - } - images.push({ height, width }); - currentOffset = ispeBox.offset + ispeBox.size; - } - if (images.length === 0) { - throw new TypeError("Invalid HEIF, no sizes found"); - } - return { - width: images[0].width, - height: images[0].height, - type, - ...images.length > 1 ? { images } : {} - }; - } -}; - -const SIZE_HEADER = 4 + 4; -const FILE_LENGTH_OFFSET = 4; -const ENTRY_LENGTH_OFFSET = 4; -const ICON_TYPE_SIZE = { - ICON: 32, - "ICN#": 32, - // m => 16 x 16 - "icm#": 16, - icm4: 16, - icm8: 16, - // s => 16 x 16 - "ics#": 16, - ics4: 16, - ics8: 16, - is32: 16, - s8mk: 16, - icp4: 16, - // l => 32 x 32 - icl4: 32, - icl8: 32, - il32: 32, - l8mk: 32, - icp5: 32, - ic11: 32, - // h => 48 x 48 - ich4: 48, - ich8: 48, - ih32: 48, - h8mk: 48, - // . => 64 x 64 - icp6: 64, - ic12: 32, - // t => 128 x 128 - it32: 128, - t8mk: 128, - ic07: 128, - // . => 256 x 256 - ic08: 256, - ic13: 256, - // . => 512 x 512 - ic09: 512, - ic14: 512, - // . => 1024 x 1024 - ic10: 1024 -}; -function readImageHeader(input, imageOffset) { - const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET; - return [ - toUTF8String(input, imageOffset, imageLengthOffset), - readUInt32BE(input, imageLengthOffset) - ]; -} -function getImageSize(type) { - const size = ICON_TYPE_SIZE[type]; - return { width: size, height: size, type }; -} -const ICNS = { - validate: (input) => toUTF8String(input, 0, 4) === "icns", - calculate(input) { - const inputLength = input.length; - const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET); - let imageOffset = SIZE_HEADER; - const images = []; - while (imageOffset < fileLength && imageOffset < inputLength) { - const imageHeader = readImageHeader(input, imageOffset); - const imageSize = getImageSize(imageHeader[0]); - images.push(imageSize); - imageOffset += imageHeader[1]; - } - if (images.length === 0) { - throw new TypeError("Invalid ICNS, no sizes found"); - } - return { - width: images[0].width, - height: images[0].height, - ...images.length > 1 ? { images } : {} - }; - } -}; - -const J2C = { - // TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC - validate: (input) => readUInt32BE(input, 0) === 4283432785, - calculate: (input) => ({ - height: readUInt32BE(input, 12), - width: readUInt32BE(input, 8) - }) -}; - -const JP2 = { - validate(input) { - const boxType = toUTF8String(input, 4, 8); - if (boxType !== "jP ") return false; - const ftypBox = findBox(input, "ftyp", 0); - if (!ftypBox) return false; - const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12); - return brand === "jp2 "; - }, - calculate(input) { - const jp2hBox = findBox(input, "jp2h", 0); - const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8); - if (ihdrBox) { - return { - height: readUInt32BE(input, ihdrBox.offset + 8), - width: readUInt32BE(input, ihdrBox.offset + 12) - }; - } - throw new TypeError("Unsupported JPEG 2000 format"); - } -}; - -const EXIF_MARKER = "45786966"; -const APP1_DATA_SIZE_BYTES = 2; -const EXIF_HEADER_BYTES = 6; -const TIFF_BYTE_ALIGN_BYTES = 2; -const BIG_ENDIAN_BYTE_ALIGN = "4d4d"; -const LITTLE_ENDIAN_BYTE_ALIGN = "4949"; -const IDF_ENTRY_BYTES = 12; -const NUM_DIRECTORY_ENTRIES_BYTES = 2; -function isEXIF(input) { - return toHexString(input, 2, 6) === EXIF_MARKER; -} -function extractSize(input, index) { - return { - height: readUInt16BE(input, index), - width: readUInt16BE(input, index + 2) - }; -} -function extractOrientation(exifBlock, isBigEndian) { - const idfOffset = 8; - const offset = EXIF_HEADER_BYTES + idfOffset; - const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian); - for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { - const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES; - const end = start + IDF_ENTRY_BYTES; - if (start > exifBlock.length) { - return; - } - const block = exifBlock.slice(start, end); - const tagNumber = readUInt(block, 16, 0, isBigEndian); - if (tagNumber === 274) { - const dataFormat = readUInt(block, 16, 2, isBigEndian); - if (dataFormat !== 3) { - return; - } - const numberOfComponents = readUInt(block, 32, 4, isBigEndian); - if (numberOfComponents !== 1) { - return; - } - return readUInt(block, 16, 8, isBigEndian); - } - } -} -function validateExifBlock(input, index) { - const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index); - const byteAlign = toHexString( - exifBlock, - EXIF_HEADER_BYTES, - EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES - ); - const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN; - const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN; - if (isBigEndian || isLittleEndian) { - return extractOrientation(exifBlock, isBigEndian); - } -} -function validateInput(input, index) { - if (index > input.length) { - throw new TypeError("Corrupt JPG, exceeded buffer limits"); - } -} -const JPG = { - validate: (input) => toHexString(input, 0, 2) === "ffd8", - calculate(_input) { - let input = _input.slice(4); - let orientation; - let next; - while (input.length) { - const i = readUInt16BE(input, 0); - validateInput(input, i); - if (input[i] !== 255) { - input = input.slice(1); - continue; - } - if (isEXIF(input)) { - orientation = validateExifBlock(input, i); - } - next = input[i + 1]; - if (next === 192 || next === 193 || next === 194) { - const size = extractSize(input, i + 5); - if (!orientation) { - return size; - } - return { - height: size.height, - orientation, - width: size.width - }; - } - input = input.slice(i + 2); - } - throw new TypeError("Invalid JPG, no size found"); - } -}; - -class BitReader { - constructor(input, endianness) { - this.input = input; - this.endianness = endianness; - } - // Skip the first 16 bits (2 bytes) of signature - byteOffset = 2; - bitOffset = 0; - /** Reads a specified number of bits, and move the offset */ - getBits(length = 1) { - let result = 0; - let bitsRead = 0; - while (bitsRead < length) { - if (this.byteOffset >= this.input.length) { - throw new Error("Reached end of input"); - } - const currentByte = this.input[this.byteOffset]; - const bitsLeft = 8 - this.bitOffset; - const bitsToRead = Math.min(length - bitsRead, bitsLeft); - if (this.endianness === "little-endian") { - const mask = (1 << bitsToRead) - 1; - const bits = currentByte >> this.bitOffset & mask; - result |= bits << bitsRead; - } else { - const mask = (1 << bitsToRead) - 1 << 8 - this.bitOffset - bitsToRead; - const bits = (currentByte & mask) >> 8 - this.bitOffset - bitsToRead; - result = result << bitsToRead | bits; - } - bitsRead += bitsToRead; - this.bitOffset += bitsToRead; - if (this.bitOffset === 8) { - this.byteOffset++; - this.bitOffset = 0; - } - } - return result; - } -} - -function calculateImageDimension(reader, isSmallImage) { - if (isSmallImage) { - return 8 * (1 + reader.getBits(5)); - } - const sizeClass = reader.getBits(2); - const extraBits = [9, 13, 18, 30][sizeClass]; - return 1 + reader.getBits(extraBits); -} -function calculateImageWidth(reader, isSmallImage, widthMode, height) { - if (isSmallImage && widthMode === 0) { - return 8 * (1 + reader.getBits(5)); - } - if (widthMode === 0) { - return calculateImageDimension(reader, false); - } - const aspectRatios = [1, 1.2, 4 / 3, 1.5, 16 / 9, 5 / 4, 2]; - return Math.floor(height * aspectRatios[widthMode - 1]); -} -const JXLStream = { - validate: (input) => { - return toHexString(input, 0, 2) === "ff0a"; - }, - calculate(input) { - const reader = new BitReader(input, "little-endian"); - const isSmallImage = reader.getBits(1) === 1; - const height = calculateImageDimension(reader, isSmallImage); - const widthMode = reader.getBits(3); - const width = calculateImageWidth(reader, isSmallImage, widthMode, height); - return { width, height }; - } -}; - -function extractCodestream(input) { - const jxlcBox = findBox(input, "jxlc", 0); - if (jxlcBox) { - return input.slice(jxlcBox.offset + 8, jxlcBox.offset + jxlcBox.size); - } - const partialStreams = extractPartialStreams(input); - if (partialStreams.length > 0) { - return concatenateCodestreams(partialStreams); - } - return void 0; -} -function extractPartialStreams(input) { - const partialStreams = []; - let offset = 0; - while (offset < input.length) { - const jxlpBox = findBox(input, "jxlp", offset); - if (!jxlpBox) break; - partialStreams.push( - input.slice(jxlpBox.offset + 12, jxlpBox.offset + jxlpBox.size) - ); - offset = jxlpBox.offset + jxlpBox.size; - } - return partialStreams; -} -function concatenateCodestreams(partialCodestreams) { - const totalLength = partialCodestreams.reduce( - (acc, curr) => acc + curr.length, - 0 - ); - const codestream = new Uint8Array(totalLength); - let position = 0; - for (const partial of partialCodestreams) { - codestream.set(partial, position); - position += partial.length; - } - return codestream; -} -const JXL = { - validate: (input) => { - const boxType = toUTF8String(input, 4, 8); - if (boxType !== "JXL ") return false; - const ftypBox = findBox(input, "ftyp", 0); - if (!ftypBox) return false; - const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12); - return brand === "jxl "; - }, - calculate(input) { - const codestream = extractCodestream(input); - if (codestream) return JXLStream.calculate(codestream); - throw new Error("No codestream found in JXL container"); - } -}; - -const KTX = { - validate: (input) => { - const signature = toUTF8String(input, 1, 7); - return ["KTX 11", "KTX 20"].includes(signature); - }, - calculate: (input) => { - const type = input[5] === 49 ? "ktx" : "ktx2"; - const offset = type === "ktx" ? 36 : 20; - return { - height: readUInt32LE(input, offset + 4), - width: readUInt32LE(input, offset), - type - }; - } -}; - -const pngSignature = "PNG\r\n\n"; -const pngImageHeaderChunkName = "IHDR"; -const pngFriedChunkName = "CgBI"; -const PNG = { - validate(input) { - if (pngSignature === toUTF8String(input, 1, 8)) { - let chunkName = toUTF8String(input, 12, 16); - if (chunkName === pngFriedChunkName) { - chunkName = toUTF8String(input, 28, 32); - } - if (chunkName !== pngImageHeaderChunkName) { - throw new TypeError("Invalid PNG"); - } - return true; - } - return false; - }, - calculate(input) { - if (toUTF8String(input, 12, 16) === pngFriedChunkName) { - return { - height: readUInt32BE(input, 36), - width: readUInt32BE(input, 32) - }; - } - return { - height: readUInt32BE(input, 20), - width: readUInt32BE(input, 16) - }; - } -}; - -const PNMTypes = { - P1: "pbm/ascii", - P2: "pgm/ascii", - P3: "ppm/ascii", - P4: "pbm", - P5: "pgm", - P6: "ppm", - P7: "pam", - PF: "pfm" -}; -const handlers = { - default: (lines) => { - let dimensions = []; - while (lines.length > 0) { - const line = lines.shift(); - if (line[0] === "#") { - continue; - } - dimensions = line.split(" "); - break; - } - if (dimensions.length === 2) { - return { - height: Number.parseInt(dimensions[1], 10), - width: Number.parseInt(dimensions[0], 10) - }; - } - throw new TypeError("Invalid PNM"); - }, - pam: (lines) => { - const size = {}; - while (lines.length > 0) { - const line = lines.shift(); - if (line.length > 16 || line.charCodeAt(0) > 128) { - continue; - } - const [key, value] = line.split(" "); - if (key && value) { - size[key.toLowerCase()] = Number.parseInt(value, 10); - } - if (size.height && size.width) { - break; - } - } - if (size.height && size.width) { - return { - height: size.height, - width: size.width - }; - } - throw new TypeError("Invalid PAM"); - } -}; -const PNM = { - validate: (input) => toUTF8String(input, 0, 2) in PNMTypes, - calculate(input) { - const signature = toUTF8String(input, 0, 2); - const type = PNMTypes[signature]; - const lines = toUTF8String(input, 3).split(/[\r\n]+/); - const handler = handlers[type] || handlers.default; - return handler(lines); - } -}; - -const PSD = { - validate: (input) => toUTF8String(input, 0, 4) === "8BPS", - calculate: (input) => ({ - height: readUInt32BE(input, 14), - width: readUInt32BE(input, 18) - }) -}; - -const svgReg = /"']|"[^"]*"|'[^']*')*>/; -const extractorRegExps = { - height: /\sheight=(['"])([^%]+?)\1/, - root: svgReg, - viewbox: /\sviewBox=(['"])(.+?)\1/i, - width: /\swidth=(['"])([^%]+?)\1/ -}; -const INCH_CM = 2.54; -const units = { - in: 96, - cm: 96 / INCH_CM, - em: 16, - ex: 8, - m: 96 / INCH_CM * 100, - mm: 96 / INCH_CM / 10, - pc: 96 / 72 / 12, - pt: 96 / 72, - px: 1 -}; -const unitsReg = new RegExp( - `^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join("|")})?$` -); -function parseLength(len) { - const m = unitsReg.exec(len); - if (!m) { - return void 0; - } - return Math.round(Number(m[1]) * (units[m[2]] || 1)); -} -function parseViewbox(viewbox) { - const bounds = viewbox.split(" "); - return { - height: parseLength(bounds[3]), - width: parseLength(bounds[2]) - }; -} -function parseAttributes(root) { - const width = extractorRegExps.width.exec(root); - const height = extractorRegExps.height.exec(root); - const viewbox = extractorRegExps.viewbox.exec(root); - return { - height: height && parseLength(height[2]), - viewbox: viewbox && parseViewbox(viewbox[2]), - width: width && parseLength(width[2]) - }; -} -function calculateByDimensions(attrs) { - return { - height: attrs.height, - width: attrs.width - }; -} -function calculateByViewbox(attrs, viewbox) { - const ratio = viewbox.width / viewbox.height; - if (attrs.width) { - return { - height: Math.floor(attrs.width / ratio), - width: attrs.width - }; - } - if (attrs.height) { - return { - height: attrs.height, - width: Math.floor(attrs.height * ratio) - }; - } - return { - height: viewbox.height, - width: viewbox.width - }; -} -const SVG = { - // Scan only the first kilo-byte to speed up the check on larger files - validate: (input) => svgReg.test(toUTF8String(input, 0, 1e3)), - calculate(input) { - const root = extractorRegExps.root.exec(toUTF8String(input)); - if (root) { - const attrs = parseAttributes(root[0]); - if (attrs.width && attrs.height) { - return calculateByDimensions(attrs); - } - if (attrs.viewbox) { - return calculateByViewbox(attrs, attrs.viewbox); - } - } - throw new TypeError("Invalid SVG"); - } -}; - -const TGA = { - validate(input) { - return readUInt16LE(input, 0) === 0 && readUInt16LE(input, 4) === 0; - }, - calculate(input) { - return { - height: readUInt16LE(input, 14), - width: readUInt16LE(input, 12) - }; - } -}; - -const CONSTANTS = { - TAG: { - WIDTH: 256, - HEIGHT: 257, - COMPRESSION: 259 - }, - TYPE: { - SHORT: 3, - LONG: 4, - LONG8: 16 - }, - ENTRY_SIZE: { - STANDARD: 12, - BIG: 20 - }, - COUNT_SIZE: { - STANDARD: 2, - BIG: 8 - } -}; -function readIFD(input, { isBigEndian, isBigTiff }) { - const ifdOffset = isBigTiff ? Number(readUInt64(input, 8, isBigEndian)) : readUInt(input, 32, 4, isBigEndian); - const entryCountSize = isBigTiff ? CONSTANTS.COUNT_SIZE.BIG : CONSTANTS.COUNT_SIZE.STANDARD; - return input.slice(ifdOffset + entryCountSize); -} -function readTagValue(input, type, offset, isBigEndian) { - switch (type) { - case CONSTANTS.TYPE.SHORT: - return readUInt(input, 16, offset, isBigEndian); - case CONSTANTS.TYPE.LONG: - return readUInt(input, 32, offset, isBigEndian); - case CONSTANTS.TYPE.LONG8: { - const value = Number(readUInt64(input, offset, isBigEndian)); - if (value > Number.MAX_SAFE_INTEGER) { - throw new TypeError("Value too large"); - } - return value; - } - default: - return 0; - } -} -function nextTag(input, isBigTiff) { - const entrySize = isBigTiff ? CONSTANTS.ENTRY_SIZE.BIG : CONSTANTS.ENTRY_SIZE.STANDARD; - if (input.length > entrySize) { - return input.slice(entrySize); - } -} -function extractTags(input, { isBigEndian, isBigTiff }) { - const tags = {}; - let temp = input; - while (temp?.length) { - const code = readUInt(temp, 16, 0, isBigEndian); - const type = readUInt(temp, 16, 2, isBigEndian); - const length = isBigTiff ? Number(readUInt64(temp, 4, isBigEndian)) : readUInt(temp, 32, 4, isBigEndian); - if (code === 0) break; - if (length === 1 && (type === CONSTANTS.TYPE.SHORT || type === CONSTANTS.TYPE.LONG || isBigTiff && type === CONSTANTS.TYPE.LONG8)) { - const valueOffset = isBigTiff ? 12 : 8; - tags[code] = readTagValue(temp, type, valueOffset, isBigEndian); - } - temp = nextTag(temp, isBigTiff); - } - return tags; -} -function determineFormat(input) { - const signature = toUTF8String(input, 0, 2); - const version = readUInt(input, 16, 2, signature === "MM"); - return { - isBigEndian: signature === "MM", - isBigTiff: version === 43 - }; -} -function validateBigTIFFHeader(input, isBigEndian) { - const byteSize = readUInt(input, 16, 4, isBigEndian); - const reserved = readUInt(input, 16, 6, isBigEndian); - if (byteSize !== 8 || reserved !== 0) { - throw new TypeError("Invalid BigTIFF header"); - } -} -const signatures = /* @__PURE__ */ new Set([ - "49492a00", - // Little Endian - "4d4d002a", - // Big Endian - "49492b00", - // BigTIFF Little Endian - "4d4d002b" - // BigTIFF Big Endian -]); -const TIFF = { - validate: (input) => { - const signature = toHexString(input, 0, 4); - return signatures.has(signature); - }, - calculate(input) { - const format = determineFormat(input); - if (format.isBigTiff) { - validateBigTIFFHeader(input, format.isBigEndian); - } - const ifdBuffer = readIFD(input, format); - const tags = extractTags(ifdBuffer, format); - const info = { - height: tags[CONSTANTS.TAG.HEIGHT], - width: tags[CONSTANTS.TAG.WIDTH], - type: format.isBigTiff ? "bigtiff" : "tiff" - }; - if (tags[CONSTANTS.TAG.COMPRESSION]) { - info.compression = tags[CONSTANTS.TAG.COMPRESSION]; - } - if (!info.width || !info.height) { - throw new TypeError("Invalid Tiff. Missing tags"); - } - return info; - } -}; - -function calculateExtended(input) { - return { - height: 1 + readUInt24LE(input, 7), - width: 1 + readUInt24LE(input, 4) - }; -} -function calculateLossless(input) { - return { - height: 1 + ((input[4] & 15) << 10 | input[3] << 2 | (input[2] & 192) >> 6), - width: 1 + ((input[2] & 63) << 8 | input[1]) - }; -} -function calculateLossy(input) { - return { - height: readInt16LE(input, 8) & 16383, - width: readInt16LE(input, 6) & 16383 - }; -} -const WEBP = { - validate(input) { - const riffHeader = "RIFF" === toUTF8String(input, 0, 4); - const webpHeader = "WEBP" === toUTF8String(input, 8, 12); - const vp8Header = "VP8" === toUTF8String(input, 12, 15); - return riffHeader && webpHeader && vp8Header; - }, - calculate(_input) { - const chunkHeader = toUTF8String(_input, 12, 16); - const input = _input.slice(20, 30); - if (chunkHeader === "VP8X") { - const extendedHeader = input[0]; - const validStart = (extendedHeader & 192) === 0; - const validEnd = (extendedHeader & 1) === 0; - if (validStart && validEnd) { - return calculateExtended(input); - } - throw new TypeError("Invalid WebP"); - } - if (chunkHeader === "VP8 " && input[0] !== 47) { - return calculateLossy(input); - } - const signature = toHexString(input, 3, 6); - if (chunkHeader === "VP8L" && signature !== "9d012a") { - return calculateLossless(input); - } - throw new TypeError("Invalid WebP"); - } -}; - -const typeHandlers = /* @__PURE__ */ new Map([ - ["bmp", BMP], - ["cur", CUR], - ["dds", DDS], - ["gif", GIF], - ["heif", HEIF], - ["icns", ICNS], - ["ico", ICO], - ["j2c", J2C], - ["jp2", JP2], - ["jpg", JPG], - ["jxl", JXL], - ["jxl-stream", JXLStream], - ["ktx", KTX], - ["png", PNG], - ["pnm", PNM], - ["psd", PSD], - ["svg", SVG], - ["tga", TGA], - ["tiff", TIFF], - ["webp", WEBP] -]); -const types = Array.from(typeHandlers.keys()); - -const firstBytes = /* @__PURE__ */ new Map([ - [0, "heif"], - [56, "psd"], - [66, "bmp"], - [68, "dds"], - [71, "gif"], - [73, "tiff"], - [77, "tiff"], - [82, "webp"], - [105, "icns"], - [137, "png"], - [255, "jpg"] -]); -function detector(input) { - const byte = input[0]; - const type = firstBytes.get(byte); - if (type && typeHandlers.get(type).validate(input)) { - return type; - } - return types.find((imageType) => typeHandlers.get(imageType).validate(input)); -} - -function lookup(input) { - const type = detector(input); - if (typeof type !== "undefined") { - const size = typeHandlers.get(type).calculate(input); - if (size !== void 0) { - size.type = size.type ?? type; - return size; - } - } - throw new TypeError("unsupported file type: " + type); -} - -async function imageMetadata(data, src) { - let result; - try { - result = lookup(data); - } catch { - throw new AstroError({ - ...NoImageMetadata, - message: NoImageMetadata.message(src) - }); - } - if (!result.height || !result.width || !result.type) { - throw new AstroError({ - ...NoImageMetadata, - message: NoImageMetadata.message(src) - }); - } - const { width, height, type, orientation } = result; - const isPortrait = (orientation || 0) >= 5; - return { - width: isPortrait ? height : width, - height: isPortrait ? width : height, - format: type, - orientation - }; -} - -async function inferRemoteSize(url) { - const response = await fetch(url); - if (!response.body || !response.ok) { - throw new AstroError({ - ...FailedToFetchRemoteImageDimensions, - message: FailedToFetchRemoteImageDimensions.message(url) - }); - } - const reader = response.body.getReader(); - let done, value; - let accumulatedChunks = new Uint8Array(); - while (!done) { - const readResult = await reader.read(); - done = readResult.done; - if (done) break; - if (readResult.value) { - value = readResult.value; - let tmp = new Uint8Array(accumulatedChunks.length + value.length); - tmp.set(accumulatedChunks, 0); - tmp.set(value, accumulatedChunks.length); - accumulatedChunks = tmp; - try { - const dimensions = await imageMetadata(accumulatedChunks, url); - if (dimensions) { - await reader.cancel(); - return dimensions; - } - } catch { - } - } - } - throw new AstroError({ - ...NoImageMetadata, - message: NoImageMetadata.message(url) - }); -} - -const PLACEHOLDER_BASE = "astro://placeholder"; -function createPlaceholderURL(pathOrUrl) { - return new URL(pathOrUrl, PLACEHOLDER_BASE); -} -function stringifyPlaceholderURL(url) { - return url.href.replace(PLACEHOLDER_BASE, ""); -} - -async function getConfiguredImageService() { - if (!globalThis?.astroAsset?.imageService) { - const { default: service } = await import( - // @ts-expect-error - './sharp_D9uxjd11.mjs' - ).catch((e) => { - const error = new AstroError(InvalidImageService); - error.cause = e; - throw error; - }); - if (!globalThis.astroAsset) globalThis.astroAsset = {}; - globalThis.astroAsset.imageService = service; - return service; - } - return globalThis.astroAsset.imageService; -} -async function getImage$1(options, imageConfig) { - if (!options || typeof options !== "object") { - throw new AstroError({ - ...ExpectedImageOptions, - message: ExpectedImageOptions.message(JSON.stringify(options)) - }); - } - if (typeof options.src === "undefined") { - throw new AstroError({ - ...ExpectedImage, - message: ExpectedImage.message( - options.src, - "undefined", - JSON.stringify(options) - ) - }); - } - if (isImageMetadata(options)) { - throw new AstroError(ExpectedNotESMImage); - } - const service = await getConfiguredImageService(); - const resolvedOptions = { - ...options, - src: await resolveSrc(options.src) - }; - let originalWidth; - let originalHeight; - if (options.inferSize && isRemoteImage(resolvedOptions.src) && isRemotePath(resolvedOptions.src)) { - const result = await inferRemoteSize(resolvedOptions.src); - resolvedOptions.width ??= result.width; - resolvedOptions.height ??= result.height; - originalWidth = result.width; - originalHeight = result.height; - delete resolvedOptions.inferSize; - } - const originalFilePath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : void 0; - const clonedSrc = isESMImportedImage(resolvedOptions.src) ? ( - // @ts-expect-error - clone is a private, hidden prop - resolvedOptions.src.clone ?? resolvedOptions.src - ) : resolvedOptions.src; - if (isESMImportedImage(clonedSrc)) { - originalWidth = clonedSrc.width; - originalHeight = clonedSrc.height; - } - if (originalWidth && originalHeight) { - const aspectRatio = originalWidth / originalHeight; - if (resolvedOptions.height && !resolvedOptions.width) { - resolvedOptions.width = Math.round(resolvedOptions.height * aspectRatio); - } else if (resolvedOptions.width && !resolvedOptions.height) { - resolvedOptions.height = Math.round(resolvedOptions.width / aspectRatio); - } else if (!resolvedOptions.width && !resolvedOptions.height) { - resolvedOptions.width = originalWidth; - resolvedOptions.height = originalHeight; - } - } - resolvedOptions.src = clonedSrc; - const layout = options.layout ?? imageConfig.layout ?? "none"; - if (resolvedOptions.priority) { - resolvedOptions.loading ??= "eager"; - resolvedOptions.decoding ??= "sync"; - resolvedOptions.fetchpriority ??= "high"; - delete resolvedOptions.priority; - } else { - resolvedOptions.loading ??= "lazy"; - resolvedOptions.decoding ??= "async"; - resolvedOptions.fetchpriority ??= "auto"; - } - if (layout !== "none") { - resolvedOptions.widths ||= getWidths({ - width: resolvedOptions.width, - layout, - originalWidth, - breakpoints: imageConfig.breakpoints?.length ? imageConfig.breakpoints : isLocalService(service) ? LIMITED_RESOLUTIONS : DEFAULT_RESOLUTIONS - }); - resolvedOptions.sizes ||= getSizesAttribute({ width: resolvedOptions.width, layout }); - delete resolvedOptions.densities; - resolvedOptions.style = addCSSVarsToStyle( - { - fit: cssFitValues.includes(resolvedOptions.fit ?? "") && resolvedOptions.fit, - pos: resolvedOptions.position - }, - resolvedOptions.style - ); - resolvedOptions["data-astro-image"] = layout; - } - const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions; - const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : []; - let imageURL = await service.getURL(validatedOptions, imageConfig); - const matchesValidatedTransform = (transform) => transform.width === validatedOptions.width && transform.height === validatedOptions.height && transform.format === validatedOptions.format; - let srcSets = await Promise.all( - srcSetTransforms.map(async (srcSet) => { - return { - transform: srcSet.transform, - url: matchesValidatedTransform(srcSet.transform) ? imageURL : await service.getURL(srcSet.transform, imageConfig), - descriptor: srcSet.descriptor, - attributes: srcSet.attributes - }; - }) - ); - if (isLocalService(service) && globalThis.astroAsset.addStaticImage && !(isRemoteImage(validatedOptions.src) && imageURL === validatedOptions.src)) { - const propsToHash = service.propertiesToHash ?? DEFAULT_HASH_PROPS; - imageURL = globalThis.astroAsset.addStaticImage( - validatedOptions, - propsToHash, - originalFilePath - ); - srcSets = srcSetTransforms.map((srcSet) => { - return { - transform: srcSet.transform, - url: matchesValidatedTransform(srcSet.transform) ? imageURL : globalThis.astroAsset.addStaticImage(srcSet.transform, propsToHash, originalFilePath), - descriptor: srcSet.descriptor, - attributes: srcSet.attributes - }; - }); - } else if (imageConfig.assetQueryParams) { - const imageURLObj = createPlaceholderURL(imageURL); - imageConfig.assetQueryParams.forEach((value, key) => { - imageURLObj.searchParams.set(key, value); - }); - imageURL = stringifyPlaceholderURL(imageURLObj); - srcSets = srcSets.map((srcSet) => { - const urlObj = createPlaceholderURL(srcSet.url); - imageConfig.assetQueryParams.forEach((value, key) => { - urlObj.searchParams.set(key, value); - }); - return { - ...srcSet, - url: stringifyPlaceholderURL(urlObj) - }; - }); - } - return { - rawOptions: resolvedOptions, - options: validatedOptions, - src: imageURL, - srcSet: { - values: srcSets, - attribute: srcSets.map((srcSet) => `${srcSet.url} ${srcSet.descriptor}`).join(", ") - }, - attributes: service.getHTMLAttributes !== void 0 ? await service.getHTMLAttributes(validatedOptions, imageConfig) : {} - }; -} - -const $$Astro$2 = createAstro("https://skills.here.run.place"); -const $$Image = createComponent(async ($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro$2, $$props, $$slots); - Astro2.self = $$Image; - const props = Astro2.props; - if (props.alt === void 0 || props.alt === null) { - throw new AstroError(ImageMissingAlt); - } - if (typeof props.width === "string") { - props.width = parseInt(props.width); - } - if (typeof props.height === "string") { - props.height = parseInt(props.height); - } - const layout = props.layout ?? imageConfig.layout ?? "none"; - if (layout !== "none") { - props.layout ??= imageConfig.layout; - props.fit ??= imageConfig.objectFit ?? "cover"; - props.position ??= imageConfig.objectPosition ?? "center"; - } - const image = await getImage(props); - const additionalAttributes = {}; - if (image.srcSet.values.length > 0) { - additionalAttributes.srcset = image.srcSet.attribute; - } - const { class: className, ...attributes } = { ...additionalAttributes, ...image.attributes }; - return renderTemplate`${maybeRenderHead()}`; -}, "/Users/alex/projects/skillit/node_modules/astro/components/Image.astro", void 0); - -const $$Astro$1 = createAstro("https://skills.here.run.place"); -const $$Picture = createComponent(async ($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); - Astro2.self = $$Picture; - const defaultFormats = ["webp"]; - const defaultFallbackFormat = "png"; - const specialFormatsFallback = ["gif", "svg", "jpg", "jpeg"]; - const { formats = defaultFormats, pictureAttributes = {}, fallbackFormat, ...props } = Astro2.props; - if (props.alt === void 0 || props.alt === null) { - throw new AstroError(ImageMissingAlt); - } - const scopedStyleClass = props.class?.match(/\bastro-\w{8}\b/)?.[0]; - if (scopedStyleClass) { - if (pictureAttributes.class) { - pictureAttributes.class = `${pictureAttributes.class} ${scopedStyleClass}`; - } else { - pictureAttributes.class = scopedStyleClass; - } - } - const layout = props.layout ?? imageConfig.layout ?? "none"; - const useResponsive = layout !== "none"; - if (useResponsive) { - props.layout ??= imageConfig.layout; - props.fit ??= imageConfig.objectFit ?? "cover"; - props.position ??= imageConfig.objectPosition ?? "center"; - } - for (const key in props) { - if (key.startsWith("data-astro-cid")) { - pictureAttributes[key] = props[key]; - } - } - const originalSrc = await resolveSrc(props.src); - const optimizedImages = await Promise.all( - formats.map( - async (format) => await getImage({ - ...props, - src: originalSrc, - format, - widths: props.widths, - densities: props.densities - }) - ) - ); - let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat; - if (!fallbackFormat && isESMImportedImage(originalSrc) && specialFormatsFallback.includes(originalSrc.format)) { - resultFallbackFormat = originalSrc.format; - } - const fallbackImage = await getImage({ - ...props, - format: resultFallbackFormat, - widths: props.widths, - densities: props.densities - }); - const imgAdditionalAttributes = {}; - const sourceAdditionalAttributes = {}; - if (props.sizes) { - sourceAdditionalAttributes.sizes = props.sizes; - } - if (fallbackImage.srcSet.values.length > 0) { - imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute; - } - const { class: className, ...attributes } = { - ...imgAdditionalAttributes, - ...fallbackImage.attributes - }; - return renderTemplate`${maybeRenderHead()} ${Object.entries(optimizedImages).map(([_, image]) => { - const srcsetAttribute = props.densities || !props.densities && !props.widths && !useResponsive ? `${image.src}${image.srcSet.values.length > 0 ? ", " + image.srcSet.attribute : ""}` : image.srcSet.attribute; - return renderTemplate``; - })} `; -}, "/Users/alex/projects/skillit/node_modules/astro/components/Picture.astro", void 0); - -const mod = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null -}, Symbol.toStringTag, { value: 'Module' })); - -function filterPreloads(data, preload) { - if (!preload) { - return null; - } - if (preload === true) { - return data; - } - return data.filter( - ({ weight, style, subset }) => preload.some((p) => { - if (p.weight !== void 0 && weight !== void 0 && !checkWeight(p.weight.toString(), weight)) { - return false; - } - if (p.style !== void 0 && p.style !== style) { - return false; - } - if (p.subset !== void 0 && p.subset !== subset) { - return false; - } - return true; - }) - ); -} -function checkWeight(input, target) { - const trimmedInput = input.trim(); - if (trimmedInput.includes(" ")) { - return trimmedInput === target; - } - if (target.includes(" ")) { - const [a, b] = target.split(" "); - const parsedInput = Number.parseInt(input); - return parsedInput >= Number.parseInt(a) && parsedInput <= Number.parseInt(b); - } - return input === target; -} - -const $$Astro = createAstro("https://skills.here.run.place"); -const $$Font = createComponent(($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); - Astro2.self = $$Font; - const { componentDataByCssVariable } = mod; - if (!componentDataByCssVariable) { - throw new AstroError(ExperimentalFontsNotEnabled); - } - const { cssVariable, preload = false } = Astro2.props; - const data = componentDataByCssVariable.get(cssVariable); - if (!data) { - throw new AstroError({ - ...FontFamilyNotFound, - message: FontFamilyNotFound.message(cssVariable) - }); - } - const filteredPreloadData = filterPreloads(data.preloads, preload); - return renderTemplate`${filteredPreloadData?.map(({ url, type }) => renderTemplate``)}`; -}, "/Users/alex/projects/skillit/node_modules/astro/components/Font.astro", void 0); - -const assetQueryParams = undefined; - const imageConfig = {"endpoint":{"route":"/_image","entrypoint":"astro/assets/endpoint/node"},"service":{"entrypoint":"astro/assets/services/sharp","config":{}},"domains":[],"remotePatterns":[],"responsiveStyles":false}; - Object.defineProperty(imageConfig, 'assetQueryParams', { - value: assetQueryParams, - enumerable: false, - configurable: true, - }); - // This is used by the @astrojs/node integration to locate images. - // It's unused on other platforms, but on some platforms like Netlify (and presumably also Vercel) - // new URL("dist/...") is interpreted by the bundler as a signal to include that directory - // in the Lambda bundle, which would bloat the bundle with images. - // To prevent this, we mark the URL construction as pure, - // so that it's tree-shaken away for all platforms that don't need it. - const outDir = /* #__PURE__ */ new URL("file:///Users/alex/projects/skillit/dist/client/"); - const serverDir = /* #__PURE__ */ new URL("file:///Users/alex/projects/skillit/dist/server/"); - const getImage = async (options) => await getImage$1(options, imageConfig); - -const fnv1a52 = (str) => { - const len = str.length; - let i = 0, t0 = 0, v0 = 8997, t1 = 0, v1 = 33826, t2 = 0, v2 = 40164, t3 = 0, v3 = 52210; - while (i < len) { - v0 ^= str.charCodeAt(i++); - t0 = v0 * 435; - t1 = v1 * 435; - t2 = v2 * 435; - t3 = v3 * 435; - t2 += v0 << 8; - t3 += v1 << 8; - t1 += t0 >>> 16; - v0 = t0 & 65535; - t2 += t1 >>> 16; - v1 = t1 & 65535; - v3 = t3 + (t2 >>> 16) & 65535; - v2 = t2 & 65535; - } - return (v3 & 15) * 281474976710656 + v2 * 4294967296 + v1 * 65536 + (v0 ^ v3 >> 4); -}; -const etag = (payload, weak = false) => { - const prefix = weak ? 'W/"' : '"'; - return prefix + fnv1a52(payload).toString(36) + payload.length.toString(36) + '"'; -}; - -async function loadRemoteImage(src) { - try { - const res = await fetch(src); - if (!res.ok) { - return void 0; - } - return Buffer.from(await res.arrayBuffer()); - } catch { - return void 0; - } -} -const handleImageRequest = async ({ - request, - loadLocalImage -}) => { - const imageService = await getConfiguredImageService(); - if (!("transform" in imageService)) { - throw new Error("Configured image service is not a local service"); - } - const url = new URL(request.url); - const transform = await imageService.parseURL(url, imageConfig); - if (!transform?.src) { - return new Response("Invalid request", { status: 400 }); - } - let inputBuffer = void 0; - if (isRemotePath(transform.src)) { - if (!isRemoteAllowed(transform.src, imageConfig)) { - return new Response("Forbidden", { status: 403 }); - } - inputBuffer = await loadRemoteImage(new URL(transform.src)); - } else { - inputBuffer = await loadLocalImage(removeQueryString(transform.src), url); - } - if (!inputBuffer) { - return new Response("Internal Server Error", { status: 500 }); - } - const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig); - return new Response(data, { - status: 200, - headers: { - "Content-Type": mime.lookup(format) ?? `image/${format}`, - "Cache-Control": "public, max-age=31536000", - ETag: etag(data.toString()), - Date: (/* @__PURE__ */ new Date()).toUTCString() - } - }); -}; - -async function loadLocalImage(src, url) { - const outDirURL = resolveOutDir(); - const idx = url.pathname.indexOf("/_image"); - if (idx > 0) { - src = src.slice(idx); - } - if (!URL.canParse("." + src, outDirURL)) { - return void 0; - } - const fileUrl = new URL("." + src, outDirURL); - if (fileUrl.protocol !== "file:") { - return void 0; - } - if (!isParentDirectory(fileURLToPath(outDirURL), fileURLToPath(fileUrl))) { - return void 0; - } - try { - return await readFile(fileUrl); - } catch { - return void 0; - } -} -const GET = async ({ request }) => { - try { - return await handleImageRequest({ request, loadLocalImage }); - } catch (err) { - console.error("Could not process image request:", err); - return new Response("Internal Server Error", { - status: 500 - }); - } -}; -function resolveOutDir() { - const serverDirPath = fileURLToPath(serverDir); - const rel = path.relative(serverDirPath, fileURLToPath(outDir)); - const serverFolder = path.basename(serverDirPath); - let serverEntryFolderURL = path.dirname(import.meta.url); - while (!serverEntryFolderURL.endsWith(serverFolder)) { - serverEntryFolderURL = path.dirname(serverEntryFolderURL); - } - const serverEntryURL = serverEntryFolderURL + "/entry.mjs"; - const outDirURL = new URL(appendForwardSlash(rel), serverEntryURL); - return outDirURL; -} -function appendForwardSlash(pth) { - return pth.endsWith("/") ? pth : pth + "/"; -} - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page as a, baseService as b, parseQuality as p }; diff --git a/dist/server/chunks/remote_B3W5fv4r.mjs b/dist/server/chunks/remote_B3W5fv4r.mjs deleted file mode 100644 index f9cec72..0000000 --- a/dist/server/chunks/remote_B3W5fv4r.mjs +++ /dev/null @@ -1,188 +0,0 @@ -function appendForwardSlash(path) { - return path.endsWith("/") ? path : path + "/"; -} -function prependForwardSlash(path) { - return path[0] === "/" ? path : "/" + path; -} -const MANY_TRAILING_SLASHES = /\/{2,}$/g; -function collapseDuplicateTrailingSlashes(path, trailingSlash) { - if (!path) { - return path; - } - return path.replace(MANY_TRAILING_SLASHES, trailingSlash ? "/" : "") || "/"; -} -function removeTrailingForwardSlash(path) { - return path.endsWith("/") ? path.slice(0, path.length - 1) : path; -} -function removeLeadingForwardSlash(path) { - return path.startsWith("/") ? path.substring(1) : path; -} -function trimSlashes(path) { - return path.replace(/^\/|\/$/g, ""); -} -function isString(path) { - return typeof path === "string" || path instanceof String; -} -const INTERNAL_PREFIXES = /* @__PURE__ */ new Set(["/_", "/@", "/.", "//"]); -const JUST_SLASHES = /^\/{2,}$/; -function isInternalPath(path) { - return INTERNAL_PREFIXES.has(path.slice(0, 2)) && !JUST_SLASHES.test(path); -} -function joinPaths(...paths) { - return paths.filter(isString).map((path, i) => { - if (i === 0) { - return removeTrailingForwardSlash(path); - } else if (i === paths.length - 1) { - return removeLeadingForwardSlash(path); - } else { - return trimSlashes(path); - } - }).join("/"); -} -function removeQueryString(path) { - const index = path.lastIndexOf("?"); - return index > 0 ? path.substring(0, index) : path; -} -function isRemotePath(src) { - if (!src) return false; - const trimmed = src.trim(); - if (!trimmed) return false; - let decoded = trimmed; - let previousDecoded = ""; - let maxIterations = 10; - while (decoded !== previousDecoded && maxIterations > 0) { - previousDecoded = decoded; - try { - decoded = decodeURIComponent(decoded); - } catch { - break; - } - maxIterations--; - } - if (/^[a-zA-Z]:/.test(decoded)) { - return false; - } - if (decoded[0] === "/" && decoded[1] !== "/" && decoded[1] !== "\\") { - return false; - } - if (decoded[0] === "\\") { - return true; - } - if (decoded.startsWith("//")) { - return true; - } - try { - const url = new URL(decoded, "http://n"); - if (url.username || url.password) { - return true; - } - if (decoded.includes("@") && !url.pathname.includes("@") && !url.search.includes("@")) { - return true; - } - if (url.origin !== "http://n") { - const protocol = url.protocol.toLowerCase(); - if (protocol === "file:") { - return false; - } - return true; - } - if (URL.canParse(decoded)) { - return true; - } - return false; - } catch { - return true; - } -} -function isParentDirectory(parentPath, childPath) { - if (!parentPath || !childPath) { - return false; - } - if (parentPath.includes("://") || childPath.includes("://")) { - return false; - } - if (isRemotePath(parentPath) || isRemotePath(childPath)) { - return false; - } - if (parentPath.includes("..") || childPath.includes("..")) { - return false; - } - if (parentPath.includes("\0") || childPath.includes("\0")) { - return false; - } - const normalizedParent = appendForwardSlash(slash(parentPath).toLowerCase()); - const normalizedChild = slash(childPath).toLowerCase(); - if (normalizedParent === normalizedChild || normalizedParent === normalizedChild + "/") { - return false; - } - return normalizedChild.startsWith(normalizedParent); -} -function slash(path) { - return path.replace(/\\/g, "/"); -} -function fileExtension(path) { - const ext = path.split(".").pop(); - return ext !== path ? `.${ext}` : ""; -} -const WITH_FILE_EXT = /\/[^/]+\.\w+$/; -function hasFileExtension(path) { - return WITH_FILE_EXT.test(path); -} - -function matchPattern(url, remotePattern) { - return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true); -} -function matchPort(url, port) { - return !port || port === url.port; -} -function matchProtocol(url, protocol) { - return !protocol || protocol === url.protocol.slice(0, -1); -} -function matchHostname(url, hostname, allowWildcard = false) { - if (!hostname) { - return true; - } else if (!allowWildcard || !hostname.startsWith("*")) { - return hostname === url.hostname; - } else if (hostname.startsWith("**.")) { - const slicedHostname = hostname.slice(2); - return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname); - } else if (hostname.startsWith("*.")) { - const slicedHostname = hostname.slice(1); - if (!url.hostname.endsWith(slicedHostname)) { - return false; - } - const subdomainWithDot = url.hostname.slice(0, -(slicedHostname.length - 1)); - return subdomainWithDot.endsWith(".") && !subdomainWithDot.slice(0, -1).includes("."); - } - return false; -} -function matchPathname(url, pathname, allowWildcard = false) { - if (!pathname) { - return true; - } else if (!allowWildcard || !pathname.endsWith("*")) { - return pathname === url.pathname; - } else if (pathname.endsWith("/**")) { - const slicedPathname = pathname.slice(0, -2); - return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname); - } else if (pathname.endsWith("/*")) { - const slicedPathname = pathname.slice(0, -1); - const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean); - return additionalPathChunks.length === 1; - } - return false; -} -function isRemoteAllowed(src, { - domains, - remotePatterns -}) { - if (!URL.canParse(src)) { - return false; - } - const url = new URL(src); - if (!["http:", "https:", "data:"].includes(url.protocol)) { - return false; - } - return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern)); -} - -export { isRemotePath as a, isParentDirectory as b, appendForwardSlash as c, removeTrailingForwardSlash as d, isInternalPath as e, fileExtension as f, collapseDuplicateTrailingSlashes as g, hasFileExtension as h, isRemoteAllowed as i, joinPaths as j, matchPattern as m, prependForwardSlash as p, removeQueryString as r, slash as s, trimSlashes as t }; diff --git a/dist/server/chunks/sharp_D9uxjd11.mjs b/dist/server/chunks/sharp_D9uxjd11.mjs deleted file mode 100644 index 59799ea..0000000 --- a/dist/server/chunks/sharp_D9uxjd11.mjs +++ /dev/null @@ -1,101 +0,0 @@ -import { A as AstroError, ao as MissingSharp } from './astro/server_CF97kUu8.mjs'; -import { b as baseService, p as parseQuality } from './node_HH9e2ntY.mjs'; - -let sharp; -const qualityTable = { - low: 25, - mid: 50, - high: 80, - max: 100 -}; -async function loadSharp() { - let sharpImport; - try { - sharpImport = (await import('sharp')).default; - } catch { - throw new AstroError(MissingSharp); - } - sharpImport.cache(false); - return sharpImport; -} -const fitMap = { - fill: "fill", - contain: "inside", - cover: "cover", - none: "outside", - "scale-down": "inside", - outside: "outside", - inside: "inside" -}; -const sharpService = { - validateOptions: baseService.validateOptions, - getURL: baseService.getURL, - parseURL: baseService.parseURL, - getHTMLAttributes: baseService.getHTMLAttributes, - getSrcSet: baseService.getSrcSet, - async transform(inputBuffer, transformOptions, config) { - if (!sharp) sharp = await loadSharp(); - const transform = transformOptions; - const kernel = config.service.config.kernel; - if (transform.format === "svg") return { data: inputBuffer, format: "svg" }; - const result = sharp(inputBuffer, { - failOnError: false, - pages: -1, - limitInputPixels: config.service.config.limitInputPixels - }); - result.rotate(); - const { format } = await result.metadata(); - const withoutEnlargement = Boolean(transform.fit); - if (transform.width && transform.height && transform.fit) { - const fit = fitMap[transform.fit] ?? "inside"; - result.resize({ - width: Math.round(transform.width), - height: Math.round(transform.height), - kernel, - fit, - position: transform.position, - withoutEnlargement - }); - } else if (transform.height && !transform.width) { - result.resize({ - height: Math.round(transform.height), - kernel, - withoutEnlargement - }); - } else if (transform.width) { - result.resize({ - width: Math.round(transform.width), - kernel, - withoutEnlargement - }); - } - if (transform.background) { - result.flatten({ background: transform.background }); - } - if (transform.format) { - let quality = void 0; - if (transform.quality) { - const parsedQuality = parseQuality(transform.quality); - if (typeof parsedQuality === "number") { - quality = parsedQuality; - } else { - quality = transform.quality in qualityTable ? qualityTable[transform.quality] : void 0; - } - } - if (transform.format === "webp" && format === "gif") { - result.webp({ quality: typeof quality === "number" ? quality : void 0, loop: 0 }); - } else { - result.toFormat(transform.format, { quality }); - } - } - const { data, info } = await result.toBuffer({ resolveWithObject: true }); - const needsCopy = "buffer" in data && data.buffer instanceof SharedArrayBuffer; - return { - data: needsCopy ? new Uint8Array(data) : data, - format: info.format - }; - } -}; -var sharp_default = sharpService; - -export { sharp_default as default }; diff --git a/dist/server/chunks/skills_BacVQUiS.mjs b/dist/server/chunks/skills_BacVQUiS.mjs deleted file mode 100644 index 8ac7d06..0000000 --- a/dist/server/chunks/skills_BacVQUiS.mjs +++ /dev/null @@ -1,109 +0,0 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; -import matter from 'gray-matter'; - -const SKILLS_DIR = path.resolve( - process.env.SKILLS_DIR || "data/skills" -); -const SLUG_RE = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/; -const MAX_SLUG_LENGTH = 64; -function isValidSlug(slug) { - return slug.length >= 2 && slug.length <= MAX_SLUG_LENGTH && SLUG_RE.test(slug); -} -function skillPath(slug) { - return path.join(SKILLS_DIR, `${slug}.md`); -} -function parseTools(val) { - if (Array.isArray(val)) return val.map(String); - if (typeof val === "string") return val.split(",").map((t) => t.trim()).filter(Boolean); - return []; -} -function parseSkill(slug, raw) { - const { data, content } = matter(raw); - return { - slug, - name: data.name || slug, - description: data.description || "", - "allowed-tools": parseTools(data["allowed-tools"] ?? data.allowedTools), - "argument-hint": data["argument-hint"] || "", - model: data.model || "", - "user-invocable": data["user-invocable"] !== false, - "disable-model-invocation": Boolean(data["disable-model-invocation"]), - context: data.context || "", - agent: data.agent || "", - author: data.author || "", - "author-email": data["author-email"] || "", - "fork-of": data["fork-of"] || "", - tags: parseTools(data.tags), - hooks: typeof data.hooks === "object" && data.hooks !== null ? data.hooks : null, - content: content.trim(), - raw - }; -} -async function listSkills() { - await fs.mkdir(SKILLS_DIR, { recursive: true }); - const files = await fs.readdir(SKILLS_DIR); - const skills = []; - for (const file of files) { - if (!file.endsWith(".md")) continue; - const slug = file.replace(/\.md$/, ""); - const raw = await fs.readFile(path.join(SKILLS_DIR, file), "utf-8"); - const { content: _, raw: __, ...meta } = parseSkill(slug, raw); - skills.push(meta); - } - return skills.sort((a, b) => a.name.localeCompare(b.name)); -} -async function getAllTags() { - const all = await listSkills(); - return [...new Set(all.flatMap((s) => s.tags))].sort(); -} -async function getForksOf(slug) { - const all = await listSkills(); - return all.filter((s) => s["fork-of"] === slug); -} -async function getSkill(slug) { - try { - const raw = await fs.readFile(skillPath(slug), "utf-8"); - return parseSkill(slug, raw); - } catch { - return null; - } -} -async function createSkill(slug, content) { - if (!isValidSlug(slug)) { - throw new Error(`Invalid slug: ${slug}`); - } - await fs.mkdir(SKILLS_DIR, { recursive: true }); - const dest = skillPath(slug); - try { - await fs.access(dest); - throw new Error(`Skill already exists: ${slug}`); - } catch (err) { - if (err instanceof Error && err.message.startsWith("Skill already exists")) { - throw err; - } - } - await fs.writeFile(dest, content, "utf-8"); - return parseSkill(slug, content); -} -async function updateSkill(slug, content) { - const dest = skillPath(slug); - try { - await fs.access(dest); - } catch { - throw new Error(`Skill not found: ${slug}`); - } - await fs.writeFile(dest, content, "utf-8"); - return parseSkill(slug, content); -} -async function deleteSkill(slug) { - const dest = skillPath(slug); - try { - await fs.access(dest); - } catch { - throw new Error(`Skill not found: ${slug}`); - } - await fs.unlink(dest); -} - -export { getAllTags as a, getForksOf as b, createSkill as c, deleteSkill as d, getSkill as g, isValidSlug as i, listSkills as l, updateSkill as u }; diff --git a/dist/server/chunks/stats_CaDi9y9J.mjs b/dist/server/chunks/stats_CaDi9y9J.mjs deleted file mode 100644 index b9291d4..0000000 --- a/dist/server/chunks/stats_CaDi9y9J.mjs +++ /dev/null @@ -1,46 +0,0 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; - -const STATS_FILE = path.resolve(process.env.STATS_FILE || "data/stats.json"); -async function readStore() { - try { - const raw = await fs.readFile(STATS_FILE, "utf-8"); - return JSON.parse(raw); - } catch { - return {}; - } -} -async function writeStore(store) { - const dir = path.dirname(STATS_FILE); - await fs.mkdir(dir, { recursive: true }); - const tmp = STATS_FILE + ".tmp"; - await fs.writeFile(tmp, JSON.stringify(store, null, 2), "utf-8"); - await fs.rename(tmp, STATS_FILE); -} -function ensure(store, slug) { - if (!store[slug]) { - store[slug] = { downloads: 0, pushes: 0, lastPushedAt: null }; - } - return store[slug]; -} -async function recordDownload(slug) { - const store = await readStore(); - ensure(store, slug).downloads++; - await writeStore(store); -} -async function recordPush(slug) { - const store = await readStore(); - const entry = ensure(store, slug); - entry.pushes++; - entry.lastPushedAt = (/* @__PURE__ */ new Date()).toISOString(); - await writeStore(store); -} -async function getStatsForSlug(slug) { - const store = await readStore(); - return store[slug] || { downloads: 0, pushes: 0, lastPushedAt: null }; -} -async function getAllStats() { - return readStore(); -} - -export { recordDownload as a, getAllStats as b, getStatsForSlug as g, recordPush as r }; diff --git a/dist/server/chunks/sync_BEq_wzpT.mjs b/dist/server/chunks/sync_BEq_wzpT.mjs deleted file mode 100644 index e9fec80..0000000 --- a/dist/server/chunks/sync_BEq_wzpT.mjs +++ /dev/null @@ -1,309 +0,0 @@ -import { l as listSkills } from './skills_BacVQUiS.mjs'; - -function isPowerShell(request) { - const ua = request.headers.get("user-agent") || ""; - return /PowerShell/i.test(ua); -} -async function buildPushScript(baseUrl, skillsDir) { - const lines = [ - "#!/usr/bin/env bash", - "set -euo pipefail", - "", - `SKILLS_DIR="${skillsDir}"`, - `BASE_URL="${baseUrl}"`, - 'FILTER="${1:-}"', - 'TOKEN_FILE="$HOME/.claude/skills.here-token"', - "", - "# Get git author if available", - 'AUTHOR_NAME=$(git config user.name 2>/dev/null || echo "")', - 'AUTHOR_EMAIL=$(git config user.email 2>/dev/null || echo "")', - "", - "# Load or register token", - 'TOKEN=""', - 'if [ -f "$TOKEN_FILE" ]; then', - ' TOKEN=$(cat "$TOKEN_FILE")', - 'elif [ -n "$AUTHOR_EMAIL" ]; then', - ' echo "No token found. Registering with $AUTHOR_EMAIL..."', - " REGISTER_RESPONSE=$(curl -sS -X POST \\", - ' -H "Content-Type: application/json" \\', - ' -d "{\\"email\\": \\"$AUTHOR_EMAIL\\", \\"name\\": \\"$AUTHOR_NAME\\"}" \\', - ' -w "\\n%{http_code}" \\', - ' "$BASE_URL/api/auth/register")', - ` REGISTER_BODY=$(echo "$REGISTER_RESPONSE" | sed '$d')`, - ' REGISTER_STATUS=$(echo "$REGISTER_RESPONSE" | tail -1)', - ' if [ "$REGISTER_STATUS" = "201" ]; then', - ' TOKEN=$(echo "$REGISTER_BODY" | jq -r .token)', - ' mkdir -p "$(dirname "$TOKEN_FILE")"', - ' echo "$TOKEN" > "$TOKEN_FILE"', - ' chmod 600 "$TOKEN_FILE"', - ' echo " Token saved to $TOKEN_FILE"', - ' elif [ "$REGISTER_STATUS" = "409" ]; then', - ' echo " Email already registered. Place your token in $TOKEN_FILE"', - ' echo " Continuing without token (unprotected skills only)..."', - " else", - ' echo " Registration failed ($REGISTER_STATUS): $REGISTER_BODY"', - ' echo " Continuing without token (unprotected skills only)..."', - " fi", - "fi", - "", - 'if [ ! -d "$SKILLS_DIR" ]; then', - ' echo "No skills directory found at $SKILLS_DIR"', - " exit 1", - "fi", - "", - 'AUTH_HEADER=""', - 'if [ -n "$TOKEN" ]; then', - ' AUTH_HEADER="Authorization: Bearer $TOKEN"', - "fi", - "", - "push_skill() {", - ' local file="$1"', - ' local slug=$(basename "$file" .md)', - ' local content=$(cat "$file")', - "", - " # Inject author into frontmatter if available and not already present", - ' if [ -n "$AUTHOR_EMAIL" ] && ! echo "$content" | grep -q "^author-email:"; then', - ` content=$(echo "$content" | awk -v name="$AUTHOR_NAME" -v email="$AUTHOR_EMAIL" 'NR==1 && /^---$/{print; if (name) print "author: " name; print "author-email: " email; next} {print}')`, - " fi", - "", - " # Build curl auth args", - ' local auth_args=""', - ' if [ -n "$AUTH_HEADER" ]; then', - ' auth_args="-H \\"$AUTH_HEADER\\""', - " fi", - "", - " # Try PUT (update), fallback to POST (create)", - " local response", - ' if [ -n "$TOKEN" ]; then', - ' response=$(curl -sS -o /dev/null -w "%{http_code}" -X PUT \\', - ' -H "Content-Type: application/json" \\', - ' -H "Authorization: Bearer $TOKEN" \\', - ' -d "{\\"content\\": $(echo "$content" | jq -Rs .)}" \\', - ' "$BASE_URL/api/skills/$slug")', - " else", - ' response=$(curl -sS -o /dev/null -w "%{http_code}" -X PUT \\', - ' -H "Content-Type: application/json" \\', - ' -d "{\\"content\\": $(echo "$content" | jq -Rs .)}" \\', - ' "$BASE_URL/api/skills/$slug")', - " fi", - "", - ' if [ "$response" = "403" ]; then', - ' echo " ✗ $slug (permission denied — token missing or invalid)"', - " return 1", - " fi", - "", - ' if [ "$response" = "404" ]; then', - ' if [ -n "$TOKEN" ]; then', - ' local post_status=$(curl -sS -o /dev/null -w "%{http_code}" -X POST \\', - ' -H "Content-Type: application/json" \\', - ' -H "Authorization: Bearer $TOKEN" \\', - ' -d "{\\"slug\\": \\"$slug\\", \\"content\\": $(echo "$content" | jq -Rs .)}" \\', - ' "$BASE_URL/api/skills")', - " else", - ' local post_status=$(curl -sS -o /dev/null -w "%{http_code}" -X POST \\', - ' -H "Content-Type: application/json" \\', - ' -d "{\\"slug\\": \\"$slug\\", \\"content\\": $(echo "$content" | jq -Rs .)}" \\', - ' "$BASE_URL/api/skills")', - " fi", - ' if [ "$post_status" = "403" ]; then', - ' echo " ✗ $slug (permission denied — token missing or invalid)"', - " return 1", - " fi", - " fi", - "", - ' echo " ✓ $slug"', - "}", - "", - "count=0", - "failed=0", - 'if [ -n "$FILTER" ]; then', - " # Push a specific skill", - ' file="$SKILLS_DIR/${FILTER%.md}.md"', - ' if [ ! -f "$file" ]; then', - ' echo "Skill not found: $file"', - " exit 1", - " fi", - ' if push_skill "$file"; then', - " count=1", - " else", - " failed=1", - " fi", - "else", - " # Push all skills", - ' for file in "$SKILLS_DIR"/*.md; do', - ' [ -f "$file" ] || continue', - ' if push_skill "$file"; then', - " count=$((count + 1))", - " else", - " failed=$((failed + 1))", - " fi", - " done", - "fi", - "", - 'echo "Pushed $count skill(s) to $BASE_URL"', - 'if [ "$failed" -gt 0 ]; then', - ' echo "$failed skill(s) failed (permission denied)"', - "fi", - "" - ]; - return lines.join("\n"); -} -async function buildSyncScript(baseUrl, skillsDir) { - const skills = await listSkills(); - const lines = [ - "#!/usr/bin/env bash", - "set -euo pipefail", - "", - `SKILLS_DIR="${skillsDir}"`, - 'mkdir -p "$SKILLS_DIR"', - "" - ]; - if (skills.length === 0) { - lines.push('echo "No skills available to sync."'); - } else { - lines.push(`echo "Syncing ${skills.length} skill(s) from ${baseUrl}..."`); - lines.push(""); - for (const skill of skills) { - const skillUrl = `${baseUrl}/${skill.slug}`; - lines.push(`curl -fsSL "${skillUrl}" -o "$SKILLS_DIR/${skill.slug}.md"`); - lines.push(`echo " ✓ ${skill.name}"`); - } - lines.push(""); - lines.push('echo "Done! Skills synced to $SKILLS_DIR"'); - } - lines.push(""); - return lines.join("\n"); -} -async function buildSyncScriptPS(baseUrl, skillsDir) { - const skills = await listSkills(); - const lines = [ - '$ErrorActionPreference = "Stop"', - "", - `$SkillsDir = "${skillsDir}"`, - "New-Item -ItemType Directory -Force -Path $SkillsDir | Out-Null", - "" - ]; - if (skills.length === 0) { - lines.push('Write-Host "No skills available to sync."'); - } else { - lines.push(`Write-Host "Syncing ${skills.length} skill(s) from ${baseUrl}..."`); - lines.push(""); - for (const skill of skills) { - const skillUrl = `${baseUrl}/${skill.slug}`; - lines.push(`Invoke-WebRequest -Uri "${skillUrl}" -OutFile (Join-Path $SkillsDir "${skill.slug}.md")`); - lines.push(`Write-Host " ✓ ${skill.name}"`); - } - lines.push(""); - lines.push('Write-Host "Done! Skills synced to $SkillsDir"'); - } - lines.push(""); - return lines.join("\n"); -} -async function buildPushScriptPS(baseUrl, skillsDir) { - const lines = [ - '$ErrorActionPreference = "Stop"', - "", - `$SkillsDir = "${skillsDir}"`, - `$BaseUrl = "${baseUrl}"`, - '$Filter = if ($args.Count -gt 0) { $args[0] } else { "" }', - '$TokenFile = Join-Path $HOME ".claude\\skills.here-token"', - "", - "# Get git author if available", - '$AuthorName = try { git config user.name 2>$null } catch { "" }', - '$AuthorEmail = try { git config user.email 2>$null } catch { "" }', - "", - "# Load or register token", - '$Token = ""', - "if (Test-Path $TokenFile) {", - " $Token = (Get-Content $TokenFile -Raw).Trim()", - "} elseif ($AuthorEmail) {", - ' Write-Host "No token found. Registering with $AuthorEmail..."', - " try {", - " $body = @{ email = $AuthorEmail; name = $AuthorName } | ConvertTo-Json", - ' $resp = Invoke-WebRequest -Uri "$BaseUrl/api/auth/register" -Method POST -ContentType "application/json" -Body $body', - " if ($resp.StatusCode -eq 201) {", - " $Token = ($resp.Content | ConvertFrom-Json).token", - " New-Item -ItemType Directory -Force -Path (Split-Path $TokenFile) | Out-Null", - " Set-Content -Path $TokenFile -Value $Token", - ' Write-Host " Token saved to $TokenFile"', - " }", - " } catch {", - " $code = $_.Exception.Response.StatusCode.value__", - " if ($code -eq 409) {", - ' Write-Host " Email already registered. Place your token in $TokenFile"', - " } else {", - ' Write-Host " Registration failed: $_"', - " }", - ' Write-Host " Continuing without token (unprotected skills only)..."', - " }", - "}", - "", - "if (-not (Test-Path $SkillsDir)) {", - ' Write-Host "No skills directory found at $SkillsDir"', - " exit 1", - "}", - "", - '$headers = @{ "Content-Type" = "application/json" }', - 'if ($Token) { $headers["Authorization"] = "Bearer $Token" }', - "", - "function Push-Skill($file) {", - " $slug = [IO.Path]::GetFileNameWithoutExtension($file)", - " $content = Get-Content $file -Raw", - "", - " # Inject author if available and not present", - ' if ($AuthorEmail -and $content -notmatch "(?m)^author-email:") {', - ' $inject = ""', - ' if ($AuthorName) { $inject += "author: $AuthorName`n" }', - ' $inject += "author-email: $AuthorEmail"', - ' $content = $content -replace "^---$", "---`n$inject" -replace "^---`n", "---`n"', - " }", - "", - " $body = @{ content = $content } | ConvertTo-Json", - " try {", - ' Invoke-WebRequest -Uri "$BaseUrl/api/skills/$slug" -Method PUT -Headers $headers -Body $body | Out-Null', - ' Write-Host " ✓ $slug"', - " return $true", - " } catch {", - " $code = $_.Exception.Response.StatusCode.value__", - " if ($code -eq 403) {", - ' Write-Host " ✗ $slug (permission denied)"', - " return $false", - " }", - " if ($code -eq 404) {", - " $postBody = @{ slug = $slug; content = $content } | ConvertTo-Json", - " try {", - ' Invoke-WebRequest -Uri "$BaseUrl/api/skills" -Method POST -Headers $headers -Body $postBody | Out-Null', - ' Write-Host " ✓ $slug"', - " return $true", - " } catch {", - " $postCode = $_.Exception.Response.StatusCode.value__", - " if ($postCode -eq 403) {", - ' Write-Host " ✗ $slug (permission denied)"', - " return $false", - " }", - " }", - " }", - " }", - ' Write-Host " ✓ $slug"', - " return $true", - "}", - "", - "$count = 0; $failed = 0", - "if ($Filter) {", - ` $file = Join-Path $SkillsDir "$($Filter -replace '\\.md$','').md"`, - ' if (-not (Test-Path $file)) { Write-Host "Skill not found: $file"; exit 1 }', - " if (Push-Skill $file) { $count++ } else { $failed++ }", - "} else {", - ' Get-ChildItem -Path $SkillsDir -Filter "*.md" | ForEach-Object {', - " if (Push-Skill $_.FullName) { $count++ } else { $failed++ }", - " }", - "}", - "", - 'Write-Host "Pushed $count skill(s) to $BaseUrl"', - 'if ($failed -gt 0) { Write-Host "$failed skill(s) failed (permission denied)" }', - "" - ]; - return lines.join("\n"); -} - -export { buildSyncScriptPS as a, buildSyncScript as b, buildPushScript as c, buildPushScriptPS as d, isPowerShell as i }; diff --git a/dist/server/chunks/tokens_CAzj9Aj8.mjs b/dist/server/chunks/tokens_CAzj9Aj8.mjs deleted file mode 100644 index cb203e0..0000000 --- a/dist/server/chunks/tokens_CAzj9Aj8.mjs +++ /dev/null @@ -1,55 +0,0 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; -import crypto from 'node:crypto'; - -const TOKENS_FILE = path.resolve(process.env.TOKENS_FILE || "data/tokens.json"); -async function readStore() { - try { - const raw = await fs.readFile(TOKENS_FILE, "utf-8"); - return JSON.parse(raw); - } catch { - return {}; - } -} -async function writeStore(store) { - const dir = path.dirname(TOKENS_FILE); - await fs.mkdir(dir, { recursive: true }); - const tmp = TOKENS_FILE + ".tmp"; - await fs.writeFile(tmp, JSON.stringify(store, null, 2), "utf-8"); - await fs.rename(tmp, TOKENS_FILE); -} -function hashToken(token) { - return crypto.createHash("sha256").update(token).digest("hex"); -} -async function generateToken(email, name) { - const store = await readStore(); - if (store[email]) { - throw new Error("Email already registered"); - } - const token = crypto.randomBytes(32).toString("hex"); - store[email] = { - hash: hashToken(token), - name, - createdAt: (/* @__PURE__ */ new Date()).toISOString() - }; - await writeStore(store); - return token; -} -async function verifyToken(email, token) { - if (!email || !token) return false; - const store = await readStore(); - const entry = store[email]; - if (!entry) return false; - return entry.hash === hashToken(token); -} -async function hasToken(email) { - const store = await readStore(); - return Boolean(store[email]); -} -function extractBearerToken(request) { - const auth = request.headers.get("Authorization") || ""; - const match = auth.match(/^Bearer\s+(\S+)$/i); - return match ? match[1] : ""; -} - -export { extractBearerToken as e, generateToken as g, hasToken as h, verifyToken as v }; diff --git a/dist/server/entry.mjs b/dist/server/entry.mjs deleted file mode 100644 index 0d79591..0000000 --- a/dist/server/entry.mjs +++ /dev/null @@ -1,69 +0,0 @@ -import { renderers } from './renderers.mjs'; -import { c as createExports, s as serverEntrypointModule } from './chunks/_@astrojs-ssr-adapter_BeL8VyJ8.mjs'; -import { manifest } from './manifest_Bz0Ba_R4.mjs'; - -const serverIslandMap = new Map();; - -const _page0 = () => import('./pages/_image.astro.mjs'); -const _page1 = () => import('./pages/api/auth/register.astro.mjs'); -const _page2 = () => import('./pages/api/auth/verify.astro.mjs'); -const _page3 = () => import('./pages/api/skills/_slug_.astro.mjs'); -const _page4 = () => import('./pages/api/skills.astro.mjs'); -const _page5 = () => import('./pages/api/sync/project.astro.mjs'); -const _page6 = () => import('./pages/api/sync.astro.mjs'); -const _page7 = () => import('./pages/gi.astro.mjs'); -const _page8 = () => import('./pages/gp.astro.mjs'); -const _page9 = () => import('./pages/i.astro.mjs'); -const _page10 = () => import('./pages/new.astro.mjs'); -const _page11 = () => import('./pages/p.astro.mjs'); -const _page12 = () => import('./pages/_slug_/edit.astro.mjs'); -const _page13 = () => import('./pages/_slug_/gi.astro.mjs'); -const _page14 = () => import('./pages/_slug_/i.astro.mjs'); -const _page15 = () => import('./pages/_slug_.astro.mjs'); -const _page16 = () => import('./pages/index.astro.mjs'); -const pageMap = new Map([ - ["node_modules/astro/dist/assets/endpoint/node.js", _page0], - ["src/pages/api/auth/register.ts", _page1], - ["src/pages/api/auth/verify.ts", _page2], - ["src/pages/api/skills/[slug].ts", _page3], - ["src/pages/api/skills/index.ts", _page4], - ["src/pages/api/sync/project.ts", _page5], - ["src/pages/api/sync/index.ts", _page6], - ["src/pages/gi.ts", _page7], - ["src/pages/gp.ts", _page8], - ["src/pages/i.ts", _page9], - ["src/pages/new.astro", _page10], - ["src/pages/p.ts", _page11], - ["src/pages/[slug]/edit.astro", _page12], - ["src/pages/[slug]/gi.ts", _page13], - ["src/pages/[slug]/i.ts", _page14], - ["src/pages/[slug].astro", _page15], - ["src/pages/index.astro", _page16] -]); - -const _manifest = Object.assign(manifest, { - pageMap, - serverIslandMap, - renderers, - actions: () => import('./noop-entrypoint.mjs'), - middleware: () => import('./_noop-middleware.mjs') -}); -const _args = { - "mode": "standalone", - "client": "file:///Users/alex/projects/skillit/dist/client/", - "server": "file:///Users/alex/projects/skillit/dist/server/", - "host": false, - "port": 4321, - "assets": "_astro", - "experimentalStaticHeaders": false -}; -const _exports = createExports(_manifest, _args); -const handler = _exports['handler']; -const startServer = _exports['startServer']; -const options = _exports['options']; -const _start = 'start'; -if (Object.prototype.hasOwnProperty.call(serverEntrypointModule, _start)) { - serverEntrypointModule[_start](_manifest, _args); -} - -export { handler, options, pageMap, startServer }; diff --git a/dist/server/manifest_Bz0Ba_R4.mjs b/dist/server/manifest_Bz0Ba_R4.mjs deleted file mode 100644 index 7b2aba7..0000000 --- a/dist/server/manifest_Bz0Ba_R4.mjs +++ /dev/null @@ -1,101 +0,0 @@ -import 'piccolore'; -import { p as decodeKey } from './chunks/astro/server_CF97kUu8.mjs'; -import 'clsx'; -import { N as NOOP_MIDDLEWARE_FN } from './chunks/astro-designed-error-pages_DSexancP.mjs'; -import 'es-module-lexer'; - -function sanitizeParams(params) { - return Object.fromEntries( - Object.entries(params).map(([key, value]) => { - if (typeof value === "string") { - return [key, value.normalize().replace(/#/g, "%23").replace(/\?/g, "%3F")]; - } - return [key, value]; - }) - ); -} -function getParameter(part, params) { - if (part.spread) { - return params[part.content.slice(3)] || ""; - } - if (part.dynamic) { - if (!params[part.content]) { - throw new TypeError(`Missing parameter: ${part.content}`); - } - return params[part.content]; - } - return part.content.normalize().replace(/\?/g, "%3F").replace(/#/g, "%23").replace(/%5B/g, "[").replace(/%5D/g, "]"); -} -function getSegment(segment, params) { - const segmentPath = segment.map((part) => getParameter(part, params)).join(""); - return segmentPath ? "/" + segmentPath : ""; -} -function getRouteGenerator(segments, addTrailingSlash) { - return (params) => { - const sanitizedParams = sanitizeParams(params); - let trailing = ""; - if (addTrailingSlash === "always" && segments.length) { - trailing = "/"; - } - const path = segments.map((segment) => getSegment(segment, sanitizedParams)).join("") + trailing; - return path || "/"; - }; -} - -function deserializeRouteData(rawRouteData) { - return { - route: rawRouteData.route, - type: rawRouteData.type, - pattern: new RegExp(rawRouteData.pattern), - params: rawRouteData.params, - component: rawRouteData.component, - generate: getRouteGenerator(rawRouteData.segments, rawRouteData._meta.trailingSlash), - pathname: rawRouteData.pathname || void 0, - segments: rawRouteData.segments, - prerender: rawRouteData.prerender, - redirect: rawRouteData.redirect, - redirectRoute: rawRouteData.redirectRoute ? deserializeRouteData(rawRouteData.redirectRoute) : void 0, - fallbackRoutes: rawRouteData.fallbackRoutes.map((fallback) => { - return deserializeRouteData(fallback); - }), - isIndex: rawRouteData.isIndex, - origin: rawRouteData.origin - }; -} - -function deserializeManifest(serializedManifest) { - const routes = []; - for (const serializedRoute of serializedManifest.routes) { - routes.push({ - ...serializedRoute, - routeData: deserializeRouteData(serializedRoute.routeData) - }); - const route = serializedRoute; - route.routeData = deserializeRouteData(serializedRoute.routeData); - } - const assets = new Set(serializedManifest.assets); - const componentMetadata = new Map(serializedManifest.componentMetadata); - const inlinedScripts = new Map(serializedManifest.inlinedScripts); - const clientDirectives = new Map(serializedManifest.clientDirectives); - const serverIslandNameMap = new Map(serializedManifest.serverIslandNameMap); - const key = decodeKey(serializedManifest.key); - return { - // in case user middleware exists, this no-op middleware will be reassigned (see plugin-ssr.ts) - middleware() { - return { onRequest: NOOP_MIDDLEWARE_FN }; - }, - ...serializedManifest, - assets, - componentMetadata, - inlinedScripts, - clientDirectives, - routes, - serverIslandNameMap, - key - }; -} - -const manifest = deserializeManifest({"hrefRoot":"file:///Users/alex/projects/skillit/","cacheDir":"file:///Users/alex/projects/skillit/node_modules/.astro/","outDir":"file:///Users/alex/projects/skillit/dist/","srcDir":"file:///Users/alex/projects/skillit/src/","publicDir":"file:///Users/alex/projects/skillit/public/","buildClientDir":"file:///Users/alex/projects/skillit/dist/client/","buildServerDir":"file:///Users/alex/projects/skillit/dist/server/","adapterName":"@astrojs/node","routes":[{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"type":"page","component":"_server-islands.astro","params":["name"],"segments":[[{"content":"_server-islands","dynamic":false,"spread":false}],[{"content":"name","dynamic":true,"spread":false}]],"pattern":"^\\/_server-islands\\/([^/]+?)\\/?$","prerender":false,"isIndex":false,"fallbackRoutes":[],"route":"/_server-islands/[name]","origin":"internal","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"type":"endpoint","isIndex":false,"route":"/_image","pattern":"^\\/_image\\/?$","segments":[[{"content":"_image","dynamic":false,"spread":false}]],"params":[],"component":"node_modules/astro/dist/assets/endpoint/node.js","pathname":"/_image","prerender":false,"fallbackRoutes":[],"origin":"internal","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/auth/register","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/auth\\/register\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"auth","dynamic":false,"spread":false}],[{"content":"register","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/auth/register.ts","pathname":"/api/auth/register","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/auth/verify","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/auth\\/verify\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"auth","dynamic":false,"spread":false}],[{"content":"verify","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/auth/verify.ts","pathname":"/api/auth/verify","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/skills/[slug]","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/skills\\/([^/]+?)\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"skills","dynamic":false,"spread":false}],[{"content":"slug","dynamic":true,"spread":false}]],"params":["slug"],"component":"src/pages/api/skills/[slug].ts","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/skills","isIndex":true,"type":"endpoint","pattern":"^\\/api\\/skills\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"skills","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/skills/index.ts","pathname":"/api/skills","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/sync/project","isIndex":false,"type":"endpoint","pattern":"^\\/api\\/sync\\/project\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"sync","dynamic":false,"spread":false}],[{"content":"project","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/sync/project.ts","pathname":"/api/sync/project","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/api/sync","isIndex":true,"type":"endpoint","pattern":"^\\/api\\/sync\\/?$","segments":[[{"content":"api","dynamic":false,"spread":false}],[{"content":"sync","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/api/sync/index.ts","pathname":"/api/sync","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/gi","isIndex":false,"type":"endpoint","pattern":"^\\/gi\\/?$","segments":[[{"content":"gi","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/gi.ts","pathname":"/gi","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/gp","isIndex":false,"type":"endpoint","pattern":"^\\/gp\\/?$","segments":[[{"content":"gp","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/gp.ts","pathname":"/gp","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/i","isIndex":false,"type":"endpoint","pattern":"^\\/i\\/?$","segments":[[{"content":"i","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/i.ts","pathname":"/i","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[{"type":"external","src":"/_astro/_slug_.DRpcPMTm.css"}],"routeData":{"route":"/new","isIndex":false,"type":"page","pattern":"^\\/new\\/?$","segments":[[{"content":"new","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/new.astro","pathname":"/new","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/p","isIndex":false,"type":"endpoint","pattern":"^\\/p\\/?$","segments":[[{"content":"p","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/p.ts","pathname":"/p","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[{"type":"external","src":"/_astro/_slug_.DRpcPMTm.css"}],"routeData":{"route":"/[slug]/edit","isIndex":false,"type":"page","pattern":"^\\/([^/]+?)\\/edit\\/?$","segments":[[{"content":"slug","dynamic":true,"spread":false}],[{"content":"edit","dynamic":false,"spread":false}]],"params":["slug"],"component":"src/pages/[slug]/edit.astro","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/[slug]/gi","isIndex":false,"type":"endpoint","pattern":"^\\/([^/]+?)\\/gi\\/?$","segments":[[{"content":"slug","dynamic":true,"spread":false}],[{"content":"gi","dynamic":false,"spread":false}]],"params":["slug"],"component":"src/pages/[slug]/gi.ts","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/[slug]/i","isIndex":false,"type":"endpoint","pattern":"^\\/([^/]+?)\\/i\\/?$","segments":[[{"content":"slug","dynamic":true,"spread":false}],[{"content":"i","dynamic":false,"spread":false}]],"params":["slug"],"component":"src/pages/[slug]/i.ts","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[{"type":"external","src":"/_astro/_slug_.DRpcPMTm.css"},{"type":"inline","content":".os-tab[data-astro-cid-yvbahnfj]{color:var(--color-gray-600)}.os-tab[data-astro-cid-yvbahnfj].active{background:#ffffff0f;color:#fff}\n"}],"routeData":{"route":"/[slug]","isIndex":false,"type":"page","pattern":"^\\/([^/]+?)\\/?$","segments":[[{"content":"slug","dynamic":true,"spread":false}]],"params":["slug"],"component":"src/pages/[slug].astro","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[{"type":"external","src":"/_astro/_slug_.DRpcPMTm.css"},{"type":"inline","content":".os-tab[data-astro-cid-j7pv25f6]{color:var(--color-gray-600, #6b7280)}.os-tab[data-astro-cid-j7pv25f6].active{background:#ffffff0f;color:#fff}\n"}],"routeData":{"route":"/","isIndex":true,"type":"page","pattern":"^\\/$","segments":[],"params":[],"component":"src/pages/index.astro","pathname":"/","prerender":false,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}}],"site":"https://skills.here.run.place","base":"/","trailingSlash":"ignore","compressHTML":true,"componentMetadata":[["/Users/alex/projects/skillit/src/pages/[slug].astro",{"propagation":"none","containsHead":true}],["/Users/alex/projects/skillit/src/pages/[slug]/edit.astro",{"propagation":"none","containsHead":true}],["/Users/alex/projects/skillit/src/pages/index.astro",{"propagation":"none","containsHead":true}],["/Users/alex/projects/skillit/src/pages/new.astro",{"propagation":"none","containsHead":true}]],"renderers":[],"clientDirectives":[["idle","(()=>{var l=(n,t)=>{let i=async()=>{await(await n())()},e=typeof t.value==\"object\"?t.value:void 0,s={timeout:e==null?void 0:e.timeout};\"requestIdleCallback\"in window?window.requestIdleCallback(i,s):setTimeout(i,s.timeout||200)};(self.Astro||(self.Astro={})).idle=l;window.dispatchEvent(new Event(\"astro:idle\"));})();"],["load","(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event(\"astro:load\"));})();"],["media","(()=>{var n=(a,t)=>{let i=async()=>{await(await a())()};if(t.value){let e=matchMedia(t.value);e.matches?i():e.addEventListener(\"change\",i,{once:!0})}};(self.Astro||(self.Astro={})).media=n;window.dispatchEvent(new Event(\"astro:media\"));})();"],["only","(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event(\"astro:only\"));})();"],["visible","(()=>{var a=(s,i,o)=>{let r=async()=>{await(await s())()},t=typeof i.value==\"object\"?i.value:void 0,c={rootMargin:t==null?void 0:t.rootMargin},n=new IntersectionObserver(e=>{for(let l of e)if(l.isIntersecting){n.disconnect(),r();break}},c);for(let e of o.children)n.observe(e)};(self.Astro||(self.Astro={})).visible=a;window.dispatchEvent(new Event(\"astro:visible\"));})();"]],"entryModules":{"\u0000noop-middleware":"_noop-middleware.mjs","\u0000virtual:astro:actions/noop-entrypoint":"noop-entrypoint.mjs","\u0000@astro-page:src/pages/api/auth/register@_@ts":"pages/api/auth/register.astro.mjs","\u0000@astro-page:src/pages/api/auth/verify@_@ts":"pages/api/auth/verify.astro.mjs","\u0000@astro-page:src/pages/api/skills/[slug]@_@ts":"pages/api/skills/_slug_.astro.mjs","\u0000@astro-page:src/pages/api/skills/index@_@ts":"pages/api/skills.astro.mjs","\u0000@astro-page:src/pages/api/sync/project@_@ts":"pages/api/sync/project.astro.mjs","\u0000@astro-page:src/pages/api/sync/index@_@ts":"pages/api/sync.astro.mjs","\u0000@astro-page:src/pages/gi@_@ts":"pages/gi.astro.mjs","\u0000@astro-page:src/pages/gp@_@ts":"pages/gp.astro.mjs","\u0000@astro-page:src/pages/i@_@ts":"pages/i.astro.mjs","\u0000@astro-page:src/pages/new@_@astro":"pages/new.astro.mjs","\u0000@astro-page:src/pages/p@_@ts":"pages/p.astro.mjs","\u0000@astro-page:src/pages/[slug]/edit@_@astro":"pages/_slug_/edit.astro.mjs","\u0000@astro-page:src/pages/[slug]/gi@_@ts":"pages/_slug_/gi.astro.mjs","\u0000@astro-page:src/pages/[slug]/i@_@ts":"pages/_slug_/i.astro.mjs","\u0000@astro-page:src/pages/[slug]@_@astro":"pages/_slug_.astro.mjs","\u0000@astro-page:src/pages/index@_@astro":"pages/index.astro.mjs","\u0000@astrojs-ssr-virtual-entry":"entry.mjs","\u0000@astro-renderers":"renderers.mjs","\u0000@astro-page:node_modules/astro/dist/assets/endpoint/node@_@js":"pages/_image.astro.mjs","\u0000@astrojs-ssr-adapter":"_@astrojs-ssr-adapter.mjs","\u0000@astrojs-manifest":"manifest_Bz0Ba_R4.mjs","/Users/alex/projects/skillit/node_modules/unstorage/drivers/fs-lite.mjs":"chunks/fs-lite_COtHaKzy.mjs","/Users/alex/projects/skillit/node_modules/astro/dist/assets/services/sharp.js":"chunks/sharp_D9uxjd11.mjs","/Users/alex/projects/skillit/src/components/SkillEditor.vue":"_astro/SkillEditor.DYeR1V3X.js","/Users/alex/projects/skillit/src/components/EditGate.vue":"_astro/EditGate.mFTQzSOo.js","/Users/alex/projects/skillit/src/components/DeleteButton.vue":"_astro/DeleteButton.CHpgpUL1.js","/Users/alex/projects/skillit/src/components/SkillSearch.vue":"_astro/SkillSearch.A7FO5axR.js","@astrojs/vue/client.js":"_astro/client.BnTlSu1B.js","/Users/alex/projects/skillit/src/pages/[slug].astro?astro&type=script&index=0&lang.ts":"_astro/_slug_.astro_astro_type_script_index_0_lang.CRZqxzg1.js","/Users/alex/projects/skillit/src/pages/index.astro?astro&type=script&index=0&lang.ts":"_astro/index.astro_astro_type_script_index_0_lang.CRZqxzg1.js","astro:scripts/before-hydration.js":""},"inlinedScripts":[["/Users/alex/projects/skillit/src/pages/[slug].astro?astro&type=script&index=0&lang.ts","const n=/Win/.test(navigator.platform);function c(t){document.querySelectorAll(\"[data-cmd]\").forEach(e=>{e.classList.toggle(\"hidden\",e.dataset.cmd!==t)}),document.querySelectorAll(\".os-tab\").forEach(e=>{e.classList.toggle(\"active\",e.dataset.os===t)})}c(n?\"win\":\"unix\");document.querySelectorAll(\".os-tab\").forEach(t=>{t.addEventListener(\"click\",()=>c(t.dataset.os))});document.querySelectorAll(\"[data-copy]\").forEach(t=>{t.addEventListener(\"click\",()=>{const o=t.parentElement.querySelector(\"[data-cmd]:not(.hidden)\")?.textContent?.trim();o&&(navigator.clipboard.writeText(o),t.textContent=\"Copied!\",setTimeout(()=>t.textContent=\"Copy\",1500))})});"],["/Users/alex/projects/skillit/src/pages/index.astro?astro&type=script&index=0&lang.ts","const n=/Win/.test(navigator.platform);function c(t){document.querySelectorAll(\"[data-cmd]\").forEach(e=>{e.classList.toggle(\"hidden\",e.dataset.cmd!==t)}),document.querySelectorAll(\".os-tab\").forEach(e=>{e.classList.toggle(\"active\",e.dataset.os===t)})}c(n?\"win\":\"unix\");document.querySelectorAll(\".os-tab\").forEach(t=>{t.addEventListener(\"click\",()=>c(t.dataset.os))});document.querySelectorAll(\"[data-copy]\").forEach(t=>{t.addEventListener(\"click\",()=>{const o=t.parentElement.querySelector(\"[data-cmd]:not(.hidden)\")?.textContent?.trim();o&&(navigator.clipboard.writeText(o),t.textContent=\"Copied!\",setTimeout(()=>t.textContent=\"Copy\",1500))})});"]],"assets":["/_astro/_slug_.DRpcPMTm.css","/favicon.svg","/_astro/DeleteButton.CHpgpUL1.js","/_astro/EditGate.mFTQzSOo.js","/_astro/SkillEditor.DYeR1V3X.js","/_astro/SkillSearch.A7FO5axR.js","/_astro/_plugin-vue_export-helper.DlAUqK2U.js","/_astro/client.BnTlSu1B.js","/_astro/runtime-dom.esm-bundler.A7MyAQcw.js"],"buildFormat":"directory","checkOrigin":true,"allowedDomains":[],"serverIslandNameMap":[],"key":"6Xc2Lr78SYdu5wzlmowCLZe6tfLEMED9cWb4WsmVKV4=","sessionConfig":{"driver":"fs-lite","options":{"base":"/Users/alex/projects/skillit/node_modules/.astro/sessions"}}}); -if (manifest.sessionConfig) manifest.sessionConfig.driverModule = () => import('./chunks/fs-lite_COtHaKzy.mjs'); - -export { manifest }; diff --git a/dist/server/noop-entrypoint.mjs b/dist/server/noop-entrypoint.mjs deleted file mode 100644 index f30dc32..0000000 --- a/dist/server/noop-entrypoint.mjs +++ /dev/null @@ -1,3 +0,0 @@ -const server = {}; - -export { server }; diff --git a/dist/server/pages/_image.astro.mjs b/dist/server/pages/_image.astro.mjs deleted file mode 100644 index 9b0c375..0000000 --- a/dist/server/pages/_image.astro.mjs +++ /dev/null @@ -1,2 +0,0 @@ -export { a as page } from '../chunks/node_HH9e2ntY.mjs'; -export { renderers } from '../renderers.mjs'; diff --git a/dist/server/pages/_slug_.astro.mjs b/dist/server/pages/_slug_.astro.mjs deleted file mode 100644 index 681d37f..0000000 --- a/dist/server/pages/_slug_.astro.mjs +++ /dev/null @@ -1,292 +0,0 @@ -import { e as createAstro, f as createComponent, k as renderComponent, l as renderScript, r as renderTemplate, m as maybeRenderHead, h as addAttribute, u as unescapeHTML } from '../chunks/astro/server_CF97kUu8.mjs'; -import 'piccolore'; -import { _ as _export_sfc, $ as $$Base } from '../chunks/_plugin-vue_export-helper_CEgY73aA.mjs'; -import { useSSRContext, defineComponent, ref, nextTick, mergeProps } from 'vue'; -import { ssrRenderTeleport, ssrInterpolate, ssrRenderAttr, ssrIncludeBooleanAttr, ssrRenderAttrs } from 'vue/server-renderer'; -import { g as getSkill, b as getForksOf } from '../chunks/skills_BacVQUiS.mjs'; -import { h as hasToken } from '../chunks/tokens_CAzj9Aj8.mjs'; -import { a as recordDownload, g as getStatsForSlug } from '../chunks/stats_CaDi9y9J.mjs'; -import { marked } from 'marked'; -/* empty css */ -export { renderers } from '../renderers.mjs'; - -const _sfc_main$1 = /* @__PURE__ */ defineComponent({ - __name: "EditGate", - props: { - slug: {}, - authorEmail: {}, - authorName: {}, - authorHasToken: { type: Boolean } - }, - setup(__props, { expose: __expose }) { - __expose(); - const props = __props; - const showModal = ref(false); - const token = ref(""); - const error = ref(""); - const verifying = ref(false); - const tokenInput = ref(); - async function handleClick() { - if (!props.authorEmail || !props.authorHasToken) { - window.location.href = `/${props.slug}/edit`; - return; - } - const saved = localStorage.getItem("skillshere-token") || ""; - if (saved) { - try { - const res = await fetch("/api/auth/verify", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ email: props.authorEmail, token: saved }) - }); - if (res.ok) { - localStorage.setItem("skillshere-token", saved); - window.location.href = `/${props.slug}/edit`; - return; - } - } catch { - } - } - showModal.value = true; - error.value = ""; - token.value = ""; - nextTick(() => tokenInput.value?.focus()); - } - async function verify() { - verifying.value = true; - error.value = ""; - try { - const res = await fetch("/api/auth/verify", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ email: props.authorEmail, token: token.value }) - }); - if (!res.ok) { - const data = await res.json(); - error.value = data.error || "Invalid token"; - return; - } - localStorage.setItem("skillshere-token", token.value); - window.location.href = `/${props.slug}/edit`; - } catch { - error.value = "Could not verify token"; - } finally { - verifying.value = false; - } - } - function forkSkill() { - showModal.value = false; - window.location.href = `/new?from=${encodeURIComponent(props.slug)}`; - } - const __returned__ = { props, showModal, token, error, verifying, tokenInput, handleClick, verify, forkSkill }; - Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); - return __returned__; - } -}); -function _sfc_ssrRender$1(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { - _push(``); - ssrRenderTeleport(_push, (_push2) => { - if ($setup.showModal) { - _push2(`

    Author Verification

    This skill is owned by ${ssrInterpolate($props.authorName || $props.authorEmail)}. Enter your token to edit.

    `); - if ($setup.error) { - _push2(`

    ${ssrInterpolate($setup.error)}

    `); - } else { - _push2(``); - } - _push2(`
    `); - } else { - _push2(``); - } - }, "body", false, _parent); - _push(``); -} -const _sfc_setup$1 = _sfc_main$1.setup; -_sfc_main$1.setup = (props, ctx) => { - const ssrContext = useSSRContext(); - (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("src/components/EditGate.vue"); - return _sfc_setup$1 ? _sfc_setup$1(props, ctx) : void 0; -}; -const EditGate = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["ssrRender", _sfc_ssrRender$1]]); - -const _sfc_main = /* @__PURE__ */ defineComponent({ - __name: "DeleteButton", - props: { - slug: {}, - authorEmail: {}, - authorName: {}, - authorHasToken: { type: Boolean } - }, - setup(__props, { expose: __expose }) { - __expose(); - const props = __props; - const deleting = ref(false); - const showModal = ref(false); - const token = ref(""); - const error = ref(""); - const tokenInput = ref(); - async function handleClick() { - if (props.authorEmail && props.authorHasToken) { - const saved = localStorage.getItem("skillshere-token") || ""; - if (saved) { - try { - const res = await fetch("/api/auth/verify", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ email: props.authorEmail, token: saved }) - }); - if (res.ok) { - doDelete(saved); - return; - } - } catch { - } - } - showModal.value = true; - error.value = ""; - token.value = ""; - nextTick(() => tokenInput.value?.focus()); - } else { - doDelete(""); - } - } - async function verifyAndDelete() { - error.value = ""; - deleting.value = true; - try { - const verifyRes = await fetch("/api/auth/verify", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ email: props.authorEmail, token: token.value }) - }); - if (!verifyRes.ok) { - const data = await verifyRes.json(); - error.value = data.error || "Invalid token"; - deleting.value = false; - return; - } - } catch { - error.value = "Could not verify token"; - deleting.value = false; - return; - } - localStorage.setItem("skillshere-token", token.value); - doDelete(token.value); - } - async function doDelete(authToken) { - if (!confirm(`Delete "${props.slug}"? This cannot be undone.`)) { - deleting.value = false; - return; - } - deleting.value = true; - error.value = ""; - try { - const headers = {}; - if (authToken) { - headers["Authorization"] = `Bearer ${authToken}`; - } - const res = await fetch(`/api/skills/${props.slug}`, { method: "DELETE", headers }); - if (res.status === 403) { - const data = await res.json(); - error.value = data.error || "Permission denied"; - showModal.value = true; - deleting.value = false; - return; - } - if (!res.ok && res.status !== 204) { - const data = await res.json().catch(() => ({ error: "Failed to delete" })); - throw new Error(data.error || "Failed to delete"); - } - window.location.href = "/"; - } catch (err) { - error.value = err instanceof Error ? err.message : "Failed to delete skill."; - deleting.value = false; - } - } - const __returned__ = { props, deleting, showModal, token, error, tokenInput, handleClick, verifyAndDelete, doDelete }; - Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); - return __returned__; - } -}); -function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { - _push(` ${ssrInterpolate($setup.deleting ? "Deleting..." : "Delete")}`); - ssrRenderTeleport(_push, (_push2) => { - if ($setup.showModal) { - _push2(`

    Delete Skill

    This skill is owned by ${ssrInterpolate($props.authorName || $props.authorEmail)}. Enter your token to delete it.

    `); - if ($setup.error) { - _push2(`

    ${ssrInterpolate($setup.error)}

    `); - } else { - _push2(``); - } - _push2(`
    `); - } else { - _push2(``); - } - }, "body", false, _parent); - _push(``); -} -const _sfc_setup = _sfc_main.setup; -_sfc_main.setup = (props, ctx) => { - const ssrContext = useSSRContext(); - (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("src/components/DeleteButton.vue"); - return _sfc_setup ? _sfc_setup(props, ctx) : void 0; -}; -const DeleteButton = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); - -const $$Astro = createAstro("https://skills.here.run.place"); -const $$slug = createComponent(async ($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); - Astro2.self = $$slug; - const { slug } = Astro2.params; - const skill = await getSkill(slug); - if (!skill) { - return Astro2.redirect("/"); - } - const accept = Astro2.request.headers.get("accept") || ""; - if (!accept.includes("text/html")) { - recordDownload(slug); - return new Response(skill.raw, { - headers: { "Content-Type": "text/markdown; charset=utf-8" } - }); - } - const authorHasToken = skill["author-email"] ? await hasToken(skill["author-email"]) : false; - const forks = await getForksOf(slug); - const stats = await getStatsForSlug(slug); - const html = await marked(skill.content); - const origin = Astro2.url.origin; - const cmds = { - unix: `curl -fsSL ${origin}/${slug}/i | bash`, - unixGlobal: `curl -fsSL ${origin}/${slug}/gi | bash`, - win: `irm ${origin}/${slug}/i | iex`, - winGlobal: `irm ${origin}/${slug}/gi | iex` - }; - return renderTemplate`${renderComponent($$result, "Base", $$Base, { "title": `${skill.name} \u2014 Skills Here`, "data-astro-cid-yvbahnfj": true }, { "default": async ($$result2) => renderTemplate` ${maybeRenderHead()} -Back -

    ${skill.name}

    ${skill.description && renderTemplate`

    ${skill.description}

    `} ${skill["allowed-tools"].length > 0 && renderTemplate`
    ${skill["allowed-tools"].map((tool) => renderTemplate` ${tool} `)}
    `} ${skill.tags.length > 0 && renderTemplate`
    ${skill.tags.map((tag) => renderTemplate` ${tag} `)}
    `} ${skill.author && renderTemplate`

    by ${skill.author}

    `} ${skill["fork-of"] && renderTemplate`

    forked from ${skill["fork-of"]}

    `} ${forks.length > 0 && renderTemplate`
    ${forks.length} fork${forks.length !== 1 ? "s" : ""}
      ${forks.map((f) => renderTemplate`
    • ${f.name} ${f.author && renderTemplate` by ${f.author}`}
    • `)}
    `}
    ${stats.downloads} download${stats.downloads !== 1 ? "s" : ""} ${stats.pushes} push${stats.pushes !== 1 ? "es" : ""} ${stats.lastPushedAt && renderTemplate` -Last updated ${new Date(stats.lastPushedAt).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })} `}

    Install this skill

    Run in your project root to add this skill.

    ${cmds.unix}
    More options

    Install globally (available in all projects):

    ${cmds.unixGlobal}
    ${renderComponent($$result2, "EditGate", EditGate, { "slug": slug, "authorEmail": skill["author-email"], "authorName": skill.author, "authorHasToken": authorHasToken, "client:load": true, "client:component-hydration": "load", "client:component-path": "/Users/alex/projects/skillit/src/components/EditGate.vue", "client:component-export": "default", "data-astro-cid-yvbahnfj": true })} ${renderComponent($$result2, "DeleteButton", DeleteButton, { "slug": slug, "authorEmail": skill["author-email"], "authorName": skill.author, "authorHasToken": authorHasToken, "client:load": true, "client:component-hydration": "load", "client:component-path": "/Users/alex/projects/skillit/src/components/DeleteButton.vue", "client:component-export": "default", "data-astro-cid-yvbahnfj": true })}
    ${unescapeHTML(html)}
    ` })} ${renderScript($$result, "/Users/alex/projects/skillit/src/pages/[slug].astro?astro&type=script&index=0&lang.ts")}`; -}, "/Users/alex/projects/skillit/src/pages/[slug].astro", void 0); - -const $$file = "/Users/alex/projects/skillit/src/pages/[slug].astro"; -const $$url = "/[slug]"; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - default: $$slug, - file: $$file, - url: $$url -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/_slug_/edit.astro.mjs b/dist/server/pages/_slug_/edit.astro.mjs deleted file mode 100644 index 5e7ccf3..0000000 --- a/dist/server/pages/_slug_/edit.astro.mjs +++ /dev/null @@ -1,38 +0,0 @@ -import { e as createAstro, f as createComponent, k as renderComponent, r as renderTemplate, m as maybeRenderHead, h as addAttribute } from '../../chunks/astro/server_CF97kUu8.mjs'; -import 'piccolore'; -import { $ as $$Base } from '../../chunks/_plugin-vue_export-helper_CEgY73aA.mjs'; -import { g as getAvailableTools, a as getAvailableModels, S as SkillEditor } from '../../chunks/models_BK7lP4G3.mjs'; -import { g as getSkill, a as getAllTags } from '../../chunks/skills_BacVQUiS.mjs'; -export { renderers } from '../../renderers.mjs'; - -const $$Astro = createAstro("https://skills.here.run.place"); -const $$Edit = createComponent(async ($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); - Astro2.self = $$Edit; - const { slug } = Astro2.params; - const skill = await getSkill(slug); - if (!skill) { - return Astro2.redirect("/"); - } - const availableTools = await getAvailableTools(); - const availableModels = await getAvailableModels(); - const allowedTools = skill["allowed-tools"].join(", "); - const hooksJson = skill.hooks ? JSON.stringify(skill.hooks, null, 2) : ""; - const availableTags = await getAllTags(); - return renderTemplate`${renderComponent($$result, "Base", $$Base, { "title": `Edit ${skill.name} \u2014 Skills Here` }, { "default": async ($$result2) => renderTemplate` ${maybeRenderHead()} -Back to ${skill.name}

    Edit Skill

    Editing ${skill.name}. Users who already installed this skill will get the updated version on their next sync.

    ${renderComponent($$result2, "SkillEditor", SkillEditor, { "mode": "edit", "slug": slug, "initialName": skill.name, "initialDescription": skill.description, "initialAllowedTools": allowedTools, "initialArgumentHint": skill["argument-hint"], "initialModel": skill.model, "initialUserInvocable": skill["user-invocable"], "initialDisableModelInvocation": skill["disable-model-invocation"], "initialContext": skill.context, "initialAgent": skill.agent, "initialHooks": hooksJson, "initialBody": skill.content, "initialAuthor": skill.author, "initialAuthorEmail": skill["author-email"], "initialTags": skill.tags.join(", "), ":availableTools": availableTools, ":availableModels": availableModels, "availableTags": availableTags.join(","), "client:load": true, "client:component-hydration": "load", "client:component-path": "/Users/alex/projects/skillit/src/components/SkillEditor.vue", "client:component-export": "default" })} ` })}`; -}, "/Users/alex/projects/skillit/src/pages/[slug]/edit.astro", void 0); - -const $$file = "/Users/alex/projects/skillit/src/pages/[slug]/edit.astro"; -const $$url = "/[slug]/edit"; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - default: $$Edit, - file: $$file, - url: $$url -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/_slug_/gi.astro.mjs b/dist/server/pages/_slug_/gi.astro.mjs deleted file mode 100644 index 7135c43..0000000 --- a/dist/server/pages/_slug_/gi.astro.mjs +++ /dev/null @@ -1,40 +0,0 @@ -import { g as getSkill } from '../../chunks/skills_BacVQUiS.mjs'; -import { i as isPowerShell } from '../../chunks/sync_BEq_wzpT.mjs'; -export { renderers } from '../../renderers.mjs'; - -const GET = async ({ params, url, request }) => { - const { slug } = params; - const skill = await getSkill(slug); - if (!skill) { - return new Response("Skill not found", { status: 404 }); - } - const origin = url.origin; - const ps = isPowerShell(request); - const script = ps ? [ - '$ErrorActionPreference = "Stop"', - '$Dir = Join-Path $HOME ".claude\\skills"', - "New-Item -ItemType Directory -Force -Path $Dir | Out-Null", - `Invoke-WebRequest -Uri "${origin}/${slug}" -OutFile (Join-Path $Dir "${slug}.md")`, - `Write-Host "✓ Installed ${skill.name} globally to $Dir\\${slug}.md"`, - "" - ].join("\n") : [ - "#!/usr/bin/env bash", - "set -euo pipefail", - "mkdir -p ~/.claude/skills", - `curl -fsSL "${origin}/${slug}" -o ~/.claude/skills/${slug}.md`, - `echo "✓ Installed ${skill.name} globally to ~/.claude/skills/${slug}.md"`, - "" - ].join("\n"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/_slug_/i.astro.mjs b/dist/server/pages/_slug_/i.astro.mjs deleted file mode 100644 index 6291075..0000000 --- a/dist/server/pages/_slug_/i.astro.mjs +++ /dev/null @@ -1,40 +0,0 @@ -import { g as getSkill } from '../../chunks/skills_BacVQUiS.mjs'; -import { i as isPowerShell } from '../../chunks/sync_BEq_wzpT.mjs'; -export { renderers } from '../../renderers.mjs'; - -const GET = async ({ params, url, request }) => { - const { slug } = params; - const skill = await getSkill(slug); - if (!skill) { - return new Response("Skill not found", { status: 404 }); - } - const origin = url.origin; - const ps = isPowerShell(request); - const script = ps ? [ - '$ErrorActionPreference = "Stop"', - '$Dir = ".claude\\skills"', - "New-Item -ItemType Directory -Force -Path $Dir | Out-Null", - `Invoke-WebRequest -Uri "${origin}/${slug}" -OutFile (Join-Path $Dir "${slug}.md")`, - `Write-Host "✓ Installed ${skill.name} to $Dir\\${slug}.md"`, - "" - ].join("\n") : [ - "#!/usr/bin/env bash", - "set -euo pipefail", - "mkdir -p .claude/skills", - `curl -fsSL "${origin}/${slug}" -o ".claude/skills/${slug}.md"`, - `echo "✓ Installed ${skill.name} to .claude/skills/${slug}.md"`, - "" - ].join("\n"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/api/auth/register.astro.mjs b/dist/server/pages/api/auth/register.astro.mjs deleted file mode 100644 index 7e648ac..0000000 --- a/dist/server/pages/api/auth/register.astro.mjs +++ /dev/null @@ -1,55 +0,0 @@ -import { h as hasToken, g as generateToken } from '../../../chunks/tokens_CAzj9Aj8.mjs'; -export { renderers } from '../../../renderers.mjs'; - -const POST = async ({ request }) => { - let body; - try { - body = await request.json(); - } catch { - return new Response(JSON.stringify({ error: "Invalid JSON" }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - const { email, name } = body; - if (!email) { - return new Response(JSON.stringify({ error: "email is required" }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - if (await hasToken(email)) { - return new Response(JSON.stringify({ error: "Email already registered" }), { - status: 409, - headers: { "Content-Type": "application/json" } - }); - } - try { - const token = await generateToken(email, name || ""); - return new Response(JSON.stringify({ token }), { - status: 201, - headers: { "Content-Type": "application/json" } - }); - } catch (err) { - const message = err instanceof Error ? err.message : "Unknown error"; - if (message.includes("already registered")) { - return new Response(JSON.stringify({ error: message }), { - status: 409, - headers: { "Content-Type": "application/json" } - }); - } - return new Response(JSON.stringify({ error: message }), { - status: 500, - headers: { "Content-Type": "application/json" } - }); - } -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - POST -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/api/auth/verify.astro.mjs b/dist/server/pages/api/auth/verify.astro.mjs deleted file mode 100644 index d98795d..0000000 --- a/dist/server/pages/api/auth/verify.astro.mjs +++ /dev/null @@ -1,40 +0,0 @@ -import { v as verifyToken } from '../../../chunks/tokens_CAzj9Aj8.mjs'; -export { renderers } from '../../../renderers.mjs'; - -const POST = async ({ request }) => { - let body; - try { - body = await request.json(); - } catch { - return new Response(JSON.stringify({ error: "Invalid JSON" }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - const { email, token } = body; - if (!email || !token) { - return new Response(JSON.stringify({ error: "email and token are required" }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - const valid = await verifyToken(email, token); - if (!valid) { - return new Response(JSON.stringify({ error: "Invalid token" }), { - status: 403, - headers: { "Content-Type": "application/json" } - }); - } - return new Response(JSON.stringify({ ok: true }), { - headers: { "Content-Type": "application/json" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - POST -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/api/skills.astro.mjs b/dist/server/pages/api/skills.astro.mjs deleted file mode 100644 index 0f9483a..0000000 --- a/dist/server/pages/api/skills.astro.mjs +++ /dev/null @@ -1,78 +0,0 @@ -import matter from 'gray-matter'; -import { l as listSkills, i as isValidSlug, c as createSkill } from '../../chunks/skills_BacVQUiS.mjs'; -import { h as hasToken, e as extractBearerToken, v as verifyToken } from '../../chunks/tokens_CAzj9Aj8.mjs'; -import { r as recordPush } from '../../chunks/stats_CaDi9y9J.mjs'; -export { renderers } from '../../renderers.mjs'; - -const GET = async () => { - const skills = await listSkills(); - return new Response(JSON.stringify(skills), { - headers: { "Content-Type": "application/json" } - }); -}; -const POST = async ({ request }) => { - let body; - try { - body = await request.json(); - } catch { - return new Response(JSON.stringify({ error: "Invalid JSON" }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - const { slug, content } = body; - if (!slug || !content) { - return new Response(JSON.stringify({ error: "slug and content are required" }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - if (!isValidSlug(slug)) { - return new Response(JSON.stringify({ error: "Invalid slug. Use lowercase alphanumeric and hyphens, 2-64 chars." }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - const parsed = matter(content); - const authorEmail = parsed.data["author-email"] || ""; - if (authorEmail && await hasToken(authorEmail)) { - const token = extractBearerToken(request); - const valid = await verifyToken(authorEmail, token); - if (!valid) { - return new Response(JSON.stringify({ error: "Valid token required to create a skill with author-email. Register first via POST /api/auth/register." }), { - status: 403, - headers: { "Content-Type": "application/json" } - }); - } - } - try { - const skill = await createSkill(slug, content); - recordPush(slug); - return new Response(JSON.stringify(skill), { - status: 201, - headers: { "Content-Type": "application/json" } - }); - } catch (err) { - const message = err instanceof Error ? err.message : "Unknown error"; - if (message.includes("already exists")) { - return new Response(JSON.stringify({ error: message }), { - status: 409, - headers: { "Content-Type": "application/json" } - }); - } - return new Response(JSON.stringify({ error: message }), { - status: 500, - headers: { "Content-Type": "application/json" } - }); - } -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET, - POST -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/api/skills/_slug_.astro.mjs b/dist/server/pages/api/skills/_slug_.astro.mjs deleted file mode 100644 index 4e60991..0000000 --- a/dist/server/pages/api/skills/_slug_.astro.mjs +++ /dev/null @@ -1,102 +0,0 @@ -import 'gray-matter'; -import { g as getSkill, d as deleteSkill, u as updateSkill } from '../../../chunks/skills_BacVQUiS.mjs'; -import { h as hasToken, e as extractBearerToken, v as verifyToken } from '../../../chunks/tokens_CAzj9Aj8.mjs'; -import { r as recordPush } from '../../../chunks/stats_CaDi9y9J.mjs'; -export { renderers } from '../../../renderers.mjs'; - -const GET = async ({ params }) => { - const skill = await getSkill(params.slug); - if (!skill) { - return new Response("Not found", { status: 404 }); - } - return new Response(skill.raw, { - headers: { "Content-Type": "text/markdown; charset=utf-8" } - }); -}; -const PUT = async ({ params, request }) => { - let body; - try { - body = await request.json(); - } catch { - return new Response(JSON.stringify({ error: "Invalid JSON" }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - if (!body.content) { - return new Response(JSON.stringify({ error: "content is required" }), { - status: 400, - headers: { "Content-Type": "application/json" } - }); - } - try { - const existing = await getSkill(params.slug); - if (!existing) { - return new Response(JSON.stringify({ error: "Skill not found" }), { - status: 404, - headers: { "Content-Type": "application/json" } - }); - } - if (existing["author-email"] && await hasToken(existing["author-email"])) { - const token = extractBearerToken(request); - const valid = await verifyToken(existing["author-email"], token); - if (!valid) { - return new Response(JSON.stringify({ error: `Only ${existing.author || existing["author-email"]} can update this skill. Provide a valid token via Authorization: Bearer header.` }), { - status: 403, - headers: { "Content-Type": "application/json" } - }); - } - } - const skill = await updateSkill(params.slug, body.content); - recordPush(params.slug); - return new Response(JSON.stringify(skill), { - headers: { "Content-Type": "application/json" } - }); - } catch (err) { - const message = err instanceof Error ? err.message : "Unknown error"; - return new Response(JSON.stringify({ error: message }), { - status: 500, - headers: { "Content-Type": "application/json" } - }); - } -}; -const DELETE = async ({ params, request }) => { - try { - const existing = await getSkill(params.slug); - if (!existing) { - return new Response(JSON.stringify({ error: "Skill not found" }), { - status: 404, - headers: { "Content-Type": "application/json" } - }); - } - if (existing["author-email"] && await hasToken(existing["author-email"])) { - const token = extractBearerToken(request); - const valid = await verifyToken(existing["author-email"], token); - if (!valid) { - return new Response(JSON.stringify({ error: `Only ${existing.author || existing["author-email"]} can delete this skill. Provide a valid token via Authorization: Bearer header.` }), { - status: 403, - headers: { "Content-Type": "application/json" } - }); - } - } - await deleteSkill(params.slug); - return new Response(null, { status: 204 }); - } catch (err) { - const message = err instanceof Error ? err.message : "Unknown error"; - return new Response(JSON.stringify({ error: message }), { - status: 500, - headers: { "Content-Type": "application/json" } - }); - } -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - DELETE, - GET, - PUT -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/api/sync.astro.mjs b/dist/server/pages/api/sync.astro.mjs deleted file mode 100644 index 3f640b7..0000000 --- a/dist/server/pages/api/sync.astro.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import { b as buildSyncScript } from '../../chunks/sync_BEq_wzpT.mjs'; -export { renderers } from '../../renderers.mjs'; - -const GET = async ({ url }) => { - const script = await buildSyncScript(url.origin, "$HOME/.claude/skills"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/api/sync/project.astro.mjs b/dist/server/pages/api/sync/project.astro.mjs deleted file mode 100644 index 72d17c4..0000000 --- a/dist/server/pages/api/sync/project.astro.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import { b as buildSyncScript } from '../../../chunks/sync_BEq_wzpT.mjs'; -export { renderers } from '../../../renderers.mjs'; - -const GET = async ({ url }) => { - const script = await buildSyncScript(url.origin, ".claude/skills"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/gi.astro.mjs b/dist/server/pages/gi.astro.mjs deleted file mode 100644 index 024e949..0000000 --- a/dist/server/pages/gi.astro.mjs +++ /dev/null @@ -1,19 +0,0 @@ -import { i as isPowerShell, a as buildSyncScriptPS, b as buildSyncScript } from '../chunks/sync_BEq_wzpT.mjs'; -export { renderers } from '../renderers.mjs'; - -const GET = async ({ url, request }) => { - const ps = isPowerShell(request); - const script = ps ? await buildSyncScriptPS(url.origin, "$HOME\\.claude\\skills") : await buildSyncScript(url.origin, "$HOME/.claude/skills"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/gp.astro.mjs b/dist/server/pages/gp.astro.mjs deleted file mode 100644 index a74de8c..0000000 --- a/dist/server/pages/gp.astro.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import { c as buildPushScript } from '../chunks/sync_BEq_wzpT.mjs'; -export { renderers } from '../renderers.mjs'; - -const GET = async ({ url }) => { - const script = await buildPushScript(url.origin, "$HOME/.claude/skills"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/i.astro.mjs b/dist/server/pages/i.astro.mjs deleted file mode 100644 index d02f072..0000000 --- a/dist/server/pages/i.astro.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import { b as buildSyncScript } from '../chunks/sync_BEq_wzpT.mjs'; -export { renderers } from '../renderers.mjs'; - -const GET = async ({ url }) => { - const script = await buildSyncScript(url.origin, ".claude/skills"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/index.astro.mjs b/dist/server/pages/index.astro.mjs deleted file mode 100644 index c894b72..0000000 --- a/dist/server/pages/index.astro.mjs +++ /dev/null @@ -1,332 +0,0 @@ -import { e as createAstro, f as createComponent, m as maybeRenderHead, h as addAttribute, r as renderTemplate, k as renderComponent, l as renderScript } from '../chunks/astro/server_CF97kUu8.mjs'; -import 'piccolore'; -import { _ as _export_sfc, $ as $$Base } from '../chunks/_plugin-vue_export-helper_CEgY73aA.mjs'; -import 'clsx'; -import { useSSRContext, defineComponent, ref, computed, onMounted, watch, nextTick, mergeProps } from 'vue'; -import { ssrRenderAttrs, ssrRenderAttr, ssrRenderList, ssrInterpolate, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderClass } from 'vue/server-renderer'; -import { l as listSkills } from '../chunks/skills_BacVQUiS.mjs'; -import { b as getAllStats } from '../chunks/stats_CaDi9y9J.mjs'; -import { i as isPowerShell, a as buildSyncScriptPS, b as buildSyncScript } from '../chunks/sync_BEq_wzpT.mjs'; -/* empty css */ -export { renderers } from '../renderers.mjs'; - -const $$Astro$1 = createAstro("https://skills.here.run.place"); -const $$SkillCard = createComponent(($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); - Astro2.self = $$SkillCard; - const { slug, name, description, "allowed-tools": allowedTools, tags = [], author, forkCount = 0, downloads = 0, pushes = 0, lastPushedAt } = Astro2.props; - const updatedLabel = lastPushedAt ? new Date(lastPushedAt).toLocaleDateString("en-US", { month: "short", day: "numeric" }) : null; - const truncated = description.length > 120 ? description.slice(0, 120) + "..." : description; - return renderTemplate`${maybeRenderHead()}

    ${name}

    ${truncated && renderTemplate`

    ${truncated}

    `} ${allowedTools.length > 0 && renderTemplate`
    ${allowedTools.map((tool) => renderTemplate` ${tool} `)}
    `} ${tags.length > 0 && renderTemplate`
    ${tags.map((tag) => renderTemplate` ${tag} `)}
    `}
    ${author && renderTemplate`

    by ${author}

    `} ${forkCount > 0 && renderTemplate` ${forkCount} `} ${downloads > 0 && renderTemplate` ${downloads} `} ${pushes > 0 && renderTemplate` ${pushes} `} ${updatedLabel && renderTemplate`${updatedLabel}`}
    `; -}, "/Users/alex/projects/skillit/src/components/SkillCard.astro", void 0); - -const PER_PAGE_GRID = 12; -const PER_PAGE_TABLE = 20; -const _sfc_main = /* @__PURE__ */ defineComponent({ - __name: "SkillSearch", - props: { - authors: {}, - tags: {}, - totalCount: {} - }, - setup(__props, { expose: __expose }) { - __expose(); - const props = __props; - const authorList = props.authors ? props.authors.split(",").map((a) => a.trim()).filter(Boolean) : []; - const tagList = props.tags ? props.tags.split(",").map((t) => t.trim()).filter(Boolean) : []; - const query = ref(""); - const forkFilter = ref(""); - const savedView = typeof localStorage !== "undefined" && localStorage.getItem("skillsViewMode"); - const viewMode = ref(savedView === "table" ? "table" : "grid"); - const currentPage = ref(1); - const filteredCount = ref(props.totalCount || 0); - const perPage = computed(() => viewMode.value === "grid" ? PER_PAGE_GRID : PER_PAGE_TABLE); - const totalPages = computed(() => Math.max(1, Math.ceil(filteredCount.value / perPage.value))); - const rangeStart = computed(() => filteredCount.value === 0 ? 0 : (currentPage.value - 1) * perPage.value + 1); - const rangeEnd = computed(() => Math.min(currentPage.value * perPage.value, filteredCount.value)); - const visiblePages = computed(() => { - const pages = []; - const total = totalPages.value; - const cur = currentPage.value; - const maxVisible = 7; - if (total <= maxVisible) { - for (let i = 1; i <= total; i++) pages.push(i); - } else { - const half = Math.floor(maxVisible / 2); - let start = Math.max(1, cur - half); - let end = start + maxVisible - 1; - if (end > total) { - end = total; - start = end - maxVisible + 1; - } - for (let i = start; i <= end; i++) pages.push(i); - } - return pages; - }); - const selectedAuthors = ref([]); - const authorQuery = ref(""); - const authorOpen = ref(false); - const authorInputEl = ref(); - const authorSuggestions = computed(() => { - const q = authorQuery.value.toLowerCase().trim(); - const selected = new Set(selectedAuthors.value.map((a) => a.toLowerCase())); - return authorList.filter((a) => !selected.has(a.toLowerCase()) && (!q || a.toLowerCase().includes(q))); - }); - let authorBlurTimer; - function onAuthorBlur() { - authorBlurTimer = setTimeout(() => { - authorOpen.value = false; - }, 200); - } - function addAuthor(author) { - clearTimeout(authorBlurTimer); - if (!selectedAuthors.value.some((a) => a.toLowerCase() === author.toLowerCase())) { - selectedAuthors.value.push(author); - } - authorQuery.value = ""; - authorInputEl.value?.focus(); - } - function removeAuthor(author) { - selectedAuthors.value = selectedAuthors.value.filter((a) => a !== author); - } - function onAuthorEnter() { - if (authorSuggestions.value.length > 0) { - addAuthor(authorSuggestions.value[0]); - } - } - function onAuthorBackspace() { - if (!authorQuery.value && selectedAuthors.value.length > 0) { - selectedAuthors.value.pop(); - } - } - const selectedTags = ref([]); - const tagQuery = ref(""); - const tagOpen = ref(false); - const tagInputEl = ref(); - const tagSuggestions = computed(() => { - const q = tagQuery.value.toLowerCase().trim(); - const selected = new Set(selectedTags.value.map((t) => t.toLowerCase())); - return tagList.filter((t) => !selected.has(t.toLowerCase()) && (!q || t.toLowerCase().includes(q))); - }); - let tagBlurTimer; - function onTagBlur() { - tagBlurTimer = setTimeout(() => { - tagOpen.value = false; - }, 200); - } - function addTag(tag) { - clearTimeout(tagBlurTimer); - if (!selectedTags.value.some((t) => t.toLowerCase() === tag.toLowerCase())) { - selectedTags.value.push(tag); - } - tagQuery.value = ""; - tagInputEl.value?.focus(); - } - function removeTag(tag) { - selectedTags.value = selectedTags.value.filter((t) => t !== tag); - } - function onTagEnter() { - if (tagSuggestions.value.length > 0) { - addTag(tagSuggestions.value[0]); - } - } - function onTagBackspace() { - if (!tagQuery.value && selectedTags.value.length > 0) { - selectedTags.value.pop(); - } - } - function setView(mode) { - viewMode.value = mode; - localStorage.setItem("skillsViewMode", mode); - const grid = document.getElementById("skills-grid"); - const table = document.getElementById("skills-table"); - if (grid && table) { - grid.classList.toggle("hidden", mode !== "grid"); - table.classList.toggle("hidden", mode !== "table"); - } - currentPage.value = 1; - nextTick(() => applyFilters()); - } - onMounted(() => { - if (viewMode.value !== "grid") { - setView(viewMode.value); - } - }); - const hasActiveFilters = computed( - () => query.value || selectedAuthors.value.length > 0 || selectedTags.value.length > 0 || forkFilter.value - ); - function applyFilters() { - const q = query.value.toLowerCase().trim(); - const authors = selectedAuthors.value.map((a) => a.toLowerCase()); - const tags = selectedTags.value.map((t) => t.toLowerCase()); - const minForks = forkFilter.value ? parseInt(forkFilter.value) : 0; - const activeId = viewMode.value === "grid" ? "skills-grid" : "skills-table"; - const inactiveId = viewMode.value === "grid" ? "skills-table" : "skills-grid"; - const activeItems = Array.from(document.querySelectorAll(`#${activeId} [data-skill]`)); - const inactiveItems = document.querySelectorAll(`#${inactiveId} [data-skill]`); - inactiveItems.forEach((el) => el.style.display = "none"); - const matching = []; - activeItems.forEach((card) => { - const name = card.dataset.name || ""; - const desc = card.dataset.description || ""; - const tools = card.dataset.tools || ""; - const cardAuthor = card.dataset.author || ""; - const cardTags = (card.dataset.tags || "").split(",").filter(Boolean); - const forks = parseInt(card.dataset.forks || "0"); - const matchText = !q || name.includes(q) || desc.includes(q) || tools.includes(q) || cardTags.some((t) => t.includes(q)); - const matchAuthor = authors.length === 0 || authors.some((a) => cardAuthor.includes(a)); - const matchTag = tags.length === 0 || tags.every((t) => cardTags.includes(t)); - const matchForks = forks >= minForks; - if (matchText && matchAuthor && matchTag && matchForks) { - matching.push(card); - } - }); - filteredCount.value = matching.length; - const maxPage = Math.max(1, Math.ceil(matching.length / perPage.value)); - if (currentPage.value > maxPage) { - currentPage.value = maxPage; - } - const start = (currentPage.value - 1) * perPage.value; - const end = start + perPage.value; - activeItems.forEach((card) => { - const idx = matching.indexOf(card); - if (idx === -1) { - card.style.display = "none"; - } else if (idx >= start && idx < end) { - card.style.display = ""; - } else { - card.style.display = "none"; - } - }); - } - function goToPage(page) { - if (page < 1 || page > totalPages.value) return; - currentPage.value = page; - applyFilters(); - } - function reset() { - query.value = ""; - selectedAuthors.value = []; - authorQuery.value = ""; - selectedTags.value = []; - tagQuery.value = ""; - forkFilter.value = ""; - currentPage.value = 1; - } - watch([query, selectedAuthors, selectedTags, forkFilter], () => { - currentPage.value = 1; - applyFilters(); - }, { deep: true }); - const __returned__ = { props, authorList, tagList, query, forkFilter, savedView, viewMode, currentPage, filteredCount, PER_PAGE_GRID, PER_PAGE_TABLE, perPage, totalPages, rangeStart, rangeEnd, visiblePages, selectedAuthors, authorQuery, authorOpen, authorInputEl, authorSuggestions, get authorBlurTimer() { - return authorBlurTimer; - }, set authorBlurTimer(v) { - authorBlurTimer = v; - }, onAuthorBlur, addAuthor, removeAuthor, onAuthorEnter, onAuthorBackspace, selectedTags, tagQuery, tagOpen, tagInputEl, tagSuggestions, get tagBlurTimer() { - return tagBlurTimer; - }, set tagBlurTimer(v) { - tagBlurTimer = v; - }, onTagBlur, addTag, removeTag, onTagEnter, onTagBackspace, setView, hasActiveFilters, applyFilters, goToPage, reset }; - Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); - return __returned__; - } -}); -function _sfc_ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) { - _push(`
    `); - ssrRenderList($setup.selectedAuthors, (a) => { - _push(`${ssrInterpolate(a)} `); - }); - _push(`
    `); - if ($setup.authorOpen && $setup.authorSuggestions.length > 0) { - _push(`
    `); - ssrRenderList($setup.authorSuggestions, (a) => { - _push(``); - }); - _push(`
    `); - } else { - _push(``); - } - _push(`
    `); - ssrRenderList($setup.selectedTags, (t) => { - _push(`${ssrInterpolate(t)} `); - }); - _push(`
    `); - if ($setup.tagOpen && $setup.tagSuggestions.length > 0) { - _push(`
    `); - ssrRenderList($setup.tagSuggestions, (t) => { - _push(``); - }); - _push(`
    `); - } else { - _push(``); - } - _push(`
    `); - if ($setup.hasActiveFilters) { - _push(``); - } else { - _push(``); - } - _push(`
    `); - if ($setup.totalPages > 1) { - _push(`
    Showing ${ssrInterpolate($setup.rangeStart)}–${ssrInterpolate($setup.rangeEnd)} of ${ssrInterpolate($setup.filteredCount)}
    Prev `); - ssrRenderList($setup.visiblePages, (p) => { - _push(``); - }); - _push(` Next
    `); - } else { - _push(``); - } - _push(``); -} -const _sfc_setup = _sfc_main.setup; -_sfc_main.setup = (props, ctx) => { - const ssrContext = useSSRContext(); - (ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("src/components/SkillSearch.vue"); - return _sfc_setup ? _sfc_setup(props, ctx) : void 0; -}; -const SkillSearch = /* @__PURE__ */ _export_sfc(_sfc_main, [["ssrRender", _sfc_ssrRender]]); - -const $$Astro = createAstro("https://skills.here.run.place"); -const $$Index = createComponent(async ($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); - Astro2.self = $$Index; - const accept = Astro2.request.headers.get("accept") || ""; - if (!accept.includes("text/html")) { - const ps = isPowerShell(Astro2.request); - const script = ps ? await buildSyncScriptPS(Astro2.url.origin, ".claude\\skills") : await buildSyncScript(Astro2.url.origin, ".claude/skills"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); - } - const skills = await listSkills(); - const forkCounts = /* @__PURE__ */ new Map(); - for (const s of skills) { - if (s["fork-of"]) { - forkCounts.set(s["fork-of"], (forkCounts.get(s["fork-of"]) || 0) + 1); - } - } - const authors = [...new Set(skills.map((s) => s.author).filter(Boolean))].sort(); - const allTags = [...new Set(skills.flatMap((s) => s.tags))].sort(); - const allStats = await getAllStats(); - return renderTemplate`${renderComponent($$result, "Base", $$Base, { "title": "Skills", "data-astro-cid-j7pv25f6": true }, { "default": async ($$result2) => renderTemplate`${skills.length === 0 ? renderTemplate`${maybeRenderHead()}

    No skills yet

    Create your first skill to get started.

    -Create your first skill -
    ` : renderTemplate`

    Skills

    Manage and distribute Claude Code skills. Skills are prompt files (.md) that Claude loads automatically to learn custom behaviors and workflows.

    Create reusable skills to standardize how Claude handles commits, code reviews, testing, deployments, and more across your team. Share them instantly with a single curl command.

    Quick install

    Sync all skills to your project. They'll be saved to .claude/skills/ and Claude Code picks them up on the next conversation.

    curl -fsSL ${Astro2.url.origin} | bash
    Install globally
    curl -fsSL ${Astro2.url.origin}/gi | bash

    Quick push

    Push your local skills to the server. Run from your project root — it reads .claude/skills/*.md and uploads them.

    curl -fsSL ${Astro2.url.origin}/p | bash
    Push a specific skill
    curl -fsSL ${Astro2.url.origin}/p | bash -s skill-name
    ${renderComponent($$result2, "SkillSearch", SkillSearch, { "authors": authors.join(","), "tags": allTags.join(","), "totalCount": skills.length, "client:load": true, "client:component-hydration": "load", "client:component-path": "/Users/alex/projects/skillit/src/components/SkillSearch.vue", "client:component-export": "default", "data-astro-cid-j7pv25f6": true })}
    ${skills.map((skill) => renderTemplate`
    ${renderComponent($$result2, "SkillCard", $$SkillCard, { ...skill, "forkCount": forkCounts.get(skill.slug) || 0, "downloads": allStats[skill.slug]?.downloads || 0, "pushes": allStats[skill.slug]?.pushes || 0, "lastPushedAt": allStats[skill.slug]?.lastPushedAt || null, "data-astro-cid-j7pv25f6": true })}
    `)}
    `}` })} ${renderScript($$result, "/Users/alex/projects/skillit/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`; -}, "/Users/alex/projects/skillit/src/pages/index.astro", void 0); - -const $$file = "/Users/alex/projects/skillit/src/pages/index.astro"; -const $$url = ""; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - default: $$Index, - file: $$file, - url: $$url -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/new.astro.mjs b/dist/server/pages/new.astro.mjs deleted file mode 100644 index 835eb8d..0000000 --- a/dist/server/pages/new.astro.mjs +++ /dev/null @@ -1,37 +0,0 @@ -import { e as createAstro, f as createComponent, k as renderComponent, r as renderTemplate, m as maybeRenderHead, h as addAttribute } from '../chunks/astro/server_CF97kUu8.mjs'; -import 'piccolore'; -import { $ as $$Base } from '../chunks/_plugin-vue_export-helper_CEgY73aA.mjs'; -import { g as getAvailableTools, a as getAvailableModels, S as SkillEditor } from '../chunks/models_BK7lP4G3.mjs'; -import { a as getAllTags, g as getSkill } from '../chunks/skills_BacVQUiS.mjs'; -export { renderers } from '../renderers.mjs'; - -const $$Astro = createAstro("https://skills.here.run.place"); -const $$New = createComponent(async ($$result, $$props, $$slots) => { - const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); - Astro2.self = $$New; - const availableTools = await getAvailableTools(); - const availableModels = await getAvailableModels(); - const availableTags = await getAllTags(); - const fromSlug = Astro2.url.searchParams.get("from"); - let forkSource = null; - if (fromSlug) { - forkSource = await getSkill(fromSlug); - } - const isFork = Boolean(forkSource); - const title = isFork ? `Fork ${forkSource.name} \u2014 Skills Here` : "New Skill \u2014 Skills Here"; - return renderTemplate`${renderComponent($$result, "Base", $$Base, { "title": title }, { "default": async ($$result2) => renderTemplate` ${maybeRenderHead()} ${isFork ? `Back to ${forkSource.name}` : "Back"}

    ${isFork ? "Fork Skill" : "New Skill"}

    ${isFork ? renderTemplate`

    Creating an independent copy of ${forkSource.name}. Change the name to generate a new slug before saving.

    ` : renderTemplate`

    Write a prompt in Markdown that tells Claude how to behave. The body is the instruction Claude receives. Use Allowed Tools to restrict which tools the skill can use.

    `}${isFork ? renderTemplate`${renderComponent($$result2, "SkillEditor", SkillEditor, { "mode": "create", "forkOf": fromSlug, "initialName": forkSource.name, "initialDescription": forkSource.description, "initialAllowedTools": forkSource["allowed-tools"].join(", "), "initialArgumentHint": forkSource["argument-hint"], "initialModel": forkSource.model, "initialUserInvocable": forkSource["user-invocable"], "initialDisableModelInvocation": forkSource["disable-model-invocation"], "initialContext": forkSource.context, "initialAgent": forkSource.agent, "initialHooks": forkSource.hooks ? JSON.stringify(forkSource.hooks, null, 2) : "", "initialBody": forkSource.content, "initialTags": forkSource.tags.join(", "), ":availableTools": availableTools, ":availableModels": availableModels, "availableTags": availableTags.join(","), "client:load": true, "client:component-hydration": "load", "client:component-path": "/Users/alex/projects/skillit/src/components/SkillEditor.vue", "client:component-export": "default" })}` : renderTemplate`${renderComponent($$result2, "SkillEditor", SkillEditor, { "mode": "create", ":availableTools": availableTools, ":availableModels": availableModels, "availableTags": availableTags.join(","), "client:load": true, "client:component-hydration": "load", "client:component-path": "/Users/alex/projects/skillit/src/components/SkillEditor.vue", "client:component-export": "default" })}`}` })}`; -}, "/Users/alex/projects/skillit/src/pages/new.astro", void 0); - -const $$file = "/Users/alex/projects/skillit/src/pages/new.astro"; -const $$url = "/new"; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - default: $$New, - file: $$file, - url: $$url -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/pages/p.astro.mjs b/dist/server/pages/p.astro.mjs deleted file mode 100644 index 6dbc79c..0000000 --- a/dist/server/pages/p.astro.mjs +++ /dev/null @@ -1,19 +0,0 @@ -import { i as isPowerShell, d as buildPushScriptPS, c as buildPushScript } from '../chunks/sync_BEq_wzpT.mjs'; -export { renderers } from '../renderers.mjs'; - -const GET = async ({ url, request }) => { - const ps = isPowerShell(request); - const script = ps ? await buildPushScriptPS(url.origin, ".claude\\skills") : await buildPushScript(url.origin, ".claude/skills"); - return new Response(script, { - headers: { "Content-Type": "text/plain; charset=utf-8" } - }); -}; - -const _page = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ - __proto__: null, - GET -}, Symbol.toStringTag, { value: 'Module' })); - -const page = () => _page; - -export { page }; diff --git a/dist/server/renderers.mjs b/dist/server/renderers.mjs deleted file mode 100644 index bfc2e42..0000000 --- a/dist/server/renderers.mjs +++ /dev/null @@ -1,81 +0,0 @@ -import { defineComponent, h, createSSRApp } from 'vue'; -import { renderToString } from 'vue/server-renderer'; - -const setup = () => {}; - -const contexts = /* @__PURE__ */ new WeakMap(); -const ID_PREFIX = "s"; -function getContext(rendererContextResult) { - if (contexts.has(rendererContextResult)) { - return contexts.get(rendererContextResult); - } - const ctx = { - currentIndex: 0, - get id() { - return ID_PREFIX + this.currentIndex.toString(); - } - }; - contexts.set(rendererContextResult, ctx); - return ctx; -} -function incrementId(rendererContextResult) { - const ctx = getContext(rendererContextResult); - const id = ctx.id; - ctx.currentIndex++; - return id; -} - -const StaticHtml = defineComponent({ - props: { - value: String, - name: String, - hydrate: { - type: Boolean, - default: true - } - }, - setup({ name, value, hydrate }) { - if (!value) return () => null; - let tagName = hydrate ? "astro-slot" : "astro-static-slot"; - return () => h(tagName, { name, innerHTML: value }); - } -}); -var static_html_default = StaticHtml; - -async function check(Component) { - return !!Component["ssrRender"] || !!Component["__ssrInlineRender"]; -} -async function renderToStaticMarkup(Component, inputProps, slotted, metadata) { - let prefix; - if (this && this.result) { - prefix = incrementId(this.result); - } - const attrs = { prefix }; - const slots = {}; - const props = { ...inputProps }; - delete props.slot; - for (const [key, value] of Object.entries(slotted)) { - slots[key] = () => h(static_html_default, { - value, - name: key === "default" ? void 0 : key, - // Adjust how this is hydrated only when the version of Astro supports `astroStaticSlot` - hydrate: metadata?.astroStaticSlot ? !!metadata.hydrate : true - }); - } - const app = createSSRApp({ render: () => h(Component, props, slots) }); - app.config.idPrefix = prefix; - await setup(); - const html = await renderToString(app); - return { html, attrs }; -} -const renderer = { - name: "@astrojs/vue", - check, - renderToStaticMarkup, - supportsAstroStaticSlot: true -}; -var server_default = renderer; - -const renderers = [Object.assign({"name":"@astrojs/vue","clientEntrypoint":"@astrojs/vue/client.js","serverEntrypoint":"@astrojs/vue/server.js"}, { ssr: server_default }),]; - -export { renderers }; diff --git a/node_modules/.vite/deps/_metadata.json b/node_modules/.vite/deps/_metadata.json deleted file mode 100644 index 42e5c32..0000000 --- a/node_modules/.vite/deps/_metadata.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "hash": "867abd67", - "configHash": "8be89d65", - "lockfileHash": "e3b0c442", - "browserHash": "88ab680e", - "optimized": {}, - "chunks": {} -} \ No newline at end of file diff --git a/node_modules/.vite/deps/package.json b/node_modules/.vite/deps/package.json deleted file mode 100644 index 3dbc1ca..0000000 --- a/node_modules/.vite/deps/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/public/favicon.svg b/public/favicon.svg index 1726c13..bcfd27b 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -2,20 +2,17 @@ - - - - - + xmlns:svg="http://www.w3.org/2000/svg"> diff --git a/src/lib/models.ts b/src/lib/models.ts index 6541e32..bfbaaf3 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -27,23 +27,17 @@ function displayName(id: string): string { .replace(/^claude-/, ''); const parts = clean.split('-'); - const words = parts.map((p, i) => { - if (/^\d+$/.test(p) && i === parts.length - 1 && parts.length > 1) { - // Last numeric part after a name: turn "4-6" into "4.6" or "4-5" into "4.5" - const prev = parts[i - 1]; - if (/^\d+$/.test(prev)) return null; // will be joined with prev - return p; - } - return p.charAt(0).toUpperCase() + p.slice(1); - }).filter(Boolean); + const words = parts.map(p => + /^\d+$/.test(p) ? p : p.charAt(0).toUpperCase() + p.slice(1) + ); // Join consecutive numbers with dots: ["4", "6"] → "4.6" const result: string[] = []; for (const w of words) { - if (/^\d+$/.test(w!) && result.length > 0 && /^\d+$/.test(result[result.length - 1])) { + if (/^\d+$/.test(w) && result.length > 0 && /^\d+$/.test(result[result.length - 1])) { result[result.length - 1] += '.' + w; } else { - result.push(w!); + result.push(w); } } diff --git a/src/lib/skills.ts b/src/lib/skills.ts index e113410..59e32c6 100644 --- a/src/lib/skills.ts +++ b/src/lib/skills.ts @@ -1,13 +1,26 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; -import matter from 'gray-matter'; +/** + * Backward-compatible wrapper around resources.ts for skills. + * All new code should use resources.ts directly. + */ +import { + listResources, + getResource, + createResource, + updateResource, + deleteResource, + getAllTags as resourceGetAllTags, + getForksOf as resourceGetForksOf, + isValidSlug, + type ResourceMeta, + type Resource, + type ResourceFormat, + type ResourceFileEntry, +} from './resources'; +import { getTypeConfig } from './registry'; -export const SKILLS_DIR = path.resolve( - process.env.SKILLS_DIR || 'data/skills' -); +export { isValidSlug }; -const SLUG_RE = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/; -const MAX_SLUG_LENGTH = 64; +export const SKILLS_DIR = getTypeConfig('skills').dataDir; export interface SkillMeta { slug: string; @@ -25,127 +38,81 @@ export interface SkillMeta { 'fork-of': string; tags: string[]; hooks: Record | null; + format: ResourceFormat; } export interface Skill extends SkillMeta { content: string; raw: string; + files: ResourceFileEntry[]; } -export function isValidSlug(slug: string): boolean { - return slug.length >= 2 && slug.length <= MAX_SLUG_LENGTH && SLUG_RE.test(slug); -} - -function skillPath(slug: string): string { - return path.join(SKILLS_DIR, `${slug}.md`); -} - -function parseTools(val: unknown): string[] { +function parseList(val: unknown): string[] { if (Array.isArray(val)) return val.map(String); if (typeof val === 'string') return val.split(',').map(t => t.trim()).filter(Boolean); return []; } -function parseSkill(slug: string, raw: string): Skill { - const { data, content } = matter(raw); +function toSkillMeta(r: ResourceMeta): SkillMeta { + const f = r.fields; return { - slug, - name: (data.name as string) || slug, - description: (data.description as string) || '', - 'allowed-tools': parseTools(data['allowed-tools'] ?? data.allowedTools), - 'argument-hint': (data['argument-hint'] as string) || '', - model: (data.model as string) || '', - 'user-invocable': data['user-invocable'] !== false, - 'disable-model-invocation': Boolean(data['disable-model-invocation']), - context: (data.context as string) || '', - agent: (data.agent as string) || '', - author: (data.author as string) || '', - 'author-email': (data['author-email'] as string) || '', - 'fork-of': (data['fork-of'] as string) || '', - tags: parseTools(data.tags), - hooks: (typeof data.hooks === 'object' && data.hooks !== null) ? data.hooks as Record : null, - content: content.trim(), - raw, + slug: r.slug, + name: r.name, + description: r.description, + 'allowed-tools': parseList(f['allowed-tools'] ?? f.allowedTools), + 'argument-hint': (f['argument-hint'] as string) || '', + model: (f.model as string) || '', + 'user-invocable': f['user-invocable'] !== false, + 'disable-model-invocation': Boolean(f['disable-model-invocation']), + context: (f.context as string) || '', + agent: (f.agent as string) || '', + author: r.author, + 'author-email': r['author-email'], + 'fork-of': r['fork-of'], + tags: r.tags, + hooks: (typeof f.hooks === 'object' && f.hooks !== null) ? f.hooks as Record : null, + format: r.format, + }; +} + +function toSkill(r: Resource): Skill { + return { + ...toSkillMeta(r), + content: r.content, + raw: r.raw, + files: r.files, }; } export async function listSkills(): Promise { - await fs.mkdir(SKILLS_DIR, { recursive: true }); - const files = await fs.readdir(SKILLS_DIR); - const skills: SkillMeta[] = []; - - for (const file of files) { - if (!file.endsWith('.md')) continue; - const slug = file.replace(/\.md$/, ''); - const raw = await fs.readFile(path.join(SKILLS_DIR, file), 'utf-8'); - const { content: _, raw: __, ...meta } = parseSkill(slug, raw); - skills.push(meta); - } - - return skills.sort((a, b) => a.name.localeCompare(b.name)); + const resources = await listResources('skills'); + return resources.map(toSkillMeta); } export async function getAllTags(): Promise { - const all = await listSkills(); - return [...new Set(all.flatMap(s => s.tags))].sort(); + return resourceGetAllTags('skills'); } export async function getForksOf(slug: string): Promise { - const all = await listSkills(); - return all.filter(s => s['fork-of'] === slug); + const resources = await resourceGetForksOf('skills', slug); + return resources.map(toSkillMeta); } export async function getSkill(slug: string): Promise { - try { - const raw = await fs.readFile(skillPath(slug), 'utf-8'); - return parseSkill(slug, raw); - } catch { - return null; - } + const r = await getResource('skills', slug); + return r ? toSkill(r) : null; } -export async function createSkill(slug: string, content: string): Promise { - if (!isValidSlug(slug)) { - throw new Error(`Invalid slug: ${slug}`); - } - - await fs.mkdir(SKILLS_DIR, { recursive: true }); - const dest = skillPath(slug); - - try { - await fs.access(dest); - throw new Error(`Skill already exists: ${slug}`); - } catch (err) { - if (err instanceof Error && err.message.startsWith('Skill already exists')) { - throw err; - } - } - - await fs.writeFile(dest, content, 'utf-8'); - return parseSkill(slug, content); +export async function createSkill(slug: string, content: string, format?: ResourceFormat): Promise { + const r = await createResource('skills', slug, content, format); + return toSkill(r); } export async function updateSkill(slug: string, content: string): Promise { - const dest = skillPath(slug); - - try { - await fs.access(dest); - } catch { - throw new Error(`Skill not found: ${slug}`); - } - - await fs.writeFile(dest, content, 'utf-8'); - return parseSkill(slug, content); + const r = await updateResource('skills', slug, content); + return toSkill(r); } export async function deleteSkill(slug: string): Promise { - const dest = skillPath(slug); - - try { - await fs.access(dest); - } catch { - throw new Error(`Skill not found: ${slug}`); - } - - await fs.unlink(dest); + return deleteResource('skills', slug); } diff --git a/src/lib/stats.ts b/src/lib/stats.ts index 648b5b5..a53e1f6 100644 --- a/src/lib/stats.ts +++ b/src/lib/stats.ts @@ -1,15 +1,19 @@ import fs from 'node:fs/promises'; import path from 'node:path'; +import type { ResourceType } from './registry'; const STATS_FILE = path.resolve(process.env.STATS_FILE || 'data/stats.json'); -export interface SkillStats { +export interface ResourceStats { downloads: number; pushes: number; lastPushedAt: string | null; } -type StatsStore = Record; +/** @deprecated Use ResourceStats */ +export type SkillStats = ResourceStats; + +type StatsStore = Record; async function readStore(): Promise { try { @@ -28,32 +32,63 @@ async function writeStore(store: StatsStore): Promise { await fs.rename(tmp, STATS_FILE); } -function ensure(store: StatsStore, slug: string): SkillStats { - if (!store[slug]) { - store[slug] = { downloads: 0, pushes: 0, lastPushedAt: null }; - } - return store[slug]; +/** Build the key used in stats.json. New format: "type:slug". Legacy keys (bare slug) are migrated lazily. */ +function statsKey(type: ResourceType, slug: string): string { + return `${type}:${slug}`; } -export async function recordDownload(slug: string): Promise { +function ensure(store: StatsStore, key: string): ResourceStats { + if (!store[key]) { + store[key] = { downloads: 0, pushes: 0, lastPushedAt: null }; + } + return store[key]; +} + +/** Lazy migration: if a bare slug key exists (legacy) and the namespaced key doesn't, migrate it. */ +function migrateKey(store: StatsStore, type: ResourceType, slug: string): string { + const newKey = statsKey(type, slug); + if (!store[newKey] && store[slug] && type === 'skills') { + store[newKey] = store[slug]; + delete store[slug]; + } + return newKey; +} + +export async function recordDownload(slug: string, type: ResourceType = 'skills'): Promise { const store = await readStore(); - ensure(store, slug).downloads++; + const key = migrateKey(store, type, slug); + ensure(store, key).downloads++; await writeStore(store); } -export async function recordPush(slug: string): Promise { +export async function recordPush(slug: string, type: ResourceType = 'skills'): Promise { const store = await readStore(); - const entry = ensure(store, slug); + const key = migrateKey(store, type, slug); + const entry = ensure(store, key); entry.pushes++; entry.lastPushedAt = new Date().toISOString(); await writeStore(store); } -export async function getStatsForSlug(slug: string): Promise { +export async function getStatsForSlug(slug: string, type: ResourceType = 'skills'): Promise { const store = await readStore(); - return store[slug] || { downloads: 0, pushes: 0, lastPushedAt: null }; + const key = statsKey(type, slug); + // Check namespaced key first, fall back to legacy bare slug for skills + return store[key] || (type === 'skills' ? store[slug] : null) || { downloads: 0, pushes: 0, lastPushedAt: null }; } -export async function getAllStats(): Promise { - return readStore(); +export async function getAllStats(type?: ResourceType): Promise> { + const store = await readStore(); + if (!type) return store; + const prefix = `${type}:`; + const filtered: Record = {}; + for (const [key, val] of Object.entries(store)) { + if (key.startsWith(prefix)) { + filtered[key.slice(prefix.length)] = val; + } else if (type === 'skills' && !key.includes(':')) { + // Legacy bare slug keys are skills + filtered[key] = val; + } + } + return filtered; } diff --git a/src/pages/[slug].astro b/src/pages/[slug].astro index e6f5b92..eae1c82 100644 --- a/src/pages/[slug].astro +++ b/src/pages/[slug].astro @@ -1,20 +1,26 @@ --- -import Base from '../layouts/Base.astro'; -import EditGate from '../components/EditGate.vue'; -import DeleteButton from '../components/DeleteButton.vue'; -import { getSkill, getForksOf } from '../lib/skills'; -import { hasToken } from '../lib/tokens'; -import { recordDownload, getStatsForSlug } from '../lib/stats'; -import { marked } from 'marked'; +/** + * Backward compatibility: / redirects to /skills/ for browsers, + * serves raw markdown for CLI (curl/wget). + */ +import { getSkill } from '../lib/skills'; +import { recordDownload } from '../lib/stats'; const { slug } = Astro.params; + +// Skip if slug matches a known route prefix (type pages handle themselves) +const reserved = new Set(['skills', 'agents', 'output-styles', 'rules', 'new', 'api', 'i', 'gi', 'p', 'gp']); +if (reserved.has(slug!)) { + return new Response(null, { status: 404 }); +} + const skill = await getSkill(slug!); if (!skill) { return Astro.redirect('/'); } -// curl / wget → raw markdown +// CLI (curl/wget) → serve raw markdown directly (backward compat) const accept = Astro.request.headers.get('accept') || ''; if (!accept.includes('text/html')) { recordDownload(slug!); @@ -23,165 +29,6 @@ if (!accept.includes('text/html')) { }); } -const authorHasToken = skill['author-email'] ? await hasToken(skill['author-email']) : false; -const forks = await getForksOf(slug!); -const stats = await getStatsForSlug(slug!); -const html = await marked(skill.content); -const origin = Astro.url.origin; -const cmds = { - unix: `curl -fsSL ${origin}/${slug}/i | bash`, - unixGlobal: `curl -fsSL ${origin}/${slug}/gi | bash`, - win: `irm ${origin}/${slug}/i | iex`, - winGlobal: `irm ${origin}/${slug}/gi | iex`, -}; +// Browser → redirect to new URL +return Astro.redirect(`/skills/${slug}`, 301); --- - - - - - - - Back - - - -
    -
    -

    {skill.name}

    - {skill.description &&

    {skill.description}

    } - {skill['allowed-tools'].length > 0 && ( -
    - {skill['allowed-tools'].map((tool) => ( - - {tool} - - ))} -
    - )} - {skill.tags.length > 0 && ( -
    - {skill.tags.map((tag) => ( - - {tag} - - ))} -
    - )} - {skill.author && ( -

    by {skill.author}

    - )} - {skill['fork-of'] && ( -

    forked from {skill['fork-of']}

    - )} - {forks.length > 0 && ( -
    - - {forks.length} fork{forks.length !== 1 ? 's' : ''} - - -
    - )} -
    - - - - - {stats.downloads} download{stats.downloads !== 1 ? 's' : ''} - - - - - - {stats.pushes} push{stats.pushes !== 1 ? 'es' : ''} - - {stats.lastPushedAt && ( - - Last updated {new Date(stats.lastPushedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })} - - )} -
    -
    - -
    -
    -

    Install this skill

    -
    - - -
    -
    -

    Run in your project root to add this skill.

    -
    - {cmds.unix} - - -
    -
    - More options -
    -
    -

    Install globally (available in all projects):

    -
    - {cmds.unixGlobal} - - -
    -
    -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    - - - - diff --git a/src/pages/[slug]/edit.astro b/src/pages/[slug]/edit.astro index 9f8e578..72f3cb2 100644 --- a/src/pages/[slug]/edit.astro +++ b/src/pages/[slug]/edit.astro @@ -1,53 +1,7 @@ --- -import Base from '../../layouts/Base.astro'; -import SkillEditor from '../../components/SkillEditor.vue'; -import { getSkill, getAllTags } from '../../lib/skills'; -import { getAvailableTools } from '../../lib/tools'; -import { getAvailableModels } from '../../lib/models'; - +/** + * Backward compatibility: //edit → /skills//edit + */ const { slug } = Astro.params; -const skill = await getSkill(slug!); - -if (!skill) { - return Astro.redirect('/'); -} - -const availableTools = await getAvailableTools(); -const availableModels = await getAvailableModels(); -const allowedTools = skill['allowed-tools'].join(', '); -const hooksJson = skill.hooks ? JSON.stringify(skill.hooks, null, 2) : ''; -const availableTags = await getAllTags(); +return Astro.redirect(`/skills/${slug}/edit`, 301); --- - - - - - - - Back to {skill.name} - -

    Edit Skill

    -

    Editing {skill.name}. Users who already installed this skill will get the updated version on their next sync.

    - - diff --git a/src/pages/[slug]/gi.ts b/src/pages/[slug]/gi.ts index 03166ae..dd68e7f 100644 --- a/src/pages/[slug]/gi.ts +++ b/src/pages/[slug]/gi.ts @@ -2,6 +2,7 @@ import type { APIRoute } from 'astro'; import { getSkill } from '../../lib/skills'; import { isPowerShell } from '../../lib/sync'; +/** Backward compat: //gi — installs skill globally to ~/.claude/skills/ */ export const GET: APIRoute = async ({ params, url, request }) => { const { slug } = params; const skill = await getSkill(slug!); @@ -17,7 +18,7 @@ export const GET: APIRoute = async ({ params, url, request }) => { '$ErrorActionPreference = "Stop"', '$Dir = Join-Path $HOME ".claude\\skills"', 'New-Item -ItemType Directory -Force -Path $Dir | Out-Null', - `Invoke-WebRequest -Uri "${origin}/${slug}" -OutFile (Join-Path $Dir "${slug}.md")`, + `Invoke-WebRequest -Uri "${origin}/skills/${slug}" -OutFile (Join-Path $Dir "${slug}.md")`, `Write-Host "✓ Installed ${skill.name} globally to $Dir\\${slug}.md"`, '', ].join('\n') @@ -25,7 +26,7 @@ export const GET: APIRoute = async ({ params, url, request }) => { '#!/usr/bin/env bash', 'set -euo pipefail', 'mkdir -p ~/.claude/skills', - `curl -fsSL "${origin}/${slug}" -o ~/.claude/skills/${slug}.md`, + `curl -fsSL "${origin}/skills/${slug}" -o ~/.claude/skills/${slug}.md`, `echo "✓ Installed ${skill.name} globally to ~/.claude/skills/${slug}.md"`, '', ].join('\n'); diff --git a/src/pages/[slug]/i.ts b/src/pages/[slug]/i.ts index 0d332a3..2f68cb8 100644 --- a/src/pages/[slug]/i.ts +++ b/src/pages/[slug]/i.ts @@ -2,6 +2,7 @@ import type { APIRoute } from 'astro'; import { getSkill } from '../../lib/skills'; import { isPowerShell } from '../../lib/sync'; +/** Backward compat: //i — installs skill to .claude/skills/ */ export const GET: APIRoute = async ({ params, url, request }) => { const { slug } = params; const skill = await getSkill(slug!); @@ -17,7 +18,7 @@ export const GET: APIRoute = async ({ params, url, request }) => { '$ErrorActionPreference = "Stop"', '$Dir = ".claude\\skills"', 'New-Item -ItemType Directory -Force -Path $Dir | Out-Null', - `Invoke-WebRequest -Uri "${origin}/${slug}" -OutFile (Join-Path $Dir "${slug}.md")`, + `Invoke-WebRequest -Uri "${origin}/skills/${slug}" -OutFile (Join-Path $Dir "${slug}.md")`, `Write-Host "✓ Installed ${skill.name} to $Dir\\${slug}.md"`, '', ].join('\n') @@ -25,7 +26,7 @@ export const GET: APIRoute = async ({ params, url, request }) => { '#!/usr/bin/env bash', 'set -euo pipefail', 'mkdir -p .claude/skills', - `curl -fsSL "${origin}/${slug}" -o ".claude/skills/${slug}.md"`, + `curl -fsSL "${origin}/skills/${slug}" -o ".claude/skills/${slug}.md"`, `echo "✓ Installed ${skill.name} to .claude/skills/${slug}.md"`, '', ].join('\n'); diff --git a/src/pages/new.astro b/src/pages/new.astro index 44853ce..a95064a 100644 --- a/src/pages/new.astro +++ b/src/pages/new.astro @@ -1,60 +1,8 @@ --- -import Base from '../layouts/Base.astro'; -import SkillEditor from '../components/SkillEditor.vue'; -import { getAvailableTools } from '../lib/tools'; -import { getAvailableModels } from '../lib/models'; -import { getSkill, getAllTags } from '../lib/skills'; - -const availableTools = await getAvailableTools(); -const availableModels = await getAvailableModels(); -const availableTags = await getAllTags(); - -// Fork support: /new?from=original-slug -const fromSlug = Astro.url.searchParams.get('from'); -let forkSource: Awaited> = null; -if (fromSlug) { - forkSource = await getSkill(fromSlug); -} - -const isFork = Boolean(forkSource); -const title = isFork ? `Fork ${forkSource!.name} — Skills Here` : 'New Skill — Skills Here'; +/** + * Backward compatibility: /new → /skills/new + * Preserves query params (e.g. ?from=slug for forking) + */ +const search = Astro.url.search; +return Astro.redirect(`/skills/new${search}`, 301); --- - - - - - - - {isFork ? `Back to ${forkSource!.name}` : 'Back'} - -

    {isFork ? 'Fork Skill' : 'New Skill'}

    - {isFork ? ( -

    Creating an independent copy of {forkSource!.name}. Change the name to generate a new slug before saving.

    - ) : ( -

    Write a prompt in Markdown that tells Claude how to behave. The body is the instruction Claude receives. Use Allowed Tools to restrict which tools the skill can use.

    - )} - {isFork ? ( - - ) : ( - - )} - diff --git a/src/styles/global.css b/src/styles/global.css index 6b8f6de..3cecbb8 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -3,9 +3,9 @@ @theme { --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif; --font-mono: "JetBrains Mono", ui-monospace, monospace; - --color-accent-400: #fb923c; - --color-accent-500: #f97316; - --color-accent-600: #ea580c; + --color-accent-400: #e04540; + --color-accent-500: #cc3530; + --color-accent-600: #a82a26; --color-surface-50: #0a0a0f; --color-surface-100: #12121a; --color-surface-200: #1a1a25; @@ -19,7 +19,7 @@ body { } ::selection { - background-color: rgb(249 115 22 / 0.3); + background-color: rgb(204 53 48 / 0.3); } /* Prose overrides for markdown content */ @@ -29,8 +29,8 @@ body { .skill-prose p { margin-bottom: 0.75rem; color: #a3a3a3; line-height: 1.7; } .skill-prose ul, .skill-prose ol { margin-bottom: 0.75rem; padding-left: 1.5rem; color: #a3a3a3; } .skill-prose li { margin-bottom: 0.25rem; line-height: 1.6; } -.skill-prose code { background: rgb(255 255 255 / 0.06); padding: 0.15rem 0.4rem; border-radius: 0.25rem; font-size: 0.85em; color: #fb923c; } +.skill-prose code { background: rgb(255 255 255 / 0.06); padding: 0.15rem 0.4rem; border-radius: 0.25rem; font-size: 0.85em; color: #e04540; } .skill-prose pre { background: rgb(0 0 0 / 0.4); padding: 1rem; border-radius: 0.5rem; overflow-x: auto; margin-bottom: 1rem; border: 1px solid rgb(255 255 255 / 0.06); } .skill-prose pre code { background: none; padding: 0; color: #d4d4d4; } -.skill-prose a { color: #fb923c; text-decoration: underline; text-underline-offset: 2px; } -.skill-prose blockquote { border-left: 3px solid #f97316; padding-left: 1rem; color: #737373; font-style: italic; } +.skill-prose a { color: #e04540; text-decoration: underline; text-underline-offset: 2px; } +.skill-prose blockquote { border-left: 3px solid #cc3530; padding-left: 1rem; color: #737373; font-style: italic; }