@heycys/gallery 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/THIRD-PARTY-NOTICES.md +1 -1
  2. package/browser/editor/page/editor.mjs +4 -2
  3. package/browser/shared/workspace-address.mjs +3 -0
  4. package/dist/{chunk-K3JKPFL5.mjs → chunk-225ALKYI.mjs} +1 -1
  5. package/dist/{chunk-PDZR3L3C.mjs → chunk-2HS7ZBPU.mjs} +1 -1
  6. package/dist/{chunk-ZFGMJVJC.mjs → chunk-3F57LEN5.mjs} +1 -1
  7. package/dist/{chunk-XZCFPKGO.mjs → chunk-5GK7HS62.mjs} +1 -1
  8. package/dist/{chunk-IA2SIEJQ.mjs → chunk-6Y3HYOBM.mjs} +1 -1
  9. package/dist/{chunk-USIHBCSW.mjs → chunk-BX5AKINW.mjs} +1 -1
  10. package/dist/{chunk-ERE2BXYV.mjs → chunk-BYNPEUDS.mjs} +1 -1
  11. package/dist/{chunk-6L6V7YR2.mjs → chunk-CRDG6EF2.mjs} +1 -1
  12. package/dist/{chunk-PLB7L22J.mjs → chunk-FJLM7YE7.mjs} +1 -1
  13. package/dist/{chunk-VPMRP2TL.mjs → chunk-FNCCVGKX.mjs} +1 -1
  14. package/dist/{chunk-65NTKF4N.mjs → chunk-FOJ3K5Z3.mjs} +1 -1
  15. package/dist/{chunk-E4IHAIJ7.mjs → chunk-FQ72LZHB.mjs} +1 -1
  16. package/dist/{chunk-BMX3VUHY.mjs → chunk-G7N7YFVD.mjs} +1 -1
  17. package/dist/{chunk-CHQU37CA.mjs → chunk-GIRXJBGC.mjs} +1 -1
  18. package/dist/{chunk-Q4MS6OFC.mjs → chunk-GQJMVSSN.mjs} +1 -1
  19. package/dist/{chunk-3SKOU6OZ.mjs → chunk-HX4DLE3J.mjs} +1 -1
  20. package/dist/chunk-IS7N3N6Q.mjs +168 -0
  21. package/dist/{chunk-GJJRBGMY.mjs → chunk-JJNHKGTD.mjs} +1 -1
  22. package/dist/{chunk-4SNV4HA5.mjs → chunk-JYK5WJPM.mjs} +1 -1
  23. package/dist/{chunk-WFGPMCTZ.mjs → chunk-L55NOXBE.mjs} +1 -1
  24. package/dist/{chunk-NHP66IWR.mjs → chunk-LCB6MARS.mjs} +1 -1
  25. package/dist/{chunk-4KUO7R2M.mjs → chunk-LJLVCU6W.mjs} +1 -1
  26. package/dist/{chunk-FFV733MA.mjs → chunk-NLDF35P5.mjs} +1 -1
  27. package/dist/{chunk-Q7P3Q5YX.mjs → chunk-NMF3IPYA.mjs} +1 -1
  28. package/dist/{chunk-2T4PZQEP.mjs → chunk-ONKC4BCC.mjs} +1 -1
  29. package/dist/{chunk-ULXSPX5H.mjs → chunk-OU6ZZVBX.mjs} +2 -2
  30. package/dist/{chunk-236JJXWY.mjs → chunk-PKVK6WFC.mjs} +2 -2
  31. package/dist/{chunk-MNWJ4EZY.mjs → chunk-QJAVCTY7.mjs} +1 -1
  32. package/dist/{chunk-BN7M3IN7.mjs → chunk-SQ3FQCCN.mjs} +2 -2
  33. package/dist/{chunk-2KAVXMKG.mjs → chunk-T4Y2ZSVX.mjs} +1 -1
  34. package/dist/{chunk-53XDTHTG.mjs → chunk-UTF7GBQU.mjs} +2 -2
  35. package/dist/{chunk-VZ2RQ3AM.mjs → chunk-UTMAY3WK.mjs} +1 -1
  36. package/dist/{chunk-3XZOA7AH.mjs → chunk-V4ZHRALW.mjs} +2 -2
  37. package/dist/{chunk-JXXHAXYH.mjs → chunk-WD4U6XXT.mjs} +1 -1
  38. package/dist/{chunk-MKIBJTJZ.mjs → chunk-XBNFXWAW.mjs} +1 -1
  39. package/dist/{chunk-C257H6IA.mjs → chunk-XZV72SQ4.mjs} +1 -1
  40. package/dist/{chunk-OEIJLMPI.mjs → chunk-YFJB534W.mjs} +1 -1
  41. package/dist/{chunk-5XV3YYLG.mjs → chunk-Z6OKLRHC.mjs} +1 -1
  42. package/dist/{chunk-6Q7ASAXJ.mjs → chunk-ZLS2FRS6.mjs} +1 -1
  43. package/dist/{chunk-7ISBBDJR.mjs → chunk-ZMHUDYLV.mjs} +1 -1
  44. package/dist/cli.mjs +1 -1
  45. package/dist/server.mjs +1 -1
  46. package/kit/runtime.js +1 -0
  47. package/package.json +1 -1
  48. package/release.json +4 -4
  49. package/skill/SKILL.md +5 -5
  50. package/web/assets/{index-czjrXVjf.js → index-D8P8uhDW.js} +1 -1
  51. package/web/index.html +1 -1
  52. package/dist/chunk-BLNQUR5R.mjs +0 -168
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{a,b,c,d,e,f,g,h}from"./chunk-C257H6IA.mjs";import"./chunk-3XZOA7AH.mjs";import"./chunk-BN7M3IN7.mjs";import"./chunk-JEUK3ZO7.mjs";import"./chunk-6QWQXHAV.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-7UZUQQ7Q.mjs";import"./chunk-4B2TB5K2.mjs";import"./chunk-KLQP46Y3.mjs";import"./chunk-4OZWXZE5.mjs";import"./chunk-3SKOU6OZ.mjs";import"./chunk-PLB7L22J.mjs";import"./chunk-HYMEEXKN.mjs";import"./chunk-E7656LR7.mjs";import"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";export{c as HOME_NOT_MADE,g as emptyRequiredOf,d as missingPageSaid,a as pageAddressOf,b as pageAloneOf,h as run,e as setsOf,f as settingsGiven};
2
+ import{a,b,c,d,e,f,g,h}from"./chunk-XZV72SQ4.mjs";import"./chunk-V4ZHRALW.mjs";import"./chunk-SQ3FQCCN.mjs";import"./chunk-JEUK3ZO7.mjs";import"./chunk-6QWQXHAV.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-7UZUQQ7Q.mjs";import"./chunk-4B2TB5K2.mjs";import"./chunk-KLQP46Y3.mjs";import"./chunk-4OZWXZE5.mjs";import"./chunk-HX4DLE3J.mjs";import"./chunk-FJLM7YE7.mjs";import"./chunk-HYMEEXKN.mjs";import"./chunk-E7656LR7.mjs";import"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";export{c as HOME_NOT_MADE,g as emptyRequiredOf,d as missingPageSaid,a as pageAddressOf,b as pageAloneOf,h as run,e as setsOf,f as settingsGiven};
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{c as _}from"./chunk-236JJXWY.mjs";import{n as G,p as Le,r as Ee,s as Ne,t as Ie,x as Oe}from"./chunk-Q7P3Q5YX.mjs";import{c as he,d as pe,e as ue,f as fe,g as we,h as ge,i as me,j as z,l as $e,n as Y,o as ke,q as be,r as ye,s as xe,t as ve,u as Se}from"./chunk-4KUO7R2M.mjs";import{M as Ae}from"./chunk-MKIBJTJZ.mjs";import"./chunk-342HXE3Q.mjs";import"./chunk-2KAVXMKG.mjs";import{d as Ce,g as je}from"./chunk-C257H6IA.mjs";import"./chunk-3XZOA7AH.mjs";import"./chunk-XZCFPKGO.mjs";import{i as ie}from"./chunk-BN7M3IN7.mjs";import{a as W}from"./chunk-JEUK3ZO7.mjs";import"./chunk-M4NRDYI5.mjs";import{a as re,b as le,e as de,f as K,g as ce}from"./chunk-PUOQ65NC.mjs";import"./chunk-6QWQXHAV.mjs";import"./chunk-6Q7ASAXJ.mjs";import"./chunk-S3SX3COT.mjs";import"./chunk-IA4PSIMD.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-F4ZA6JRZ.mjs";import"./chunk-7M2BQQGZ.mjs";import"./chunk-6NLXUKAY.mjs";import"./chunk-VRPVVMRB.mjs";import"./chunk-7UZUQQ7Q.mjs";import{a as H,b as j,c as P,d as D,f as oe}from"./chunk-4B2TB5K2.mjs";import{a as te,e as B,f as ae}from"./chunk-KLQP46Y3.mjs";import{b as se}from"./chunk-4OZWXZE5.mjs";import"./chunk-USIHBCSW.mjs";import"./chunk-3SKOU6OZ.mjs";import"./chunk-ZTHICSSF.mjs";import"./chunk-PLB7L22J.mjs";import"./chunk-PAREWQGB.mjs";import{j as ne}from"./chunk-BFJGHSQN.mjs";import"./chunk-U5XL7D6A.mjs";import"./chunk-HYMEEXKN.mjs";import"./chunk-UMHUSOPJ.mjs";import"./chunk-W5NPH5UA.mjs";import"./chunk-ECZBLQKK.mjs";import"./chunk-E7656LR7.mjs";import{f as Z,j as ee}from"./chunk-TKWEX4FD.mjs";import{b as X,e as _e}from"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";_e();import{existsSync as Ue}from"node:fs";import R from"node:fs/promises";import O from"node:path";import{isInstance as Ke}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as He,INSTANCE as Ye}from"../browser/shared/components/installed.mjs";import{attr as M,hasClass as q,walk as Re}from"../browser/shared/html-tree.mjs";import{assetFile as Qe,imageFile as Te,referencedFile as Me}from"../browser/shared/media.mjs";import{pageAssetAddress as Ve,pageExists as Je,pageFiles as Xe}from"../browser/shared/pages.mjs";import{layoutOf as U}from"../browser/shared/workspace.mjs";var Q=[1280,1920,600],De=["light","dark"],Ze=900,et=3e4,tt=new Set(["iframe","frame","object","embed"]),at=/^\d+$/,ot={x:[0,11],y:[0,1/0],w:[1,12],h:[1,24]};function st(e,{catalog:g,folder:o,slug:h}){let i=[],s=d=>d?.sourceCodeLocation?.startLine??1,n=(d,a)=>i.push({line:typeof d=="number"?d:s(d),what:a}),t=X(e.replace(/^/," "),{sourceCodeLocationInfo:!0}),c=[],f=[];Re(t,d=>{d.tagName&&(d.tagName==="main"&&q(d,"gallery-page")&&c.push(d),q(d,"gallery-board")&&f.push(d),q(d,"gallery-card")&&!q(d.parentNode,"gallery-board")&&n(d,`a card (class gallery-card) that is no board's child: each card stands right in a <div class="gallery-board" data-board-id="\u2026">, which lays it out, and this one is laid out by none`))},{inTemplates:!1}),c.length===0&&(f.length>0||j(e).cards.length>0)&&n(1,`no <main class="gallery-page">: a page's boards stand in one (it is how a block knows it is on a page: context.place "page", and how the page follows the theme)`);let y=new Map;for(let d of f){let a=d.parentNode;for(;a&&!(a.tagName==="main"&&q(a,"gallery-page"));)a=a.parentNode;c.length&&!a&&n(d,`a board outside <main class="gallery-page">: its cards' blocks would not know they are on a page`);let r=M(d,"data-board-id");r===void 0||r===""?n(d,"a board with no data-board-id: write one (main, side\u2026), of lowercase letters, digits and hyphens, once in the page"):H.test(r)?y.has(r)?n(d,`data-board-id="${r}" again (line ${y.get(r)} has it): each board's id is its own`):y.set(r,s(d)):n(d,`data-board-id="${r}": a board's id is lowercase letters, digits and single hyphens (main, side-2)`)}let S=new Map,N=new Map;for(let d of j(e).cards){let{node:a}=d,r=M(a,"data-card-id"),k=r&&H.test(r)?`card ${r}`:"this card";r===void 0||r===""?n(a,"a card with no data-card-id: write one (c<n>, the lowest none holds, or a name of your own), of lowercase letters, digits and hyphens: its place, its writes and the reader's state go by it"):H.test(r)?S.has(r)?n(a,`data-card-id="${r}" again (line ${S.get(r)} has it): each card's id is its own, and the page's writes go by it`):S.set(r,s(a)):n(a,`data-card-id="${r}": a card's id is lowercase letters, digits and single hyphens (c3, water)`);let u=0;Re(a,x=>{x!==a&&Ke(x)&&(u+=1)},{inTemplates:!1}),u===0?n(a,`${k} holds no instance of a custom block (an element with ${He}): a card is one block's instance, gallery/static's for what only shows`):u>1?n(a,`${k} holds ${u} instances: a card holds one (put each on a card of its own)`):d.instance&&d.instance.parentNode!==a&&n(d.instance,`${k}'s instance stands inside another element of the card: write it right in the card's <section>`);let b={};for(let x of["x","y","w","h"]){let A=M(a,`data-${x}`),[L,E]=ot[x];A===void 0?n(a,`${k} has no data-${x}: a card says its place and size in whole cells, data-x data-y data-w data-h`):at.test(A.trim())?Number(A)<L||Number(A)>E?n(a,`${k}'s data-${x}="${A}": ${x} is ${E===1/0?`${L} or more`:`${L} to ${E}`}${x==="w"?" (a row is 12 cells)":""}`):b[x]=Number(A):n(a,`${k}'s data-${x}="${A}" is no whole number`)}b.x!==void 0&&b.w!==void 0&&b.x+b.w>12?n(a,`${k} reaches past the row's end: data-x ${b.x} and data-w ${b.w} make ${b.x+b.w}, and a row is 12 cells (x + w is 12 at most)`):Object.keys(b).length===4&&N.set(d.board,[...N.get(d.board)??[],{id:r??null,...b,line:s(a)}]),d.block&&nt(d.block,g,x=>n(d.instance,`${k}'s block ${d.block}: ${x}`))}for(let d of N.values())for(let a=0;a<d.length;a++)for(let r=a+1;r<d.length;r++){let[k,u]=[d[a],d[r]];k.x<u.x+u.w&&u.x<k.x+k.w&&k.y<u.y+u.h&&u.y<k.y+k.h&&n(u.line,`card ${u.id??"here"} (x ${u.x}, y ${u.y}, ${u.w} \xD7 ${u.h}) shares cells with card ${k.id??`at line ${k.line}`} (x ${k.x}, y ${k.y}, ${k.w} \xD7 ${k.h}): no two cards of a board overlap; move one to a free spot (gallery page add finds one for a new card)`)}return i.push(...it(e,{folder:o,slug:h})),i.sort((d,a)=>d.line-a.line)}function nt(e,g,o){let h=g.packages.get(e);if(h){h.places.includes("page")||o(`a block of documents (its manifest's places has no "page"): on a custom page its card says so and runs nothing`);return}let i=g.problems.get(e);g.settings.disabled.includes(e)?o("turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868: its card says so and runs nothing (the user turns it on again)"):i?o(`it does not load (${ee("en",i.problem)}): gallery block check ${e} says why`):ae(e)&&B(e)?o(`one of Gallery's own blocks, not yet in this workspace: gallery block add ${B(e).pack===te?B(e).name:e} puts it in`):o("no custom block of that id in this workspace: gallery block list lists them")}function it(e,{folder:g,slug:o}){let h=[],i=`${Ve(o,"assets/")}`;for(let s of ne(e,()=>!0)){let n=s.value.trim(),t=["a","area"].includes(s.node.tagName)&&s.how==="href",c=Me(n)??(n.startsWith(i)?Me(n.slice(i.length-7)):null),f=`"${n.length>60?`${n.slice(0,60)}\u2026`:n}"`,y=s.how==="css"?`<style>'s url() ${f}`:`<${s.node.tagName}>'s ${s.how==="style"?"style url()":s.how} ${f}`;if(c!==null){Qe(c)?tt.has(s.node.tagName)&&!Te(c)?h.push({line:s.line,what:`${y}: a frame of a file of the page's assets/ downloads it and shows nothing, as the server hands out a page's own file that is no picture, stylesheet or script for saving only: write what it shows in the page itself, frame a site by its https address, or offer the file with a link, <a href="${c}" download>`}):Ue(O.join(g,c))||h.push({line:s.line,what:`${y}: ${c} is not in the page's folder (${W(O.join(g,"assets"))}): put the file there${Te(c)?"":", or link to it"}`}):h.push({line:s.line,what:`${y} names a file the server serves none by: the page's own files go right in pages/${o}/assets/, each named with letters, digits, dots, dashes and underscores (assets/cover.png)`});continue}t||!n||/^(?:[a-z][a-z0-9+.-]*:|\/|#|\?)/i.test(n)||h.push({line:s.line,what:`${y} is relative to /pages/${o}, where nothing is served: put the file in pages/${o}/assets/ and write assets/<file>`})}return h}function rt(e,g){let o=P(e).text,h=[];for(let i of j(o).cards){let s=i.block?g.packages.get(i.block):null;if(!s?.settings?.some(f=>f.required)||!s.parts.settings)continue;let n=G(D(o,i),_,{...s,parts:{settings:s.parts.settings}})?.parts.find(({name:f})=>f==="settings"),t={};try{t=n?.text.trim()?JSON.parse(n.text):{}}catch{continue}let c=je(s,t);c.length&&h.push({id:i.id,block:i.block,line:i.node.sourceCodeLocation?.startLine??1,empty:c})}return h}var lt=({id:e,block:g,empty:o})=>`card ${e} (${g}) holds no ${o.map(({key:h,label:i,zh:s})=>`${h} (${s&&s!==i?`${i}, ${s}`:i})`).join(" and no ")} in its settings, which it cannot show anything without: it shows its ask for one (the grip at its top right \u203A \u8BBE\u7F6E\u2026), and no picture of the page shows what it is for. Ask the user for it, or take it from what the workspace says (\u5199\u4F5C\u504F\u597D, the documents), write it in the card's settings part, and tell them in the handoff which you did`,dt=(e,g=!1)=>{let o=h=>M(e.node,`data-${h}`)??"-";return`x ${o("x")}, y ${o("y")}, ${o("w")} \xD7 ${o("h")}${g?` on ${e.board??"-"}`:""}`},Fe=e=>`${e.board},${M(e.node,"data-x")},${M(e.node,"data-y")}`,Pe=e=>`${M(e.node,"data-w")},${M(e.node,"data-h")}`;function ct(e,g,o){let[h,i]=[P(e).text,P(g).text],[s,n]=[j(h).cards,j(i).cards],t=new Set([...s,...n].map(a=>a.board)).size>1,c=a=>dt(a,t),f={added:[],removed:[],moved:[],resized:[],data:[],markup:[],page:null,kept:0};for(let a of s)n.some(r=>r.id===a.id)||f.removed.push({id:a.id,block:a.block,cells:c(a)});for(let a of n)s.some(r=>r.id===a.id)||f.added.push({id:a.id,block:a.block,cells:c(a)});for(let a of n){let r=s.find($=>$.id===a.id);if(!r)continue;let[k,u]=[Fe(r)!==Fe(a),Pe(r)!==Pe(a)];k&&f.moved.push({id:a.id,block:a.block,was:c(r),now:c(a)}),u&&f.resized.push({id:a.id,block:a.block,was:c(r),now:c(a)});let[b,x]=[D(h,r),D(i,a)];if(b===x){!k&&!u&&(f.kept+=1);continue}let A=r.block===a.block?o.packages.get(a.block):null,L=A?{...A,parts:Object.fromEntries(Object.entries(A.parts).filter(([,$])=>$.edit==="data"))}:null,[E,l]=L?[G(b,_,L),G(x,_,L)]:[null,null];if(!E||!l){f.markup.push({id:a.id,block:A?a.block:null});continue}let v=E.parts.flatMap(({name:$,text:m},I)=>m===l.parts[I].text?[]:[{name:$,...Y(m,l.parts[I].text),runs:ke(m,l.parts[I].text)}]);v.length&&f.data.push({id:a.id,block:a.block,parts:v}),E.outside!==l.outside&&f.markup.push({id:a.id,block:a.block})}let y=(a,r)=>{let k="",u=0;for(let b of[...r].sort((x,A)=>x.start-A.start))k+=a.slice(u,b.start),u=b.end;return k+a.slice(u)},[S,N]=[y(h,s),y(i,n)],d=a=>a.replace(/\s+/g," ");return d(S)!==d(N)&&(f.page=Y(S.replace(/^\s*\n/gm,""),N.replace(/^\s*\n/gm,""))),f}var ze="(the user's, on the page)",We="(put there by Gallery)";function ht(e,g){let o=n=>{let t=new Map;for(let c of g)if(c.by===n)for(let[f,y]of Object.entries(c.cards??{}))t.set(f,new Set([...t.get(f)??[],...Array.isArray(y)?y:[]]));return t},h=o("page"),i=o("gallery"),s=n=>t=>{let c=!!h.get(t.id)?.has(n);return{...t,user:c,...!c&&i.get(t.id)?.has(n)?{gallery:!0}:{}}};return{...e,added:e.added.map(s("added")),removed:e.removed.map(s("removed")),moved:e.moved.map(s("cells")),resized:e.resized.map(s("cells")),data:e.data.map(s("content")),markup:e.markup.map(s("content"))}}function pt(e,g){let o=({id:t,block:c})=>`${t}${c?` (${c})`:""}`,h=t=>t.user?` ${ze}`:t.gallery?` ${We}`:"",i=[];for(let t of e.added)i.push(` added ${o(t)} at ${t.cells}${h(t)}`);for(let t of e.removed)i.push(` removed ${o(t)}, which stood at ${t.cells}${h(t)}`);for(let t of e.moved)i.push(` moved ${o(t)}: ${t.was} then ${t.now}${h(t)}`);for(let t of e.resized)e.moved.some(c=>c.id===t.id)||i.push(` resized ${o(t)}: ${t.was} then ${t.now}${h(t)}`);for(let t of e.data)i.push(` data ${o(t)}: ${$e(t.parts)}${h(t)}`,...Le(t.parts).map(c=>` ${c}`));for(let t of e.markup)i.push(` markup ${o(t)}: its markup outside its place and its data parts${t.block?"":" (a block the workspace has not: its markup whole)"}${h(t)}`);if(e.page&&i.push(` page its own HTML outside the cards: -${e.page.removed} +${e.page.added} of its ${e.page.lines} line${e.page.lines===1?"":"s"}`),i.length===0)return[`No change since ${g}: every card where it was, with the data it had.`];let s=["added","removed","moved","resized","data","markup"].some(t=>e[t].some(c=>c.user)),n=["added","removed","moved","resized","data","markup"].some(t=>e[t].some(c=>c.gallery));return[`Changes since ${g}:`,...i,...e.kept?[e.kept===1?" The other card as it was.":` The other ${e.kept} cards as they were.`]:[],...s?[` Each change marked ${ze} is the user's own gesture on the page since then (a move, a resize, a card added or deleted there, what they typed in it), which the page wrote: leave it as it is, never put it back.`]:[],...n?[` Each change marked ${We} is Gallery's own doing, not the user's and not yours: the cards it put on the home page when it made it (\u95EE\u5019\u4E0E\u65E5\u671F, \u4FBF\u7B7E): leave it as it is.`]:[]]}async function ut(e,g){let{qa:o,state:h}=U(e),i=O.join(o,g,"checked.html"),s=await R.readFile(i,"utf8").catch(()=>null);if(s!==null){let{mtime:y}=await R.stat(i);return{text:s,since:`the last check that found nothing (${qe(y)}, local time, ${W(i)})`,at:y.getTime()}}let n=O.join(h,"pages",g),t=(await R.readdir(n).catch(()=>[])).filter(y=>/^\d{15}-\d{4}\.html$/.test(y)).sort();if(t.length===0)return null;let c=O.join(n,t.at(-1)),f=Number(t.at(-1).slice(0,15));return{text:await R.readFile(c,"utf8"),since:`the page as it was before its last write (${qe(new Date(f))}, local time; used because no check has passed yet)`,at:f}}var qe=e=>`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")} ${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`;function ft(e,g){let o=t=>`<${t.localName}${t.getAttribute("src")?` src="${t.getAttribute("src").slice(0,80)}"`:""}>`,h=[...document.querySelectorAll(".gallery-board > .gallery-card")].map(t=>{let c=t.parentElement.getBoundingClientRect(),f=t.getBoundingClientRect(),y=[...t.children].find(S=>S.matches(e));return{id:t.getAttribute("data-card-id"),block:y?.getAttribute(g)??null,out:f.width>0&&(f.left<c.left-1||f.right>c.right+1),tall:t.scrollHeight>t.clientHeight+1?{needs:t.scrollHeight,has:t.clientHeight}:null,wide:t.scrollWidth>t.clientWidth+1?{needs:t.scrollWidth,has:t.clientWidth}:null,fallback:!!y?.hasAttribute("data-doc-fallback"),error:(t.querySelector(".doc-kit-error")?.textContent??"").trim()||null,broken:[...t.querySelectorAll("img")].filter(S=>S.complete&&S.naturalWidth===0).map(o)}}),i=[...document.querySelectorAll("img")].filter(t=>!t.closest(".gallery-card")&&t.complete&&t.naturalWidth===0).map(o),s=document.documentElement.scrollWidth,n=[...globalThis.__galleryQueries?.pending.values()??[]].map(({kind:t,block:c,at:f})=>({kind:t,block:c,waited:Date.now()-f}));return{cards:h,broken:i,stuck:n,wide:s>innerWidth+1?s:0,columns:document.querySelector(".gallery-board")?.getAttribute("data-columns")??null}}async function wt(e,{address:g,out:o,readers:h=new Set,wait:i=ge,limits:s={}}){let{loading:n=he,ready:t=et,answer:c=pe,closing:f=de,looking:y=ue}=s,S=new Map,N=new Map,d=[],a=!1,r=(l,v,$,m,I=S)=>{if(a)return;let w=I.get(l)??{card:v,what:$,looks:[]};w.looks.push(m),I.set(l,w)},k="a browser context opened",u=(l,v,$=c)=>(k=v,ye(l,v,$)),b=Q.flatMap(l=>De.map(v=>({width:l,theme:v,view:`${l} ${v}`}))),x=null,A=async({width:l,theme:v,view:$})=>{let m=await u(x.newPage(),"a tab opened");try{m.on("pageerror",p=>r(`error ${z(p)}`,null,`the page threw: ${z(p)}`,$)),m.on("console",p=>{p.type()==="error"&&!/^Failed to load resource/.test(p.text())&&r(`console ${p.text().split(`
2
+ import{c as _}from"./chunk-PKVK6WFC.mjs";import{n as G,p as Le,r as Ee,s as Ne,t as Ie,x as Oe}from"./chunk-NMF3IPYA.mjs";import{c as he,d as pe,e as ue,f as fe,g as we,h as ge,i as me,j as z,l as $e,n as Y,o as ke,q as be,r as ye,s as xe,t as ve,u as Se}from"./chunk-LJLVCU6W.mjs";import{M as Ae}from"./chunk-XBNFXWAW.mjs";import"./chunk-342HXE3Q.mjs";import"./chunk-T4Y2ZSVX.mjs";import{d as Ce,g as je}from"./chunk-XZV72SQ4.mjs";import"./chunk-V4ZHRALW.mjs";import"./chunk-5GK7HS62.mjs";import{i as ie}from"./chunk-SQ3FQCCN.mjs";import{a as W}from"./chunk-JEUK3ZO7.mjs";import"./chunk-M4NRDYI5.mjs";import{a as re,b as le,e as de,f as K,g as ce}from"./chunk-PUOQ65NC.mjs";import"./chunk-6QWQXHAV.mjs";import"./chunk-ZLS2FRS6.mjs";import"./chunk-S3SX3COT.mjs";import"./chunk-IA4PSIMD.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-F4ZA6JRZ.mjs";import"./chunk-7M2BQQGZ.mjs";import"./chunk-6NLXUKAY.mjs";import"./chunk-VRPVVMRB.mjs";import"./chunk-7UZUQQ7Q.mjs";import{a as H,b as j,c as P,d as D,f as oe}from"./chunk-4B2TB5K2.mjs";import{a as te,e as B,f as ae}from"./chunk-KLQP46Y3.mjs";import{b as se}from"./chunk-4OZWXZE5.mjs";import"./chunk-BX5AKINW.mjs";import"./chunk-HX4DLE3J.mjs";import"./chunk-ZTHICSSF.mjs";import"./chunk-FJLM7YE7.mjs";import"./chunk-PAREWQGB.mjs";import{j as ne}from"./chunk-BFJGHSQN.mjs";import"./chunk-U5XL7D6A.mjs";import"./chunk-HYMEEXKN.mjs";import"./chunk-UMHUSOPJ.mjs";import"./chunk-W5NPH5UA.mjs";import"./chunk-ECZBLQKK.mjs";import"./chunk-E7656LR7.mjs";import{f as Z,j as ee}from"./chunk-TKWEX4FD.mjs";import{b as X,e as _e}from"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";_e();import{existsSync as Ue}from"node:fs";import R from"node:fs/promises";import O from"node:path";import{isInstance as Ke}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as He,INSTANCE as Ye}from"../browser/shared/components/installed.mjs";import{attr as M,hasClass as q,walk as Re}from"../browser/shared/html-tree.mjs";import{assetFile as Qe,imageFile as Te,referencedFile as Me}from"../browser/shared/media.mjs";import{pageAssetAddress as Ve,pageExists as Je,pageFiles as Xe}from"../browser/shared/pages.mjs";import{layoutOf as U}from"../browser/shared/workspace.mjs";var Q=[1280,1920,600],De=["light","dark"],Ze=900,et=3e4,tt=new Set(["iframe","frame","object","embed"]),at=/^\d+$/,ot={x:[0,11],y:[0,1/0],w:[1,12],h:[1,24]};function st(e,{catalog:g,folder:o,slug:h}){let i=[],s=d=>d?.sourceCodeLocation?.startLine??1,n=(d,a)=>i.push({line:typeof d=="number"?d:s(d),what:a}),t=X(e.replace(/^/," "),{sourceCodeLocationInfo:!0}),c=[],f=[];Re(t,d=>{d.tagName&&(d.tagName==="main"&&q(d,"gallery-page")&&c.push(d),q(d,"gallery-board")&&f.push(d),q(d,"gallery-card")&&!q(d.parentNode,"gallery-board")&&n(d,`a card (class gallery-card) that is no board's child: each card stands right in a <div class="gallery-board" data-board-id="\u2026">, which lays it out, and this one is laid out by none`))},{inTemplates:!1}),c.length===0&&(f.length>0||j(e).cards.length>0)&&n(1,`no <main class="gallery-page">: a page's boards stand in one (it is how a block knows it is on a page: context.place "page", and how the page follows the theme)`);let y=new Map;for(let d of f){let a=d.parentNode;for(;a&&!(a.tagName==="main"&&q(a,"gallery-page"));)a=a.parentNode;c.length&&!a&&n(d,`a board outside <main class="gallery-page">: its cards' blocks would not know they are on a page`);let r=M(d,"data-board-id");r===void 0||r===""?n(d,"a board with no data-board-id: write one (main, side\u2026), of lowercase letters, digits and hyphens, once in the page"):H.test(r)?y.has(r)?n(d,`data-board-id="${r}" again (line ${y.get(r)} has it): each board's id is its own`):y.set(r,s(d)):n(d,`data-board-id="${r}": a board's id is lowercase letters, digits and single hyphens (main, side-2)`)}let S=new Map,N=new Map;for(let d of j(e).cards){let{node:a}=d,r=M(a,"data-card-id"),k=r&&H.test(r)?`card ${r}`:"this card";r===void 0||r===""?n(a,"a card with no data-card-id: write one (c<n>, the lowest none holds, or a name of your own), of lowercase letters, digits and hyphens: its place, its writes and the reader's state go by it"):H.test(r)?S.has(r)?n(a,`data-card-id="${r}" again (line ${S.get(r)} has it): each card's id is its own, and the page's writes go by it`):S.set(r,s(a)):n(a,`data-card-id="${r}": a card's id is lowercase letters, digits and single hyphens (c3, water)`);let u=0;Re(a,x=>{x!==a&&Ke(x)&&(u+=1)},{inTemplates:!1}),u===0?n(a,`${k} holds no instance of a custom block (an element with ${He}): a card is one block's instance, gallery/static's for what only shows`):u>1?n(a,`${k} holds ${u} instances: a card holds one (put each on a card of its own)`):d.instance&&d.instance.parentNode!==a&&n(d.instance,`${k}'s instance stands inside another element of the card: write it right in the card's <section>`);let b={};for(let x of["x","y","w","h"]){let A=M(a,`data-${x}`),[L,E]=ot[x];A===void 0?n(a,`${k} has no data-${x}: a card says its place and size in whole cells, data-x data-y data-w data-h`):at.test(A.trim())?Number(A)<L||Number(A)>E?n(a,`${k}'s data-${x}="${A}": ${x} is ${E===1/0?`${L} or more`:`${L} to ${E}`}${x==="w"?" (a row is 12 cells)":""}`):b[x]=Number(A):n(a,`${k}'s data-${x}="${A}" is no whole number`)}b.x!==void 0&&b.w!==void 0&&b.x+b.w>12?n(a,`${k} reaches past the row's end: data-x ${b.x} and data-w ${b.w} make ${b.x+b.w}, and a row is 12 cells (x + w is 12 at most)`):Object.keys(b).length===4&&N.set(d.board,[...N.get(d.board)??[],{id:r??null,...b,line:s(a)}]),d.block&&nt(d.block,g,x=>n(d.instance,`${k}'s block ${d.block}: ${x}`))}for(let d of N.values())for(let a=0;a<d.length;a++)for(let r=a+1;r<d.length;r++){let[k,u]=[d[a],d[r]];k.x<u.x+u.w&&u.x<k.x+k.w&&k.y<u.y+u.h&&u.y<k.y+k.h&&n(u.line,`card ${u.id??"here"} (x ${u.x}, y ${u.y}, ${u.w} \xD7 ${u.h}) shares cells with card ${k.id??`at line ${k.line}`} (x ${k.x}, y ${k.y}, ${k.w} \xD7 ${k.h}): no two cards of a board overlap; move one to a free spot (gallery page add finds one for a new card)`)}return i.push(...it(e,{folder:o,slug:h})),i.sort((d,a)=>d.line-a.line)}function nt(e,g,o){let h=g.packages.get(e);if(h){h.places.includes("page")||o(`a block of documents (its manifest's places has no "page"): on a custom page its card says so and runs nothing`);return}let i=g.problems.get(e);g.settings.disabled.includes(e)?o("turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868: its card says so and runs nothing (the user turns it on again)"):i?o(`it does not load (${ee("en",i.problem)}): gallery block check ${e} says why`):ae(e)&&B(e)?o(`one of Gallery's own blocks, not yet in this workspace: gallery block add ${B(e).pack===te?B(e).name:e} puts it in`):o("no custom block of that id in this workspace: gallery block list lists them")}function it(e,{folder:g,slug:o}){let h=[],i=`${Ve(o,"assets/")}`;for(let s of ne(e,()=>!0)){let n=s.value.trim(),t=["a","area"].includes(s.node.tagName)&&s.how==="href",c=Me(n)??(n.startsWith(i)?Me(n.slice(i.length-7)):null),f=`"${n.length>60?`${n.slice(0,60)}\u2026`:n}"`,y=s.how==="css"?`<style>'s url() ${f}`:`<${s.node.tagName}>'s ${s.how==="style"?"style url()":s.how} ${f}`;if(c!==null){Qe(c)?tt.has(s.node.tagName)&&!Te(c)?h.push({line:s.line,what:`${y}: a frame of a file of the page's assets/ downloads it and shows nothing, as the server hands out a page's own file that is no picture, stylesheet or script for saving only: write what it shows in the page itself, frame a site by its https address, or offer the file with a link, <a href="${c}" download>`}):Ue(O.join(g,c))||h.push({line:s.line,what:`${y}: ${c} is not in the page's folder (${W(O.join(g,"assets"))}): put the file there${Te(c)?"":", or link to it"}`}):h.push({line:s.line,what:`${y} names a file the server serves none by: the page's own files go right in pages/${o}/assets/, each named with letters, digits, dots, dashes and underscores (assets/cover.png)`});continue}t||!n||/^(?:[a-z][a-z0-9+.-]*:|\/|#|\?)/i.test(n)||h.push({line:s.line,what:`${y} is relative to /pages/${o}, where nothing is served: put the file in pages/${o}/assets/ and write assets/<file>`})}return h}function rt(e,g){let o=P(e).text,h=[];for(let i of j(o).cards){let s=i.block?g.packages.get(i.block):null;if(!s?.settings?.some(f=>f.required)||!s.parts.settings)continue;let n=G(D(o,i),_,{...s,parts:{settings:s.parts.settings}})?.parts.find(({name:f})=>f==="settings"),t={};try{t=n?.text.trim()?JSON.parse(n.text):{}}catch{continue}let c=je(s,t);c.length&&h.push({id:i.id,block:i.block,line:i.node.sourceCodeLocation?.startLine??1,empty:c})}return h}var lt=({id:e,block:g,empty:o})=>`card ${e} (${g}) holds no ${o.map(({key:h,label:i,zh:s})=>`${h} (${s&&s!==i?`${i}, ${s}`:i})`).join(" and no ")} in its settings, which it cannot show anything without: it shows its ask for one (the grip at its top right \u203A \u8BBE\u7F6E\u2026), and no picture of the page shows what it is for. Ask the user for it, or take it from what the workspace says (\u5199\u4F5C\u504F\u597D, the documents), write it in the card's settings part, and tell them in the handoff which you did`,dt=(e,g=!1)=>{let o=h=>M(e.node,`data-${h}`)??"-";return`x ${o("x")}, y ${o("y")}, ${o("w")} \xD7 ${o("h")}${g?` on ${e.board??"-"}`:""}`},Fe=e=>`${e.board},${M(e.node,"data-x")},${M(e.node,"data-y")}`,Pe=e=>`${M(e.node,"data-w")},${M(e.node,"data-h")}`;function ct(e,g,o){let[h,i]=[P(e).text,P(g).text],[s,n]=[j(h).cards,j(i).cards],t=new Set([...s,...n].map(a=>a.board)).size>1,c=a=>dt(a,t),f={added:[],removed:[],moved:[],resized:[],data:[],markup:[],page:null,kept:0};for(let a of s)n.some(r=>r.id===a.id)||f.removed.push({id:a.id,block:a.block,cells:c(a)});for(let a of n)s.some(r=>r.id===a.id)||f.added.push({id:a.id,block:a.block,cells:c(a)});for(let a of n){let r=s.find($=>$.id===a.id);if(!r)continue;let[k,u]=[Fe(r)!==Fe(a),Pe(r)!==Pe(a)];k&&f.moved.push({id:a.id,block:a.block,was:c(r),now:c(a)}),u&&f.resized.push({id:a.id,block:a.block,was:c(r),now:c(a)});let[b,x]=[D(h,r),D(i,a)];if(b===x){!k&&!u&&(f.kept+=1);continue}let A=r.block===a.block?o.packages.get(a.block):null,L=A?{...A,parts:Object.fromEntries(Object.entries(A.parts).filter(([,$])=>$.edit==="data"))}:null,[E,l]=L?[G(b,_,L),G(x,_,L)]:[null,null];if(!E||!l){f.markup.push({id:a.id,block:A?a.block:null});continue}let v=E.parts.flatMap(({name:$,text:m},I)=>m===l.parts[I].text?[]:[{name:$,...Y(m,l.parts[I].text),runs:ke(m,l.parts[I].text)}]);v.length&&f.data.push({id:a.id,block:a.block,parts:v}),E.outside!==l.outside&&f.markup.push({id:a.id,block:a.block})}let y=(a,r)=>{let k="",u=0;for(let b of[...r].sort((x,A)=>x.start-A.start))k+=a.slice(u,b.start),u=b.end;return k+a.slice(u)},[S,N]=[y(h,s),y(i,n)],d=a=>a.replace(/\s+/g," ");return d(S)!==d(N)&&(f.page=Y(S.replace(/^\s*\n/gm,""),N.replace(/^\s*\n/gm,""))),f}var ze="(the user's, on the page)",We="(put there by Gallery)";function ht(e,g){let o=n=>{let t=new Map;for(let c of g)if(c.by===n)for(let[f,y]of Object.entries(c.cards??{}))t.set(f,new Set([...t.get(f)??[],...Array.isArray(y)?y:[]]));return t},h=o("page"),i=o("gallery"),s=n=>t=>{let c=!!h.get(t.id)?.has(n);return{...t,user:c,...!c&&i.get(t.id)?.has(n)?{gallery:!0}:{}}};return{...e,added:e.added.map(s("added")),removed:e.removed.map(s("removed")),moved:e.moved.map(s("cells")),resized:e.resized.map(s("cells")),data:e.data.map(s("content")),markup:e.markup.map(s("content"))}}function pt(e,g){let o=({id:t,block:c})=>`${t}${c?` (${c})`:""}`,h=t=>t.user?` ${ze}`:t.gallery?` ${We}`:"",i=[];for(let t of e.added)i.push(` added ${o(t)} at ${t.cells}${h(t)}`);for(let t of e.removed)i.push(` removed ${o(t)}, which stood at ${t.cells}${h(t)}`);for(let t of e.moved)i.push(` moved ${o(t)}: ${t.was} then ${t.now}${h(t)}`);for(let t of e.resized)e.moved.some(c=>c.id===t.id)||i.push(` resized ${o(t)}: ${t.was} then ${t.now}${h(t)}`);for(let t of e.data)i.push(` data ${o(t)}: ${$e(t.parts)}${h(t)}`,...Le(t.parts).map(c=>` ${c}`));for(let t of e.markup)i.push(` markup ${o(t)}: its markup outside its place and its data parts${t.block?"":" (a block the workspace has not: its markup whole)"}${h(t)}`);if(e.page&&i.push(` page its own HTML outside the cards: -${e.page.removed} +${e.page.added} of its ${e.page.lines} line${e.page.lines===1?"":"s"}`),i.length===0)return[`No change since ${g}: every card where it was, with the data it had.`];let s=["added","removed","moved","resized","data","markup"].some(t=>e[t].some(c=>c.user)),n=["added","removed","moved","resized","data","markup"].some(t=>e[t].some(c=>c.gallery));return[`Changes since ${g}:`,...i,...e.kept?[e.kept===1?" The other card as it was.":` The other ${e.kept} cards as they were.`]:[],...s?[` Each change marked ${ze} is the user's own gesture on the page since then (a move, a resize, a card added or deleted there, what they typed in it), which the page wrote: leave it as it is, never put it back.`]:[],...n?[` Each change marked ${We} is Gallery's own doing, not the user's and not yours: the cards it put on the home page when it made it (\u95EE\u5019\u4E0E\u65E5\u671F, \u4FBF\u7B7E): leave it as it is.`]:[]]}async function ut(e,g){let{qa:o,state:h}=U(e),i=O.join(o,g,"checked.html"),s=await R.readFile(i,"utf8").catch(()=>null);if(s!==null){let{mtime:y}=await R.stat(i);return{text:s,since:`the last check that found nothing (${qe(y)}, local time, ${W(i)})`,at:y.getTime()}}let n=O.join(h,"pages",g),t=(await R.readdir(n).catch(()=>[])).filter(y=>/^\d{15}-\d{4}\.html$/.test(y)).sort();if(t.length===0)return null;let c=O.join(n,t.at(-1)),f=Number(t.at(-1).slice(0,15));return{text:await R.readFile(c,"utf8"),since:`the page as it was before its last write (${qe(new Date(f))}, local time; used because no check has passed yet)`,at:f}}var qe=e=>`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")} ${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`;function ft(e,g){let o=t=>`<${t.localName}${t.getAttribute("src")?` src="${t.getAttribute("src").slice(0,80)}"`:""}>`,h=[...document.querySelectorAll(".gallery-board > .gallery-card")].map(t=>{let c=t.parentElement.getBoundingClientRect(),f=t.getBoundingClientRect(),y=[...t.children].find(S=>S.matches(e));return{id:t.getAttribute("data-card-id"),block:y?.getAttribute(g)??null,out:f.width>0&&(f.left<c.left-1||f.right>c.right+1),tall:t.scrollHeight>t.clientHeight+1?{needs:t.scrollHeight,has:t.clientHeight}:null,wide:t.scrollWidth>t.clientWidth+1?{needs:t.scrollWidth,has:t.clientWidth}:null,fallback:!!y?.hasAttribute("data-doc-fallback"),error:(t.querySelector(".doc-kit-error")?.textContent??"").trim()||null,broken:[...t.querySelectorAll("img")].filter(S=>S.complete&&S.naturalWidth===0).map(o)}}),i=[...document.querySelectorAll("img")].filter(t=>!t.closest(".gallery-card")&&t.complete&&t.naturalWidth===0).map(o),s=document.documentElement.scrollWidth,n=[...globalThis.__galleryQueries?.pending.values()??[]].map(({kind:t,block:c,at:f})=>({kind:t,block:c,waited:Date.now()-f}));return{cards:h,broken:i,stuck:n,wide:s>innerWidth+1?s:0,columns:document.querySelector(".gallery-board")?.getAttribute("data-columns")??null}}async function wt(e,{address:g,out:o,readers:h=new Set,wait:i=ge,limits:s={}}){let{loading:n=he,ready:t=et,answer:c=pe,closing:f=de,looking:y=ue}=s,S=new Map,N=new Map,d=[],a=!1,r=(l,v,$,m,I=S)=>{if(a)return;let w=I.get(l)??{card:v,what:$,looks:[]};w.looks.push(m),I.set(l,w)},k="a browser context opened",u=(l,v,$=c)=>(k=v,ye(l,v,$)),b=Q.flatMap(l=>De.map(v=>({width:l,theme:v,view:`${l} ${v}`}))),x=null,A=async({width:l,theme:v,view:$})=>{let m=await u(x.newPage(),"a tab opened");try{m.on("pageerror",p=>r(`error ${z(p)}`,null,`the page threw: ${z(p)}`,$)),m.on("console",p=>{p.type()==="error"&&!/^Failed to load resource/.test(p.text())&&r(`console ${p.text().split(`
3
3
  `)[0]}`,null,`the console says ${p.text().split(`
4
4
  `)[0]}`,$)}),m.on("response",p=>{let C=new URL(p.url());p.status()>=400&&C.origin===new URL(g).origin&&C.pathname!=="/favicon.ico"&&r(`request ${C.pathname}`,null,`${C.pathname} answered ${p.status()}`,$)}),await u(be(m,{add:p=>r(`dialog ${p}`,null,`it opened a dialog (${p}), which stops a reader's page until it is answered`,$)}),"the tab was set to refuse dialogs"),await u(me(m),"the tab was set to watch the page's reads of the workspace"),await u(m.setViewport({width:l,height:Ze}),`the window went to ${l}px`),await u(m.emulateMediaFeatures([{name:"prefers-color-scheme",value:v}]),`the ${v} theme came`),await u(m.goto(g,{waitUntil:"load",timeout:0}),"the page opened",n),await u(m.waitForSelector("html[data-doc-ready][data-doc-drawn]",{timeout:0}),"the page was drawn (its html got data-doc-drawn)",t),await u(m.evaluate(()=>document.fonts?.ready.then(()=>!0)),"the page's fonts loaded");let I=await u(m.$("main"),"the page's main was found")??await u(m.$("body"),"the page's body was found");await u(I.evaluate(Oe,{still:fe,step:we,wait:i}),"the page held still");let w=await u(m.evaluate(ft,Ye,He),"the page was looked at");for(let{kind:p,block:C,waited:Ge}of w.stuck){let V=w.cards.filter(F=>C?F.block===C:h.has(F.block)),J=F=>`the workspace had not answered ${F} read of "${p}" ${Math.round(Ge/1e3)} s after it asked, so its picture shows it before it drew what it reads, which the picture then does not tell (open the page in Gallery to see it)`;if(V.length)for(let F of V)r(`unanswered ${F.id} ${p}`,F.id,J("its"),$,N);else r(`unanswered ${p}`,null,J("a card's"),$,N)}w.wide&&r("wide",null,`the page is ${w.wide}px wide in a window ${l}px wide: something of its own reaches past the window (a width of its own, a long word), and a reader scrolls it sideways`,$);for(let p of w.broken)r(`broken ${p}`,null,`a picture that does not load: ${p}`,$);for(let p of w.cards){p.fallback&&r(`fallback ${p.id}`,p.id,`its block failed: the card shows what its instance holds, read-only${p.error?` (${p.error.slice(0,200)})`:""}`,$),p.out&&r(`out ${p.id}`,p.id,"it is drawn out of its board",$),p.tall&&r(`tall ${p.id}`,p.id,`what it holds does not fit it: ${p.tall.needs}px high in a card that shows ${p.tall.has}px, the rest scrolling inside the card (give the card more cells, data-h, or a size its block lists; a block whose content grows says card.fit "content")`,$),p.wide&&r(`wide ${p.id}`,p.id,`what it holds is wider than the card: ${p.wide.needs}px in a card ${p.wide.has}px wide`,$);for(let C of p.broken)r(`broken ${p.id} ${C}`,p.id,`a picture that does not load: ${C}`,$)}let T=O.join(o,`${l}-${v}.png`);await u(m.screenshot({path:T,fullPage:!0}),"the page was pictured"),a||d.push(T)}finally{await K(m.close(),f)}},L=l=>({problems:[...S.values()],notes:[...N.values()],pictures:d,unverified:null,stuck:!1,...l}),E=null;try{x=await u(e.createBrowserContext(),"a browser context opened");for(let l of b)E=l,await gt(A(l),y,()=>k);return L({})}catch(l){return await Se(e)?L({unverified:`the browser went while it looked (${z(l)})`}):l.stuck?(r("stopped",null,mt(l,b.indexOf(E??b[0])<b.length-1),(E??b[0]).view),L({stuck:!0})):L({unverified:`the look stopped: ${z(l)}`})}finally{a=!0,await K(x?.close(),f)}}function gt(e,g,o){let h=0,i=new Promise((s,n)=>{h=setTimeout(()=>n(Object.assign(new Error(o()),{stuck:!0,doing:o(),limit:g,whole:!0})),g)});return Promise.race([e,i]).finally(()=>clearTimeout(h))}function mt(e,g){return`${e.whole?`the look was not done in ${xe(e.limit)}, waiting until ${e.doing}`:ve(e)}; the look stopped here and the browser was closed${g?", so the looks after it were not made":""}. A script of the page that never ends does this, and so may a browser that stalled: run the check once more, and if it stops at the same place again, the page holds it up`}function Be(e){let g=[...new Set(e.map(i=>i.split(" ")[0]))],o=[...new Set(e.map(i=>i.split(" ")[1]))],h=i=>i.length<2?i.join(""):`${i.slice(0,-1).join(", ")} and ${i.at(-1)}`;return`at ${h(g)}px${o.length===De.length?"":`, ${h(o)}`}`}async function Ht(e,g){if(g.length!==1)throw new se("gallery page check takes one page's slug.");let[o]=g,h=Xe(o,e);Je(o,e)||(console.error(await Ce(o,e)),process.exit(1));let i=new Date,s=await R.readFile(h.html,"utf8"),n=O.basename(h.html),t=Z(e),{boards:c,cards:f}=j(s);console.log(`${o}: ${W(h.html)}, ${c.length} board${c.length===1?"":"s"} and ${f.length} card${f.length===1?"":"s"}`);let y=[],S=st(s,{catalog:t,folder:h.folder,slug:o});for(let{line:l,what:v}of S)y.push(` FAIL ${n}:${l}: ${v}`);console.log(S.length?`Structure: ${S.length} problem${S.length===1?"":"s"}`:"Structure: nothing wrong (the page's own HTML, scripts and frames its own; every board's and card's id once, one instance a card, the cells on the board and none shared, every block one a page runs, every file of assets/ there)");for(let l of y)console.log(l);for(let l of j(P(s).text).cards)console.log(` ${l.id} ${l.block??"(no instance)"} x ${l.x}, y ${l.y}, ${l.w} \xD7 ${l.h}${c.length>1?` on ${l.board}`:""} ${n}:${l.node.sourceCodeLocation?.startLine}`);let N=rt(s,t);for(let l of N)console.log(` note ${n}:${l.line}: ${lt(l)}`);let d=await ut(e,o),a=d?await oe(U(e).state,o,d.at):[];console.log((d?pt(ht(ct(d.text,s,t),a),d.since):["No earlier version to tell changes against: the next check that finds nothing keeps this one, and says what changed since."]).join(`
5
- `));let r=new Map(j(P(s).text).cards.map(l=>[l.id,l.node.sourceCodeLocation?.startLine??1])),k=(l,v=null,$=0)=>{if(l)return{line:`FAIL ${o}: ${l} problem${l===1?"":"s"}`,code:1};if(v)return{line:`UNVERIFIED ${o}: ${v}; its structure was checked, and nothing is wrong with it`,code:3};let m=N.length?`; and ${N.length===1?"one card asks":`${N.length} cards ask`} for a setting no one gave (see "note" above): ${N.map(({id:I,empty:w})=>`${I} (${w.map(({key:T})=>T).join(", ")})`).join(", ")}`:"";return{line:`OK ${o}: its structure, and its ${f.length} card${f.length===1?"":"s"} at ${Q.join(", ")}px in light and dark${$?`; but ${$===1?"one card was":`${$} cards were`} pictured before the workspace answered it (see "note" above), so ${$===1?"its picture does":"their pictures do"} not show what ${$===1?"it reads":"they read"}`:""}${m}`,code:0}},u=await ie({command:`gallery page check ${o}`}),b=async(l,v,$=0)=>{let{line:m,code:I}=k(l,v,$);if(console.log(m),I===0){let w=O.join(U(e).qa,o,"checked.html");await R.mkdir(O.dirname(w),{recursive:!0}),await R.writeFile(w,s),await R.utimes(w,i,i)}process.exitCode=I};if(!u.ok)return b(S.length,`${u.message}, so the page was not looked at`);let x=re();if(!x)return b(S.length,"no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one), so the page was not looked at");await Ie(e);let A=await Ee(e,{directory:h.folder,files:h,text:s}),L=O.join(U(e).qa,o,"check"),E=null;try{let{pageAloneOf:l}=await import("./chunk-2T4PZQEP.mjs"),v=l(u.port,A.slug);console.log(`Looked at: ${v} (a scratch copy of ${o}, gone at the end: nothing a block does as it opens writes ${n}), at ${Q.join(", ")}px, light and dark`);try{E=await ce({executablePath:x,args:le()})}catch(w){return b(S.length,`the browser ${x} did not start, twice (${z(w)}), so the page was not looked at`)}await R.rm(L,{recursive:!0,force:!0}),await R.mkdir(L,{recursive:!0});let $=new Set([...t.packages.values()].filter(({needs:w})=>w?.includes("workspace")).map(({id:w})=>w)),m=await wt(E.browser,{address:v,out:L,readers:$});m.stuck&&(await E.close(),E=null);for(let{card:w,what:T,looks:p}of m.problems)console.log(` FAIL ${n}:${w?r.get(w)??1:1}: ${w?`card ${w}: `:""}${T} (${Be(p)})`);let I=new Map(j(s).cards.map(w=>[w.id,w.block]));for(let{card:w,what:T,looks:p}of m.notes)console.log(` note ${n}:${w?r.get(w)??1:1}: ${w?`card ${w}${I.get(w)?` (${I.get(w)})`:""}: `:""}${T} (${Be(p)})`);return m.pictures.length&&(console.log(`Pictures of the page in ${W(L)}: ${m.pictures.map(w=>O.basename(w)).join(", ")}`),console.log(Ae([{folder:O.dirname(L),files:m.pictures}]))),b(S.length+m.problems.length,m.unverified,new Set(m.notes.map(({card:w})=>w??"")).size)}finally{await E?.close(),await Ne(e,A.slug)}}export{We as GALLERYS_MARK,Q as LOOK_WIDTHS,De as THEMES,ze as USERS_MARK,ut as baselineOf,pt as changesSaid,rt as emptyRequired,lt as emptyRequiredSaid,wt as look,ht as markedTheUsers,ct as pageChanges,Ht as pageCheckCommand,st as structureProblems};
5
+ `));let r=new Map(j(P(s).text).cards.map(l=>[l.id,l.node.sourceCodeLocation?.startLine??1])),k=(l,v=null,$=0)=>{if(l)return{line:`FAIL ${o}: ${l} problem${l===1?"":"s"}`,code:1};if(v)return{line:`UNVERIFIED ${o}: ${v}; its structure was checked, and nothing is wrong with it`,code:3};let m=N.length?`; and ${N.length===1?"one card asks":`${N.length} cards ask`} for a setting no one gave (see "note" above): ${N.map(({id:I,empty:w})=>`${I} (${w.map(({key:T})=>T).join(", ")})`).join(", ")}`:"";return{line:`OK ${o}: its structure, and its ${f.length} card${f.length===1?"":"s"} at ${Q.join(", ")}px in light and dark${$?`; but ${$===1?"one card was":`${$} cards were`} pictured before the workspace answered it (see "note" above), so ${$===1?"its picture does":"their pictures do"} not show what ${$===1?"it reads":"they read"}`:""}${m}`,code:0}},u=await ie({command:`gallery page check ${o}`}),b=async(l,v,$=0)=>{let{line:m,code:I}=k(l,v,$);if(console.log(m),I===0){let w=O.join(U(e).qa,o,"checked.html");await R.mkdir(O.dirname(w),{recursive:!0}),await R.writeFile(w,s),await R.utimes(w,i,i)}process.exitCode=I};if(!u.ok)return b(S.length,`${u.message}, so the page was not looked at`);let x=re();if(!x)return b(S.length,"no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one), so the page was not looked at");await Ie(e);let A=await Ee(e,{directory:h.folder,files:h,text:s}),L=O.join(U(e).qa,o,"check"),E=null;try{let{pageAloneOf:l}=await import("./chunk-ONKC4BCC.mjs"),v=l(u.port,A.slug);console.log(`Looked at: ${v} (a scratch copy of ${o}, gone at the end: nothing a block does as it opens writes ${n}), at ${Q.join(", ")}px, light and dark`);try{E=await ce({executablePath:x,args:le()})}catch(w){return b(S.length,`the browser ${x} did not start, twice (${z(w)}), so the page was not looked at`)}await R.rm(L,{recursive:!0,force:!0}),await R.mkdir(L,{recursive:!0});let $=new Set([...t.packages.values()].filter(({needs:w})=>w?.includes("workspace")).map(({id:w})=>w)),m=await wt(E.browser,{address:v,out:L,readers:$});m.stuck&&(await E.close(),E=null);for(let{card:w,what:T,looks:p}of m.problems)console.log(` FAIL ${n}:${w?r.get(w)??1:1}: ${w?`card ${w}: `:""}${T} (${Be(p)})`);let I=new Map(j(s).cards.map(w=>[w.id,w.block]));for(let{card:w,what:T,looks:p}of m.notes)console.log(` note ${n}:${w?r.get(w)??1:1}: ${w?`card ${w}${I.get(w)?` (${I.get(w)})`:""}: `:""}${T} (${Be(p)})`);return m.pictures.length&&(console.log(`Pictures of the page in ${W(L)}: ${m.pictures.map(w=>O.basename(w)).join(", ")}`),console.log(Ae([{folder:O.dirname(L),files:m.pictures}]))),b(S.length+m.problems.length,m.unverified,new Set(m.notes.map(({card:w})=>w??"")).size)}finally{await E?.close(),await Ne(e,A.slug)}}export{We as GALLERYS_MARK,Q as LOOK_WIDTHS,De as THEMES,ze as USERS_MARK,ut as baselineOf,pt as changesSaid,rt as emptyRequired,lt as emptyRequiredSaid,wt as look,ht as markedTheUsers,ct as pageChanges,Ht as pageCheckCommand,st as structureProblems};
@@ -1,6 +1,6 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{E as re,J as ae,K as ne,O as ie,P as ce,a as C,b as Q,c as F,g as X,h as Z,n as D,o as ee,r as te,s as se,t as oe}from"./chunk-Q7P3Q5YX.mjs";import{j as K}from"./chunk-4KUO7R2M.mjs";import{d as le}from"./chunk-C257H6IA.mjs";import{i as q}from"./chunk-BN7M3IN7.mjs";import{a as L}from"./chunk-JEUK3ZO7.mjs";import{a as M,b as z,g as J}from"./chunk-PUOQ65NC.mjs";import{b as x,c as T}from"./chunk-4B2TB5K2.mjs";import{b as E}from"./chunk-4OZWXZE5.mjs";import{f as H,j as Y}from"./chunk-TKWEX4FD.mjs";import{b as V,e as pe}from"./chunk-A55HN5OK.mjs";pe();import N from"node:fs/promises";import P from"node:path";import{isInstance as ge}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as me}from"../browser/shared/components/installed.mjs";import{attr as we,walk as $e}from"../browser/shared/html-tree.mjs";import{pageExists as ye,pageFiles as be}from"../browser/shared/pages.mjs";import{layoutOf as Ee}from"../browser/shared/workspace.mjs";var xe="card ids aside",ke="nothing else in page.html changed (card ids aside)",Se=e=>new Promise(s=>setTimeout(s,e)),Te=/^\/__gallery\/pages\/[a-z0-9-]+\/cards$/,de=e=>{let s=null;return $e(V(e,{sourceCodeLocationInfo:!0}),n=>{s??=ge(n)?n:null},{inTemplates:!1}),s},fe=(e,s)=>{let n=s.node.sourceCodeLocation.startTag.endOffset;return{frame:e.slice(s.start,n).replace(/\s+data-[xywh]="[^"]*"/g,""),rest:e.slice(n,s.end)}};function Ce(e,s,n,a){let[o,d]=[x(e).cards,x(s).cards],c=[],t=r=>`card ${r.id}${r.block?` (${r.block})`:""}`,l=r=>["x","y","w","h"].map(i=>`${i} ${we(r.node,`data-${i}`)??"-"}`).join(", ");for(let r of o){let i=d.find(g=>g.id===r.id);if(!i){c.push(`${t(r)} taken out`);continue}let m=r.board!==i.board;(m||l(r)!==l(i))&&c.push(`${t(r)}'s place, ${l(r)}${m?` on ${r.board}`:""} then ${l(i)}${m?` on ${i.board}`:""}`);let[h,p]=[fe(e,r),fe(s,i)];if(h.frame===p.frame&&h.rest===p.rest)continue;if(r.id!==n){c.push(t(r));continue}h.frame!==p.frame&&c.push(`${t(r)}'s own frame (an attribute of its <section> but its place)`);let[f,$]=[D(h.rest,de,a),D(p.rest,de,a)];!f||!$?c.push(`${t(r)}'s instance`):f.outside!==$.outside&&c.push(`${t(r)} itself, outside its data parts (a part edited as text or none, or what its instance holds besides its parts)`)}for(let r of d)o.some(i=>i.id===r.id)||c.push(`a ${t(r)} put in`);let w=(r,i)=>{let m="",h=0;for(let p of[...i].sort((f,$)=>f.start-$.start))m+=r.slice(h,p.start),h=p.end;return(m+r.slice(h)).replace(/\s+/g," ")};return(w(e,o)!==w(s,d)||!c.length)&&c.push("the page's own HTML outside its cards (its head, its style, its header)"),c.join("; ")}function Ie(e,s,{card:n,found:a}){let[o,d]=[T(e).text,T(s).text],t=ee(o,d,l=>x(l).cards.find(w=>w.id===n)?.instance??null,a);return t.outside&&(t.outside={...t.outside,what:Ce(o,d,n,a)}),t}async function Oe(e){try{return await e.waitForSelector("[data-doc-ready]",{timeout:C}).catch(s=>{if(s.name==="TimeoutError")throw s;return e.waitForSelector("[data-doc-ready]",{timeout:C})}),await e.waitForFunction(()=>globalThis.__galleryTryEditable===!0&&!!document.querySelector("script[data-ge-page]"),{timeout:C}),!0}catch(s){if(s.name!=="TimeoutError")throw s;return!1}}function ve(e){return e?.startsWith("stopped")?`the page service refused the board's write (${e.slice(7).trim()||"no reason given"}), and the page showed itself again as the file holds it`:{refused:"the page service refused the board's write: the card was changed or taken out meanwhile (someone else's write of page.html), and the page showed itself again as the file holds it",offline:"the page could not reach the server (offline)",reloading:"the page loaded itself again (page.html or a custom block it holds changed meanwhile, or the page service refused a write)",syncing:`its write took more than ${F/1e3}s to be answered`}[e]}function Ae(e){let s=[],n=new Map;return e.on("request",a=>{if(a.method()!=="POST"||!Te.test(new URL(a.url()).pathname))return;let o={done:!1,status:null,answer:null,failed:null};s.push(o),n.set(a,o)}),e.on("response",a=>{let o=n.get(a.request());o&&(o.status=a.status(),o.done=!0,o.status!==200&&a.json().then(d=>{o.answer=d},()=>{}))}),e.on("requestfailed",a=>{let o=n.get(a);o&&(o.failed=a.failure()?.errorText??"failed",o.done=!0)}),{mark:async()=>s.length,async until(a){let o=Date.now();for(let d=0;;await Se(100)){let c=s.slice(a);if(c.length===0){if(Date.now()-o>Q)return"unchanged";continue}if(c.some(l=>!l.done)){if(d=0,Date.now()-o>F)return"syncing";continue}if(++d<4)continue;if(c.some(l=>l.failed))return"offline";let t=c.find(l=>l.status!==200);return t?t.answer?.refused||t.status===409&&!t.answer?"refused":`stopped ${t.answer?.reason??`HTTP ${t.status}`}`:"saved"}}}}function Re({card:e,found:s}){let n={...s,parts:Object.fromEntries(Object.entries(s.parts).filter(([,a])=>a.edit==="data"))};return{where:{card:e},ready:Oe,saves:Ae,changes:(a,o)=>Ie(a,o,{card:e,found:n}),plain:()=>!1,stayed:ve,outside:"problem",outsideSaid:a=>`card ${e}'s data parts: ${a.what}, where a reader's gesture on the card is to change its data parts alone`,aside:xe,inside:ke,framed:a=>a.closest(".gallery-card")??a}}var Le=e=>` ${e.id} ${e.block??"(no instance)"} x ${e.x}, y ${e.y}, w ${e.w}, h ${e.h}${e.board?` on board ${e.board}`:""}`;async function Ke(e,{named:s,values:n,seconds:a={},keep:o,replace:d=!1}){if(s.length===0)throw new E("Name the page and the card: gallery page try <slug> <card id> and the gesture.");if(s.length===1)throw new E(`Name the card of ${s[0]} to try: gallery page try ${s[0]} <card id> and the gesture (its data-card-id; gallery page check ${s[0]} lists the cards).`);if(s.length>2)throw new E("gallery page try takes a page's slug and a card's id.");let c=await X(n,a,d),[t,l]=s,w=n.has("--steps")?P.resolve(n.get("--steps")):null,r=c?[c]:await Z(w),i=be(t,e);ye(t,e)||(console.error(await le(t,e)),process.exit(1));let m=await N.readFile(i.html,"utf8"),{cards:h}=x(T(m).text),p=h.find(u=>u.id===l);if(!p)throw new E(h.length?`${t} has no card ${l}: its cards are
2
+ import{E as re,J as ae,K as ne,O as ie,P as ce,a as C,b as Q,c as F,g as X,h as Z,n as D,o as ee,r as te,s as se,t as oe}from"./chunk-NMF3IPYA.mjs";import{j as K}from"./chunk-LJLVCU6W.mjs";import{d as le}from"./chunk-XZV72SQ4.mjs";import{i as q}from"./chunk-SQ3FQCCN.mjs";import{a as L}from"./chunk-JEUK3ZO7.mjs";import{a as M,b as z,g as J}from"./chunk-PUOQ65NC.mjs";import{b as x,c as T}from"./chunk-4B2TB5K2.mjs";import{b as E}from"./chunk-4OZWXZE5.mjs";import{f as H,j as Y}from"./chunk-TKWEX4FD.mjs";import{b as V,e as pe}from"./chunk-A55HN5OK.mjs";pe();import N from"node:fs/promises";import P from"node:path";import{isInstance as ge}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as me}from"../browser/shared/components/installed.mjs";import{attr as we,walk as $e}from"../browser/shared/html-tree.mjs";import{pageExists as ye,pageFiles as be}from"../browser/shared/pages.mjs";import{layoutOf as Ee}from"../browser/shared/workspace.mjs";var xe="card ids aside",ke="nothing else in page.html changed (card ids aside)",Se=e=>new Promise(s=>setTimeout(s,e)),Te=/^\/__gallery\/pages\/[a-z0-9-]+\/cards$/,de=e=>{let s=null;return $e(V(e,{sourceCodeLocationInfo:!0}),n=>{s??=ge(n)?n:null},{inTemplates:!1}),s},fe=(e,s)=>{let n=s.node.sourceCodeLocation.startTag.endOffset;return{frame:e.slice(s.start,n).replace(/\s+data-[xywh]="[^"]*"/g,""),rest:e.slice(n,s.end)}};function Ce(e,s,n,a){let[o,d]=[x(e).cards,x(s).cards],c=[],t=r=>`card ${r.id}${r.block?` (${r.block})`:""}`,l=r=>["x","y","w","h"].map(i=>`${i} ${we(r.node,`data-${i}`)??"-"}`).join(", ");for(let r of o){let i=d.find(g=>g.id===r.id);if(!i){c.push(`${t(r)} taken out`);continue}let m=r.board!==i.board;(m||l(r)!==l(i))&&c.push(`${t(r)}'s place, ${l(r)}${m?` on ${r.board}`:""} then ${l(i)}${m?` on ${i.board}`:""}`);let[h,p]=[fe(e,r),fe(s,i)];if(h.frame===p.frame&&h.rest===p.rest)continue;if(r.id!==n){c.push(t(r));continue}h.frame!==p.frame&&c.push(`${t(r)}'s own frame (an attribute of its <section> but its place)`);let[f,$]=[D(h.rest,de,a),D(p.rest,de,a)];!f||!$?c.push(`${t(r)}'s instance`):f.outside!==$.outside&&c.push(`${t(r)} itself, outside its data parts (a part edited as text or none, or what its instance holds besides its parts)`)}for(let r of d)o.some(i=>i.id===r.id)||c.push(`a ${t(r)} put in`);let w=(r,i)=>{let m="",h=0;for(let p of[...i].sort((f,$)=>f.start-$.start))m+=r.slice(h,p.start),h=p.end;return(m+r.slice(h)).replace(/\s+/g," ")};return(w(e,o)!==w(s,d)||!c.length)&&c.push("the page's own HTML outside its cards (its head, its style, its header)"),c.join("; ")}function Ie(e,s,{card:n,found:a}){let[o,d]=[T(e).text,T(s).text],t=ee(o,d,l=>x(l).cards.find(w=>w.id===n)?.instance??null,a);return t.outside&&(t.outside={...t.outside,what:Ce(o,d,n,a)}),t}async function Oe(e){try{return await e.waitForSelector("[data-doc-ready]",{timeout:C}).catch(s=>{if(s.name==="TimeoutError")throw s;return e.waitForSelector("[data-doc-ready]",{timeout:C})}),await e.waitForFunction(()=>globalThis.__galleryTryEditable===!0&&!!document.querySelector("script[data-ge-page]"),{timeout:C}),!0}catch(s){if(s.name!=="TimeoutError")throw s;return!1}}function ve(e){return e?.startsWith("stopped")?`the page service refused the board's write (${e.slice(7).trim()||"no reason given"}), and the page showed itself again as the file holds it`:{refused:"the page service refused the board's write: the card was changed or taken out meanwhile (someone else's write of page.html), and the page showed itself again as the file holds it",offline:"the page could not reach the server (offline)",reloading:"the page loaded itself again (page.html or a custom block it holds changed meanwhile, or the page service refused a write)",syncing:`its write took more than ${F/1e3}s to be answered`}[e]}function Ae(e){let s=[],n=new Map;return e.on("request",a=>{if(a.method()!=="POST"||!Te.test(new URL(a.url()).pathname))return;let o={done:!1,status:null,answer:null,failed:null};s.push(o),n.set(a,o)}),e.on("response",a=>{let o=n.get(a.request());o&&(o.status=a.status(),o.done=!0,o.status!==200&&a.json().then(d=>{o.answer=d},()=>{}))}),e.on("requestfailed",a=>{let o=n.get(a);o&&(o.failed=a.failure()?.errorText??"failed",o.done=!0)}),{mark:async()=>s.length,async until(a){let o=Date.now();for(let d=0;;await Se(100)){let c=s.slice(a);if(c.length===0){if(Date.now()-o>Q)return"unchanged";continue}if(c.some(l=>!l.done)){if(d=0,Date.now()-o>F)return"syncing";continue}if(++d<4)continue;if(c.some(l=>l.failed))return"offline";let t=c.find(l=>l.status!==200);return t?t.answer?.refused||t.status===409&&!t.answer?"refused":`stopped ${t.answer?.reason??`HTTP ${t.status}`}`:"saved"}}}}function Re({card:e,found:s}){let n={...s,parts:Object.fromEntries(Object.entries(s.parts).filter(([,a])=>a.edit==="data"))};return{where:{card:e},ready:Oe,saves:Ae,changes:(a,o)=>Ie(a,o,{card:e,found:n}),plain:()=>!1,stayed:ve,outside:"problem",outsideSaid:a=>`card ${e}'s data parts: ${a.what}, where a reader's gesture on the card is to change its data parts alone`,aside:xe,inside:ke,framed:a=>a.closest(".gallery-card")??a}}var Le=e=>` ${e.id} ${e.block??"(no instance)"} x ${e.x}, y ${e.y}, w ${e.w}, h ${e.h}${e.board?` on board ${e.board}`:""}`;async function Ke(e,{named:s,values:n,seconds:a={},keep:o,replace:d=!1}){if(s.length===0)throw new E("Name the page and the card: gallery page try <slug> <card id> and the gesture.");if(s.length===1)throw new E(`Name the card of ${s[0]} to try: gallery page try ${s[0]} <card id> and the gesture (its data-card-id; gallery page check ${s[0]} lists the cards).`);if(s.length>2)throw new E("gallery page try takes a page's slug and a card's id.");let c=await X(n,a,d),[t,l]=s,w=n.has("--steps")?P.resolve(n.get("--steps")):null,r=c?[c]:await Z(w),i=be(t,e);ye(t,e)||(console.error(await le(t,e)),process.exit(1));let m=await N.readFile(i.html,"utf8"),{cards:h}=x(T(m).text),p=h.find(u=>u.id===l);if(!p)throw new E(h.length?`${t} has no card ${l}: its cards are
3
3
  ${h.map(Le).join(`
4
- `)}`:`${t} has no card yet: gallery page add ${t} <block> puts one on it.`);let f=P.basename(i.html),$=p.node.sourceCodeLocation?.startLine??null;p.instance||(console.error(`Card ${l} of ${t} (${f}:${$}) holds no instance of a custom block (an element with ${me}): there is nothing on it to try.`),process.exit(1));let g=p.block,_=H(e),k=_.packages.get(g);if(!k){let u=_.problems.get(g);console.error(u?.off?`${g} is turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868: its card says so on the page and runs nothing.`:u?`${g} does not load (${Y("en",u.problem)}), so its card runs nothing: gallery block check ${g} says why.`:`No custom block ${g} in this workspace, so its card runs nothing: gallery block list says which there are${g.startsWith("gallery/")?`, and gallery block add ${g.slice(8)} puts one of Gallery's own in`:""}.`),process.exit(1)}k.places.includes("page")||(console.error(`${g} is a block of documents (its manifest's places has no "page"): on a custom page its card says so and runs nothing, so there is nothing to try there (gallery block try tries it in a document).`),process.exit(1)),console.log(`${g} in card ${l} of ${t}, at ${f}:${$}: ${L(i.html)}`),w&&console.log(`Steps: ${r.length} from ${L(w)}, made one after another in one page`);let S=await q({command:`gallery page try ${t}`});if(!S.ok){console.log(`UNVERIFIED ${t}: ${S.message}`),process.exitCode=3;return}let{pageAloneOf:j}=await import("./chunk-2T4PZQEP.mjs");await oe(e);let B=[],G=async u=>{let b=await te(e,{directory:i.folder,files:i,text:u});return B.push(b.slug),b},I=Re({card:l,found:k});try{let u=o?{slug:t,file:i.html}:await G(m),b=j(S.port,u.slug);console.log(o?`Page: ${b} (the custom page alone, editable: the Agent's own; --keep: what ${re(r)} write stays in ${f}, and every page open on it shows it, the user's too; the server runs on after this command)`:`Page: ${b} (a scratch copy of ${t}, its page alone, editable, made for this trial and gone at its end: ${f} is not written, and no page of the user's shows the trial; the server runs on after this command)`);let O=M();if(!O){console.log(`UNVERIFIED ${t}: no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one), so nothing was tried`),process.exitCode=3;return}let v;try{v=await J({executablePath:O,args:z()})}catch(R){console.log(`UNVERIFIED ${t}: the browser ${O} did not start, twice, each time with a fresh profile (${K(R)}; GALLERY_BROWSER=<its executable> picks another), so nothing was tried`),process.exitCode=3;return}let A=P.join(Ee(e).qa,t,"try");try{await N.rm(A,{recursive:!0,force:!0}),await N.mkdir(A,{recursive:!0});let R=async y=>{if(o)return{address:b,file:u.file};let W=await G(y);return{address:j(S.port,W.slug),file:W.file}},U;try{U=await ae(v.browser,{root:e,address:b,fresh:R,steps:r,keep:o,file:u.file,name:f,line:$,found:k,out:A,host:I})}catch(y){if(y instanceof E&&y.made&&console.log(ce({name:f,steps:r,keep:o,host:I},y.made).join(`
4
+ `)}`:`${t} has no card yet: gallery page add ${t} <block> puts one on it.`);let f=P.basename(i.html),$=p.node.sourceCodeLocation?.startLine??null;p.instance||(console.error(`Card ${l} of ${t} (${f}:${$}) holds no instance of a custom block (an element with ${me}): there is nothing on it to try.`),process.exit(1));let g=p.block,_=H(e),k=_.packages.get(g);if(!k){let u=_.problems.get(g);console.error(u?.off?`${g} is turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868: its card says so on the page and runs nothing.`:u?`${g} does not load (${Y("en",u.problem)}), so its card runs nothing: gallery block check ${g} says why.`:`No custom block ${g} in this workspace, so its card runs nothing: gallery block list says which there are${g.startsWith("gallery/")?`, and gallery block add ${g.slice(8)} puts one of Gallery's own in`:""}.`),process.exit(1)}k.places.includes("page")||(console.error(`${g} is a block of documents (its manifest's places has no "page"): on a custom page its card says so and runs nothing, so there is nothing to try there (gallery block try tries it in a document).`),process.exit(1)),console.log(`${g} in card ${l} of ${t}, at ${f}:${$}: ${L(i.html)}`),w&&console.log(`Steps: ${r.length} from ${L(w)}, made one after another in one page`);let S=await q({command:`gallery page try ${t}`});if(!S.ok){console.log(`UNVERIFIED ${t}: ${S.message}`),process.exitCode=3;return}let{pageAloneOf:j}=await import("./chunk-ONKC4BCC.mjs");await oe(e);let B=[],G=async u=>{let b=await te(e,{directory:i.folder,files:i,text:u});return B.push(b.slug),b},I=Re({card:l,found:k});try{let u=o?{slug:t,file:i.html}:await G(m),b=j(S.port,u.slug);console.log(o?`Page: ${b} (the custom page alone, editable: the Agent's own; --keep: what ${re(r)} write stays in ${f}, and every page open on it shows it, the user's too; the server runs on after this command)`:`Page: ${b} (a scratch copy of ${t}, its page alone, editable, made for this trial and gone at its end: ${f} is not written, and no page of the user's shows the trial; the server runs on after this command)`);let O=M();if(!O){console.log(`UNVERIFIED ${t}: no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one), so nothing was tried`),process.exitCode=3;return}let v;try{v=await J({executablePath:O,args:z()})}catch(R){console.log(`UNVERIFIED ${t}: the browser ${O} did not start, twice, each time with a fresh profile (${K(R)}; GALLERY_BROWSER=<its executable> picks another), so nothing was tried`),process.exitCode=3;return}let A=P.join(Ee(e).qa,t,"try");try{await N.rm(A,{recursive:!0,force:!0}),await N.mkdir(A,{recursive:!0});let R=async y=>{if(o)return{address:b,file:u.file};let W=await G(y);return{address:j(S.port,W.slug),file:W.file}},U;try{U=await ae(v.browser,{root:e,address:b,fresh:R,steps:r,keep:o,file:u.file,name:f,line:$,found:k,out:A,host:I})}catch(y){if(y instanceof E&&y.made&&console.log(ce({name:f,steps:r,keep:o,host:I},y.made).join(`
5
5
  `)),y.stuck)return ne(t,y,f,o);throw y}let{lines:ue,code:he}=ie({slug:t,name:f,steps:r,keep:o,host:I},U);console.log(ue.join(`
6
6
  `)),process.exitCode=he}finally{await v.close()}}finally{for(let u of B)await se(e,u)}}export{xe as a,ke as b,de as c,Ce as d,Ie as e,Ae as f,Re as g,Ke as h};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{d as m,i as g,k as p}from"./chunk-BN7M3IN7.mjs";import{b as a,f as l,i as c}from"./chunk-4OZWXZE5.mjs";import"./chunk-5L7RYZCL.mjs";import{reportsDirectory as i}from"../browser/shared/paths.mjs";import{joinDefaultTree as b,joinedLine as k}from"../browser/shared/drafts.mjs";var D=5e3;async function v(f){let{positional:s,options:u}=l({options:["--no-browser"],argv:f});if(s.length>1)throw new a("Name one document at most.");let{slug:o=null,block:w=null}=s.length?await c(s[0]):{};console.log(`\u5DE5\u4F5C\u533A\uFF1A${i}`);let e=await g({slug:o,baseline:o!==null});if(e.ok||console.error(e.message),e.reason==="missing"){let{HOME:n,pageExists:d}=await import("../browser/shared/pages.mjs"),{missingPageSaid:E,HOME_NOT_MADE:r}=await import("./chunk-2T4PZQEP.mjs");d(o,i)?console.error(`"${o}" is a custom page, not a document: gallery page open ${o} opens it and gives its address.`):o===n&&await E(o,i)===r&&console.error(r)}if(o!==null&&e.reason!=="missing"){let{roundBegins:n}=await import("./chunk-5XV3YYLG.mjs");await n(o,e.ok?{}:{wait:D})}if(o!==null&&e.reason!=="missing"){let n=k(await b(i,o));n&&console.log(n)}e.ok||process.exit(1);let t=await p(o,e,w);for(let n of t)console.log(n);console.log(await m(t,u))}export{v as run};
2
+ import{d as m,i as g,k as p}from"./chunk-SQ3FQCCN.mjs";import{b as a,f as l,i as c}from"./chunk-4OZWXZE5.mjs";import"./chunk-5L7RYZCL.mjs";import{reportsDirectory as i}from"../browser/shared/paths.mjs";import{joinDefaultTree as b,joinedLine as k}from"../browser/shared/drafts.mjs";var D=5e3;async function v(f){let{positional:s,options:u}=l({options:["--no-browser"],argv:f});if(s.length>1)throw new a("Name one document at most.");let{slug:o=null,block:w=null}=s.length?await c(s[0]):{};console.log(`\u5DE5\u4F5C\u533A\uFF1A${i}`);let e=await g({slug:o,baseline:o!==null});if(e.ok||console.error(e.message),e.reason==="missing"){let{HOME:n,pageExists:d}=await import("../browser/shared/pages.mjs"),{missingPageSaid:E,HOME_NOT_MADE:r}=await import("./chunk-ONKC4BCC.mjs");d(o,i)?console.error(`"${o}" is a custom page, not a document: gallery page open ${o} opens it and gives its address.`):o===n&&await E(o,i)===r&&console.error(r)}if(o!==null&&e.reason!=="missing"){let{roundBegins:n}=await import("./chunk-Z6OKLRHC.mjs");await n(o,e.ok?{}:{wait:D})}if(o!==null&&e.reason!=="missing"){let n=k(await b(i,o));n&&console.log(n)}e.ok||process.exit(1);let t=await p(o,e,w);for(let n of t)console.log(n);console.log(await m(t,u))}export{v as run};
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{spawn as J}from"node:child_process";import b from"node:fs";import m from"node:fs/promises";import Q from"node:os";import P from"node:path";import{escapeMarkup as X}from"../browser/shared/escape.mjs";import{spawn as C}from"node:child_process";import{existsSync as H,readFileSync as M}from"node:fs";import w from"node:path";var V=e=>!["","0",void 0].includes(e),z=(e,r)=>(r.PATH??"").split(w.delimiter).some(t=>t&&H(w.join(t,e))),U=()=>{try{return process.platform==="linux"&&/microsoft/i.test(M("/proc/version","utf8"))}catch{return!1}};function K(e,{platform:r=process.platform,env:t=process.env,wsl:o=U()}={}){let n=encodeURI(e);return V(t.GALLERY_NO_BROWSER)?{skip:"GALLERY_NO_BROWSER is set"}:r==="win32"?{command:w.join(t.SystemRoot||t.windir||"C:\\Windows","System32","rundll32.exe"),args:["url.dll,FileProtocolHandler",n]}:r==="darwin"?{command:"open",args:[n]}:o?{command:"cmd.exe",args:["/c","start",'""',n.replace(/[&^]/g,"^$&")]}:!t.DISPLAY&&!t.WAYLAND_DISPLAY?{skip:"no display here (neither DISPLAY nor WAYLAND_DISPLAY is set)"}:z("xdg-open",t)?{command:"xdg-open",args:[n]}:{skip:"xdg-open is not installed"}}var q="Opened it in the default browser (if that is not Chrome or Edge, open the address there to edit).",T=e=>e.opened?q:`Not opened in a browser: ${e.why}.`;async function I(e,r){let t=K(e,r);return t.skip?{opened:!1,why:t.skip}:new Promise(o=>{let n;try{n=C(t.command,t.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(s){return o({opened:!1,why:`${w.basename(t.command)} did not start (${s.code??s.message})`})}n.once("error",s=>o({opened:!1,why:`${w.basename(t.command)} did not start (${s.code??s.message})`})),n.once("spawn",()=>{n.unref(),o({opened:!0})})})}import{packageRoot as Z,projectRoot as G,release as O,reportsDirectory as h}from"../browser/shared/paths.mjs";import{workspaceId as ee,registerQuietly as te}from"../browser/shared/workspace-registry.mjs";import{serviceLocation as re,workspaceBase as ne}from"../browser/shared/service-location.mjs";import{fullAddress as oe}from"../browser/shared/page-address.mjs";import{findPreviewServer as se,galleryVersion as F,portIsFree as ie,previewServerFor as ae,readAnnouncement as ce}from"../browser/shared/preview-server.mjs";import{documentLinks as le}from"../browser/shared/reports.mjs";import{defaultWorkspace as de,documentDirectory as pe,documentFiles as ue}from"../browser/shared/workspace.mjs";var $="\u4EA4\u7ED9\u7528\u6237\uFF08\u73B0\u5728\u5C31\u628A\u8FD9\u4E2A\u5730\u5740\u7ED9\u7528\u6237\uFF1B\u7528 Chrome \u6216 Edge \u6253\u5F00\uFF09\uFF1A",fe="Agent \u81EA\u7528\uFF08\u53EA\u6709\u6587\u6863\u9875\uFF0C\u4E0D\u4EA4\u7ED9\u7528\u6237\uFF09\uFF1A",me=e=>`send the user ${e} now, in a message of its own, before any other step; then `;function Xe(e,r){let t=e.at(-1)??"";return`Next: ${t.startsWith($)?me(t.slice($.length)):""}${r}`}async function Ze(e,r){let t=e.at(-1)??"";return t.startsWith($)?r.has("--no-browser")?"Not opened in a browser (--no-browser).":T(await I(t.slice($.length))):null}var D="GALLERY_NO_PREVIEW",he=e=>!["","0",void 0].includes(e),et=e=>e.has("--no-preview")||he(process.env[D]),we=4317,$e=20,ye=(e=process.env)=>{let r=Number(e.GALLERY_PORT);return Number.isInteger(r)&&r>0&&r<65536?r:we},ge=6e4,ve=5*1024*1024,xe=P.join(G,"node_modules","vite","bin","vite.js"),ke=P.join(Z,"dist","server.mjs"),Le=e=>new Promise(r=>setTimeout(r,e)),Se=de(),R=re(),f=R.serverLog,W=()=>ne(h),A=(e,r)=>`http://127.0.0.1:${e}${W()}/generated/${r}.html`,be=(e,r)=>`${A(e,r)}?agent`,Y=e=>`http://127.0.0.1:${e}/`,Ae=async(e,r)=>{let t=await le(h).then(n=>n.links,()=>null),o=oe(`http://127.0.0.1:${e}`,r,t);return W()?o.replace("/#",`/#~${ee(h)}/`):o};async function Pe({first:e=ye(),count:r=$e}={}){let t=Number((await m.readFile(R.lastPortFile,"utf8").catch(()=>"")).trim()),o=Array.from({length:Math.max(0,r)},(n,s)=>e+s);return Number.isInteger(t)&&t>0&&t<65536?[t,...o.filter(n=>n!==t)]:o}async function Re(){return await m.mkdir(P.dirname(f),{recursive:!0}),await m.stat(f).then(r=>r.size,()=>0)>ve&&await m.rename(f,`${f}.1`).catch(()=>{}),b.openSync(f,"a")}async function Ee(e,r){if(!O){let{writeSharedAssets:p}=await import("./chunk-6L6V7YR2.mjs");await p()}let t=await Re();b.writeSync(t,`
2
+ import{spawn as J}from"node:child_process";import b from"node:fs";import m from"node:fs/promises";import Q from"node:os";import P from"node:path";import{escapeMarkup as X}from"../browser/shared/escape.mjs";import{spawn as C}from"node:child_process";import{existsSync as H,readFileSync as M}from"node:fs";import w from"node:path";var V=e=>!["","0",void 0].includes(e),z=(e,r)=>(r.PATH??"").split(w.delimiter).some(t=>t&&H(w.join(t,e))),U=()=>{try{return process.platform==="linux"&&/microsoft/i.test(M("/proc/version","utf8"))}catch{return!1}};function K(e,{platform:r=process.platform,env:t=process.env,wsl:o=U()}={}){let n=encodeURI(e);return V(t.GALLERY_NO_BROWSER)?{skip:"GALLERY_NO_BROWSER is set"}:r==="win32"?{command:w.join(t.SystemRoot||t.windir||"C:\\Windows","System32","rundll32.exe"),args:["url.dll,FileProtocolHandler",n]}:r==="darwin"?{command:"open",args:[n]}:o?{command:"cmd.exe",args:["/c","start",'""',n.replace(/[&^]/g,"^$&")]}:!t.DISPLAY&&!t.WAYLAND_DISPLAY?{skip:"no display here (neither DISPLAY nor WAYLAND_DISPLAY is set)"}:z("xdg-open",t)?{command:"xdg-open",args:[n]}:{skip:"xdg-open is not installed"}}var q="Opened it in the default browser (if that is not Chrome or Edge, open the address there to edit).",T=e=>e.opened?q:`Not opened in a browser: ${e.why}.`;async function I(e,r){let t=K(e,r);return t.skip?{opened:!1,why:t.skip}:new Promise(o=>{let n;try{n=C(t.command,t.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(s){return o({opened:!1,why:`${w.basename(t.command)} did not start (${s.code??s.message})`})}n.once("error",s=>o({opened:!1,why:`${w.basename(t.command)} did not start (${s.code??s.message})`})),n.once("spawn",()=>{n.unref(),o({opened:!0})})})}import{packageRoot as Z,projectRoot as G,release as O,reportsDirectory as h}from"../browser/shared/paths.mjs";import{workspaceId as ee,registerQuietly as te}from"../browser/shared/workspace-registry.mjs";import{serviceLocation as re,workspaceBase as ne}from"../browser/shared/service-location.mjs";import{fullAddress as oe}from"../browser/shared/page-address.mjs";import{findPreviewServer as se,galleryVersion as F,portIsFree as ie,previewServerFor as ae,readAnnouncement as ce}from"../browser/shared/preview-server.mjs";import{documentLinks as le}from"../browser/shared/reports.mjs";import{defaultWorkspace as de,documentDirectory as pe,documentFiles as ue}from"../browser/shared/workspace.mjs";var $="\u4EA4\u7ED9\u7528\u6237\uFF08\u73B0\u5728\u5C31\u628A\u8FD9\u4E2A\u5730\u5740\u7ED9\u7528\u6237\uFF1B\u7528 Chrome \u6216 Edge \u6253\u5F00\uFF09\uFF1A",fe="Agent \u81EA\u7528\uFF08\u53EA\u6709\u6587\u6863\u9875\uFF0C\u4E0D\u4EA4\u7ED9\u7528\u6237\uFF09\uFF1A",me=e=>`send the user ${e} now, in a message of its own, before any other step; then `;function Xe(e,r){let t=e.at(-1)??"";return`Next: ${t.startsWith($)?me(t.slice($.length)):""}${r}`}async function Ze(e,r){let t=e.at(-1)??"";return t.startsWith($)?r.has("--no-browser")?"Not opened in a browser (--no-browser).":T(await I(t.slice($.length))):null}var D="GALLERY_NO_PREVIEW",he=e=>!["","0",void 0].includes(e),et=e=>e.has("--no-preview")||he(process.env[D]),we=4317,$e=20,ye=(e=process.env)=>{let r=Number(e.GALLERY_PORT);return Number.isInteger(r)&&r>0&&r<65536?r:we},ge=6e4,ve=5*1024*1024,xe=P.join(G,"node_modules","vite","bin","vite.js"),ke=P.join(Z,"dist","server.mjs"),Le=e=>new Promise(r=>setTimeout(r,e)),Se=de(),R=re(),f=R.serverLog,W=()=>ne(h),A=(e,r)=>`http://127.0.0.1:${e}${W()}/generated/${r}.html`,be=(e,r)=>`${A(e,r)}?agent`,Y=e=>`http://127.0.0.1:${e}/`,Ae=async(e,r)=>{let t=await le(h).then(n=>n.links,()=>null),o=oe(`http://127.0.0.1:${e}`,r,t);return W()?o.replace("/#",`/#~${ee(h)}/`):o};async function Pe({first:e=ye(),count:r=$e}={}){let t=Number((await m.readFile(R.lastPortFile,"utf8").catch(()=>"")).trim()),o=Array.from({length:Math.max(0,r)},(n,s)=>e+s);return Number.isInteger(t)&&t>0&&t<65536?[t,...o.filter(n=>n!==t)]:o}async function Re(){return await m.mkdir(P.dirname(f),{recursive:!0}),await m.stat(f).then(r=>r.size,()=>0)>ve&&await m.rename(f,`${f}.1`).catch(()=>{}),b.openSync(f,"a")}async function Ee(e,r){if(!O){let{writeSharedAssets:p}=await import("./chunk-CRDG6EF2.mjs");await p()}let t=await Re();b.writeSync(t,`
3
3
  [${new Date().toISOString()}] ${r}: Gallery ${F} on 127.0.0.1:${e} for ${h}
4
- `);let[o,n]=O?[[ke,"--port",String(e)],Q.homedir()]:[[xe,"--host","127.0.0.1","--port",String(e),"--strictPort"],G],s=J(process.execPath,o,{cwd:n,env:{...process.env,GALLERY_WORKSPACE:Se,GALLERY_SERVER_KIND:"cli"},detached:!0,stdio:["ignore",t,t],windowsHide:!0});return b.closeSync(t),s.unref(),s}async function Ne({slug:e=null,command:r=`gallery open${e?` ${e}`:""}`,ports:t=null,starting:o=ge,baseline:n=!1}={}){await te(h);let s=()=>!0;if(e){let a=ue(pe(e,h)),c=await m.readFile(a.html,"utf8").catch(()=>null);if(c===null)return{ok:!1,reason:"missing",message:`No document "${e}": ${a.html} does not exist (gallery new ${e} "<\u6807\u9898>" makes one; gallery list lists those there are).`};n&&await import("./chunk-K3JKPFL5.mjs").then(({previewBaseline:x})=>x(e,c));let i=await m.readFile(a.json,"utf8").then(JSON.parse).catch(()=>({})),v=[/<title>([^<]*)<\/title>/i.exec(c)?.[1]?.trim(),typeof i.title=="string"?i.title.trim():""].filter(Boolean);s=x=>v.length===0||v.some(_=>x.includes(_)||x.includes(X(_)))}let p=t??await Pe(),k=p.length?`${Math.min(...p)} to ${Math.max(...p)}`:"none",L=`gallery open${e?` ${e}`:""}`,E=async(a,c=[])=>{let i=await ae({ports:p.slice(a),start:v=>Ee(v,r)});return i.busy?.newer?{failed:{ok:!1,reason:"newer",message:`A newer Gallery (${i.busy.version}) serves this Gallery data directory (port ${i.busy.port}, pid ${i.busy.pid}) and gave no answer in 10s; this is Gallery ${F}. Update this one (npm i -g @heycys/gallery@latest), or run ${L} again in a while.`}}:i.busy?{failed:{ok:!1,reason:"busy",message:`The shared Gallery server (port ${i.busy.port}, pid ${i.busy.pid}) took the request and gave no answer in 10s: it is busy or stuck. Run ${L} again in a while, or stop that process first (gallery stop): a second server for this data directory is not started beside it.`}}:i.stuck?{failed:{ok:!1,reason:"stuck",message:`An older Gallery's server serves this Gallery data directory and did not stop: ${i.stuck.message}`}}:i.port===null?{failed:{ok:!1,reason:"ports",message:`No server for this data directory runs, and no port from ${k} is free to start one on: stop a server on one of them (or name another first port: GALLERY_PORT=<n>), then run ${L}.`}}:{...i,passed:[...c,...i.passed]}},u=await E(0);if(u.failed)return u.failed;let{port:l,started:d,passed:S,replaced:j}=u,y=u.running??null,N=Date.now()+o,g="",B=async()=>{if(e){let c=await fetch(`${A(l,e)}?present`,{signal:AbortSignal.timeout(5e3)}).catch(()=>null),i=c?.ok?await c.text():"";return g=c?i?`HTTP ${c.status} without the title`:`HTTP ${c.status}`:"no answer",!!(i&&s(i))}let a=await fetch(`http://127.0.0.1:${l}/__gallery/workspace/info`,{signal:AbortSignal.timeout(5e3)}).catch(()=>null);return g=a?`HTTP ${a.status}`:"no answer",!!a?.ok};for(;;await Le(300)){if(Date.now()>N)return{ok:!1,reason:"timeout",message:`${e?A(l,e):Y(l)} did not answer${e?" with the document's title":""} in ${o/1e3}s (${g})${d?`; the server's output is in ${f}`:""}.`};if(d){let a=await se({answering:!0});if(a&&a.pid!==d.pid){if(d.exitCode===null)try{process.kill(d.pid)}catch{}({port:l}=a),y={pid:a.pid,kind:(await ce())?.kind??"cli",version:null},d=null;continue}if(!a&&d.exitCode===null){g="the server started has not announced itself yet";continue}if(!a){if(!await ie(l)){if(u=await E(p.indexOf(l)+1,[...S,`${l} (taken by another program while the server started)`]),u.failed)return u.failed;({port:l,started:d,passed:S}=u),y=u.running??null,N=Date.now()+o;continue}let c=await m.readFile(f,"utf8").catch(()=>"");return{ok:!1,reason:"stopped",message:`The Gallery server on port ${l} stopped (exit ${d.exitCode}). Its last words (${f}):
4
+ `);let[o,n]=O?[[ke,"--port",String(e)],Q.homedir()]:[[xe,"--host","127.0.0.1","--port",String(e),"--strictPort"],G],s=J(process.execPath,o,{cwd:n,env:{...process.env,GALLERY_WORKSPACE:Se,GALLERY_SERVER_KIND:"cli"},detached:!0,stdio:["ignore",t,t],windowsHide:!0});return b.closeSync(t),s.unref(),s}async function Ne({slug:e=null,command:r=`gallery open${e?` ${e}`:""}`,ports:t=null,starting:o=ge,baseline:n=!1}={}){await te(h);let s=()=>!0;if(e){let a=ue(pe(e,h)),c=await m.readFile(a.html,"utf8").catch(()=>null);if(c===null)return{ok:!1,reason:"missing",message:`No document "${e}": ${a.html} does not exist (gallery new ${e} "<\u6807\u9898>" makes one; gallery list lists those there are).`};n&&await import("./chunk-225ALKYI.mjs").then(({previewBaseline:x})=>x(e,c));let i=await m.readFile(a.json,"utf8").then(JSON.parse).catch(()=>({})),v=[/<title>([^<]*)<\/title>/i.exec(c)?.[1]?.trim(),typeof i.title=="string"?i.title.trim():""].filter(Boolean);s=x=>v.length===0||v.some(_=>x.includes(_)||x.includes(X(_)))}let p=t??await Pe(),k=p.length?`${Math.min(...p)} to ${Math.max(...p)}`:"none",L=`gallery open${e?` ${e}`:""}`,E=async(a,c=[])=>{let i=await ae({ports:p.slice(a),start:v=>Ee(v,r)});return i.busy?.newer?{failed:{ok:!1,reason:"newer",message:`A newer Gallery (${i.busy.version}) serves this Gallery data directory (port ${i.busy.port}, pid ${i.busy.pid}) and gave no answer in 10s; this is Gallery ${F}. Update this one (npm i -g @heycys/gallery@latest), or run ${L} again in a while.`}}:i.busy?{failed:{ok:!1,reason:"busy",message:`The shared Gallery server (port ${i.busy.port}, pid ${i.busy.pid}) took the request and gave no answer in 10s: it is busy or stuck. Run ${L} again in a while, or stop that process first (gallery stop): a second server for this data directory is not started beside it.`}}:i.stuck?{failed:{ok:!1,reason:"stuck",message:`An older Gallery's server serves this Gallery data directory and did not stop: ${i.stuck.message}`}}:i.port===null?{failed:{ok:!1,reason:"ports",message:`No server for this data directory runs, and no port from ${k} is free to start one on: stop a server on one of them (or name another first port: GALLERY_PORT=<n>), then run ${L}.`}}:{...i,passed:[...c,...i.passed]}},u=await E(0);if(u.failed)return u.failed;let{port:l,started:d,passed:S,replaced:j}=u,y=u.running??null,N=Date.now()+o,g="",B=async()=>{if(e){let c=await fetch(`${A(l,e)}?present`,{signal:AbortSignal.timeout(5e3)}).catch(()=>null),i=c?.ok?await c.text():"";return g=c?i?`HTTP ${c.status} without the title`:`HTTP ${c.status}`:"no answer",!!(i&&s(i))}let a=await fetch(`http://127.0.0.1:${l}/__gallery/workspace/info`,{signal:AbortSignal.timeout(5e3)}).catch(()=>null);return g=a?`HTTP ${a.status}`:"no answer",!!a?.ok};for(;;await Le(300)){if(Date.now()>N)return{ok:!1,reason:"timeout",message:`${e?A(l,e):Y(l)} did not answer${e?" with the document's title":""} in ${o/1e3}s (${g})${d?`; the server's output is in ${f}`:""}.`};if(d){let a=await se({answering:!0});if(a&&a.pid!==d.pid){if(d.exitCode===null)try{process.kill(d.pid)}catch{}({port:l}=a),y={pid:a.pid,kind:(await ce())?.kind??"cli",version:null},d=null;continue}if(!a&&d.exitCode===null){g="the server started has not announced itself yet";continue}if(!a){if(!await ie(l)){if(u=await E(p.indexOf(l)+1,[...S,`${l} (taken by another program while the server started)`]),u.failed)return u.failed;({port:l,started:d,passed:S}=u),y=u.running??null,N=Date.now()+o;continue}let c=await m.readFile(f,"utf8").catch(()=>"");return{ok:!1,reason:"stopped",message:`The Gallery server on port ${l} stopped (exit ${d.exitCode}). Its last words (${f}):
5
5
  ${c.split(`
6
6
  `).slice(-15).join(`
7
7
  `)}`}}}if(await B())break}return await m.writeFile(R.lastPortFile,`${l}
@@ -1,4 +1,4 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{e as D,f as x}from"./chunk-XZCFPKGO.mjs";import{a as d,b as u,c as w,d as y}from"./chunk-S3SX3COT.mjs";import{b as c,d as f,e as m,g as p,h as g,i as a,j as h}from"./chunk-VRPVVMRB.mjs";import{k as l}from"./chunk-PLB7L22J.mjs";import{a as s}from"./chunk-UMHUSOPJ.mjs";import S from"node:path";import{FILE as j}from"../browser/shared/annotations.mjs";import{editStateDirectory as L,reportsDirectory as i}from"../browser/shared/paths.mjs";import{documentDirectory as $,documentFiles as k}from"../browser/shared/workspace.mjs";function O({say:e=!0}={}){return o=>{let{text:t,changes:n}=c(o.html,{finish:l});if(e&&n.length&&console.log(p(o.htmlPath,n,{pending:!0}).join(`
2
+ import{e as D,f as x}from"./chunk-5GK7HS62.mjs";import{a as d,b as u,c as w,d as y}from"./chunk-S3SX3COT.mjs";import{b as c,d as f,e as m,g as p,h as g,i as a,j as h}from"./chunk-VRPVVMRB.mjs";import{k as l}from"./chunk-FJLM7YE7.mjs";import{a as s}from"./chunk-UMHUSOPJ.mjs";import S from"node:path";import{FILE as j}from"../browser/shared/annotations.mjs";import{editStateDirectory as L,reportsDirectory as i}from"../browser/shared/paths.mjs";import{documentDirectory as $,documentFiles as k}from"../browser/shared/workspace.mjs";function O({say:e=!0}={}){return o=>{let{text:t,changes:n}=c(o.html,{finish:l});if(e&&n.length&&console.log(p(o.htmlPath,n,{pending:!0}).join(`
3
3
  `)),e){let r=f(o.html);r.length&&console.log(D(o.htmlPath,r,r.length,{pending:!0}).join(`
4
4
  `));for(let N of x(o.htmlPath,m(s(o.html),o.metadata),{pending:!0}))console.log(N)}return t}}function b(e){for(let o of e){for(let t of g(o.html))console.log(`note ${o.slug}: ${t} (read-only in the preview)`);for(let t of a(o.html))console.log(`note ${o.slug}: ${t}`);for(let t of h(o.html))console.log(`note ${o.slug}: ${t}`)}}async function q(e){for(let o of e){let t=await w({stateDirectory:L,reportsDirectory:i,slug:o});for(let n of y(k($(o,i)).html,t))console.log(n)}}async function z(e){for(let o of e){let t=await d({stateDirectory:L,reportsDirectory:i,slug:o});for(let n of u(S.join($(o,i),j),t))console.log(n)}}export{O as a,b,q as c,z as d};
@@ -1,4 +1,4 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{g as i,h as g}from"./chunk-BN7M3IN7.mjs";import{b as m,f as u}from"./chunk-4OZWXZE5.mjs";import"./chunk-5L7RYZCL.mjs";import{spawn as P}from"node:child_process";import h from"node:fs/promises";import R from"node:path";import{projectRoot as v,release as G,reportsDirectory as S}from"../browser/shared/paths.mjs";import{answerOf as k,findPreviewServer as x,portIsFree as y,readAnnouncement as b}from"../browser/shared/preview-server.mjs";import{serviceLocation as E}from"../browser/shared/service-location.mjs";import{registerQuietly as A}from"../browser/shared/workspace-registry.mjs";import{defaultWorkspace as C}from"../browser/shared/workspace.mjs";var n=C(),I=a=>new Promise(t=>setTimeout(t,a));async function V(a){await A(S);let{positional:t,values:l}=u({values:["--port"],argv:a});if(t.length>0)throw new m(`gallery serve takes no arguments: ${t[0]}`);let o=l.has("--port")?Number(l.get("--port")):null;if(o!==null&&!(Number.isInteger(o)&&o>0&&o<65536))throw new m(`--port takes a port number: ${l.get("--port")}`);let s=await b(),f=s?await k(s,1e4):"no";f!=="no"&&(console.error(`The shared Gallery server runs already: ${i(s.port)} (pid ${s.pid}${f==="busy"?", not answering now":""}). gallery stop stops it; one server serves a Gallery data directory.`),process.exit(1));let r=null;if(o!==null)await y(o)||(console.error(`Port ${o} is taken: name another (--port), or leave it out for the first free one.`),process.exit(1)),r=o;else{for(let e of await g())if(await y(e)){r=e;break}r===null&&(console.error("No port from 4317 is free: name one (--port <n>)."),process.exit(1))}if(G){process.env.GALLERY_SERVER_KIND="cli";let{startProductionServer:e}=await import("./chunk-4SNV4HA5.mjs");await e({reportsDirectory:n,port:r,kind:"cli"}),await h.writeFile(E().lastPortFile,`${r}
3
- `).catch(()=>{}),console.log(`Gallery serves ${n} at ${i(r)} (Chrome or Edge). Ctrl+C stops it.`);return}let{writeSharedAssets:$}=await import("./chunk-6L6V7YR2.mjs");await $();let c=P(process.execPath,[R.join(v,"node_modules","vite","bin","vite.js"),"--host","127.0.0.1","--port",String(r),"--strictPort"],{cwd:v,env:{...process.env,GALLERY_WORKSPACE:n,GALLERY_SERVER_KIND:"cli"},stdio:"inherit"});for(let e of["SIGINT","SIGTERM"])process.on(e,()=>c.kill(e));let w=new Promise(e=>c.once("exit",(d,p)=>e(d??(p?1:0))));for(;;){let e=await Promise.race([w.then(p=>({code:p})),I(300).then(()=>null)]);if(e&&process.exit(e.code),(await x({answering:!0,timeout:2e3}))?.pid===c.pid)break}await h.writeFile(E().lastPortFile,`${r}
2
+ import{g as i,h as g}from"./chunk-SQ3FQCCN.mjs";import{b as m,f as u}from"./chunk-4OZWXZE5.mjs";import"./chunk-5L7RYZCL.mjs";import{spawn as P}from"node:child_process";import h from"node:fs/promises";import R from"node:path";import{projectRoot as v,release as G,reportsDirectory as S}from"../browser/shared/paths.mjs";import{answerOf as k,findPreviewServer as x,portIsFree as y,readAnnouncement as b}from"../browser/shared/preview-server.mjs";import{serviceLocation as E}from"../browser/shared/service-location.mjs";import{registerQuietly as A}from"../browser/shared/workspace-registry.mjs";import{defaultWorkspace as C}from"../browser/shared/workspace.mjs";var n=C(),I=a=>new Promise(t=>setTimeout(t,a));async function V(a){await A(S);let{positional:t,values:l}=u({values:["--port"],argv:a});if(t.length>0)throw new m(`gallery serve takes no arguments: ${t[0]}`);let o=l.has("--port")?Number(l.get("--port")):null;if(o!==null&&!(Number.isInteger(o)&&o>0&&o<65536))throw new m(`--port takes a port number: ${l.get("--port")}`);let s=await b(),f=s?await k(s,1e4):"no";f!=="no"&&(console.error(`The shared Gallery server runs already: ${i(s.port)} (pid ${s.pid}${f==="busy"?", not answering now":""}). gallery stop stops it; one server serves a Gallery data directory.`),process.exit(1));let r=null;if(o!==null)await y(o)||(console.error(`Port ${o} is taken: name another (--port), or leave it out for the first free one.`),process.exit(1)),r=o;else{for(let e of await g())if(await y(e)){r=e;break}r===null&&(console.error("No port from 4317 is free: name one (--port <n>)."),process.exit(1))}if(G){process.env.GALLERY_SERVER_KIND="cli";let{startProductionServer:e}=await import("./chunk-JYK5WJPM.mjs");await e({reportsDirectory:n,port:r,kind:"cli"}),await h.writeFile(E().lastPortFile,`${r}
3
+ `).catch(()=>{}),console.log(`Gallery serves ${n} at ${i(r)} (Chrome or Edge). Ctrl+C stops it.`);return}let{writeSharedAssets:$}=await import("./chunk-CRDG6EF2.mjs");await $();let c=P(process.execPath,[R.join(v,"node_modules","vite","bin","vite.js"),"--host","127.0.0.1","--port",String(r),"--strictPort"],{cwd:v,env:{...process.env,GALLERY_WORKSPACE:n,GALLERY_SERVER_KIND:"cli"},stdio:"inherit"});for(let e of["SIGINT","SIGTERM"])process.on(e,()=>c.kill(e));let w=new Promise(e=>c.once("exit",(d,p)=>e(d??(p?1:0))));for(;;){let e=await Promise.race([w.then(p=>({code:p})),I(300).then(()=>null)]);if(e&&process.exit(e.code),(await x({answering:!0,timeout:2e3}))?.pid===c.pid)break}await h.writeFile(E().lastPortFile,`${r}
4
4
  `).catch(()=>{}),console.log(`Gallery serves ${n} at ${i(r)} (Chrome or Edge). Ctrl+C stops it.`),process.exit(await w)}export{V as run};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{a,b}from"./chunk-FFV733MA.mjs";import"./chunk-WFGPMCTZ.mjs";import"./chunk-7UZUQQ7Q.mjs";import"./chunk-4B2TB5K2.mjs";import"./chunk-KLQP46Y3.mjs";import"./chunk-4OZWXZE5.mjs";import"./chunk-E7656LR7.mjs";import"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";export{a as copiedLines,b as run};
2
+ import{a,b}from"./chunk-NLDF35P5.mjs";import"./chunk-L55NOXBE.mjs";import"./chunk-7UZUQQ7Q.mjs";import"./chunk-4B2TB5K2.mjs";import"./chunk-KLQP46Y3.mjs";import"./chunk-4OZWXZE5.mjs";import"./chunk-E7656LR7.mjs";import"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";export{a as copiedLines,b as run};
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{a as w}from"./chunk-JEUK3ZO7.mjs";import{a as te}from"./chunk-6QWQXHAV.mjs";import{d as F,e as W}from"./chunk-7UZUQQ7Q.mjs";import{a as H,b as L,d as G,e as $,f as E,g as R,h as U,i as q,j as Y,o as V,r as X,s as Q,t as Z}from"./chunk-KLQP46Y3.mjs";import{a as P,b as d,f as ee}from"./chunk-4OZWXZE5.mjs";import{i as K}from"./chunk-3SKOU6OZ.mjs";import{f as S,j as C,s as _,t as B,v as j}from"./chunk-TKWEX4FD.mjs";import v from"node:fs";import N from"node:path";import{blocksHidden as $e}from"../browser/editor/components/registry.mjs";import{inLanguage as be,told as ve}from"../browser/shared/i18n/index.mjs";import{PACK_ID as xe}from"../browser/shared/pack-manifest.mjs";import{readKeys as Se,writeKey as se}from"../browser/shared/net-keys.mjs";import{HOST as Ne,netHostsOf as Oe}from"../browser/shared/net-policy.mjs";import{PACKAGE_ID as je,SLOT as Ee}from"../browser/shared/components/installed.mjs";import{DEVICE_NAMES as Ae,layoutOf as A,PACKAGE_MANIFEST as ie,shallowPackages as le}from"../browser/shared/workspace.mjs";var fe=(e,t,{script:o,flow:n,data:a,page:s})=>`{
2
+ import{a as w}from"./chunk-JEUK3ZO7.mjs";import{a as te}from"./chunk-6QWQXHAV.mjs";import{d as F,e as W}from"./chunk-7UZUQQ7Q.mjs";import{a as H,b as L,d as G,e as $,f as E,g as R,h as U,i as q,j as Y,o as V,r as X,s as Q,t as Z}from"./chunk-KLQP46Y3.mjs";import{a as P,b as d,f as ee}from"./chunk-4OZWXZE5.mjs";import{i as K}from"./chunk-HX4DLE3J.mjs";import{f as S,j as C,s as _,t as B,v as j}from"./chunk-TKWEX4FD.mjs";import v from"node:fs";import N from"node:path";import{blocksHidden as $e}from"../browser/editor/components/registry.mjs";import{inLanguage as be,told as ve}from"../browser/shared/i18n/index.mjs";import{PACK_ID as xe}from"../browser/shared/pack-manifest.mjs";import{readKeys as Se,writeKey as se}from"../browser/shared/net-keys.mjs";import{HOST as Ne,netHostsOf as Oe}from"../browser/shared/net-policy.mjs";import{PACKAGE_ID as je,SLOT as Ee}from"../browser/shared/components/installed.mjs";import{DEVICE_NAMES as Ae,layoutOf as A,PACKAGE_MANIFEST as ie,shallowPackages as le}from"../browser/shared/workspace.mjs";var fe=(e,t,{script:o,flow:n,data:a,page:s})=>`{
3
3
  "id": "${e}",
4
4
  "apiVersion": 1,
5
5
  "version": "0.1.0",
@@ -167,4 +167,4 @@ DocKit.component({
167
167
  });
168
168
  `;function ne(e,{script:t=!1,flow:o=!1,data:n=!1,page:a=!1}={}){let s=e.split("/")[1],l={script:t||n,flow:o,data:n,page:a};return{"component.json":fe(e,s,l),"template.html":oe(e,"\u6807\u9898","\u5199\u5728\u8FD9\u91CC\u3002",{blocks:o&&["<p></p>"],json:n&&'{"items":[]}'}),"example.html":oe(e,"\u4E00\u4E2A\u4F8B\u5B50","\u8FD9\u91CC\u5199\u8FD9\u4E2A\u5757\u5728\u4E00\u4EFD\u6587\u6863\u91CC\u7684\u6837\u5B50\u3002",{blocks:o&&we,json:n&&'{"items":[{"text":"\u7B2C\u4E00\u6761"},{"text":"\u7B2C\u4E8C\u6761"}]}'}),"writing.md":ue(e,s,l),"style.css":ge(e,l),...l.script?{"kit.js":n?ye(e):ke(e)}:{}}}var x="local";function re(e){let t=e.includes("/")?e:`${x}/${e}`;if(!je.test(t))throw new d(`Not a block's id: ${e} (<scope>/<name>, each in lowercase letters, digits and hyphens; a <name> alone is ${x}/<name>).`);let o=t.split("/").find(n=>Ae.has(n));if(o)throw new d(`Not a block's id: ${e} (Windows keeps ${o} for a device).`);return t}function Ie(e,t){let o=re(t),n=t.includes("/")?null:$(t);if(!n)return o;let a=S(e);return a.packages.has(o)||a.problems.has(o)||v.existsSync(M(e,o))?o:n.id}var M=(e,t)=>N.join(A(e).components,...t.split("/")),u=e=>e.pack===H?e.name:e.id,z=()=>G().map(u).join(", "),ce=({name:e,file:t})=>`${w(t)} is one level too shallow, and no catalog reads it: a custom block is components/<scope>/<name>/, so move it to components/${x}/${e}/`;function Ce(e,t){let o=le(e).find(({name:s})=>s===t.split("/")[1]),n=E(t)&&$(t);if(n)return`No block ${t} in ${w(A(e).components)}: it is one of Gallery's own, which gallery block add ${u(n)} puts in.`;let a=t.startsWith(`${x}/`)?$(t.slice(x.length+1)):null;return o?ce(o):`No block ${t} in ${w(A(e).components)}: gallery block list says which there are${a?`; Gallery has a block of that name, ${a.id}`:""}.`}function Ge(e,t,{script:o,flow:n,data:a,page:s,recipe:l}){let r=t.split("/")[0],m=$(t);if(E(t))throw new d(`The scope ${r}/ is kept for Gallery's own blocks: give yours another (${x}/<name>, or a <name> alone)${m?`; gallery block add ${u(m)} puts Gallery's in, and gallery block new <id> --recipe ${u(m)} starts one of yours from it`:""}.`);if(R(e).packs?.[r])throw new d(`The scope ${r}/ is the pack ${r}'s, which gallery block pack install put in (installing it again would not keep a block of yours there): give yours another (${x}/<name>, or a <name> alone).`);let h=l===void 0?null:$(l);if(l!==void 0&&!h)throw new d(`No block of Gallery's own is called ${l}: ${z()||"none"}.`);let f=M(e,t);if(v.existsSync(f)||S(e).problems.has(t)){let c=!v.existsSync(N.join(f,ie));console.error(c?`A folder is there with no component.json: ${w(f)}: move it, or give this block another name.`:`Block already exists: ${w(f)}: gallery block show ${t} says what it is; give a new one another name.`),process.exit(1)}let i=h?V(h,t):ne(t,{script:o,flow:n,data:a,page:s});try{v.mkdirSync(f,{recursive:!0});for(let c of L(Object.keys(i)))v.mkdirSync(N.dirname(N.join(f,c)),{recursive:!0}),v.writeFileSync(N.join(f,c),i[c])}catch(c){if(!c.code)throw c;console.error(`Cannot write ${w(f)} (${c.code}).`),process.exit(1)}if(console.log(`Created ${w(f)}: ${Object.keys(i).join(", ")}`),h){console.log(`Made from Gallery's ${h.id} ${h.version}, every word that named it naming ${t}: change its name, words and description in component.json first (two blocks of one name read alike in "/"), and in the same files what is still ${h.name}'s: preview.svg (the picture the menu shows beside the description, still ${h.name}'s drawing: draw yours or delete it), writing.md (how to write it, still about ${h.name}) and example.html (the instance check runs and show prints, still ${h.name}'s words), then what you came for (references/building-blocks.md has every field and the rules), and run gallery block check ${t}, which passes as it stands now.`);return}let p=o||a;console.log(`Next: say in component.json what it is (its name, description and parts), write template.html, what ${s?"a custom page's \u6DFB\u52A0\u81EA\u5B9A\u4E49\u5757 puts on it":'"/" puts in a document'}, and example.html, an instance as a writer would fill it, then writing.md and style.css${p?" and kit.js":""} (references/building-blocks.md has every field and the rules${n?", and Slots what its slot body holds":""}${s?"; references/pages-and-data.md a card's size and settings and what it reads":""}${p?"; references/block-script.md its script and how it writes back":""}), and run gallery block check ${t}, which passes as it stands now.`),a&&console.log("It keeps a list of lines (the part items, a script of JSON on one line, as context.editJSON writes it): kit.js reads it with context.readJSON and writes it with context.editJSON, from a field (DocKit.input) and a button, hidden where nothing is written; example() adds a line by the function the field calls, and works on template.html's empty instance. Rename the part, the fields of its JSON and the controls for what the block keeps."),s?console.log(`It is a custom page's card (places ["page"], a card of two sizes): gallery page add <slug> ${t} puts one on a page, then gallery page try <slug> <card id> <gesture> tries a reader's gesture on it${a?' (--type .component-field "words" --then Enter)':""}; for a document too, put "document" in places.`):a&&console.log(`In a document: write the element as example.html does, then gallery block try <slug> --type .component-field "words" --then Enter tries the field (the part and the class are the scaffold's: rename them with the block).`)}function Pe(e,t){let o=$(t);if(!o)throw new d(`No block of Gallery's own is called ${t}: ${z()||"none"} (gallery block list says each).`);let n;try{n=q(e,o)}catch(s){if(s.code!=="changed")throw s;console.error(`${w(s.folder)} was changed after gallery block add put it there (or another hand put it there), so it is not replaced: to keep those changes, make a block of your own from Gallery's with gallery block new <id> --recipe ${u(o)} and move them into it; to take Gallery's ${o.version}, delete the folder and run gallery block add ${u(o)} again.`),process.exit(1)}let a=o.places.includes("document")?`a document can write it now (gallery block show ${o.id} says how)`:"custom pages can place it now";n.did==="same"?console.log(`${o.id} ${o.version} is in already, as Gallery ships it: ${w(n.folder)}`):n.did==="updated"?console.log(`Updated ${o.id} from ${n.from??"an older version"} to ${o.version}: ${w(n.folder)}`):console.log(`Added ${o.id} ${o.version}: ${w(n.folder)}`),n.did!=="same"&&console.log(`It is Gallery's, as it ships: no check or try is needed, and ${a}. Change nothing in its folder, or gallery block add will not update it again: for a block like it of your own, gallery block new <id> --recipe ${u(o)}.`)}var k=({zh:e,en:t})=>e===t?e:`${e} / ${t}`;function Ke(e){if(B(e))return null;let t=_(e);return t?C("en",t):"it has no template.html"}var Je={disabled:"disabled by the user: its instances show as they stand, no script and no style"},I=e=>e?.length?` \u8981\u7528\uFF1A${e.join(", ")}`:"";function ae(e,{id:t,name:o,version:n,description:a,state:s,needs:l},r){console.log(`${t} ${k(o)}`);let h=(e.settings.packsOff??[]).includes(t.split("/")[0])?`available; its pack ${t.split("/")[0]} is switched off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868, so no menu or library offers it, and a document can still write it`:r==="document"&&s==="hidden"?"available; not in the document's menus, by the user's switch, and a document can still write it":"available";console.log(` \u7248\u672C\uFF1A${n}\uFF08${h}\uFF09`),console.log(` \u8BF4\u660E\uFF1A${k(a)}`),I(l)&&console.log(I(l));let f=r==="document"&&Ke(e.packages.get(t));f&&console.log(` \u6A21\u677F\uFF1Athe menus cannot insert it, and a document can still write it: ${f}`)}function Te(e){let t=S(e),o=j(t),n=o.filter(({reason:i})=>i),a=o.filter(({reason:i})=>!i),s=a.filter(({state:i})=>i!=="disabled"),l=s.filter(({places:i})=>i.includes("document")),r=s.filter(({places:i})=>i.includes("page")),m=le(e),h=G().map(i=>({block:i,state:U(e,i)})).filter(({block:i,state:p})=>!p.added||p.behind||p.changed&&Y(i.version,p.version)),f=$e(t.settings.hidden);if(console.log(`\u5DE5\u4F5C\u533A\uFF1A${w(e)}`),a.length+n.length+m.length===0)console.log("No custom blocks yet. A document is written with Gallery's blocks and whole blocks; gallery block add <name> puts one of Gallery's own in (below), and gallery block new <id> starts one when the user wants a block to use again.");else{console.log(l.length?`\u6587\u6863\u91CC\u53EF\u7528 (in documents: ${l.length}; gallery block show <id> says how to write each):`:"\u6587\u6863\u91CC\u53EF\u7528 (in documents): none now.");for(let p of l)ae(t,p,"document");console.log(r.length?`\u81EA\u5B9A\u4E49\u9875\u53EF\u7528 (on custom pages: ${r.length}):`:"\u81EA\u5B9A\u4E49\u9875\u53EF\u7528 (on custom pages): none now.");for(let p of r)p.places.includes("document")?console.log(`${p.id} ${k(p.name)} (above: in documents too)`):ae(t,p,"page");let i=a.filter(({state:p})=>p==="disabled");i.length+n.length+m.length>0&&console.log("Not to use now:");for(let{id:p,name:c,version:y,state:O}of i)console.log(`${p} ${k(c)} ${y} ${Je[O]}`);for(let{id:p,reason:c,version:y}of n)console.log(`${p}${y?` ${y}`:""} does not load: ${c.en}`);for(let p of m)console.log(ce(p))}h.length&&console.log("Gallery's own blocks, to add as they are (no check or try needed):");for(let{block:i,state:p}of h){let c=i.places.map(y=>y==="document"?"documents":"custom pages").join(" and ");console.log(`${i.id} ${k(i.title)} ${i.version} (${c})`),console.log(` \u8BF4\u660E\uFF1A${k(i.description)}`),p.changed?console.log(` the workspace's copy (${p.version??"no version"}) was changed after it was added, so it is not updated: to take Gallery's ${i.version}, delete ${w(M(e,i.id))} and run gallery block add ${u(i)} (to keep the changes, gallery block new <id> --recipe ${u(i)} and move them into it)`):console.log(p.added?` gallery block add ${u(i)} (the workspace has ${p.version??"an older one"}: this updates it)`:` gallery block add ${u(i)}`)}f.length&&console.log(`Built-in blocks the user took out of the document's menus (a document can still write them): ${f.join(", ")}`)}var De=(e,{at:t,edit:o,optional:n,min:a,max:s})=>{let l=[n?"optional":"",a!==void 0?`at least ${a}`:"",s!==void 0?`at most ${s}`:""].filter(Boolean),r=o==="flow"?`${Ee}="${e}"`:t;return` ${e} ${r} ${o==="flow"?"flow (blocks of the document: write any block in it)":o}${l.length?` (${l.join(", ")})`:""}`};function de(e,t,o){console.log(`${t} ${k(e.name)}`),console.log(` \u7248\u672C\uFF1A${e.version}\uFF08${o}\uFF09`),console.log(` \u8BF4\u660E\uFF1A${k(e.description)}`),console.log(` \u7528\u5728\uFF1A${e.places.map(l=>l==="document"?"documents":"custom pages").join(", ")}`),I(e.needs)&&console.log(I(e.needs)),console.log(` ${w(e.folder)}`);let n=Object.entries(e.parts);console.log(n.length?"Parts (edit text: the user types there; flow: blocks of the document; none, or data: the component's):":"No parts.");for(let[l,r]of n)console.log(De(l,r));let a=K(e,"writing.md")?.trimEnd();console.log(a?`How to write it (writing.md):
169
169
  ${a}`:"How to write it: the block has no writing.md.");let s=K(e,"example.html")?.trimEnd();console.log(s?`The example (example.html):
170
- ${s}`:"The example: the block has no example.html.")}function Me(e,t){let o=S(e),n=o.problems.get(t),a=o.packages.get(t)??(n?.off?n:void 0);if(!a){let r=n?.problem,m=!r&&E(t)?$(t):null;if(m)return Fe(m);console.error(r?`${t} does not load: ${C("en",r)}`:Ce(e,t)),process.exit(1)}let{state:s}=j(o).find(r=>r.id===t),l={normal:"available",hidden:"available; not in the document's menus, by the user's switch",disabled:"disabled by the user"}[s]??s;de(a,t,l),console.log("In a document: write the element as the example does, straight in the page or a section, with no data-block-id, which the export gives it.")}async function ze(e,t,o,{remove:n}){let a=Se(e);if(t===void 0){let s=[...new Set(j(S(e)).flatMap(({needs:m})=>Oe(m??[])))],l=Object.keys(a).sort();console.log(l.length?`Keys kept (.gallery/keys.json), by host: ${l.join(", ")}.`:"No key kept (.gallery/keys.json holds none).");let r=s.filter(m=>!l.includes(m)).sort();r.length&&console.log(`Hosts the workspace's blocks reach with no key: ${r.join(", ")} (a key is needed only where a block's address names {key}).`);return}if(!Ne.test(t))throw new d(`Not a host a block's needs can name: ${t} (a lowercase name, no scheme, port or path; *. before it for the names under it).`);if(n){if(o!==void 0)throw new d("gallery block key <host> --remove takes no key.");return t in a?(await se(e,t,null),console.log(`Took away the key for ${t}. A block's address that names {key} on it is refused (code "key") until one is kept again.`)):console.log(`No key kept for ${t}: nothing to take away.`)}if(o===void 0)return console.log(t in a?`A key is kept for ${t} (never printed): an address on it that names {key} is fetched with it.`:`No key kept for ${t}: gallery block key ${t} <key> keeps one.`);if(!o.trim()||/[\r\n]/.test(o))throw new d("A key is one line of characters, not empty.");await se(e,t,o),console.log(`Kept the key for ${t} in ${w(A(e).keys)}, which no page, export or cache holds: Gallery writes it where a block's address on ${t} names {key}, as it fetches for the block. Never write the key into a block's files or a page: they are shown and exported.`)}function Fe(e){let t=JSON.parse(v.readFileSync(N.join(e.folder,ie),"utf8"));de({name:e.title,description:e.description,version:e.version,places:e.places,needs:t.needs,folder:e.folder,parts:t.parts??{}},e.id,"Gallery's own, not in this workspace yet");let o=e.places.includes("document")?", and a document writes it as the example above does, straight in the page or a section, with no data-block-id, which the export gives it":`, and gallery page add <slug> ${u(e)} puts a card of it on a custom page`;console.log(`Not in this workspace yet: gallery block add ${u(e)} puts it in as it ships (no check, no try)${o}.`)}var he=e=>be("en",()=>ve(e))??e.message,J=(e,t)=>t.length?[` ${e}: ${t.join(", ")}`]:[];function We(e,t){let o;try{o=X(e,te(t))}catch(a){if(!a.code)throw a;console.error(`Not installed: ${he(a)}`),process.exit(1)}let n=o.added.length+o.updated.length+o.same.length+o.kept.length;o.from===null?console.log(`Installed the pack ${o.id} ${o.version} (${k(o.name)}), ${n} block${n===1?"":"s"}: ${w(o.folder)}`):o.did==="updated"?console.log(`Updated the pack ${o.id} from ${o.from??"an older version"} to ${o.version}: ${w(o.folder)}`):console.log(`The pack ${o.id} ${o.version} is in already, as installed: ${w(o.folder)}`);for(let a of[...J("added",o.added),...o.did==="updated"?J("updated",o.updated):[],...J("taken out (not in this version)",o.removed)])console.log(a);o.kept.length&&console.log(` kept as they are, changed since they were installed: ${o.kept.join(", ")} (to take this version's, delete the block's folder and install the pack again)`),o.ownKept&&console.log(" its pack.json was changed since it was installed, and is kept as it is"),console.log(`Its blocks are offered in "/" and \u6DFB\u52A0\u81EA\u5B9A\u4E49\u5757 while its switch in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868 is on (gallery block pack list says each pack's); gallery block list says each block.`)}function D(e){let t=Z(e);console.log(`\u5DE5\u4F5C\u533A\uFF1A${w(e)}`);let o={default:"the default pack, where a block made with no pack named goes",official:"Gallery's own",installed:"a pack installed",own:"the workspace's own blocks, no pack.json"};for(let n of t){let a=[n.version?`${n.id} ${n.version}`:n.id,o[n.kind],n.enabled?"on":"off",`${n.blocks} block${n.blocks===1?"":"s"}`,...n.author?[`by ${n.author}`]:[]];console.log(`${k(n.name)} (${a.join(", ")})`),n.description&&console.log(` \u8BF4\u660E\uFF1A${k(n.description)}`),n.problem&&console.log(` its pack.json does not read: ${n.problem.en}`),n.changed.length&&console.log(` changed since it was installed: ${n.changed.join(", ")}${n.newer?` (Gallery's is ${n.newer}, not put over them)`:""}`)}t.every(({kind:n})=>n==="default")&&console.log("No other block packs: gallery block pack install <folder|zip> installs one.")}function _e(e,t){if(!xe.test(t))throw new d(`Not a pack's id: ${t} (lowercase letters, digits and hyphens: gallery block pack list says each).`);let o;try{o=Q(e,t)}catch(n){if(!n.code)throw n;console.error(`Not removed: ${he(n)}`),process.exit(1)}console.log(`Removed the pack ${o.id}${o.version?` ${o.version}`:""} (${o.blocks.length} block${o.blocks.length===1?"":"s"}): what documents and pages hold of its blocks stays, shown as blocks that are not there.`)}var T={install:We,list:D,remove:_e};function Be(e,t,o){if(!t)throw new d("Say what to do with packs: install <folder|zip>, list, remove <pack>.");if(!Object.hasOwn(T,t))throw new d(`No such pack command: ${t} (install, list, remove).`);if(T[t]===D){if(o.length)throw new d("gallery block pack list takes nothing else.");return D(e)}if(o.length!==1)throw new d(t==="install"?"gallery block pack install takes one folder or zip: gallery block pack install <folder|zip>.":"gallery block pack remove takes one pack's id: gallery block pack remove <pack>.");return T[t](e,o[0])}var g={new:(e,t,o)=>Ge(e,t,o),add:Pe,list:Te,show:Me,check:async(e,t,{documents:o})=>(await import("./chunk-NHP66IWR.mjs")).checkCommand(e,t,{documents:o}),try:async(e,t)=>(await import("./chunk-7ISBBDJR.mjs")).tryCommand(e,t),key:ze,pack:Be},He=["--press","--drag","--to","--key","--type","--select","--then","--steps"],Le={"--key":"--key takes a selector and a key: --key <selector> <key> (Enter, Space, ArrowRight, a letter, Shift+Tab).","--type":"--type takes a selector and the words to type: --type <selector> <words> (quoted when they hold a blank).","--select":"--select takes a selector and an option: --select <selector> <value> (the option's value or its words)."};function pe(e){let t=e.indexOf("--"),o=new Set,n={};for(let[a,s]of Object.entries(Le)){let l=(t===-1?e:e.slice(0,t)).findIndex(h=>h===a||h.startsWith(`${a}=`));if(l===-1)continue;let r=l+(e[l].includes("=")?1:2),m=e[r];if(m===void 0||r===t||P(m)||o.has(r))throw new d(s);o.add(r),n[a]=m}return{argv:e.filter((a,s)=>!o.has(s)),seconds:n}}function pt(e){let{argv:t,seconds:o}=pe(e);return{argv:t,key:o["--key"]??null}}async function mt(e,{workspace:t}){try{return await Re(e,t)}catch(o){let n=e.find(a=>!P(a));throw o instanceof d&&n==="try"&&(o.synopsis=F),o instanceof d&&n==="pack"&&(o.synopsis=W),o}}async function Re(e,t){let{argv:o,seconds:n}=pe(e),{positional:a,options:s,values:l}=ee({options:["--script","--flow","--data","--page","--keep","--documents","--replace","--remove"],values:[...He,"--recipe"],argv:o}),r=l.get("--recipe"),m=new Map([...l].filter(([b])=>b!=="--recipe")),[h,f,...i]=a,p=Object.keys(g).join(", ");if(!h)throw new d(`Say what to do: ${p}.`);if(!Object.hasOwn(g,h))throw new d(`No such block command: ${h} (${p}).`);let c=g[h];for(let b of["--script","--flow","--data","--page"])if(s.has(b)&&c!==g.new)throw new d(`${b} goes with new, not ${h}.`);if(s.has("--documents")&&c!==g.check)throw new d(`--documents goes with check, not ${h}.`);if(s.has("--remove")&&c!==g.key)throw new d(`--remove goes with key, not ${h}.`);if(r!==void 0&&c!==g.new)throw new d(`--recipe goes with new, not ${h}.`);let y=["--script","--flow","--data","--page"].filter(b=>s.has(b));if(r!==void 0&&y.length)throw new d(`--recipe makes a block of what Gallery's ${r} holds: ${y[0]} goes with a new block of none.${y[0]==="--page"&&$(r)?.places.includes("page")?` ${r} already is a card for a custom page (its places hold page): leave --page out.`:""}`);if(s.has("--flow")&&s.has("--data"))throw new d("--flow and --data do not go together: --flow is a slot for blocks of the document's own, --data a list of lines a reader keeps in the block's JSON. Make the one you need with new, and add the other by hand.");if(s.has("--flow")&&s.has("--page"))throw new d("--flow and --page do not go together: a custom page renders no document's blocks, so a block for a page has no slot.");let O=[...m.keys(),...Object.keys(n).filter(b=>!m.has(b)),...s.has("--keep")?["--keep"]:[],...s.has("--replace")?["--replace"]:[]];if(c===g.try)return c(t,{named:a.slice(1),values:m,seconds:n,keep:s.has("--keep"),replace:s.has("--replace")});if(O.length)throw new d(`${O[0]} goes with try, not ${h}.`);if(c===g.list){if(f!==void 0)throw new d(`gallery block ${h} takes nothing else.`);return c(t)}if(c===g.pack)return c(t,f,i);if(c===g.key){if(i.length>1)throw new d("gallery block key takes a host and its key: gallery block key <host> <key>.");return c(t,f,i[0],{remove:s.has("--remove")})}if(c===g.add){if(f===void 0||i.length>0)throw new d(`gallery block add takes one name of Gallery's own blocks: ${z()}.`);return c(t,f)}if(f===void 0||i.length>0)throw new d(`gallery block ${h} takes one id.`);let me=c===g.show||c===g.check?Ie(t,f):re(f);return c(t,me,{script:s.has("--script"),flow:s.has("--flow"),data:s.has("--data"),page:s.has("--page"),documents:s.has("--documents"),recipe:r})}export{re as a,Ie as b,M as c,u as d,ce as e,Ce as f,He as g,pe as h,pt as i,mt as j};
170
+ ${s}`:"The example: the block has no example.html.")}function Me(e,t){let o=S(e),n=o.problems.get(t),a=o.packages.get(t)??(n?.off?n:void 0);if(!a){let r=n?.problem,m=!r&&E(t)?$(t):null;if(m)return Fe(m);console.error(r?`${t} does not load: ${C("en",r)}`:Ce(e,t)),process.exit(1)}let{state:s}=j(o).find(r=>r.id===t),l={normal:"available",hidden:"available; not in the document's menus, by the user's switch",disabled:"disabled by the user"}[s]??s;de(a,t,l),console.log("In a document: write the element as the example does, straight in the page or a section, with no data-block-id, which the export gives it.")}async function ze(e,t,o,{remove:n}){let a=Se(e);if(t===void 0){let s=[...new Set(j(S(e)).flatMap(({needs:m})=>Oe(m??[])))],l=Object.keys(a).sort();console.log(l.length?`Keys kept (.gallery/keys.json), by host: ${l.join(", ")}.`:"No key kept (.gallery/keys.json holds none).");let r=s.filter(m=>!l.includes(m)).sort();r.length&&console.log(`Hosts the workspace's blocks reach with no key: ${r.join(", ")} (a key is needed only where a block's address names {key}).`);return}if(!Ne.test(t))throw new d(`Not a host a block's needs can name: ${t} (a lowercase name, no scheme, port or path; *. before it for the names under it).`);if(n){if(o!==void 0)throw new d("gallery block key <host> --remove takes no key.");return t in a?(await se(e,t,null),console.log(`Took away the key for ${t}. A block's address that names {key} on it is refused (code "key") until one is kept again.`)):console.log(`No key kept for ${t}: nothing to take away.`)}if(o===void 0)return console.log(t in a?`A key is kept for ${t} (never printed): an address on it that names {key} is fetched with it.`:`No key kept for ${t}: gallery block key ${t} <key> keeps one.`);if(!o.trim()||/[\r\n]/.test(o))throw new d("A key is one line of characters, not empty.");await se(e,t,o),console.log(`Kept the key for ${t} in ${w(A(e).keys)}, which no page, export or cache holds: Gallery writes it where a block's address on ${t} names {key}, as it fetches for the block. Never write the key into a block's files or a page: they are shown and exported.`)}function Fe(e){let t=JSON.parse(v.readFileSync(N.join(e.folder,ie),"utf8"));de({name:e.title,description:e.description,version:e.version,places:e.places,needs:t.needs,folder:e.folder,parts:t.parts??{}},e.id,"Gallery's own, not in this workspace yet");let o=e.places.includes("document")?", and a document writes it as the example above does, straight in the page or a section, with no data-block-id, which the export gives it":`, and gallery page add <slug> ${u(e)} puts a card of it on a custom page`;console.log(`Not in this workspace yet: gallery block add ${u(e)} puts it in as it ships (no check, no try)${o}.`)}var he=e=>be("en",()=>ve(e))??e.message,J=(e,t)=>t.length?[` ${e}: ${t.join(", ")}`]:[];function We(e,t){let o;try{o=X(e,te(t))}catch(a){if(!a.code)throw a;console.error(`Not installed: ${he(a)}`),process.exit(1)}let n=o.added.length+o.updated.length+o.same.length+o.kept.length;o.from===null?console.log(`Installed the pack ${o.id} ${o.version} (${k(o.name)}), ${n} block${n===1?"":"s"}: ${w(o.folder)}`):o.did==="updated"?console.log(`Updated the pack ${o.id} from ${o.from??"an older version"} to ${o.version}: ${w(o.folder)}`):console.log(`The pack ${o.id} ${o.version} is in already, as installed: ${w(o.folder)}`);for(let a of[...J("added",o.added),...o.did==="updated"?J("updated",o.updated):[],...J("taken out (not in this version)",o.removed)])console.log(a);o.kept.length&&console.log(` kept as they are, changed since they were installed: ${o.kept.join(", ")} (to take this version's, delete the block's folder and install the pack again)`),o.ownKept&&console.log(" its pack.json was changed since it was installed, and is kept as it is"),console.log(`Its blocks are offered in "/" and \u6DFB\u52A0\u81EA\u5B9A\u4E49\u5757 while its switch in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868 is on (gallery block pack list says each pack's); gallery block list says each block.`)}function D(e){let t=Z(e);console.log(`\u5DE5\u4F5C\u533A\uFF1A${w(e)}`);let o={default:"the default pack, where a block made with no pack named goes",official:"Gallery's own",installed:"a pack installed",own:"the workspace's own blocks, no pack.json"};for(let n of t){let a=[n.version?`${n.id} ${n.version}`:n.id,o[n.kind],n.enabled?"on":"off",`${n.blocks} block${n.blocks===1?"":"s"}`,...n.author?[`by ${n.author}`]:[]];console.log(`${k(n.name)} (${a.join(", ")})`),n.description&&console.log(` \u8BF4\u660E\uFF1A${k(n.description)}`),n.problem&&console.log(` its pack.json does not read: ${n.problem.en}`),n.changed.length&&console.log(` changed since it was installed: ${n.changed.join(", ")}${n.newer?` (Gallery's is ${n.newer}, not put over them)`:""}`)}t.every(({kind:n})=>n==="default")&&console.log("No other block packs: gallery block pack install <folder|zip> installs one.")}function _e(e,t){if(!xe.test(t))throw new d(`Not a pack's id: ${t} (lowercase letters, digits and hyphens: gallery block pack list says each).`);let o;try{o=Q(e,t)}catch(n){if(!n.code)throw n;console.error(`Not removed: ${he(n)}`),process.exit(1)}console.log(`Removed the pack ${o.id}${o.version?` ${o.version}`:""} (${o.blocks.length} block${o.blocks.length===1?"":"s"}): what documents and pages hold of its blocks stays, shown as blocks that are not there.`)}var T={install:We,list:D,remove:_e};function Be(e,t,o){if(!t)throw new d("Say what to do with packs: install <folder|zip>, list, remove <pack>.");if(!Object.hasOwn(T,t))throw new d(`No such pack command: ${t} (install, list, remove).`);if(T[t]===D){if(o.length)throw new d("gallery block pack list takes nothing else.");return D(e)}if(o.length!==1)throw new d(t==="install"?"gallery block pack install takes one folder or zip: gallery block pack install <folder|zip>.":"gallery block pack remove takes one pack's id: gallery block pack remove <pack>.");return T[t](e,o[0])}var g={new:(e,t,o)=>Ge(e,t,o),add:Pe,list:Te,show:Me,check:async(e,t,{documents:o})=>(await import("./chunk-LCB6MARS.mjs")).checkCommand(e,t,{documents:o}),try:async(e,t)=>(await import("./chunk-ZMHUDYLV.mjs")).tryCommand(e,t),key:ze,pack:Be},He=["--press","--drag","--to","--key","--type","--select","--then","--steps"],Le={"--key":"--key takes a selector and a key: --key <selector> <key> (Enter, Space, ArrowRight, a letter, Shift+Tab).","--type":"--type takes a selector and the words to type: --type <selector> <words> (quoted when they hold a blank).","--select":"--select takes a selector and an option: --select <selector> <value> (the option's value or its words)."};function pe(e){let t=e.indexOf("--"),o=new Set,n={};for(let[a,s]of Object.entries(Le)){let l=(t===-1?e:e.slice(0,t)).findIndex(h=>h===a||h.startsWith(`${a}=`));if(l===-1)continue;let r=l+(e[l].includes("=")?1:2),m=e[r];if(m===void 0||r===t||P(m)||o.has(r))throw new d(s);o.add(r),n[a]=m}return{argv:e.filter((a,s)=>!o.has(s)),seconds:n}}function pt(e){let{argv:t,seconds:o}=pe(e);return{argv:t,key:o["--key"]??null}}async function mt(e,{workspace:t}){try{return await Re(e,t)}catch(o){let n=e.find(a=>!P(a));throw o instanceof d&&n==="try"&&(o.synopsis=F),o instanceof d&&n==="pack"&&(o.synopsis=W),o}}async function Re(e,t){let{argv:o,seconds:n}=pe(e),{positional:a,options:s,values:l}=ee({options:["--script","--flow","--data","--page","--keep","--documents","--replace","--remove"],values:[...He,"--recipe"],argv:o}),r=l.get("--recipe"),m=new Map([...l].filter(([b])=>b!=="--recipe")),[h,f,...i]=a,p=Object.keys(g).join(", ");if(!h)throw new d(`Say what to do: ${p}.`);if(!Object.hasOwn(g,h))throw new d(`No such block command: ${h} (${p}).`);let c=g[h];for(let b of["--script","--flow","--data","--page"])if(s.has(b)&&c!==g.new)throw new d(`${b} goes with new, not ${h}.`);if(s.has("--documents")&&c!==g.check)throw new d(`--documents goes with check, not ${h}.`);if(s.has("--remove")&&c!==g.key)throw new d(`--remove goes with key, not ${h}.`);if(r!==void 0&&c!==g.new)throw new d(`--recipe goes with new, not ${h}.`);let y=["--script","--flow","--data","--page"].filter(b=>s.has(b));if(r!==void 0&&y.length)throw new d(`--recipe makes a block of what Gallery's ${r} holds: ${y[0]} goes with a new block of none.${y[0]==="--page"&&$(r)?.places.includes("page")?` ${r} already is a card for a custom page (its places hold page): leave --page out.`:""}`);if(s.has("--flow")&&s.has("--data"))throw new d("--flow and --data do not go together: --flow is a slot for blocks of the document's own, --data a list of lines a reader keeps in the block's JSON. Make the one you need with new, and add the other by hand.");if(s.has("--flow")&&s.has("--page"))throw new d("--flow and --page do not go together: a custom page renders no document's blocks, so a block for a page has no slot.");let O=[...m.keys(),...Object.keys(n).filter(b=>!m.has(b)),...s.has("--keep")?["--keep"]:[],...s.has("--replace")?["--replace"]:[]];if(c===g.try)return c(t,{named:a.slice(1),values:m,seconds:n,keep:s.has("--keep"),replace:s.has("--replace")});if(O.length)throw new d(`${O[0]} goes with try, not ${h}.`);if(c===g.list){if(f!==void 0)throw new d(`gallery block ${h} takes nothing else.`);return c(t)}if(c===g.pack)return c(t,f,i);if(c===g.key){if(i.length>1)throw new d("gallery block key takes a host and its key: gallery block key <host> <key>.");return c(t,f,i[0],{remove:s.has("--remove")})}if(c===g.add){if(f===void 0||i.length>0)throw new d(`gallery block add takes one name of Gallery's own blocks: ${z()}.`);return c(t,f)}if(f===void 0||i.length>0)throw new d(`gallery block ${h} takes one id.`);let me=c===g.show||c===g.check?Ie(t,f):re(f);return c(t,me,{script:s.has("--script"),flow:s.has("--flow"),data:s.has("--data"),page:s.has("--page"),documents:s.has("--documents"),recipe:r})}export{re as a,Ie as b,M as c,u as d,ce as e,Ce as f,He as g,pe as h,pt as i,mt as j};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{a as y,b as C}from"./chunk-Q4UEPUWF.mjs";import{a as A}from"./chunk-FFV733MA.mjs";import{c as P,d as W}from"./chunk-WFGPMCTZ.mjs";import"./chunk-7UZUQQ7Q.mjs";import"./chunk-4B2TB5K2.mjs";import"./chunk-KLQP46Y3.mjs";import{b as j,f as M}from"./chunk-4OZWXZE5.mjs";import"./chunk-E7656LR7.mjs";import"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";import{randomBytes as R}from"node:crypto";import{existsSync as X,readdirSync as G,readFileSync as Y,statSync as _}from"node:fs";import c from"node:fs/promises";import q from"node:os";import i from"node:path";import{release as J,reportsDirectory as V,skillDirectory as H}from"../browser/shared/paths.mjs";import{copyOldDocuments as Q,ensureWorkspace as Z,layoutOf as z,oldStateOf as K}from"../browser/shared/workspace.mjs";var S=o=>_(o,{throwIfNoEntry:!1})?.isDirectory()??!1;function ee({agent:o=null,project:e=!1,dir:r=null,cwd:t=process.cwd(),env:s=process.env}={}){if(r)return[{agent:null,target:i.resolve(t,r),skills:null}];let a=o?[o]:Object.keys(y),u=d=>e?i.join(i.resolve(t),y[d].project):i.resolve(y[d].home(s)),p=a.filter(d=>S(u(d)));return(o||p.length?o?a:p:["claude"]).map(d=>{let h=i.join(u(d),"skills");return{agent:d,target:i.join(h,"gallery"),skills:h}})}function te(o){try{return C(Y(i.join(o,"SKILL.md"),"utf8"))}catch{return null}}function T(o){let e=_(o,{throwIfNoEntry:!1});if(!e)return{kind:"absent"};if(!e.isDirectory())return{kind:"other",why:"it is a file"};let r=G(o);if(r.length===0)return{kind:"absent"};if(r.includes(".git"))return{kind:"other",why:"it is a git checkout"};let t=te(o),s=u=>r.includes(u);return(s("package.json")&&s("src")||s("reports"))&&(t==="gallery"||t==="html-report-studio")?{kind:"fat",name:t}:t==="gallery"&&!s("package.json")&&!s("src")&&!s("reports")?{kind:"thin"}:{kind:"other",why:t?`its SKILL.md is the skill "${t}"`:"it holds no Gallery skill"}}function oe(o){return S(o)?G(o,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.name.startsWith(".")).map(e=>i.join(o,e.name)).filter(e=>T(e).kind==="fat"):[]}function re(o){let e=i.join(K(o),"servers");return S(e)?G(e).filter(r=>r.endsWith(".json")).flatMap(r=>{try{let{pid:t,port:s}=JSON.parse(Y(i.join(e,r),"utf8"));return!Number.isInteger(t)||t<=0||t===process.pid?[]:(process.kill(t,0),[{pid:t,port:s}])}catch(t){return t.code==="EPERM"?[{pid:Number.NaN,port:null}]:[]}}):[]}async function O(o){let e=0,r=0,t=async s=>{for(let a of await c.readdir(s,{withFileTypes:!0})){let u=i.join(s,a.name);a.isDirectory()?await t(u):(e++,r+=(await c.lstat(u)).size)}};return await t(o).catch(()=>{}),{files:e,bytes:r}}var B=o=>`${(o/1024/1024).toFixed(1)} MB`,se=(o,e)=>`${o} ${e}${o===1?"":"s"}`;async function v(o,e){for(let r=0;;r++)try{return await c.rename(o,e)}catch(t){if(process.platform!=="win32"||r>=10||!["EPERM","EBUSY","EACCES"].includes(t.code))throw t;await new Promise(s=>setTimeout(s,100*(r+1)))}}function ne(o,e=new Date){let r=`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`,t=i.join(z(o).gallery,`old-skill-${r}`);for(let s=1;;s++){let a=s===1?t:`${t}-${s}`;if(!X(a))return a}}async function ie(o,e){await c.mkdir(i.dirname(e),{recursive:!0});try{return await v(o,e),null}catch(s){if(s.code!=="EXDEV")return`${s.code??s.message}`}let r=await O(o);await c.cp(o,e,{recursive:!0,preserveTimestamps:!0,verbatimSymlinks:!0,errorOnExist:!0,force:!1});let t=await O(e);return t.files!==r.files||t.bytes!==r.bytes?`the copy holds ${t.files} files, ${t.bytes} bytes, of ${r.files}, ${r.bytes}: the old folder was left as it was`:(await c.rm(o,{recursive:!0,force:!0}),null)}async function U(o){let e=[],r=async t=>{for(let s of await c.readdir(t,{withFileTypes:!0})){let a=i.join(t,s.name);s.isDirectory()?await r(a):e.push([i.relative(o,a).split(i.sep).join("/"),await c.readFile(a)])}};return await r(o),e.sort(([t],[s])=>t<s?-1:t>s?1:0)}var le=(o,e)=>o.length===e.length&&o.every(([r,t],s)=>r===e[s][0]&&t.equals(e[s][1]));async function ae(o,e,r){if(r==="thin"&&le(await U(o),await U(e)))return"same";let t=i.dirname(e);await c.mkdir(t,{recursive:!0});let s=R(4).toString("hex"),a=i.join(t,`.gallery-skill-new-${s}`);if(await c.cp(o,a,{recursive:!0}),r==="absent")return X(e)&&await c.rmdir(e),await v(a,e),"new";let u=i.join(t,`.gallery-skill-old-${s}`);await v(e,u);try{await v(a,e)}catch(p){throw await v(u,e).catch(()=>{}),await c.rm(a,{recursive:!0,force:!0}),p}return await c.rm(u,{recursive:!0,force:!0}),"updated"}async function $e(o,{version:e}){let{positional:r,options:t,values:s}=M({options:["--project"],values:["--agent","--dir"],argv:o});if(r[0]!=="install")throw new j(r.length?`No such skill command: ${r[0]} (install).`:"Say what to do: gallery skill install.");if(r.length>1)throw new j(`gallery skill install takes no other argument: ${r[1]}`);let a=s.get("--agent")??null;if(a!==null&&!Object.hasOwn(y,a))throw new j(`--agent is claude or codex, not ${a}.`);let u=s.get("--dir")??null;if(u!==null&&(a!==null||t.has("--project")))throw new j("--dir names the skill's folder itself: not with --agent or --project.");let p=ee({agent:a,project:t.has("--project"),dir:u}),d=[],h=p.map(n=>({...n,...T(n.target)}));for(let{target:n,kind:l,why:f}of h)l==="other"&&d.push(`${n} holds something that is not a Gallery skill (${f}): move it away, or pass --dir <another folder>.`);let N=[...new Set(h.flatMap(({target:n,kind:l,skills:f})=>[...l==="fat"?[n]:[],...f?oe(f):[]]))];for(let n of N)for(let{pid:l,port:f}of re(n))d.push(Number.isNaN(l)?`The older Gallery skill ${n} has a preview server running that this user cannot see: stop it first.`:`The older Gallery skill ${n} has its preview server running (pid ${l}${f?`, port ${f}`:""}): stop it first (close the window that runs it, or end process ${l}), then run gallery skill install again.`);if(d.length){for(let n of d)console.error(n);console.error("Nothing was changed."),process.exit(1)}if(N.length){let n=V;try{let{ours:l,reads:f}=await Z(n);l||(console.error(W(n,f)),process.exit(1))}catch(l){if(!l.code)throw l;console.error(P(n,l.code)),process.exit(1)}console.log(`\u5DE5\u4F5C\u533A\uFF1A${n}`);for(let l of N){console.log(`An older Gallery skill (the whole tools) is in ${l}: its documents go into the workspace, then it moves out of the skills folder.`);let f=i.join(l,"reports");if(S(f)){let m=await Q({from:f,to:n,state:K(l)});for(let w of A(m,f,n))console.log(` ${w}`)}else console.log(" It holds no documents (no reports/ folder).");let g=i.join(l,"exports");if(S(g)){let m=z(n).exports;await c.mkdir(m,{recursive:!0});let w=[],I=[];for(let E of(await c.readdir(g)).filter(x=>x.endsWith(".html")).sort())try{await c.copyFile(i.join(g,E),i.join(m,E),c.constants.COPYFILE_EXCL),w.push(E)}catch(x){if(x.code!=="EEXIST")throw x;I.push(E)}w.length&&console.log(` Exports: copied ${se(w.length,"file")} into ${m}: ${w.join(", ")}`),I.length&&console.log(` Exports not copied (the name is taken in ${m}; they stay in the moved folder's exports/): ${I.join(", ")}`)}let{bytes:k}=await O(l),$=await O(i.join(l,"node_modules")),D=ne(n),L=await ie(l,D);L&&(console.error(`Could not move ${l} to ${D} (${L}). Its documents are copied; move the folder out of the skills folder yourself (it is never needed in it again), then run gallery skill install again.`),process.exit(1)),console.log(` Moved the old skill to ${D} (${B(k)}${$.files?`; its node_modules/, ${B($.bytes)}, may be deleted: nothing reads it any more`:""}).`)}}let F=H,b=null;if(!J){let{buildSkill:n}=await import("./chunk-UGWMMEJ5.mjs");b=await c.mkdtemp(i.join(q.tmpdir(),"gallery-skill-")),F=i.join(b,"gallery"),n(F,{version:e})}try{let n=!1;for(let{agent:l,target:f}of h){let g=T(f).kind,k=await ae(F,f,g),$=l?` for ${y[l].name}`:"";console.log(k==="same"?`The Gallery skill ${e}${$} is installed already, unchanged: ${f}`:`${k==="updated"?"Updated":"Installed"} the Gallery skill ${e}${$}: ${f}`),n||=k!=="same"}n&&console.log("Open a new Agent session to use it.")}finally{b&&await c.rm(b,{recursive:!0,force:!0})}}export{y as AGENTS,T as kindOf,$e as run,ee as targetsOf};
2
+ import{a as y,b as C}from"./chunk-Q4UEPUWF.mjs";import{a as A}from"./chunk-NLDF35P5.mjs";import{c as P,d as W}from"./chunk-L55NOXBE.mjs";import"./chunk-7UZUQQ7Q.mjs";import"./chunk-4B2TB5K2.mjs";import"./chunk-KLQP46Y3.mjs";import{b as j,f as M}from"./chunk-4OZWXZE5.mjs";import"./chunk-E7656LR7.mjs";import"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";import{randomBytes as R}from"node:crypto";import{existsSync as X,readdirSync as G,readFileSync as Y,statSync as _}from"node:fs";import c from"node:fs/promises";import q from"node:os";import i from"node:path";import{release as J,reportsDirectory as V,skillDirectory as H}from"../browser/shared/paths.mjs";import{copyOldDocuments as Q,ensureWorkspace as Z,layoutOf as z,oldStateOf as K}from"../browser/shared/workspace.mjs";var S=o=>_(o,{throwIfNoEntry:!1})?.isDirectory()??!1;function ee({agent:o=null,project:e=!1,dir:r=null,cwd:t=process.cwd(),env:s=process.env}={}){if(r)return[{agent:null,target:i.resolve(t,r),skills:null}];let a=o?[o]:Object.keys(y),u=d=>e?i.join(i.resolve(t),y[d].project):i.resolve(y[d].home(s)),p=a.filter(d=>S(u(d)));return(o||p.length?o?a:p:["claude"]).map(d=>{let h=i.join(u(d),"skills");return{agent:d,target:i.join(h,"gallery"),skills:h}})}function te(o){try{return C(Y(i.join(o,"SKILL.md"),"utf8"))}catch{return null}}function T(o){let e=_(o,{throwIfNoEntry:!1});if(!e)return{kind:"absent"};if(!e.isDirectory())return{kind:"other",why:"it is a file"};let r=G(o);if(r.length===0)return{kind:"absent"};if(r.includes(".git"))return{kind:"other",why:"it is a git checkout"};let t=te(o),s=u=>r.includes(u);return(s("package.json")&&s("src")||s("reports"))&&(t==="gallery"||t==="html-report-studio")?{kind:"fat",name:t}:t==="gallery"&&!s("package.json")&&!s("src")&&!s("reports")?{kind:"thin"}:{kind:"other",why:t?`its SKILL.md is the skill "${t}"`:"it holds no Gallery skill"}}function oe(o){return S(o)?G(o,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.name.startsWith(".")).map(e=>i.join(o,e.name)).filter(e=>T(e).kind==="fat"):[]}function re(o){let e=i.join(K(o),"servers");return S(e)?G(e).filter(r=>r.endsWith(".json")).flatMap(r=>{try{let{pid:t,port:s}=JSON.parse(Y(i.join(e,r),"utf8"));return!Number.isInteger(t)||t<=0||t===process.pid?[]:(process.kill(t,0),[{pid:t,port:s}])}catch(t){return t.code==="EPERM"?[{pid:Number.NaN,port:null}]:[]}}):[]}async function O(o){let e=0,r=0,t=async s=>{for(let a of await c.readdir(s,{withFileTypes:!0})){let u=i.join(s,a.name);a.isDirectory()?await t(u):(e++,r+=(await c.lstat(u)).size)}};return await t(o).catch(()=>{}),{files:e,bytes:r}}var B=o=>`${(o/1024/1024).toFixed(1)} MB`,se=(o,e)=>`${o} ${e}${o===1?"":"s"}`;async function v(o,e){for(let r=0;;r++)try{return await c.rename(o,e)}catch(t){if(process.platform!=="win32"||r>=10||!["EPERM","EBUSY","EACCES"].includes(t.code))throw t;await new Promise(s=>setTimeout(s,100*(r+1)))}}function ne(o,e=new Date){let r=`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`,t=i.join(z(o).gallery,`old-skill-${r}`);for(let s=1;;s++){let a=s===1?t:`${t}-${s}`;if(!X(a))return a}}async function ie(o,e){await c.mkdir(i.dirname(e),{recursive:!0});try{return await v(o,e),null}catch(s){if(s.code!=="EXDEV")return`${s.code??s.message}`}let r=await O(o);await c.cp(o,e,{recursive:!0,preserveTimestamps:!0,verbatimSymlinks:!0,errorOnExist:!0,force:!1});let t=await O(e);return t.files!==r.files||t.bytes!==r.bytes?`the copy holds ${t.files} files, ${t.bytes} bytes, of ${r.files}, ${r.bytes}: the old folder was left as it was`:(await c.rm(o,{recursive:!0,force:!0}),null)}async function U(o){let e=[],r=async t=>{for(let s of await c.readdir(t,{withFileTypes:!0})){let a=i.join(t,s.name);s.isDirectory()?await r(a):e.push([i.relative(o,a).split(i.sep).join("/"),await c.readFile(a)])}};return await r(o),e.sort(([t],[s])=>t<s?-1:t>s?1:0)}var le=(o,e)=>o.length===e.length&&o.every(([r,t],s)=>r===e[s][0]&&t.equals(e[s][1]));async function ae(o,e,r){if(r==="thin"&&le(await U(o),await U(e)))return"same";let t=i.dirname(e);await c.mkdir(t,{recursive:!0});let s=R(4).toString("hex"),a=i.join(t,`.gallery-skill-new-${s}`);if(await c.cp(o,a,{recursive:!0}),r==="absent")return X(e)&&await c.rmdir(e),await v(a,e),"new";let u=i.join(t,`.gallery-skill-old-${s}`);await v(e,u);try{await v(a,e)}catch(p){throw await v(u,e).catch(()=>{}),await c.rm(a,{recursive:!0,force:!0}),p}return await c.rm(u,{recursive:!0,force:!0}),"updated"}async function $e(o,{version:e}){let{positional:r,options:t,values:s}=M({options:["--project"],values:["--agent","--dir"],argv:o});if(r[0]!=="install")throw new j(r.length?`No such skill command: ${r[0]} (install).`:"Say what to do: gallery skill install.");if(r.length>1)throw new j(`gallery skill install takes no other argument: ${r[1]}`);let a=s.get("--agent")??null;if(a!==null&&!Object.hasOwn(y,a))throw new j(`--agent is claude or codex, not ${a}.`);let u=s.get("--dir")??null;if(u!==null&&(a!==null||t.has("--project")))throw new j("--dir names the skill's folder itself: not with --agent or --project.");let p=ee({agent:a,project:t.has("--project"),dir:u}),d=[],h=p.map(n=>({...n,...T(n.target)}));for(let{target:n,kind:l,why:f}of h)l==="other"&&d.push(`${n} holds something that is not a Gallery skill (${f}): move it away, or pass --dir <another folder>.`);let N=[...new Set(h.flatMap(({target:n,kind:l,skills:f})=>[...l==="fat"?[n]:[],...f?oe(f):[]]))];for(let n of N)for(let{pid:l,port:f}of re(n))d.push(Number.isNaN(l)?`The older Gallery skill ${n} has a preview server running that this user cannot see: stop it first.`:`The older Gallery skill ${n} has its preview server running (pid ${l}${f?`, port ${f}`:""}): stop it first (close the window that runs it, or end process ${l}), then run gallery skill install again.`);if(d.length){for(let n of d)console.error(n);console.error("Nothing was changed."),process.exit(1)}if(N.length){let n=V;try{let{ours:l,reads:f}=await Z(n);l||(console.error(W(n,f)),process.exit(1))}catch(l){if(!l.code)throw l;console.error(P(n,l.code)),process.exit(1)}console.log(`\u5DE5\u4F5C\u533A\uFF1A${n}`);for(let l of N){console.log(`An older Gallery skill (the whole tools) is in ${l}: its documents go into the workspace, then it moves out of the skills folder.`);let f=i.join(l,"reports");if(S(f)){let m=await Q({from:f,to:n,state:K(l)});for(let w of A(m,f,n))console.log(` ${w}`)}else console.log(" It holds no documents (no reports/ folder).");let g=i.join(l,"exports");if(S(g)){let m=z(n).exports;await c.mkdir(m,{recursive:!0});let w=[],I=[];for(let E of(await c.readdir(g)).filter(x=>x.endsWith(".html")).sort())try{await c.copyFile(i.join(g,E),i.join(m,E),c.constants.COPYFILE_EXCL),w.push(E)}catch(x){if(x.code!=="EEXIST")throw x;I.push(E)}w.length&&console.log(` Exports: copied ${se(w.length,"file")} into ${m}: ${w.join(", ")}`),I.length&&console.log(` Exports not copied (the name is taken in ${m}; they stay in the moved folder's exports/): ${I.join(", ")}`)}let{bytes:k}=await O(l),$=await O(i.join(l,"node_modules")),D=ne(n),L=await ie(l,D);L&&(console.error(`Could not move ${l} to ${D} (${L}). Its documents are copied; move the folder out of the skills folder yourself (it is never needed in it again), then run gallery skill install again.`),process.exit(1)),console.log(` Moved the old skill to ${D} (${B(k)}${$.files?`; its node_modules/, ${B($.bytes)}, may be deleted: nothing reads it any more`:""}).`)}}let F=H,b=null;if(!J){let{buildSkill:n}=await import("./chunk-UGWMMEJ5.mjs");b=await c.mkdtemp(i.join(q.tmpdir(),"gallery-skill-")),F=i.join(b,"gallery"),n(F,{version:e})}try{let n=!1;for(let{agent:l,target:f}of h){let g=T(f).kind,k=await ae(F,f,g),$=l?` for ${y[l].name}`:"";console.log(k==="same"?`The Gallery skill ${e}${$} is installed already, unchanged: ${f}`:`${k==="updated"?"Updated":"Installed"} the Gallery skill ${e}${$}: ${f}`),n||=k!=="same"}n&&console.log("Open a new Agent session to use it.")}finally{b&&await c.rm(b,{recursive:!0,force:!0})}}export{y as AGENTS,T as kindOf,$e as run,ee as targetsOf};