@heycys/gallery 0.2.2 → 0.2.4

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 (222) hide show
  1. package/README.md +1 -1
  2. package/THIRD-PARTY-NOTICES.md +1 -1
  3. package/assets/preview/runtime.js +156 -0
  4. package/assets/preview/shell.html +107 -0
  5. package/assets/writing-preferences.md +1 -1
  6. package/browser/editor/components/divider/index.mjs +1 -1
  7. package/browser/editor/page/annotate/card.mjs +6 -0
  8. package/browser/editor/page/annotate/index.mjs +22 -2
  9. package/browser/editor/page/columns/index.mjs +1 -1
  10. package/browser/editor/page/conflicts.mjs +1 -1
  11. package/browser/editor/page/drag/index.mjs +1 -1
  12. package/browser/editor/page/editor.mjs +43 -5
  13. package/browser/editor/page/focus.mjs +104 -0
  14. package/browser/editor/page/handle/index.mjs +14 -2
  15. package/browser/editor/page/links/index.mjs +2 -2
  16. package/browser/editor/page/quiet.mjs +3 -3
  17. package/browser/editor/page/resize/index.mjs +1 -1
  18. package/browser/editor/page/session.mjs +4 -1
  19. package/browser/editor/page/ui.mjs +1 -1
  20. package/browser/shared/annotations.mjs +22 -3
  21. package/browser/shared/block-packs.mjs +13 -4
  22. package/browser/shared/document-look.mjs +14 -0
  23. package/browser/shared/drafts.mjs +1 -1
  24. package/browser/shared/extension-manifest.mjs +40 -12
  25. package/browser/shared/favorite-merge.mjs +17 -0
  26. package/browser/shared/favorites.mjs +77 -0
  27. package/browser/shared/i18n/en.mjs +123 -24
  28. package/browser/shared/outline-ops.mjs +109 -0
  29. package/browser/shared/outline.mjs +6 -0
  30. package/browser/shared/pages.mjs +20 -8
  31. package/browser/shared/paths.mjs +5 -2
  32. package/browser/shared/preference-documents.mjs +137 -0
  33. package/browser/shared/presence.mjs +94 -0
  34. package/browser/shared/preview-server.mjs +8 -5
  35. package/browser/shared/qa-levels.mjs +9 -1
  36. package/browser/shared/session.mjs +4 -0
  37. package/browser/shared/shipped-blocks.mjs +22 -4
  38. package/browser/shared/startup.mjs +101 -0
  39. package/browser/shared/workspace-address.mjs +3 -0
  40. package/browser/shared/workspace-columns.mjs +1 -1
  41. package/browser/shared/workspace-look.mjs +21 -8
  42. package/browser/shared/workspace-registry.mjs +6 -3
  43. package/browser/shared/workspace.mjs +37 -10
  44. package/browser/shared/writing-preferences.mjs +2 -42
  45. package/dist/chunk-25LYSMAE.mjs +2 -0
  46. package/dist/chunk-2I6ZVC5O.mjs +2 -0
  47. package/dist/{chunk-M4NRDYI5.mjs → chunk-2MYTOOP6.mjs} +1 -1
  48. package/dist/chunk-2VNENLER.mjs +2 -0
  49. package/dist/chunk-3FERXZF5.mjs +4 -0
  50. package/dist/chunk-3M6SBBGU.mjs +2 -0
  51. package/dist/chunk-3VCAAF34.mjs +2 -0
  52. package/dist/{chunk-JXXHAXYH.mjs → chunk-3ZTRLGSA.mjs} +1 -1
  53. package/dist/chunk-4FRA5AUE.mjs +2 -0
  54. package/dist/chunk-4LR2QEC2.mjs +4 -0
  55. package/dist/chunk-56SVJENP.mjs +966 -0
  56. package/dist/chunk-5CQISL2G.mjs +4 -0
  57. package/dist/{chunk-RRKJMHNX.mjs → chunk-5I5ZDDWC.mjs} +5 -5
  58. package/dist/chunk-5IHDLEB4.mjs +10 -0
  59. package/dist/chunk-5LRDMV7O.mjs +2 -0
  60. package/dist/chunk-5MVUYRKG.mjs +5 -0
  61. package/dist/chunk-5TLLIZT7.mjs +2 -0
  62. package/dist/chunk-6ILJWFYW.mjs +4 -0
  63. package/dist/chunk-6N25CJ6Y.mjs +3 -0
  64. package/dist/{chunk-SQ6Y2ZMA.mjs → chunk-7DTINW6U.mjs} +2 -2
  65. package/dist/chunk-7KWAGKIK.mjs +2 -0
  66. package/dist/chunk-7WNUOAFK.mjs +2 -0
  67. package/dist/chunk-7XCRW5RC.mjs +2 -0
  68. package/dist/{chunk-ERE2BXYV.mjs → chunk-7XSDTILF.mjs} +1 -1
  69. package/dist/chunk-ABKYFOVR.mjs +2 -0
  70. package/dist/chunk-AMUF7PUN.mjs +2 -0
  71. package/dist/{chunk-PLB7L22J.mjs → chunk-B2EIMERT.mjs} +2 -2
  72. package/dist/{chunk-QNECWMGR.mjs → chunk-B45IAAU6.mjs} +1 -1
  73. package/dist/chunk-B6RAGF4R.mjs +2 -0
  74. package/dist/chunk-BSJKFE7I.mjs +4 -0
  75. package/dist/chunk-C72EEVLK.mjs +2 -0
  76. package/dist/chunk-CRAUKZ23.mjs +4 -0
  77. package/dist/chunk-F4CT35KL.mjs +2 -0
  78. package/dist/chunk-F63BNJLG.mjs +2 -0
  79. package/dist/chunk-FBKUPS44.mjs +2 -0
  80. package/dist/chunk-FL52ZL5Z.mjs +15 -0
  81. package/dist/chunk-FOZCU4VW.mjs +2 -0
  82. package/dist/chunk-G5HV7BC3.mjs +2 -0
  83. package/dist/{chunk-ERLAIBOA.mjs → chunk-GB5SOYQJ.mjs} +2 -2
  84. package/dist/chunk-GN3SG3IF.mjs +2 -0
  85. package/dist/{chunk-6QWQXHAV.mjs → chunk-HFTBVEZK.mjs} +1 -1
  86. package/dist/chunk-IOW5HLRK.mjs +2 -0
  87. package/dist/chunk-IQ3GJNTI.mjs +6 -0
  88. package/dist/chunk-K6SPFBUJ.mjs +2 -0
  89. package/dist/chunk-K7Y7SPTS.mjs +2 -0
  90. package/dist/chunk-L2IJCEUH.mjs +2 -0
  91. package/dist/{chunk-GPIWQ4X4.mjs → chunk-L3VT6LM4.mjs} +1 -1
  92. package/dist/chunk-L4WLQYFC.mjs +5 -0
  93. package/dist/{chunk-FFV733MA.mjs → chunk-LAMCAGK6.mjs} +1 -1
  94. package/dist/chunk-LHGKPMTI.mjs +2 -0
  95. package/dist/chunk-LJZIYVNA.mjs +3 -0
  96. package/dist/chunk-LSVCTLS2.mjs +2 -0
  97. package/dist/chunk-LZY74XTP.mjs +2 -0
  98. package/dist/chunk-MC4LRSVH.mjs +2 -0
  99. package/dist/chunk-MCEXN4G5.mjs +2 -0
  100. package/dist/chunk-MTLAOCFF.mjs +181 -0
  101. package/dist/chunk-MZ66LN3B.mjs +2 -0
  102. package/dist/chunk-N5QWJRRI.mjs +2 -0
  103. package/dist/chunk-NF4MMOUB.mjs +2 -0
  104. package/dist/chunk-NHJYAJ73.mjs +3 -0
  105. package/dist/chunk-NRSD7SVY.mjs +2 -0
  106. package/dist/chunk-NT23I4XW.mjs +2 -0
  107. package/dist/chunk-NUALABIS.mjs +3 -0
  108. package/dist/chunk-NW6LAU22.mjs +2 -0
  109. package/dist/chunk-NWWHDGKF.mjs +5 -0
  110. package/dist/chunk-OFRCVMSJ.mjs +2 -0
  111. package/dist/chunk-OKVQQ3CX.mjs +4 -0
  112. package/dist/chunk-OM24O4KR.mjs +8 -0
  113. package/dist/{chunk-4B2TB5K2.mjs → chunk-PBMOC7KA.mjs} +2 -2
  114. package/dist/chunk-PVTCP43W.mjs +2 -0
  115. package/dist/chunk-Q62HZAJS.mjs +2 -0
  116. package/dist/chunk-QBJWIR3Q.mjs +2 -0
  117. package/dist/chunk-QDSEZX7Z.mjs +6 -0
  118. package/dist/chunk-QR4V4A2Z.mjs +15 -0
  119. package/dist/{chunk-QVGOPHOF.mjs → chunk-QRLVVZ3R.mjs} +1 -1
  120. package/dist/chunk-QW3QG67J.mjs +2 -0
  121. package/dist/chunk-R2T2EVWY.mjs +8 -0
  122. package/dist/{chunk-GJJRBGMY.mjs → chunk-R5RERE6G.mjs} +1 -1
  123. package/dist/chunk-RFHEWT3Y.mjs +5 -0
  124. package/dist/chunk-RS2Z2JQP.mjs +2 -0
  125. package/dist/chunk-S6YEC4GE.mjs +16 -0
  126. package/dist/chunk-SHZLMGGW.mjs +2 -0
  127. package/dist/chunk-TALJQM2O.mjs +2 -0
  128. package/dist/chunk-TLNJWEFY.mjs +22 -0
  129. package/dist/{chunk-6Q7ASAXJ.mjs → chunk-TQZU7D7C.mjs} +1 -1
  130. package/dist/chunk-UTKNWYBA.mjs +2 -0
  131. package/dist/chunk-V3TM3TEN.mjs +2 -0
  132. package/dist/chunk-V3XROSP5.mjs +7 -0
  133. package/dist/{chunk-6QBHU4DF.mjs → chunk-V5JTW2LH.mjs} +1 -1
  134. package/dist/chunk-VAXLSISW.mjs +4 -0
  135. package/dist/chunk-VBHI3RG6.mjs +2 -0
  136. package/dist/{chunk-6L6V7YR2.mjs → chunk-VKZJRGDR.mjs} +1 -1
  137. package/dist/chunk-VZXZM7NS.mjs +2 -0
  138. package/dist/chunk-WDS6HEPE.mjs +2 -0
  139. package/dist/chunk-WHGANNEY.mjs +13 -0
  140. package/dist/chunk-WMJWC4QY.mjs +56 -0
  141. package/dist/{chunk-VZ2RQ3AM.mjs → chunk-WWONJJQS.mjs} +1 -1
  142. package/dist/chunk-X4WNLFIK.mjs +2 -0
  143. package/dist/chunk-XNNCQROX.mjs +11 -0
  144. package/dist/chunk-XRYECF23.mjs +170 -0
  145. package/dist/{chunk-K3JKPFL5.mjs → chunk-Z4NEXXFK.mjs} +1 -1
  146. package/dist/{chunk-236JJXWY.mjs → chunk-ZFVF2YPV.mjs} +2 -2
  147. package/dist/chunk-ZM2IX3R2.mjs +2 -0
  148. package/dist/chunk-ZNGGDUZI.mjs +2 -0
  149. package/dist/chunk-ZOEJQOKT.mjs +2 -0
  150. package/dist/cli.mjs +1 -1
  151. package/dist/server.mjs +1 -1
  152. package/dist/update-fetch.mjs +1 -1
  153. package/dist/worker.mjs +1 -1
  154. package/kit/runtime.js +1 -0
  155. package/package.json +1 -1
  156. package/release.json +4 -4
  157. package/skill/SKILL.md +54 -148
  158. package/skill/references/building-blocks.md +4 -4
  159. package/skill/references/charts-and-figures.md +73 -0
  160. package/skill/references/extensions.md +47 -4
  161. package/skill/references/pages-and-data.md +22 -3
  162. package/skill/references/preference-files.md +7 -0
  163. package/skill/references/previews.md +17 -0
  164. package/skill/references/writing-html.md +21 -82
  165. package/web/assets/index-B4uUluLM.js +15 -0
  166. package/web/assets/index-C3vHT8sH.css +1 -0
  167. package/web/index.html +2 -2
  168. package/dist/chunk-2KAVXMKG.mjs +0 -4
  169. package/dist/chunk-2T4PZQEP.mjs +0 -2
  170. package/dist/chunk-3SKOU6OZ.mjs +0 -10
  171. package/dist/chunk-3XZOA7AH.mjs +0 -170
  172. package/dist/chunk-4KUO7R2M.mjs +0 -16
  173. package/dist/chunk-4OZWXZE5.mjs +0 -5
  174. package/dist/chunk-4SNV4HA5.mjs +0 -2
  175. package/dist/chunk-53XDTHTG.mjs +0 -4
  176. package/dist/chunk-5XV3YYLG.mjs +0 -2
  177. package/dist/chunk-65NTKF4N.mjs +0 -6
  178. package/dist/chunk-6GV3CBB2.mjs +0 -2
  179. package/dist/chunk-6NLXUKAY.mjs +0 -4
  180. package/dist/chunk-6XD6U3QA.mjs +0 -5
  181. package/dist/chunk-7EFHNQ5B.mjs +0 -3
  182. package/dist/chunk-7ISBBDJR.mjs +0 -2
  183. package/dist/chunk-7M2BQQGZ.mjs +0 -2
  184. package/dist/chunk-7UZUQQ7Q.mjs +0 -554
  185. package/dist/chunk-ALZ6ZENZ.mjs +0 -3
  186. package/dist/chunk-BLNQUR5R.mjs +0 -168
  187. package/dist/chunk-BMX3VUHY.mjs +0 -2
  188. package/dist/chunk-BN7M3IN7.mjs +0 -8
  189. package/dist/chunk-C257H6IA.mjs +0 -2
  190. package/dist/chunk-CHQU37CA.mjs +0 -2
  191. package/dist/chunk-DR73Y2UJ.mjs +0 -3
  192. package/dist/chunk-E4IHAIJ7.mjs +0 -2
  193. package/dist/chunk-EURLTOTZ.mjs +0 -4
  194. package/dist/chunk-F4ZA6JRZ.mjs +0 -3
  195. package/dist/chunk-GKOBB6DH.mjs +0 -2
  196. package/dist/chunk-GMJD7ID3.mjs +0 -2
  197. package/dist/chunk-IA2SIEJQ.mjs +0 -2
  198. package/dist/chunk-JEUK3ZO7.mjs +0 -2
  199. package/dist/chunk-JPG2LBQM.mjs +0 -11
  200. package/dist/chunk-KLQP46Y3.mjs +0 -4
  201. package/dist/chunk-LMUZQK5O.mjs +0 -2
  202. package/dist/chunk-MKIBJTJZ.mjs +0 -6
  203. package/dist/chunk-MNWJ4EZY.mjs +0 -2
  204. package/dist/chunk-NHP66IWR.mjs +0 -5
  205. package/dist/chunk-OEIJLMPI.mjs +0 -2
  206. package/dist/chunk-PDZR3L3C.mjs +0 -2
  207. package/dist/chunk-PUOQ65NC.mjs +0 -2
  208. package/dist/chunk-Q4MS6OFC.mjs +0 -2
  209. package/dist/chunk-Q7P3Q5YX.mjs +0 -13
  210. package/dist/chunk-QP7BOHE4.mjs +0 -2
  211. package/dist/chunk-S3SX3COT.mjs +0 -20
  212. package/dist/chunk-TANZRINB.mjs +0 -2
  213. package/dist/chunk-UGWMMEJ5.mjs +0 -15
  214. package/dist/chunk-ULXSPX5H.mjs +0 -5
  215. package/dist/chunk-USIHBCSW.mjs +0 -15
  216. package/dist/chunk-VPMRP2TL.mjs +0 -2
  217. package/dist/chunk-WFGPMCTZ.mjs +0 -4
  218. package/dist/chunk-XZCFPKGO.mjs +0 -2
  219. package/dist/chunk-ZFGMJVJC.mjs +0 -2
  220. package/web/assets/index-FLb9jCfl.css +0 -1
  221. package/web/assets/index-czjrXVjf.js +0 -15
  222. /package/dist/{chunk-PAREWQGB.mjs → chunk-NOGQX56R.mjs} +0 -0
@@ -1,13 +0,0 @@
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 Oe,f as we,g as ge,h as $e,i as We,j as ne,l as Y,m as Ge,n as Ae,o as Ke,p as Ve,q as ze,r as g,t as Qe,u as Ye}from"./chunk-4KUO7R2M.mjs";import{M as Xe}from"./chunk-MKIBJTJZ.mjs";import{f as Te,i as Je}from"./chunk-BN7M3IN7.mjs";import{a as K}from"./chunk-JEUK3ZO7.mjs";import{a as me}from"./chunk-M4NRDYI5.mjs";import{a as Ue,b as Ze,f as pe,g as qe}from"./chunk-PUOQ65NC.mjs";import{e as Ne,g as te}from"./chunk-S3SX3COT.mjs";import{b as Se}from"./chunk-VRPVVMRB.mjs";import{b as T,i as Pe}from"./chunk-4OZWXZE5.mjs";import{a as Be}from"./chunk-HYMEEXKN.mjs";import{f as Ee,j as He}from"./chunk-TKWEX4FD.mjs";import{randomBytes as Ct}from"node:crypto";import{existsSync as It}from"node:fs";import N from"node:fs/promises";import A from"node:path";import{isInstance as Re,isSlot as jt,partOf as Mt}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as ke,FALLBACK as Rt,FIELDS as Dt,INSTANCE as ft,PACKAGE_ID as _t,SLOT as Ft}from"../browser/shared/components/installed.mjs";import{attr as ce,walk as Ht}from"../browser/shared/html-tree.mjs";import{documentDirectory as Pt,documentFiles as Bt,layoutOf as se,packageFolders as Jt,slugTaken as Ut}from"../browser/shared/workspace.mjs";var et=10,Ce=6,Zt=3,qt=100,De=1024,_e=900,Wt=4e3,le=3e4,Gt=1500,Ie=3e4,je=500,Kt=5e3,Vt=200,tt=20,nt=160,ye=12,zt=3600*1e3,Qt=["p","pi","pin"],he=e=>new Promise(t=>setTimeout(t,e));async function at(e){let{_keyDefinitions:t}=await import("./chunk-43B75J5T.mjs"),n=Object.hasOwn(t,e)?[e]:e.split("+"),a=new Set(["Control","Shift","Alt","Meta"]);if(n.some(s=>!Object.hasOwn(t,s))||n.slice(0,-1).some(s=>!a.has(s)))throw new T(`Not a key: ${e} (a key as a browser names it, Enter, Space, Escape, Tab, ArrowRight, a letter or a digit, after modifiers joined by "+": Shift+Tab, Control+Enter).`);return n}var ie={press:"<selector>",drag:'<selector>, with "to": <selector>',key:"[<selector>, <key>]",type:"[<selector>, <words>]",select:"[<selector>, <value>]"};async function ut(e,t=null){let n=d=>new T(t?`${t[0].toUpperCase()}${t.slice(1)}: ${d}`:`${d[0].toUpperCase()}${d.slice(1)}`);if(!e||typeof e!="object"||Array.isArray(e))throw n(`a step is an object naming one gesture: ${Object.entries(ie).map(([d,h])=>`"${d}": ${h}`).join(", ")}, and "then": <key> after it.`);let a=Object.keys(e).filter(d=>!Object.hasOwn(ie,d)&&!["to","then","replace"].includes(d));if(a.length)throw n(`no such field: ${a.join(", ")} (a step names one of ${Object.keys(ie).join(", ")}, "to" with a drag, "replace": true with typing and "then" after any).`);let s=Object.keys(ie).filter(d=>e[d]!==void 0),o=d=>t?`"${d}"`:`--${d}`;if(s.length!==1)throw n(s.length?`one gesture at a time: ${s.map(o).join(" or ")}.`:t?`name the gesture: ${Object.keys(ie).map(o).join(", ")}.`:"Say the gesture: --press <selector>, --drag <selector> --to <selector>, --key <selector> <key>, --type <selector> <words> or --select <selector> <value>; or --steps <file>.");let[i]=s;if(e.to!==void 0&&i!=="drag")throw n(`${o("to")} goes with ${o("drag")}: ${t?'"drag": <selector>, "to": <selector>':"--drag <selector> --to <selector>"}.`);if(i==="drag"&&e.to===void 0)throw n(`${o("drag")} takes ${o("to")}: ${t?'"drag": <selector>, "to": <selector>':"--drag <selector> --to <selector>"}, where it is dropped.`);if(e.replace!==void 0&&i!=="type")throw n(`${o("replace")} goes with ${o("type")}: it selects what the field holds before the words go in.`);if(e.replace!==void 0&&e.replace!==!0)throw n(`${o("replace")} is true: ${t?'"replace": true':"--replace"} selects what the field holds before the words go in.`);let l=(d,h)=>{if(typeof d!="string"||!d)throw n(`${h} is words: ${JSON.stringify(d)}.`);return d},c=(d,h)=>{if(!Array.isArray(d)||d.length!==2)throw n(`${o(i)} takes ${t?`[<selector>, ${h}]`:`<selector> ${h}`}.`);return[l(d[0],"a selector"),l(d[1],h)]},r={kind:i};if(i==="press"&&(r.at=l(e.press,"a selector")),i==="drag"&&Object.assign(r,{at:l(e.drag,"a selector"),to:l(e.to,"a selector")}),i==="key"){let[d,h]=c(e.key,"<key>");Object.assign(r,{at:d,key:h,keys:await at(h)})}return i==="type"&&([r.at,r.text]=c(e.type,"<words>"),e.replace&&(r.replace=!0)),i==="select"&&([r.at,r.value]=c(e.select,"<value>")),e.then!==void 0&&(r.then={key:l(e.then,"a key"),keys:await at(l(e.then,"a key"))}),r}async function Yt(e,t={},n=!1){if(n&&e.has("--steps"))throw new T('--steps <file> holds every gesture: --replace goes in a step of it, as { "type": [".name", "\u65B0\u540D\u5B57"], "replace": true }, not beside it.');if(e.has("--steps")){let s=["--press","--drag","--to","--key","--type","--select","--then"].filter(o=>e.has(o));if(s.length)throw new T(`--steps <file> holds every gesture: ${s.join(", ")} goes in it, not beside it.`);return null}let a={};for(let s of["press","drag","to","then"])e.has(`--${s}`)&&(a[s]=e.get(`--${s}`));for(let s of["key","type","select"])e.has(`--${s}`)&&(a[s]=[e.get(`--${s}`),t[`--${s}`]]);return n&&(a.replace=!0),ut(a)}async function Xt(e){let t=A.basename(e),n;try{n=await N.readFile(e,"utf8")}catch(o){throw new T(`No steps file: ${K(e)} (${o.code??ne(o)}).`)}let a;try{a=JSON.parse(n.replace(/^/,""))}catch(o){throw new T(`${t} is no JSON: ${ne(o)}. A steps file is a list of steps, as [{ "press": ".add" }, { "type": [".name", "\u65B0\u540D\u5B57"], "then": "Enter" }].`)}if(!Array.isArray(a)||a.length===0)throw new T(`${t} holds no list of steps: write [{ "press": ".add" }, { "type": [".name", "\u65B0\u540D\u5B57"], "then": "Enter" }].`);if(a.length>tt)throw new T(`${t} holds ${a.length} steps, and a trial makes ${tt} at most: try fewer at a time.`);let s=[];for(let[o,i]of a.entries())s.push(await ut(i,`step ${o+1} of ${t}`));return s}var pt=e=>{let t=e.parentNode;for(;t&&!Re(t);)t=t.parentNode;return t??null},en=(e,t)=>{for(let n=e.parentNode;n&&n!==t;n=n.parentNode)if(jt(n))return ce(n,Ft);return null};function wt(e){let t=[];return Ht(Be(e),n=>{if(!Re(n))return;let a=pt(n);t.push({element:n,id:ce(n,ke),blockId:ce(n,"data-block-id")??null,line:n.sourceCodeLocation?.startLine,in:a?{id:ce(a,ke),line:a.sourceCodeLocation?.startLine,slot:en(n,a)}:null})},{inTemplates:!1}),t}var gt=({line:e,in:t},n)=>`${n}:${e}${t?`, in ${t.slot?`the slot ${t.slot} of `:""}${t.id} at ${n}:${t.line}`:""}`,tn=(e,{id:t,blockId:n})=>n??(e.filter(a=>a.id===t).length===1?t:null);function nn(e,t,{slug:n,name:a}){let s=()=>e.map(c=>` ${tn(e,c)??"(no id yet: gallery export gives it one)"} ${c.id} at ${gt(c,a)}`).join(`
3
- `);if(t===null){if(e.length===1)return 0;throw new T(`${n} holds ${e.length} instances: name one, gallery block try ${n} <instance id> \u2026
4
- ${s()}`)}let o=e.findIndex(({blockId:c})=>c===t);if(o>=0)return o;let i=t.includes("/")?t:`local/${t}`,l=_t.test(i)?e.flatMap((c,r)=>c.id===i?[r]:[]):[];if(l.length===1)return l[0];throw new T(l.length?`${n} holds ${l.length} instances of ${i}: name one by its id
5
- ${s()}`:`${n} holds no instance ${t}:
6
- ${s()}`)}var an=e=>e.replace(/\s+data-block-id="[^"]*"/g,""),st=e=>an(Se(e).text),sn=(e,t)=>(typeof t=="function"?t(e):wt(e)[t]?.element)??null;function ot(e,t,n){let a=sn(e,t);if(!a||ce(a,ke)!==n.id)return null;let s=[],o=Object.entries(n.parts).map(([r,{at:d}])=>{let h=Mt(a,d).filter(f=>f.sourceCodeLocation?.endTag&&!Re(f)&&pt(f)===a).map(({sourceCodeLocation:{startTag:f,endTag:u}})=>({start:f.endOffset,end:u.startOffset}));return s.push(...h),{name:r,text:h.map(({start:f,end:u})=>e.slice(f,u)).join(`
7
- `)}}),i=s.sort((r,d)=>r.start-d.start||d.end-r.end).filter((r,d)=>!s.slice(0,d).some(h=>h.start<=r.start&&r.end<=h.end)),l="",c=0;for(let{start:r,end:d}of i)l+=e.slice(c,r),c=d;return{parts:o,outside:l+e.slice(c)}}function on(e,t,n,a){let[s,o]=[ot(e,n,a),ot(t,n,a)];return!s||!o?{parts:[],outside:null,gone:!0}:{parts:s.parts.flatMap(({name:l,text:c},r)=>c===o.parts[r].text?[]:[{name:l,...Ae(c,o.parts[r].text),how:Ve(c,o.parts[r].text),runs:Ke(c,o.parts[r].text)}]),outside:s.outside===o.outside?null:Ae(s.outside,o.outside),gone:!1}}function rn(e){let t=n=>n.length>nt?`${n.slice(0,nt)}\u2026`:n;return e.flatMap(({name:n,runs:a=[]})=>{let s=a.flatMap(({removed:l,added:c})=>[...l.map(r=>`- ${t(r)}`),...c.map(r=>`+ ${t(r)}`)]),o=e.length>1?" ":" ",i=s.slice(0,ye).map(l=>`${o}${l}`);return s.length>ye&&i.push(`${o}\u2026 ${s.length-ye} more line${s.length-ye===1?"":"s"}`),e.length>1?[` ${n}:`,...i]:i})}async function cn(e,t=null){let{components:n,marker:a}=se(e);return await mt([t,a,n].filter(Boolean))+me+te+je}async function ln(e,{directory:t,files:n,text:a}){let{scratch:s}=se(e);await N.mkdir(s,{recursive:!0});let o;do o=`try-${Ct(4).toString("hex")}`;while(Ut(o,e)||It(A.join(s,o)));let i=A.join(s,o);await N.mkdir(i),await N.cp(A.join(t,"assets"),A.join(i,"assets"),{recursive:!0}).catch(c=>{if(c.code!=="ENOENT")throw c}),await N.copyFile(n.json,A.join(i,A.basename(n.json))).catch(c=>{if(c.code!=="ENOENT")throw c});let l=A.join(i,A.basename(n.html));return await N.writeFile(l,a),{slug:o,folder:i,file:l}}async function $t(e,t){let{scratch:n,state:a}=se(e);await N.rm(A.join(n,t),{recursive:!0,force:!0,maxRetries:5,retryDelay:200}).catch(()=>{});for(let s of await N.readdir(a).catch(()=>[]))await N.rm(A.join(a,s,t),{recursive:!0,force:!0,maxRetries:3,retryDelay:100}).catch(()=>{})}async function dn(e,t=Date.now()){let{scratch:n}=se(e);for(let a of await N.readdir(n,{withFileTypes:!0}).catch(()=>[])){if(!a.isDirectory()||!/^try-[a-f0-9]{8}$/.test(a.name))continue;let{mtimeMs:s}=await N.stat(A.join(n,a.name)).catch(()=>({mtimeMs:t}));t-s>=zt&&await $t(e,a.name)}}async function mt(e){let t=[...e];for(let a of e)for(let s of await N.readdir(a,{recursive:!0,withFileTypes:!0}).catch(()=>[]))t.push(A.join(s.parentPath,s.name));let n=await Promise.all(t.map(a=>N.stat(a).then(({mtimeMs:s})=>s,()=>0)));return Math.max(...n)}var hn=e=>fetch(`${e}/__gallery/workspace/components`,{signal:AbortSignal.timeout(2e3)}).then(t=>t.ok?t.json():null).then(t=>Array.isArray(t?.packages)?t.packages:null,()=>null);async function fn(e,t,n){let{components:a,marker:s}=se(e),o=Jt(e).find(m=>m.id.toLowerCase()===t)?.folder??A.join(a,...t.split("/")),[i,l]=await Promise.all([mt([s,o]),hn(n)]),{packages:c,problems:r,settings:d}=Ee(e),h=l?.find(m=>m.id===t)??null,f=l?h?.state??"none":null,u=f==="normal"||f==="hidden",w=d.disabled.includes(t),k=r.get(t),y=k&&!w&&u?He("en",k.problem):null,p=l!==null&&c.has(t)&&!u;return{by:i+(y?Ne:me+te),held:y,behind:p,off:w,stamp:(c.get(t)??k)?.stamp??null,state:f,reason:h?.reason?.en??null}}var yt=({state:e,reason:t})=>e==="none"?"no such custom block":t?`it as not loading (${t})`:"it turned off";function un(e,{said:t,unparsed:n=null,off:a,behind:s=!1,state:o,reason:i}){let l="the instance shows what it holds, read-only, so a reader can do nothing with it";return n?`${l}: its kit.js did not parse, so no component of it started, and the console says ${n}`:t.length?`${l}: its component failed as the page started it, and the console says ${t.join("; ")}`:a?`${l}: ${e} is turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868`:s?`${l}: the server has not taken ${e} as components/ holds it, where it loads: its catalog in use has ${yt({state:o,reason:i})}`:o==="disabled"&&!i?`${l}: ${e} is turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868`:o==="broken"||o==="disabled"?`${l}: the server has ${e} as not loading (${i}): gallery block check ${e} says why`:o==="none"?`${l}: the server has not taken ${e} as components/ holds it (its catalog in use has no such custom block)`:o?`${l}: the page was served before the server took ${e} as components/ holds it, and did not load itself again with it`:`${l}: its component failed or never started, and the console said nothing of it`}var pn=(e,t,n)=>t.held?`${e} does not load as components/ holds it (${t.held}), and the server keeps it as it was until components/ has not changed for ${Ne/1e3}s, as it keeps a custom block written file by file`:t.behind?`components/ holds ${e} as loading, and the server's catalog in use still has ${yt(t)}: it takes what components/ holds once that has not changed for ${te/1e3}s`:n?`${e} or gallery.json changed a moment ago, and the server takes the change once components/ has not changed for ${te/1e3}s, the page served before loading itself again for it`:`the server took ${e} as components/ holds it, and the page served before is to load itself again with it`,wn=(e,t,n)=>t.held?`the server still keeps ${e} as it was`:t.behind?`the server has still not taken ${e} as components/ holds it`:`the server took ${e} as components/ holds it, and the page did not load itself again with it in ${n/1e3}s`;async function gn({root:e,id:t,origin:n,loadedAt:a,loaded:s,told:o=Kt,say:i=l=>console.log(l)}){let l=Date.now(),c,r=0,d=0,h=!1;for(;;await he(Vt)){let f=await fn(e,t,n),u=Date.now();c!==void 0&&f.stamp!==c&&(r=u),c=f.stamp,f.behind&&!d&&(d=u);let w=Math.max(f.by,...[r,d].filter(Boolean).map(y=>y+me+te)),k=s()?"the page loaded itself again":f.off?`gallery.json turns ${t} off now`:a>=w?`the page was asked for after the server took ${t} as components/ holds it`:u>w+o?wn(t,f,o):null;if(k)return h&&i(`Waited ${((u-l)/1e3).toFixed(1)}s: ${k}`),f;h||w-u<=je&&u-l<=je||(h=!0,i(`Waiting: ${pn(t,f,w>u)}, ${Math.ceil((w+o-u)/1e3)}s more at most`))}}function $n({instance:e,at:t,card:n}){return typeof n=="string"?[...[...document.querySelectorAll(".gallery-board > .gallery-card")].find(s=>s.getAttribute("data-card-id")===n)?.children??[]].find(s=>s.matches(e))??null:[...document.querySelectorAll(e)][t]??null}function mn(e,t){let n=u=>`<${u.localName}${u.classList.length?` class="${u.getAttribute("class")}"`:""}>`,a;try{a=e.querySelector(t)}catch{return{invalid:!0}}if(!a)return{none:!0,held:[...new Set([...e.querySelectorAll("[class]")].filter(u=>u.getClientRects().length>0).flatMap(u=>[...u.classList].map(w=>`.${w}`)))].slice(0,16)};let s=((a instanceof HTMLElement?a.innerText:a.textContent)??"").replace(/\s+/g," ").trim(),o={named:n(a),words:s.length>40?`${s.slice(0,40)}\u2026`:s},i=[...a.getClientRects()].filter(({width:u,height:w})=>u>0&&w>0);if(!i.length)return{...o,hidden:!0};let{left:l,top:c,right:r,bottom:d,width:h,height:f}=i.reduce((u,w)=>u.width*u.height>=w.width*w.height?u:w);return{...o,box:{left:l,top:c,right:r,bottom:d,x:l+h/2,y:c+f/2}}}function yn(e,{selector:t,x:n,y:a}){let s=e.querySelector(t),o=document.elementFromPoint(n,a);return!o||s.contains(o)?null:`<${o.localName}${o.classList.length?` class="${o.getAttribute("class")}"`:""}>`}function kn(e,{at:t,to:n}){let[a,s]=[e.querySelector(t),e.querySelector(n)];return a===s?"same":a.contains(s)?"inside":null}function kt(e){let t=a=>a instanceof Element?`<${a.localName}${a.classList.length?` class="${a.getAttribute("class")}"`:""}>`:"the page",n={edits:[],taken:0,states:[],started:null,dropped:null,effect:null};addEventListener("doc-component-edit",a=>{a.target===e&&(n.edits.push({taken:a.defaultPrevented,parts:(a.detail?.parts??[]).map(({name:s})=>s)}),a.defaultPrevented&&(n.taken+=1))}),new MutationObserver(a=>{for(let{oldValue:s}of a)n.states.push(s);n.states.push(document.documentElement.getAttribute("data-ge-save"))}).observe(document.documentElement,{attributes:!0,attributeFilter:["data-ge-save"],attributeOldValue:!0}),document.addEventListener("dragstart",a=>{n.started=t(a.target)},!0),document.addEventListener("drop",a=>{n.dropped=t(a.target)},!0),document.addEventListener("dragend",a=>{n.effect=a.dataTransfer?.dropEffect??null},!0),globalThis.__galleryTry=n}function bn(){return Object.assign(globalThis.__galleryTry,{edits:[],started:null,dropped:null,effect:null}),{taken:globalThis.__galleryTry.taken}}function bt(e){let t=[...e.querySelectorAll("input, select, textarea")].map(n=>n instanceof HTMLInputElement&&["checkbox","radio"].includes(n.type)?n.checked?"ticked":"not ticked":n.value);return{words:(e.innerText??"").replace(/\s+/g," ").trim(),fields:t}}function vn(e){let n=(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement?e.value:e.textContent??"").replace(/\s+/g," ").trim();return n.length>40?`${n.slice(0,40)}\u2026`:n}function xn(e){let t=document.activeElement,n="";if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)try{n=t.value.slice(t.selectionStart??0,t.selectionEnd??0)}catch{}else{let s=getSelection();s&&!s.isCollapsed&&e.contains(s.anchorNode)&&(n=s.toString())}let a=n.replace(/\s+/g," ").trim();return a.length>40?`${a.slice(0,40)}\u2026`:a}function En(e){let t=document.activeElement;if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)try{return t.selectionStart===null?null:t.selectionEnd===t.value.length}catch{return null}let n=getSelection();if(!n?.rangeCount||!e.contains(n.focusNode))return null;let a=document.createRange();return a.selectNodeContents(e),a.setStart(n.focusNode,n.focusOffset),a.toString().trim()===""}function Sn(e){let t=document.activeElement;if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement){t.select();return}let n=document.createRange();n.selectNodeContents(e),getSelection()?.removeAllRanges(),getSelection()?.addRange(n)}function it(e){let t=document.activeElement;return t&&(t===e||e.contains(t)||t instanceof HTMLElement&&t.isContentEditable&&t.contains(e))?null:`<${t?.localName??"body"}>`}function Tn(e){let t=document.activeElement;if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement){try{t.setSelectionRange(t.value.length,t.value.length)}catch{}return}let n=document.createRange();n.selectNodeContents(e),n.collapse(!1),getSelection()?.removeAllRanges(),getSelection()?.addRange(n)}function Nn(e,{selector:t,value:n}){let a=e.querySelector(t);if(!(a instanceof HTMLSelectElement))return{notSelect:`<${a.localName}${a.classList.length?` class="${a.getAttribute("class")}"`:""}>`};let s=[...a.options],o=s.find(i=>i.value===n)??s.find(i=>i.textContent.trim()===n);return o?a.disabled||o.disabled?{disabled:!0}:(a.focus(),o.selected=!0,a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0})),{chosen:o.textContent.trim()}):{options:s.map(i=>i.value===i.textContent.trim()?i.value:`${i.value} (${i.textContent.trim()})`)}}async function Fe(e,{still:t,step:n,wait:a=0}){let s=globalThis.__galleryQueries??null,o=Date.now()+a,i=()=>s!==null&&s.pending.size>0&&Date.now()<o,l=()=>new Promise(r=>{requestAnimationFrame(r),setTimeout(r,100)});await l(),await l();let c=e.outerHTML;for(let r=0,d=Date.now()+t;r<3;){if(Date.now()>d)return null;await new Promise(f=>setTimeout(f,n));let h=e.outerHTML;i()?(r=0,d=Date.now()+t):r=h===c?r+1:0,c=h}return c}function On(e,t,{left:n,top:a,right:s,bottom:o}){let i=0;for(let[l,c,r,d]of[[e.x,t.x,n,s],[e.y,t.y,a,o]]){if(c===l)continue;let[h,f]=[(r-l)/(c-l),(d-l)/(c-l)];i=Math.max(i,Math.min(h,f))}return i*Math.hypot(t.x-e.x,t.y-e.y)}function An(e,t){let n=Math.hypot(t.x-e.x,t.y-e.y),a=c=>n===0?{x:e.x,y:e.y}:{x:e.x+(t.x-e.x)*c/n,y:e.y+(t.y-e.y)*c/n},s=Math.min(Ce,n),o=On(e,t,t)-Zt,i=o>s?o:n,l=[a(s/2),a(s)];for(let c=1;c<=et;c++)l.push(a(s+(i-s)*c/et));return i!==n&&l.push({x:t.x,y:t.y}),l}var de={press:"press",drag:"drag",key:"key",type:"typing",select:"choice"},ae=(e,{named:t,words:n})=>`${e} (${t}${n?` "${n}"`:""})`,rt=e=>Object.assign(new T(e),{unfound:!0});async function vt(e,t){let n=t.slice(0,-1);for(let a of n)await e.keyboard.down(a);await e.keyboard.press(t.at(-1));for(let a of n.toReversed())await e.keyboard.up(a)}async function Ln(e,t,n){let a=!1;for(let[s]of n.matchAll(/[\x00-\x7f]+|[^\x00-\x7f]+/gu)){if(/^[\x00-\x7f]/.test(s)){await e.keyboard.type(s);continue}a=!0;for(let o of Qt)await t.send("Input.imeSetComposition",{text:o,selectionStart:o.length,selectionEnd:o.length});await t.send("Input.insertText",{text:s})}return a?/[\x00-\x7f]/.test(n)?"its ASCII key by key and the rest through an input method":"through an input method, composed then committed":"key by key"}async function Cn(e,t,n,a){let s=await In(e,t,n,a);return n.then?(await vt(e,n.then.keys),{...s,said:`${s.said}, then ${n.then.key} pressed where the focus was`}):s}async function In(e,t,n,a){let s=async c=>{let r=await g(t.evaluate(mn,c),"the page was asked what the selector finds");if(r.invalid)throw new T(`Not a selector: ${c}.`);if(r.none)throw rt(`Nothing in the instance is ${c}${r.held.length?`: what it shows has ${r.held.join(", ")}`:": it shows nothing with a class"}.`);if(r.hidden)throw rt(`${c} finds ${r.named} in the instance, which is not shown (it has no box on the page), so a reader cannot reach it: name what it shows.`);return r},o=await s(n.at);if(n.kind==="press"){let{x:c,y:r}=o.box,d=await g(t.evaluate(yn,{selector:n.at,x:c,y:r}),"the page was asked what stands at the press");return await e.mouse.move(c,r),await e.mouse.down(),await e.mouse.up(),{said:`a press on ${ae(n.at,o)}, with the pointer at its middle`,over:d}}if(n.kind==="drag"){let c=await s(n.to),r=await g(t.evaluate(kn,{at:n.at,to:n.to}),"the page was asked where the drag ends");if(r)throw new T(`${r==="same"?`--drag and --to find the same element, ${o.named}`:`--to ${n.to} finds ${c.named}, which stands in what --drag ${n.at} finds, ${o.named}`}: a drag ends where it is dropped, on another element of the instance (another column, another row), which --to names.`);if(Math.hypot(c.box.x-o.box.x,c.box.y-o.box.y)<Ce)throw new T(`The middles of what --drag ${n.at} and --to ${n.to} find stand less than ${Ce}px apart, too near for a drag to start: name with --to where it is dropped, further off.`);let d=An(o.box,c.box);await e.mouse.move(o.box.x,o.box.y),await e.mouse.down();for(let{x:h,y:f}of d)await e.mouse.move(h,f);return await he(qt),await e.mouse.up(),{said:`a drag of ${ae(n.at,o)} to ${ae(n.to,c)}, with the pointer in ${d.length} moves, released as it comes onto it`}}if(n.kind==="select"){let c=await g(t.evaluate(Nn,{selector:n.at,value:n.value}),"the page was asked to choose the option");if(c.notSelect)throw new T(`${n.at} finds ${c.notSelect} in the instance, which is no <select>: --select names a <select> the instance draws, and the option by its value or its words.`);if(c.options)throw new T(`${n.at} has no option ${JSON.stringify(n.value)}: ${c.options.length?`its options are ${c.options.join(", ")}`:"it has no option"}.`);if(c.disabled)throw new T(`${n.at} or its option ${JSON.stringify(n.value)} is disabled, so a reader cannot choose it.`);return{said:`${JSON.stringify(c.chosen)} chosen in ${ae(n.at,o)}, as a reader picks an option`}}let i=await t.$(n.at);if(n.kind==="type"){let c=!1,r=await g(e.evaluate(vn,i),"the page was asked what the field holds");await g(e.evaluate(it,i),"the page was asked where the focus is")&&(await e.mouse.click(o.box.x,o.box.y),await g(e.evaluate(Tn,i),"the caret went to the end"),c=!0),n.replace&&await g(e.evaluate(Sn,i),"all the field holds was selected");let d=await g(e.evaluate(it,i),"the page was asked where the focus is"),h=await g(e.evaluate(xn,i),"the page was asked what is selected"),f=c||!r||n.replace||h?!0:await g(e.evaluate(En,i),"the page was asked where the caret is"),u=await Ln(e,a,n.text),w=c?", pressed first":", where the focus was",k='(--replace, or "replace": true in a step, puts them in its place)',y=n.replace?`${w}, ${r?`all it held (${JSON.stringify(r)}) selected first (--replace), so that the words took its place`:"nothing in it to replace"}`:h?`${w}, ${h===r?"all it held":"part of it"} (${JSON.stringify(h)}) selected already (a step before), so that the words took its place`:c?`, pressed first and the caret at its end${r?`: it held ${JSON.stringify(r)}, and the words went after it ${k}`:""}`:r?f===!1?`, where the focus was, the caret inside what it held (${JSON.stringify(r)}), where a step before left it (a press puts it where the pointer lands, an arrow key moves it), so that the words went in there, not after it ${k}`:f?`, where the focus was, the caret at its end: it held ${JSON.stringify(r)}, and the words went after it ${k}`:`, where the focus was: it held ${JSON.stringify(r)}, and the words went in at the caret, where a step before left it ${k}`:", where the focus was";return{said:`${JSON.stringify(n.text)} typed in ${ae(n.at,o)}${y}, ${u}`,unfocused:d,typed:!0}}await g(i.focus(),"the focus went to the element");let l=await g(e.evaluate(c=>document.activeElement===c||c.contains(document.activeElement)?null:`<${document.activeElement?.localName??"body"}>`,i),"the page was asked where the focus is");return await vt(e,n.keys),{said:`${n.key} pressed with the focus given to ${ae(n.at,o)}, as Tab gives it`,unfocused:l}}var xt=e=>fetch(`${e}/__gallery/workspace/info`,{signal:AbortSignal.timeout(2e3)}).then(t=>t.ok,()=>!1);async function jn(e,t,n){let a=Date.now();for(let s=0,o=0;;await he(100)){let{seen:i,now:l}=await g(e.evaluate(r=>({seen:globalThis.__galleryTry.states.slice(r),now:document.documentElement.getAttribute("data-ge-save")}),t),"the page was asked where saving stands"),c=l!=="saved"||i.some(r=>r!=="saved");if(c&&l==="saved")return"saved";if(l==="stopped"||l==="reloading")return l;if(s=l==="held"?s+1:0,s>=3)return"held";if(o=l==="offline"?o+1:0,o>0&&o%10===0&&!await xt(n))return"offline";if(!c&&Date.now()-a>Gt)return"unchanged";if(Date.now()-a>Ie)return l}}var Mn=e=>({held:"a card waits for a reader: someone else changed the part meanwhile, and the page held its write for the reader there, which closing the page dropped",offline:"the page could not reach the server (offline)",stopped:"the page stopped saving (stopped): the server refused its write",reloading:"the page loaded itself again (doc.html or a custom block it holds changed meanwhile)",waiting:`it waited ${Ie/1e3}s to be saved and never was`,syncing:`its save took more than ${Ie/1e3}s`})[e];function Rn(e,{parts:t,outside:n,gone:a},{gesture:s,name:o,held:i=!1,scratch:l=!1,aside:c="data-block-id aside"}){if(l)return{unverified:`${e}${!a&&t.length?`, the copy holding what the ${s} wrote, ${Y(t)}`:""}: the trial was made on a scratch copy, gone now, and ${o} holds nothing of it`};let r=n?`; outside the instance's parts -${n.removed} +${n.added} lines someone else wrote meanwhile, which stay`:"";return a?{unverified:`${e}, and ${o} holds the instance no more where it stood: someone else wrote the file meanwhile`}:t.length===0?{unverified:`${e}: ${o} is as it was${n?" in the instance's parts":""} (${c})${r}`}:i?{unverified:`${e}: what ${o} holds of ${Y(t)} is someone else's, which stays${r}`}:{unverified:`${e}: ${o} holds what the ${s} wrote, ${Y(t)}, kept (--keep)${r}`}}function Dn(e,t,{over:n,unfocused:a,refusals:s,name:o}){let i=[];return n&&i.push(`the press landed on ${n}, which stands over it there`),a&&i.push(e==="type"?`the element takes no typing (a field or an editable element), so the words went to ${a}`:`the element takes no focus (a button, a field or a tabindex), so the key went to ${a}`),t.started&&!t.dropped?i.push(`an HTML5 drag started (dragstart on ${t.started}) and nothing took its drop where it was released (dragend's dropEffect ${t.effect??"none"}): a list a card is dropped on cancels dragenter as well as dragover (preventDefault), or a release as the pointer comes onto it drops nothing`):t.dropped&&t.edits.length===0&&i.push(`it was dropped on ${t.dropped}, and no context.edit came of it`),t.edits.some(({taken:l})=>l)?i.push("context.edit was taken, and its change left what the parts hold as it was"):t.edits.length?i.push(`context.edit was called and the page refused it${s.length?`: the console says ${s.join("; ")}`:""}`):t.started||i.push(e==="type"?"no context.edit came of it: the component answers no typing there, or writes what was typed only on a key or as the field loses the focus (then Enter, --then Enter), or asked while context.canEdit() was false":`no context.edit came of it: the component answers no ${de[e]} there, or asked while context.canEdit() was false`),`the ${de[e]} wrote nothing to ${o}: ${i.join("; ")}`}async function Et(e,t){await We(e);let n={own:new Map,others:new Map,dialogs:new Map,pending:[],page:0,from:0},a=new RegExp(`/__gallery/components/${t}/kit\\.js[^:\\s)]*:(\\d+)`),s=(i,l,{at:c="",unparsed:r=!1}={})=>{if(l<n.from)return;let d=i.split(`
8
- `)[0],h=a.exec(i)??a.exec(c);i.includes(t)||h?n.own.set(d,{line:Number(h?.[1])||null,page:l,unparsed:r&&a.test(c)}):n.others.set(d,{page:l})};e.on("request",i=>{i.isNavigationRequest()&&i.frame()===e.mainFrame()&&(n.page+=1)}),e.on("console",i=>{if(!["error","warn","warning"].includes(i.type())||/^Failed to load resource/.test(i.text()))return;let{page:l}=n;n.pending.push(Promise.all(i.args().map(c=>c.evaluate(r=>r instanceof Error?r.stack:String(r)).catch(()=>""))).then(c=>s(c.join(" ")||i.text(),l)))});let o=await ze(e,{add:i=>n.dialogs.set(i,{page:n.page})});return o.on("Runtime.exceptionThrown",({exceptionDetails:{exception:i,text:l,url:c,lineNumber:r,stackTrace:d}})=>{s(i?.description??String(i?.value??l),n.page,{at:c?`${c}:${r+1}`:"",unparsed:!d&&i?.className==="SyntaxError"})}),await o.send("Runtime.enable"),n}function _n(e){e.from=e.page;for(let t of[e.own,e.others,e.dialogs])for(let[n,{page:a}]of t)a<e.from&&t.delete(n)}var re=e=>Promise.race([Promise.all(e.pending),he(2e3)]);async function Fn(e){let t=n=>e.waitForSelector(n,{timeout:le}).catch(a=>{if(a.name==="TimeoutError")throw a;return e.waitForSelector(n,{timeout:le})});try{return await t("[data-doc-ready]"),await t("html[data-ge-editing][data-ge-save]"),await e.waitForFunction(()=>globalThis.__galleryTryEditable===!0&&document.documentElement.getAttribute("data-ge-save")==="saved",{timeout:le}),!0}catch(n){if(n.name!=="TimeoutError")throw n;return!1}}async function St(e,{where:t,id:n}){let a=await g(e.evaluateHandle($n,{instance:ft,...t}),"the page was asked for the instance"),s=await g(a.evaluate((o,{fallback:i,id:l})=>!(o instanceof Element)||o.getAttribute("data-doc-component")!==l?null:(DocKit.reveal?.(o),{fallback:o.hasAttribute(i),height:o.getBoundingClientRect().height}),{fallback:Rt,id:n}),"the page was asked for the instance");return s?(await e.setViewport({width:De,height:Math.min(Wt,Math.max(_e,Math.ceil(s.height)+240))}),await g(a.evaluate(o=>o.scrollIntoView({block:"center",behavior:"instant"})),"the instance was brought into view"),await g(a.evaluate(Fe,{still:we,step:ge,wait:$e}),"the instance held still"),{host:a,fallback:s.fallback}):null}function Hn({at:e,found:t}){return{where:{at:e},ready:Fn,saves:n=>({mark:()=>g(n.evaluate(()=>globalThis.__galleryTry.states.length),"the page was asked where saving stands"),until:(a,s)=>jn(n,a,s)}),changes:(n,a)=>on(st(n),st(a),e,t),plain:(n,a,s)=>a===n&&Se(n).changes.length>0&&s.parts.length>0,stayed:Mn,outside:"others",aside:"data-block-id aside",inside:Tt}}async function Pn(e){return g(e.evaluate(({instance:t,fields:n})=>{let a=document.activeElement;return a instanceof HTMLElement&&a.closest(t)&&a.matches(n)?(a.blur(),!0):!1},{instance:ft,fields:Dt}),"the focus left the instance's field")}async function Bn(e){await e.keyboard.down("Control"),await e.keyboard.press("z"),await e.keyboard.up("Control")}var Jn=e=>`${e}${[11,12,13].includes(e%100)?"th":["th","st","nd","rd"][e%10]??"th"}`,Un=3,Le=(e,t)=>e.length===1?`the ${de[e[0].kind]}`:`step ${t+1}`,V=e=>e.length===1?`the ${de[e[0].kind]}`:"the steps";function Zn(e,t){if(e.words!==t.words){let a=0;for(;a<e.words.length&&e.words[a]===t.words[a];)a++;let s=o=>JSON.stringify(`${a>20?"\u2026":""}${o.slice(Math.max(0,a-20),a+30)}${o.length>a+30?"\u2026":""}`);return`its words read ${s(e.words)} there and ${s(t.words)} here`}let n=e.fields.findIndex((a,s)=>a!==t.fields[s]);if(n>=0||e.fields.length!==t.fields.length){let a=n>=0?n:Math.min(e.fields.length,t.fields.length);return`its field ${a+1} (of ${e.fields.length}) holds ${JSON.stringify(e.fields[a]??null)} there and ${JSON.stringify(t.fields[a]??null)} here`}return null}var ct=["ticked","not ticked"],qn=["true","false","checked","done"],Wn={amp:"&",lt:"<",gt:">",quot:'"',apos:"'",nbsp:" "},Me=e=>new Set(e.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}]+/gu)??[]),lt=e=>e.replace(/<[^>]*>/g," ").replace(/"(?:[^"\\]|\\.)*"\s*:/g," ").replace(/&(?:#(\d+)|#x([\da-f]+)|([a-z]+));/gi,(t,n,a,s)=>{let o=n?Number(n):a?Number.parseInt(a,16):null;return o!==null?o<=1114111?String.fromCodePoint(o):t:Wn[s.toLowerCase()]??t}),dt=e=>qn.map(t=>(e.join(`
9
- `).toLowerCase().match(new RegExp(`\\b${t}\\b`,"g"))??[]).length).join();function Gn(e){let t=new Set,n=!1;for(let{parts:a}of e)for(let{runs:s=[]}of a)for(let{removed:o,added:i}of s){let[l,c]=[Me(o.map(lt).join(`
10
- `)),Me(i.map(lt).join(`
11
- `))];for(let r of c)l.has(r)||t.add(r);for(let r of l)c.has(r)||t.add(r);dt(o)!==dt(i)&&(n=!0)}return{words:t,ticks:n}}function Kn(e,t,n){let a=({words:h,fields:f})=>Me([h,...f.filter(u=>!ct.includes(u))].join(" ")),[s,o]=[a(e),a(t)],i=[...[...s].filter(h=>!o.has(h)),...[...o].filter(h=>!s.has(h))],l=h=>/[^\x00-\x7f]/.test(h),c=h=>[...n.words].some(f=>f===h||[h,f].every(u=>[...u].length>=2)&&[f,h].some(u=>l(u))&&(h.includes(f)||f.includes(h))),r=i.filter(c),d=h=>JSON.stringify(h.fields.filter(f=>ct.includes(f)));return n.ticks&&d(e)!==d(t)&&r.push("a box ticked"),r}async function Vn(e,{root:t,address:n,fresh:a,steps:s,keep:o,file:i,name:l,line:c,found:r,out:d,host:h}){let f=await g(e.createBrowserContext(),"a browser context opened"),u=await g(f.newPage(),"a tab opened"),w=await g(Et(u,r.id),"the tab was set to listen"),k=h.saves(u),y=[w],p={problems:[],notes:[],steps:[]},m=($,O=`${l}:${c}`)=>p.problems.push({where:O,what:$}),L=!o,D=L?`the copy of ${l}`:l,_=new URL(n).origin,C=0,F=0;u.on("request",$=>{!$.isNavigationRequest()||$.frame()!==u.mainFrame()||(C+=1,F=Date.now())});let M=null,H=null,S=async()=>h.changes(H,await N.readFile(i,"utf8").catch(()=>"")),b=($,O,v=!1)=>({...p,unverified:Rn($,O,{gesture:s.length===1?de[s[0].kind]:"steps",name:l,held:v,scratch:L,aside:h.aside}).unverified}),j=h.stayed,Z=await g(u.createCDPSession(),"the tab opened a session");await g(u.evaluateOnNewDocument(()=>addEventListener("doc-editable",()=>{globalThis.__galleryTryEditable=!0})),"the tab was set to tell when the page takes edits"),await g(u.setViewport({width:De,height:_e}),"the window was sized"),await g(u.emulateMediaFeatures([{name:"prefers-color-scheme",value:"light"}]),"the light theme came");try{await g(u.goto(n,{waitUntil:"load",timeout:0}),"the page opened",Oe);let $=null,O=null;for(let x=1;!$;x++){let E=C;try{if(!await h.ready(u))return{...p,unverified:`the page did not come to edit in ${le/1e3}s, so nothing was tried`};if($=await St(u,{where:h.where,id:r.id}),!$)return{...p,unverified:`the page does not hold the instance where ${l} has it (${l} changed meanwhile?), so nothing was tried`};if(await he(Math.max(0,await cn(t,L?null:i)-Date.now())),$.fallback&&(O=await gn({root:t,id:r.id,origin:_,loadedAt:F,loaded:()=>C!==E})),C!==E)throw new Error("the page loaded itself again");if($.fallback)break;if(H=await N.readFile(i,"utf8"),await g($.host.evaluate(kt),"the page was asked to listen"),C!==E)throw new Error("the page loaded itself again")}catch(I){if(C===E||x===Un)throw I;$=null,_n(w)}}let{host:v}=$;if($.fallback){await re(w);let x=[...w.own].map(([E,{line:I,unparsed:z}])=>({words:`${E}${I?` (kit.js:${I})`:""}`,unparsed:z}));return w.own.clear(),m(un(r.id,{said:x.map(({words:E})=>E),unparsed:x.find(({unparsed:E})=>E)?.words??null,...O})),await ht(v,p,d,h.framed)}M=C;let P=H,X=null;for(let[x,E]of s.entries()){let I=Le(s,x),{taken:z}=await g(u.evaluate(bn),"the page was asked to listen"),fe=await k.mark(),W=await Cn(u,v,E,Z),Q=await k.until(fe,_),G=await N.readFile(i,"utf8").catch(()=>""),J=h.changes(P,G);if(p.steps.push({said:W.said,parts:J.parts,outside:J.outside,plain:h.plain(H,P,J),taken:z}),C>M)return b(`after ${I}, ${j("reloading")}`,await S());if(j(Q))return b(`after ${I}, ${j(Q)}`,await S(),Q==="held");if(J.gone)return b(`after ${I}`,await S());X={step:E,gestured:W,heard:await g(u.evaluate(()=>globalThis.__galleryTry),"the page was asked what it heard")};for(let{name:ve,how:R}of J.parts)R&&p.notes.push({where:`${l}:${c}`,what:`${I}'s write lays the part ${ve} out anew (${R}): ${Ge}`});J.parts.length&&(p.steps.at(-1).before=P),P=G}await ht(v,p,d,h.framed);let B=await g(v.evaluate(Fe,{still:we,step:ge,wait:$e}).then(()=>v.evaluate(bt)),"the instance held still"),q=p.steps.filter(({parts:x})=>x.length),be=p.steps.map(x=>x.outside).filter(Boolean);if(h.outside==="problem"?p.steps.forEach((x,E)=>{x.outside&&m(`${Le(s,E)} changed ${l} outside ${h.outsideSaid(x.outside)}`)}):be.length&&(p.others={removed:be.reduce((x,{removed:E})=>x+E,0),added:be.reduce((x,{added:E})=>x+E,0)}),q.length===0){await re(w);let x=[...w.own.keys()].filter(I=>I.includes("context.edit"));for(let I of x)w.own.delete(I);let E=Dn(X.step.kind,X.heard,{...X.gestured,refusals:x,name:D});return m(s.length===1?E:`none of the ${s.length} steps wrote anything to ${D}; of the last, step ${s.length}, ${E}`),p}if(!o){let x=await k.mark();if(await Pn(u)){let W=await k.until(x,_);if(C>M)return b(`as the focus left the instance's field, ${j("reloading")}`,await S());if(j(W))return b(`as the focus left the instance's field, ${j(W)}`,await S(),W==="held")}let E=await g(u.evaluate(()=>globalThis.__galleryTry.taken),"the page was asked what it took"),I=s.length===1,z=0,fe=0;e:for(let[W,Q]of[...q.entries()].toReversed()){let G=Le(s,p.steps.indexOf(Q)),J=Math.max(1,(q[W+1]?.taken??E)-Q.taken),ve=R=>I?R===1?"one Ctrl+Z":`${R} Ctrl+Z`:`${R===1?"the Ctrl+Z":`${R} Ctrl+Z`} for ${G}`;for(let R=1;;R++){let oe=R===1?`the Ctrl+Z for ${G}`:`the ${Jn(R)} Ctrl+Z for ${G}`,At=await k.mark();await Bn(u);let ue=await k.until(At,_),Lt=await N.readFile(i,"utf8").catch(()=>""),xe=h.changes(Q.before,Lt);if(C>M)return b(`after ${oe}, ${j("reloading")}`,await S());if(j(ue))return b(`after ${oe}, ${j(ue)}`,await S(),ue==="held");if(xe.gone)return b(`after ${oe}`,await S());if(ue==="unchanged"){m(`${R===1&&I?"one Ctrl+Z":oe} wrote nothing, so ${D} keeps what ${G} wrote: a reader's undo does not take it back (the component keeps Ctrl+Z from the page where the focus is, or wrote by no context.edit)`);break e}if(xe.parts.length===0){fe+=R;break}if(R>=J){m(`after ${ve(R)}${J>1?", one for each write the page took of it,":""} ${D} is not as it was${I?"":` before ${G}`}, ${Y(xe.parts)} still differing: a reader's undo does not give it back (the component writes again as it hears the part change)`);break e}}z+=1}z===q.length&&Object.assign(p,{undone:z,presses:fe})}if(p.problems.length)return p;await pe(u.close());let Ot=x=>p.notes.push({where:`${l}:${c}`,what:x}),ee=await Qn(f,{...await a(P),host:h,found:r,after:B,written:Gn(q),out:d,hearings:y,problem:m,note:Ot,called:V(s)});return p.readBack=ee.back,p.aside=ee.aside??!1,ee.picture&&(p.fresh=ee.picture),ee.unverified?p.unverified=`${ee.unverified}, so it was not read back`:p.others&&(p.unverified=`someone else wrote ${l} meanwhile, outside the instance's parts (the user's page, an Agent), which stays: try it again once the file holds still`),p}catch($){if($ instanceof T){if(p.steps.length&&($.made=p),!$.unfound||(await re(w),w.own.size===0&&w.dialogs.size===0))throw $;return m(`${$.message[0].toLowerCase()}${$.message.slice(1).replace(/\.$/,"")}; its component did not draw it, and the console says why`),p}let O=M===null?null:await S();if(O&&C>M)return b(`after a gesture, ${j("reloading")}`,O);if(await Ye(e)){let v=`the browser went while waiting until ${$.doing??"the page answered"}`;return O?b(v,O):{...p,unverified:`${v}, so nothing was tried`}}return $.stuck?m(`the page stopped answering while waiting until ${$.doing}: a script that never ends, or a component that changes what it hears`,"the page"):m(`the trial stopped: ${ne($)}`,"the page"),p}finally{let $=new Set;for(let O of y){await re(O);for(let[v,{line:P}]of O.own)!$.has(v)&&$.add(v)&&p.problems.push({where:P?`kit.js:${P}`:"the page",what:`the console says ${v}`});for(let v of O.others.keys())!$.has(v)&&$.add(v)&&p.notes.push({where:"the page",what:`the console says ${v}`});for(let v of O.dialogs.keys())!$.has(v)&&$.add(v)&&p.problems.push({where:"the page",what:`it opened a dialog (${v}), which stops a reader's page until it is answered: show what it says in the instance`})}await pe(f.close())}}function zn(e,t,n,a){console.log(`FAIL ${e}: ${Qe(t)}, so nothing was tried and the browser was closed${a?"":`; the copy of ${n} was taken away`}. A script that never ends does this, and so may a browser that stalled: run the command once more`),process.exitCode=1}async function Qn(e,{address:t,file:n,host:a,found:s,after:o,written:i,out:l,hearings:c,problem:r,note:d,called:h}){let f=await g(e.newPage(),"a tab opened");c.push(await g(Et(f,s.id),"the fresh tab was set to listen"));let u=a.saves(f),w=c.at(-1),k=new URL(t).origin;await g(f.evaluateOnNewDocument(()=>addEventListener("doc-editable",()=>{globalThis.__galleryTryEditable=!0})),"the fresh tab was set to tell when the page takes edits"),await g(f.setViewport({width:De,height:_e}),"the window was sized"),await g(f.emulateMediaFeatures([{name:"prefers-color-scheme",value:"light"}]),"the light theme came");let y=`a fresh page of what ${h} wrote`,p={back:!1};try{let m=await N.readFile(n,"utf8");if(await g(f.goto(t,{waitUntil:"load",timeout:0}),"the fresh page opened",Oe),!await a.ready(f))return{back:!1,unverified:`${y} did not come to edit in ${le/1e3}s`};let L=await St(f,{where:a.where,id:s.id});if(!L)return r(`${y} does not hold the instance where the file has it: what the steps wrote is no instance of ${s.id} as the page reads it`),p;if(L.fallback){await re(w);let b=[...w.own].map(([j,{line:Z}])=>`${j}${Z?` (kit.js:${Z})`:""}`);return w.own.clear(),r(`${y} shows the instance in its fallback, what it holds read-only: its component failed as the page started it, ${b.length?`and the console says ${b.join("; ")}`:"and the console said nothing of it"}: what ${h} wrote is what its mount cannot read`),p}await g(L.host.evaluate(kt),"the fresh page was asked to listen");let D=await u.until(await u.mark(),k);if(D==="offline")return{back:!1,unverified:`${y}: ${a.stayed(D)}`};if(D!=="unchanged"&&D!=="saved")return r(`${y}: ${a.stayed(D)??D}`),p;let _=a.changes(m,await N.readFile(n,"utf8").catch(()=>""));if(_.gone)return{back:!1,unverified:`${y}: its file holds the instance no more where it stood (someone else wrote it meanwhile)`};if(D==="saved"||_.parts.length)return r(`${y} writes ${_.parts.length?Y(_.parts):"it again"} with no gesture as it opens, so that a page would write each time it opened: draw what the parts hold as they are, and write on a gesture alone`),p;let C=await g(L.host.evaluate(Fe,{still:we,step:ge,wait:$e}).then(()=>L.host.evaluate(bt)),"the fresh page's instance held still"),F=Zn(o,C);if(!F)return{back:!0};let M=A.join(l,"fresh.png");await g(L.host.screenshot({path:M}),"the fresh page's instance was pictured").catch(()=>{});let H=`${y} shows the instance otherwise than the page did after ${h.replace(/^the steps$/,"the last step")}: ${F}`,S=Kn(o,C,i);return S.length?(r(`${H} (the fresh page's picture: ${K(M)}), and what differs is of what ${h} wrote (${S.slice(0,3).map(b=>b==="a box ticked"?b:JSON.stringify(b)).join(", ")}). What it draws of what it wrote is to come from its parts alone, read as it wrote them: a value kept in memory, or written in a form its mount does not read, is gone on the next page`),{...p,picture:M}):(d(`${H}; none of it is of what ${h} wrote, and a fresh page keeps no filter or tab chosen, no editor left open, no words typed and not committed (--then Enter commits them), and need not. Its picture: ${K(M)}. What a reader keeps belongs in a part`),{back:!0,aside:!0,picture:M})}catch(m){return await xt(k)?(m.stuck?r(`${y} stopped answering while waiting until ${m.doing}: a script that never ends, or a component that changes what it hears`,"the page"):r(`${y} could not be read back: ${ne(m)}`,"the page"),p):{back:!1,unverified:`the server stopped answering as ${y} opened`}}finally{await pe(f.close())}}async function ht(e,t,n,a=null){let s=A.join(n,"after.png");try{let o=a?await g(e.evaluateHandle(a),"the instance's frame was found"):e;await g(o.screenshot({path:s}),"the instance was pictured"),t.picture=s}catch(o){if(o.stuck)throw o}return t}var U={gesture:"Gesture: ",step:"Step ",wrote:"Wrote: ",undone:"Undone: ",kept:"Kept (--keep): ",readBack:"Read back: ",picture:"Picture of the instance after "},Tt="nothing outside the instance changed (data-block-id aside)",Yn="open it: no one has looked at it for you";function Xn({slug:e,name:t,steps:n,keep:a,host:s=null},o){let i=n.length>1,l=a?t:`the copy of ${t}`,c=s?.aside??"data-block-id aside",r=Nt({name:t,several:i,keep:a,host:s},o.steps),d=o.steps.filter(({parts:p})=>p.length),h=a&&d.some(({plain:p})=>p)?", its plain HTML the kit's markup":"",f=o.presses??o.undone;if(a&&d.length)r.push(`${U.kept}${t} holds what ${V(n)} wrote`);else if(o.undone){let p=i?f===o.undone?`${f} Ctrl+Z, one for each step that wrote, the last first, each giving ${l} back as it was before its step`:`${f} Ctrl+Z for the ${o.undone} step${o.undone===1?"":"s"} that wrote, one for each write the page took, the last first, each step's giving ${l} back as it was before it`:f===1?`one Ctrl+Z, and ${l} is as it was`:`${f} Ctrl+Z, one for each write the page took of ${V(n)}, and ${l} is as it was`;r.push(`${U.undone}${p} (${c}${h})`)}o.readBack&&r.push(`${U.readBack}${a?`${t} opened again in a fresh page`:`a fresh page of what ${V(n)} wrote (a copy of it)`}: the instance mounts, writes nothing as it opens, and shows what the page showed after ${i?"the last step":V(n)}${o.aside?` of what ${i?"they":"it"} wrote; what else the page showed there, which nothing wrote, it does not (the note)`:""}`);for(let{where:p,what:m}of o.problems)r.push(` FAIL ${p}: ${m}`);for(let{where:p,what:m}of o.notes)r.push(` note ${p}: ${m}`);o.picture&&r.push(`${U.picture}${i?"the last step":V(n)}: ${K(o.picture)} (${Yn})`);let u=[o.picture,o.fresh].filter(Boolean);u.length&&r.push(Xe([{folder:A.dirname(u[0]),files:u}]));let w=o.problems.length;if(w)return{lines:[...r,`FAIL ${e}: ${w} problem${w===1?"":"s"}`],code:1};if(o.unverified)return{lines:[...r,`UNVERIFIED ${e}: ${o.unverified}`],code:3};let k=[...new Set(d.flatMap(({parts:p})=>p.map(({name:m})=>m)))].join(" and "),y=a?", kept (--keep)":`, ${f===1?"one Ctrl+Z":`${f} Ctrl+Z`} took ${i?"them":"it"} back`;return{lines:[...r,`OK ${e}: ${V(n)} wrote ${k}${y}, and a fresh page read ${i?"them":"it"} back${a?"":`; ${t} not written (a scratch copy)`}`],code:0}}function Nt({several:e,keep:t,host:n=null},a){let s=[];for(let[o,i]of a.entries()){if(s.push(e?`${U.step}${o+1}: ${i.said}`:`${U.gesture}${i.said}`),i.parts.length===0){e&&s.push(`${U.wrote}nothing`);continue}let l=t&&i.plain?"; and the page wrote the document's plain HTML as the kit's markup, as its first save of an edit does (gallery check and gallery export say what, by line, once), which stays":"",c=i.outside?n?.outside==="problem"?`; and outside ${n.outsideSaid(i.outside)}`:`; outside the instance's parts -${i.outside.removed} +${i.outside.added} lines someone else wrote meanwhile (the user's page, an Agent), which stay`:`; ${n?.inside??Tt}`;s.push(`${U.wrote}${Y(i.parts)}${c}${l}`,...rn(i.parts))}return s}function ea({name:e,steps:t,keep:n,host:a=null},s){let o=s.steps.length,i=o===1?"step 1":`steps 1 to ${o}`,l=s.steps.some(({parts:d})=>d.length),c=Nt({name:e,several:t.length>1,keep:n,host:a},s.steps),r=`step ${o+1} was not made, for the mistake below`;return n?c.push(l?`${U.kept}${e} holds what ${i} wrote, which stays; ${r}`:`Not made: ${r}; ${i} wrote nothing to ${e}`):c.push(`Not made: ${r}; ${i} ${l?"wrote to":"made"} a scratch copy, gone now, and ${e} holds nothing of ${o===1?"it":"them"}`),c}async function ka(e,{named:t,values:n,seconds:a={},keep:s,replace:o=!1}){let i=await Yt(n,a,o),l=i?[i]:null;if(t.length===0)throw new T("Name the document: gallery block try <slug> [<instance id>] and the gesture.");if(t.length>2)throw new T("gallery block try takes a document and an instance's id at most.");let c=n.has("--steps")?A.resolve(n.get("--steps")):null,r=l??await Xt(c),{slug:d,block:h}=await Pe(t[0]),f=Pt(d,e),u=Bt(f),w=u.html,k=await N.readFile(w,"utf8").catch(()=>null);k===null&&(console.error(`No document "${d}": ${K(w)} does not exist (gallery list lists those there are).`),process.exit(1));let y=wt(k);y.length===0&&(console.error(`${d} holds no instance of a custom block (an element with ${ke}): gallery block list says which there are, and gallery block show <id> how to write one.`),process.exit(1));let p=A.basename(w),m=nn(y,t[1]??h,{slug:d,name:p}),{id:L,line:D}=y[m],_=Ee(e),C=_.packages.get(L);if(!C){let S=_.problems.get(L);console.error(S?.off?`${L} is turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868: its instances show what they hold, read-only, so a reader can do nothing with them.`:S?`${L} does not load, so its instances show what they hold, read-only: gallery block check ${L} says why.`:`No component ${L} in this workspace, so its instance shows what it holds, read-only: gallery block list says which there are.`),process.exit(1)}console.log(`${L} in ${d}, ${gt(y[m],p)}: ${K(w)}`),c&&console.log(`Steps: ${r.length} from ${K(c)}, made one after another in one page`);let F=await Je({slug:d,command:`gallery block try ${d}`});if(!F.ok){console.log(`UNVERIFIED ${d}: ${F.message}`),process.exitCode=3;return}await dn(e);let M=[],H=async S=>{let b=await ln(e,{directory:f,files:u,text:S});return M.push(b.slug),b};try{let S=s?{slug:d,file:w}:await H(k),b=Te(F.port,S.slug);console.log(s?`Page: ${b} (the document's page alone, editable: the Agent's own; --keep: what ${V(r)} write stays in ${p}; the server runs on after this command)`:`Page: ${b} (a scratch copy of ${d}, its page alone, editable, made for this trial and gone at its end: ${p} is not written, and no page of the user's shows the trial; the server runs on after this command)`);let j=Ue();if(!j){console.log(`UNVERIFIED ${d}: no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one), so nothing was tried`),process.exitCode=3;return}let Z;try{Z=await qe({executablePath:j,args:Ze()})}catch(O){console.log(`UNVERIFIED ${d}: the browser ${j} did not start, twice, each time with a fresh profile (${ne(O)}; GALLERY_BROWSER=<its executable> picks another), so nothing was tried`),process.exitCode=3;return}let $=A.join(se(e).qa,d,"try");try{await N.rm($,{recursive:!0,force:!0}),await N.mkdir($,{recursive:!0});let O=async B=>{if(s)return{address:b,file:S.file};let q=await H(B);return{address:Te(F.port,q.slug),file:q.file}},v;try{v=await Vn(Z.browser,{root:e,address:b,fresh:O,steps:r,keep:s,file:S.file,name:p,line:D,found:C,out:$,host:Hn({at:m,found:C})})}catch(B){if(B instanceof T&&B.made&&console.log(ea({name:p,steps:r,keep:s},B.made).join(`
12
- `)),B.stuck)return zn(d,B,p,s);throw B}let{lines:P,code:X}=Xn({slug:d,name:p,steps:r,keep:s},v);console.log(P.join(`
13
- `)),process.exitCode=X}finally{await Z.close()}}finally{for(let S of M)await $t(e,S)}}export{le as a,Gt as b,Ie as c,at as d,ie as e,ut as f,Yt as g,Xt as h,wt as i,gt as j,nn as k,an as l,st as m,ot as n,on as o,rn as p,cn as q,ln as r,$t as s,dn as t,fn as u,un as v,gn as w,Fe as x,An as y,Rn as z,Dn as A,Et as B,_n as C,Hn as D,V as E,Zn as F,Me as G,Gn as H,Kn as I,Vn as J,zn as K,U as L,Tt as M,Yn as N,Xn as O,ea as P,ka as Q};
@@ -1,2 +0,0 @@
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 S,b as K,c as E,d as v,e as x,f as H}from"./chunk-GMJD7ID3.mjs";import{a as D,b as j}from"./chunk-JEUK3ZO7.mjs";import{b as M,f as R,h as T}from"./chunk-4OZWXZE5.mjs";import O from"node:fs/promises";import _ from"node:path";import{iconKind as ee}from"../browser/shared/emoji/icon-value.mjs";import{descendantsIn as J,parentIn as C}from"../browser/shared/outline.mjs";import{topOf as U}from"../browser/shared/outline-shape.mjs";import{fullAddress as z,namedPlace as te}from"../browser/shared/page-address.mjs";import{reportsDirectory as G}from"../browser/shared/paths.mjs";import{documentLinks as Q,listReportSlugs as oe,roleOf as ne}from"../browser/shared/reports.mjs";import{documentDirectory as se,documentFiles as le,isSlugName as ie}from"../browser/shared/workspace.mjs";import{isWorkspace as W,readRegistry as re,workspaceKey as Y}from"../browser/shared/workspace-registry.mjs";import{findIn as ce,rankReports as V,reportLines as ae}from"../browser/shared/search.mjs";async function X(i=G){let n=(await oe(i)).filter(ie);return(await Promise.all(n.map(async a=>{let r=se(a,i),{html:u,json:s}=le(r),g=await O.stat(u).catch(()=>null);if(!g?.isFile()||await ne(r)==="instructions")return null;let l=await O.readFile(s,"utf8").then(JSON.parse).catch(()=>({})),d=t=>typeof t=="string"?t.replace(/\s+/g," ").trim():"";return{slug:a,title:d(l.title)||a,description:d(l.description),edited:g.mtimeMs,file:u}}))).filter(Boolean)}var P=i=>{let n=new Date(i),o=a=>String(a).padStart(2,"0");return`${n.getFullYear()}-${o(n.getMonth()+1)}-${o(n.getDate())} ${o(n.getHours())}:${o(n.getMinutes())}`},k=i=>`${i} document${i===1?"":"s"}`;async function de(i,n,o){let a=[...new Set(o.toLowerCase().split(/\s+/).filter(Boolean))],r=new Set(n.map(({slug:s})=>s));return(await Promise.all(i.filter(({slug:s})=>!r.has(s)).map(async s=>{let g=ae(await O.readFile(s.file,"utf8").catch(()=>"")),l=a.map(d=>ce(g,d,{most:1})).filter(({count:d})=>d>0);return l.length?{...s,words:l.length,count:l.reduce((d,{count:t})=>d+t,0),hit:l[0].hits[0].text}:null}))).filter(Boolean).sort((s,g)=>g.words-s.words||g.count-s.count||g.edited-s.edited)}var q=i=>[...i.documents.values()].filter(n=>typeof n.url=="string"),F=i=>`${i} web link${i===1?"":"s"}`;async function ge(i,n){if(i.length>1)throw new M("--tree takes one document at most (its slug, link or address).");let o=await S(),a=new Map(n.map(e=>[e.slug,e])),r=new Map((o.extensions??[]).map(e=>[e.id,e])),u=o.columns.filter(e=>(!e.extension||r.has(e.extension))&&!e.hidden&&!e.away),s=u.length>1?u:null,g=o.children[""]??[],l=null;if(i.length===1){let e=await H(i[0],"--tree",o);if(e.refused){for(let h of await j({reading:!0}))console.log(h);console.error(e.refused),process.exit(1)}l=e.slug,g=[l]}for(let e of await j({reading:!0}))console.log(e);let d=e=>console.log(`${e.title}\u680F\uFF08\u6269\u5C55 ${e.id}\uFF1A${e.error?`\u6761\u76EE\u8BFB\u4E0D\u51FA\u6765\uFF1A${e.error.message}`:`${e.count} \u4E2A\u6761\u76EE`}\uFF1Bgallery extension check ${e.id} \u6253\u51FA\u5B83\u4EEC\uFF09`),t=()=>{for(let e of r.values())d(e)},p=u.filter(e=>!e.extension).flatMap(e=>J(o.children,U(e.id))),f=p.filter(e=>o.documents.get(e)?.url!==void 0).length,m=p.length-f;if(m+f===0){console.log('No documents yet: gallery new <slug> "<title>" makes one.'),l===null&&t();return}let w=f?`${k(m)} and ${F(f)}`:k(m);if(l===null)console.log(`${w}, as the sidebar shows them (one under another indented)${s?", column by column":""}:`);else{let e=J(o.children,l),h=e.some($=>o.documents.get($)?.url!==void 0)?`${e.length} ${e.length===1?"entry":"entries"}`:k(e.length);console.log(x(o,l)),console.log(e.length?`${v(o,l)} and the ${h} under it, as the sidebar shows them:`:`${v(o,l)}, with no document under it:`)}let c=(e,h)=>{let{title:$,description:y,icon:b,url:B,draft:N}=o.documents.get(e),A=a.get(e)?.edited,L=E(o,e),I=B!==void 0?[`\u7F51\u9875\u94FE\u63A5\uFF1A${B}`]:N?[N.missing?"\u522B\u5904\u7684\u5E95\u7A3F\uFF0C\u627E\u4E0D\u5230\u4E86":L?`\u300C${L}\u300D\u7684\u5E95\u7A3F\uFF1A${N.path}`:`\u522B\u5904\u7684\u5E95\u7A3F\uFF1A${N.path}`]:[...L?[`\u300C${L}\u300D\u7684\u6587\u6863`]:[],...y?[`\u8BF4\u660E\uFF1A${y}`]:[],...A?[`\u4E0A\u6B21\u7F16\u8F91\uFF1A${P(A)}`]:[]];console.log(`${" ".repeat(h)}${e} ${ee(b)==="emoji"?`${b} `:""}${$}${I.length?` \uFF08${I.join("\uFF1B")}\uFF09`:""}`);for(let Z of o.children[e]??[])c(Z,h+1)};if(l!==null||!s){for(let e of g)c(e,0);l===null&&t();return}for(let e of s){if(e.extension){d(r.get(e.extension)),r.delete(e.extension);continue}let h=o.children[U(e.id)]??[];console.log(`${K(e)}\u680F${h.length?"":"\uFF08\u7A7A\uFF09"}`);for(let $ of h)c($,1)}t()}async function fe(i){let n=_.resolve(G),o=(t,p)=>Y(t)===Y(p),a=[n,...re().workspaces.map(({root:t})=>t).filter(t=>!o(t,n))],r=a.filter(W),u=a.filter(t=>!W(t)),s=(await Promise.all(r.map(async t=>(await X(t)).map(p=>({...p,root:t}))))).flat(),g=i.join(" ").trim(),l=V(s,g),d=`${r.length} workspace${r.length===1?"":"s"}`;if(console.log(`Searched ${d} of this machine (gallery workspaces lists them; the current one: ${n}).`),s.length===0)console.log(`No documents in ${r.length===1?"it":"any of them"} yet.`);else if(l.length===0)console.log(`No document's title, description or slug in the ${d} holds ${g.split(/\s+/).map(t=>`"${t}"`).join(" or ")}: gallery list --all lists all ${s.length}.`);else{console.log(g?`${l.length} of ${k(s.length)}, the best match first:`:`${k(s.length)}, the one edited last first:`);let t=new Map,p=f=>(t.has(f)||t.set(f,Promise.all([Q(f),S(f)]).then(([{links:m},w])=>({links:m,tree:w}))),t.get(f));for(let{root:f,slug:m,title:w,description:c,edited:e,file:h}of l){let{links:$,tree:y}=await p(f);console.log(`\u5DE5\u4F5C\u533A\uFF1A${f}`),console.log(`${m} ${w}`),c&&console.log(` \u8BF4\u660E\uFF1A${c}`),C(y.children,m)&&console.log(` ${x(y,m)}`),console.log(` \u5730\u5740\uFF1A${z("",{slug:m},$)}`),console.log(` \u4E0A\u6B21\u7F16\u8F91\uFF1A${P(e)}`),console.log(` ${D(h)}`)}console.log('One in another workspace is worked on there: pass its \u5DE5\u4F5C\u533A as --workspace to every command (gallery open <slug> --workspace "<\u5DE5\u4F5C\u533A>" gives its address).')}u.length&&console.log(`Not searched, no longer there (gallery workspaces --forget <path> forgets one, nothing on disk changed): ${u.join(", ")}`)}async function Me(i){let{positional:n,options:o}=R({options:["--tree","--all"],argv:i});if(o.has("--all")){if(o.has("--tree"))throw new M("--all and --tree go apart: --tree is the current workspace's tree.");return fe(n)}let a=await X();if(o.has("--tree"))return ge(n,a);let r=n.join(" ").trim(),{links:u}=await Q(),s=n.length===1?te(n[0],u):null,g=s&&s.slug!==n[0],l=g?a.filter(({slug:c})=>c===s.slug):V(a,r),d=[...l,...r&&!g?await de(a,l,r):[]],t=await S(),p=r.toLowerCase().split(/\s+/).filter(Boolean),f=g?[]:q(t).filter(({slug:c,title:e,url:h})=>!p.length||p.some($=>`${e} ${h} ${c}`.toLowerCase().includes($))),m=n.length===1&&d.length===0&&f.length===0?await T(n[0]):null;for(let c of await j({reading:!0}))console.log(c);let w=()=>{if(!f.length)return;let c=q(t).length;console.log(r?`${f.length} of ${F(c)} in the sidebar:`:`${F(c)} in the sidebar:`);for(let{slug:e,title:h,url:$}of f)console.log(`${e} ${h}`),console.log(` \u7F51\u9875\u94FE\u63A5\uFF1A${$}`),C(t.children,e)&&console.log(` ${x(t,e)}`)};if(m)console.log(m);else if(a.length===0)console.log('No documents yet: gallery new <slug> "<title>" makes one.'),w();else if(d.length===0&&f.length===0)console.log(`No document's title, description, slug or text holds ${r.split(/\s+/).map(c=>`"${c}"`).join(" or ")}: gallery list lists all ${a.length}.`);else if(d.length===0)w();else{console.log(r?`${d.length} of ${k(a.length)}, the best match first:`:`${k(a.length)}, the one edited last first:`);for(let{slug:c,title:e,description:h,edited:$,file:y,hit:b}of d)console.log(`${c} ${e}`),h&&console.log(` \u8BF4\u660E\uFF1A${h}`),b&&console.log(` \u6B63\u6587\uFF1A${b}`),C(t.children,c)&&console.log(` ${x(t,c)}`),console.log(` \u5730\u5740\uFF1A${z("",{slug:c},u)}`),console.log(` \u4E0A\u6B21\u7F16\u8F91\uFF1A${P($)}`),console.log(` ${D(y)}`);w()}}export{X as a,P as b,Me as c};
@@ -1,20 +0,0 @@
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 De,b as Fe}from"./chunk-IA4PSIMD.mjs";import{b as Ie}from"./chunk-F4ZA6JRZ.mjs";import{a as be,b as Ne,c as ht,d as Te,e as Ee,f as Re}from"./chunk-6NLXUKAY.mjs";import{b as je,c as Me,e as Ae,g as Gt}from"./chunk-VRPVVMRB.mjs";import{a as he}from"./chunk-UMHUSOPJ.mjs";import{a as $e,d as xe,e as Se,f as ve,g as Oe}from"./chunk-W5NPH5UA.mjs";import{e as ye,f as ge,g as ke,h as Kt}from"./chunk-ECZBLQKK.mjs";import{a as J,m as we}from"./chunk-E7656LR7.mjs";import{g as me,u as pe}from"./chunk-TKWEX4FD.mjs";var Mn=3e4,An=12e4,Nn=1500,Je=1e4,Pe=p=>p.reduce((u,{key:d,tag:f})=>u.set(`${d}
3
- ${f}`,(u.get(`${d}
4
- ${f}`)??0)+1),new Map);function Le({now:p=Date.now,hold:u=Mn,limit:d=An,quiet:f=Nn}={}){let b=new Map,h=new Map,x=new Map,l=new Map,c=new Map;return{wrote(g,k){l.set(g,J(k))},judge(g,{source:k,mtime:R}){if(k===null)return b.delete(g),x.delete(g),{held:!1,signs:[],wait:0,own:!1};let N=J(k),S=c.get(g)?.hash===N?c.get(g).signs:null;S||(S=Ne(k),c.set(g,{hash:N,signs:S}));let Q=p(),L=(U,D=!1)=>(b.delete(g),h.set(g,Pe(S)),x.set(g,k),{held:!1,signs:[],wait:U,own:D});if(l.get(g)===N)return L(0,!0);let _=h.get(g)??new Map,z=Pe(S);if([...z].some(([U,D])=>D>(_.get(U)??0))){let U=Math.min(R,Q),D=b.get(g)??U;b.set(g,D);let V=Math.min(u-(Q-U),d-(Q-D));if(V>0)return{held:!0,signs:S.filter(({key:s,tag:w})=>z.get(`${s}
5
- ${w}`)>(_.get(`${s}
6
- ${w}`)??0)),wait:V,own:!1,taken:x.get(g)}}return L(Math.min(f,Math.max(0,f-(Q-R))))}}}import{documentKey as nr}from"../browser/shared/workspace-address.mjs";import{serviceLocation as rr}from"../browser/shared/service-location.mjs";import{createHmac as or,randomBytes as ee}from"node:crypto";import{existsSync as ar,mkdirSync as sr,readFileSync as ir,writeFileSync as cr}from"node:fs";import H from"node:fs/promises";import P from"node:path";import{FILE as fr}from"../browser/shared/annotations.mjs";import{escapeTyped as lr}from"../browser/shared/escape.mjs";import{writeAtomic as Jt}from"../browser/shared/files.mjs";import{sendJson as Y}from"../browser/shared/http.mjs";import{REQUEST_ID as Xt}from"../browser/shared/ids.mjs";import{UPLOAD_REQUEST_LIMIT as ur}from"../browser/shared/media.mjs";import{reportsDirectory as dr}from"../browser/shared/paths.mjs";import{sameDirectory as mr}from"../browser/shared/preview-server.mjs";import{slugPattern as rt}from"../browser/shared/reports.mjs";import{TODO_MOST as pr}from"../browser/shared/workspace-query.mjs";import{documentDirectory as wr,documentFiles as Nt,isDocumentSource as hr}from"../browser/shared/workspace.mjs";import Qt from"node:fs/promises";import _e from"node:path";import{checkAnnotations as Tn,cleanAnchor as En,cleanItem as Ue,FILE as Rn,itemsText as In,readItems as Dn,treeText as We}from"../browser/shared/annotations.mjs";import{writeAtomic as Fn}from"../browser/shared/files.mjs";import{slugPattern as Pn}from"../browser/shared/reports.mjs";import{documentDirectory as Be,documentFiles as Jn}from"../browser/shared/workspace.mjs";var Ln=600*1e3,_n=600*1e3;function Un(p){let{units:u,boxes:d}=ke(p),f=[...u].sort((l,c)=>l.elStart-c.elStart),b=new Map(f.map((l,c)=>[l.id,c])),h=new Map(f.map(l=>[l.id,We(l.node)])),x={h2:null,h3:null,h4:null};return f.map(l=>{let c=[];for(let N=l;N;N=N.parent===null?null:u[N.parent]){let S=d[N.box];if(S?.kind==="panel"&&S.key!==null){let L=u.find(_=>_.kind==="tab"&&_.parent===S.unit&&_.key===S.key);L&&c.unshift({tab:h.get(L.id)})}let Q=S?.unit===null||S?.unit===void 0?null:u[S.unit];if(Q?.tag==="details"&&S.kind==="details"){let L=Q.node.childNodes.find(_=>_.tagName==="summary");L&&c.push({details:We(L)})}}let g=c.find(N=>N.tab)?.tab,k=c.find(N=>N.details)?.details,R=[g,x.h2,x.h3,x.h4,k].filter(Boolean);return l.tag==="h2"?Object.assign(x,{h2:h.get(l.id),h3:null,h4:null}):l.tag==="h3"?Object.assign(x,{h3:h.get(l.id),h4:null}):l.tag==="h4"&&(x.h4=h.get(l.id)),{id:l.blockId,text:h.get(l.id),parent:l.parent===null?null:b.get(l.parent)??null,where:R,heading:/^h[2-4]$/.test(l.tag)}})}function Ye({reportsDirectory:p,read:u,write:d=Fn,dropped:f=()=>{},now:b=Date.now}){let h=new Map,x=new Map,l=new Map,c=(s,w)=>{let r=l.get(s);if(r?.text===w)return r.units;let a=Un(w);return l.set(s,{text:w,units:a}),a},g=s=>_e.join(Be(s,p),Rn),k=s=>typeof s=="string"&&Pn.test(s);async function R(s){let w=await Qt.readFile(g(s),"utf8").catch(()=>null);return{text:w,items:w===null?[]:Dn(w)}}async function N(s,w,r){let a=In(w);return a===r||(a===null?await Qt.rm(g(s),{force:!0}):await d(g(s),a)),S(a)}let S=s=>s===null?"":J(s),Q=s=>{let w=h.get(s)??new Map;for(let[r,a]of w)b()-a>Ln&&w.delete(r);return[...w.keys()]},L=(s,w)=>w.forEach(r=>h.get(s)?.delete(r)),_=s=>{let w=x.get(s)??x.set(s,new Map).get(s);for(let[r,a]of w)b()-a>_n&&w.delete(r);return w};async function z(s,{keep:w=null,items:r=null,before:a=void 0}={}){let O=r?{items:r,text:a}:await R(s),v=await u(s).catch(()=>null);if(!v)return{items:O.items,units:[],places:new Map,version:S(O.text),missing:!0};let I=c(s,v.text),T=_(s),$=Tn(O.items,I,{keep:new Set([...T.keys(),w])});for(let A of T.keys())$.waiting.has(A)||T.delete(A);if($.dropped.length>0){let A=h.get(s)??h.set(s,new Map).get(s);for(let tt of $.dropped)A.set(tt.id,b())}let M=$.changed||r?await N(s,$.items,O.text):S(O.text);return $.dropped.length>0&&f(s,$.dropped),{items:$.items,units:I,places:$.places,version:M,missing:!1}}let Z=(s,{items:w,version:r})=>({ok:!0,version:r,items:w,dropped:Q(s)});async function U(s){if(!k(s))return[400,{ok:!1,reason:"body"}];let w=await z(s);return w.missing?[404,{ok:!1,reason:"missing"}]:[200,Z(s,w)]}async function D(s){if(!k(s))return[400,{ok:!1,reason:"body"}];let w=await z(s);if(w.missing)return[404,{ok:!1,reason:"missing"}];let r=null,a=Jn(Be(s,p));try{r=JSON.parse(await Qt.readFile(a.json,"utf8"))}catch{}let O=await u(s).catch(()=>null),v=/<h1\b[^>]*>([\s\S]*?)<\/h1>/i.exec(O?.text??"")?.[1]?.replace(/<[^>]*>/g,"").trim(),I=typeof r?.title=="string"&&r.title.trim()?r.title.trim():v||s,T=w.units.some(M=>M.heading),$=w.items.map(M=>{let A=w.units[w.places.get(M.id)?.at],tt=A?.where?.length?A.where:A?.heading?[A.text]:[];return{where:tt,top:T&&tt.length===0,blocks:M.anchor.blocks.filter(ot=>w.units.some($t=>$t.id===ot)),whole:M.anchor.kind==="blocks",quote:M.anchor.quote,text:M.text}});return[200,{ok:!0,title:I,path:_e.resolve(a.html),items:$}]}async function V(s){let{slug:w}=s??{};if(!k(w))return[400,{ok:!1,reason:"body"}];if(!await u(w).catch(()=>null))return[404,{ok:!1,reason:"missing"}];let r=await R(w);if(s.anchors&&typeof s.anchors=="object"&&!Array.isArray(s.anchors)){let T=r.items.map(M=>{let A=Object.hasOwn(s.anchors,M.id)?En(s.anchors[M.id]):null;return A&&A.kind===M.anchor.kind?{...M,anchor:A}:M}),$=await N(w,T,r.text);return[200,Z(w,{items:T,version:$})]}let a=r.items,O=null,v=null;if(s.put!==void 0){let T=a.find(M=>M.id===s.put?.id),$=Ue({...s.put,created:T?.created??s.put?.created});if(!$)return[400,{ok:!1,reason:"item"}];a=T?a.map(M=>M.id===$.id?$:M):[...a,$],O=$.id,T||_(w).set($.id,b()),L(w,[$.id])}else if(typeof s.remove=="string")a=a.filter(T=>T.id!==s.remove);else if(s.clear===!0)v=a,a=[];else if(Array.isArray(s.restore)){let T=new Map(a.map(A=>[A.id,A])),$=s.restore.map(A=>Ue(A,A?.updated)).filter(A=>A&&!(T.get(A.id)?.updated>A.updated)),M=new Set($.map(A=>A.id));for(let A of M)T.has(A)||_(w).set(A,b());a=[...a.filter(A=>!M.has(A.id)),...$],L(w,[...M])}else return[400,{ok:!1,reason:"body"}];let I=await z(w,{keep:O,items:a,before:r.text});return[200,{...Z(w,I),...v?{removed:v}:{}}]}async function st(s){if(!k(s))return;let{text:w}=await R(s);w!==null&&await z(s)}return{list:U,copy:D,change:V,afterWrite:st}}import yt from"node:fs/promises";import gt from"node:path";import{writeAtomic as Ze}from"../browser/shared/files.mjs";import{slugPattern as Vt}from"../browser/shared/reports.mjs";var Pt=1,Mt={seen:"seen.html",base:"base.html",state:"state.json"},Wn=4,Bn=1800*1e3;function Ce({stateDirectory:p=null,shown:u,folderOf:d,isPage:f=()=>!1,log:b=null,now:h=Date.now,quiet:x=Bn}){let l=new Map,c=r=>gt.join(p,"changes",r),g=Promise.resolve(),k=r=>{let a=g.then(r);return g=a.catch(O=>b?.(`changes: ${O.message}`)),a};async function R(r){if(!p)return l.get(r)?.state??null;try{let a=JSON.parse(await yt.readFile(gt.join(c(r),Mt.state),"utf8"));return a?.v===Pt&&typeof a.seen=="string"?a:null}catch{return null}}async function N(r,a){return p?yt.readFile(gt.join(c(r),Mt[a]),"utf8").catch(()=>null):l.get(r)?.[a]??null}async function S(r,a,O={}){if(!p){let v=l.get(r)??{};l.set(r,{...v,...O,state:a});return}await yt.mkdir(c(r),{recursive:!0});for(let[v,I]of Object.entries(O))I===null?await yt.rm(gt.join(c(r),Mt[v]),{force:!0}):await Ze(gt.join(c(r),Mt[v]),I);await Ze(gt.join(c(r),Mt.state),`${JSON.stringify(a)}
7
- `)}async function Q(r){l.delete(r),p&&await yt.rm(c(r),{recursive:!0,force:!0,maxRetries:3})}let L=async r=>Math.round((await yt.stat(d(r)).catch(()=>null))?.birthtimeMs??0),_=r=>r?.base?`${r.since}|${r.writes}`:null,z=r=>Number.isFinite(r?.draft)&&h()-r.draft<x?r.draft:null,Z=(r,a,O,v=z(r))=>[{v:Pt,born:r?.born??0,seen:a,...v===null?{}:{draft:v}},{seen:O,base:null}];async function U(r){let a=await R(r);if(!a)return null;let O=await L(r);return a.born&&O&&a.born!==O?(await Q(r),null):a}async function D(r,a){if(typeof a!="string"||!Vt.test(r)||f(r))return!1;let O=J(a),v=await U(r);if(!v)return await S(r,{v:Pt,born:await L(r),seen:O},{seen:a}),!1;if(v.seen===O)return!1;let I=await N(r,"seen"),T=new Date(h()).toISOString();if(I===null)return await S(r,...Z(v,O,a)),!1;let $=u(I),M=u(a);if(!v.base){if(!ht($,M))return await S(r,...Z(v,O,a)),!1;if(z(v)!==null||Te($))return await S(r,...Z(v,O,a,h())),!1;let{draft:ot,...$t}=v;return await S(r,{...$t,seen:O,base:J($),since:T,at:T,writes:1},{seen:a,base:$}),!0}let A=await N(r,"base");if(A===null||!ht(A,M))return await S(r,...Z(v,O,a)),!0;let tt=ht($,M)!==null;return await S(r,{...v,seen:O,...tt?{at:T,writes:v.writes+1}:{}},{seen:a}),tt}async function V(r,a,O,v){if(!Vt.test(r)||f(r))return!1;let I=await U(r),T=J(a);if(!I?.base)return await S(r,...Z(I??{born:await L(r)},T,a,v?null:z(I))),!1;let $=await N(r,"base");if($!==null&&O)try{$=O($)}catch(M){b?.(`changes: ${r}: the baseline did not take the edit (${M.message})`)}return $===null||!ht($,u(a))?(await S(r,...Z(I,T,a)),!0):(await S(r,{...I,seen:T,base:J($)},{seen:a,base:$}),!1)}async function st(r,a){if(!Vt.test(r)||f(r))return{ended:!1,moved:!1};let O=typeof a=="string"?await D(r,a):!1,v=await U(r);if(v?.draft===void 0)return{ended:!1,moved:O};let{draft:I,...T}=v;return await S(r,T),{ended:z(v)!==null,moved:O}}let s=new Map;async function w(r,a){await D(r,a);let O=u(a),v=J(O),I=await U(r);if(!I?.base)return{pending:!1,version:v};let T=`${r} ${I.base} ${v}`,$=s.get(T);if($===void 0){let M=await N(r,"base");for($=M===null?null:ht(M,O),s.set(T,$);s.size>Wn;)s.delete(s.keys().next().value)}return $?{pending:!0,version:v,stamp:_(I),since:I.since,writes:I.writes,...$}:{pending:!1,version:v}}return{look:(r,a)=>k(()=>D(r,a)),wrote:(r,a,O=null,{reader:v=!1}={})=>k(()=>V(r,a,O,v)),endDraft:(r,a=null)=>k(()=>st(r,a)),read:(r,a)=>k(()=>w(r,a)),stamp:r=>k(async()=>_(await U(r))),snapshot:r=>k(async()=>{let a=await U(r);return a?{state:a,seen:await N(r,"seen"),base:await N(r,"base")}:null}),clear:r=>k(async()=>{let a=await U(r);a?.base&&await S(r,{v:Pt,born:a.born,seen:a.seen},{base:null})}),restore:(r,a)=>k(async()=>{a?.state&&await S(r,a.state,{seen:a.seen,base:a.base})}),forget:r=>k(()=>Q(r)),idle:()=>k(async()=>{})}}import{randomBytes as Yn}from"node:crypto";import ct from"node:fs/promises";import kt from"node:path";import{FILE as Zn,readItems as Cn}from"../browser/shared/annotations.mjs";import{writeAtomic as Hn}from"../browser/shared/files.mjs";import{documentDirectory as zn}from"../browser/shared/workspace.mjs";var Kn=20,Ke=/^\d{8}T\d{6}Z-[a-f0-9]{8}\.json$/,He=80,Ge=({stateDirectory:p,slug:u})=>kt.join(p,"dropped-annotations",u),Qe=p=>({id:p.id,text:p.text,quote:p.anchor?.quote??"",kind:p.anchor?.kind??"text"});async function Ve({stateDirectory:p,reportsDirectory:u,slug:d,time:f,items:b}){let h=Ge({stateDirectory:p,reportsDirectory:u,slug:d});await ct.mkdir(h,{recursive:!0});let x=f.replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z");await Hn(kt.join(h,`${x}-${Yn(4).toString("hex")}.json`),JSON.stringify({time:f,items:b}));let l=(await ct.readdir(h)).filter(c=>Ke.test(c)).sort();await Promise.all(l.slice(0,Math.max(0,l.length-Kn)).map(c=>ct.rm(kt.join(h,c),{force:!0})))}async function no({stateDirectory:p,reportsDirectory:u,slug:d}){let f=Ge({stateDirectory:p,reportsDirectory:u,slug:d}),b=(await ct.readdir(f).catch(()=>[])).filter(l=>Ke.test(l)).sort();if(b.length===0)return[];let h=new Set(Cn(await ct.readFile(kt.join(zn(d,u),Zn),"utf8").catch(()=>"")).map(l=>l.id)),x=[];for(let l of b){let c=kt.join(f,l);try{let g=JSON.parse(await ct.readFile(c,"utf8")),k=Array.isArray(g?.items)?g.items.filter(R=>typeof R?.id=="string"&&!h.has(R.id)):[];typeof g?.time=="string"&&k.length&&x.push({time:g.time,items:k})}catch{}await ct.rm(c,{force:!0}).catch(()=>{})}return x}var Gn=(p,u=new Date)=>{let d=new Date(p),f=h=>String(h).padStart(2,"0"),b=`${f(d.getHours())}:${f(d.getMinutes())}`;return d.toDateString()===u.toDateString()?b:`${d.getFullYear()}-${f(d.getMonth()+1)}-${f(d.getDate())} ${b}`},ze=p=>{let u=String(p??"").replace(/\s+/g," ").trim();return JSON.stringify(u.length>He?`${u.slice(0,He-1)}\u2026`:u)};function qt(p,{time:u=null,items:d},{today:f=new Date}={}){let b=kt.resolve(p),h=`${d.length} \u6279\u6CE8 (annotation${d.length===1?"":"s"})`;return[`annotations ${b}: ${u?`at ${Gn(u,f)}, `:""}Gallery deleted ${h} whose words are gone from the document (rewritten or deleted):`,...d.map(({id:x,text:l,quote:c,kind:g})=>` ${x} ${ze(l)} on ${g==="blocks"?"the blocks ":""}${ze(c)}`)]}function ro(p,u,{today:d=new Date}={}){return u.length?[...u.flatMap(f=>qt(p,f,{today:d}))," they were the reader's: say in your hand-off which your edit carried out and which you left, and never write them back"]:[]}import{randomBytes as Qn}from"node:crypto";import bt from"node:fs/promises";import At from"node:path";import{writeAtomic as Vn}from"../browser/shared/files.mjs";var qn=20,qe=/^\d{8}T\d{6}Z-[a-f0-9]{8}\.json$/,Xe=({stateDirectory:p,slug:u})=>At.join(p,"rewrites",u);async function tn({stateDirectory:p,reportsDirectory:u,slug:d,time:f,changes:b}){let h=Xe({stateDirectory:p,reportsDirectory:u,slug:d});await bt.mkdir(h,{recursive:!0});let x=f.replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z");await Vn(At.join(h,`${x}-${Qn(4).toString("hex")}.json`),JSON.stringify({time:f,changes:b}));let l=(await bt.readdir(h)).filter(c=>qe.test(c)).sort();await Promise.all(l.slice(0,Math.max(0,l.length-qn)).map(c=>bt.rm(At.join(h,c),{force:!0})))}async function en({stateDirectory:p,reportsDirectory:u,slug:d}){let f=Xe({stateDirectory:p,reportsDirectory:u,slug:d}),b=(await bt.readdir(f).catch(()=>[])).filter(x=>qe.test(x)).sort(),h=[];for(let x of b){let l=At.join(f,x);try{let c=JSON.parse(await bt.readFile(l,"utf8"));typeof c?.time=="string"&&Array.isArray(c.changes)&&h.push(c)}catch{}await bt.rm(l,{force:!0}).catch(()=>{})}return h}var Xn=(p,u=new Date)=>{let d=new Date(p),f=h=>String(h).padStart(2,"0"),b=`${f(d.getHours())}:${f(d.getMinutes())}`;return d.toDateString()===u.toDateString()?b:`${d.getFullYear()}-${f(d.getMonth()+1)}-${f(d.getDate())} ${b}`};function fo(p,u,{today:d=new Date}={}){if(!u.length)return[];let f=At.resolve(p),b=[];for(let{time:h,changes:x}of u){let l=[];for(let{line:c,rule:g,key:k}of[...x].sort((R,N)=>R.line-N.line)){let R=`line ${c} ${g}${k?` ${k}`:""}`;l.includes(R)||l.push(R)}b.push(`preview ${f}: at ${Xn(h,d)}, when the reader edited the page, the preview wrote your natural HTML as the kit's markup: ${l.join(", ")}`),b.push(...x.filter(c=>c.note).map(({line:c,rule:g,note:k})=>` line ${c}, ${g}: ${k}`))}return b.push(" re-read the file before editing it (those lines are the file's as you had left it)"),b}import{todoRef as tr}from"../browser/shared/workspace-query.mjs";var er=(p,u)=>p.length===u.length&&p.every((d,f)=>d===u[f]);function nn(p,u,d,f){let b=Fe(u),h=De(d,{at:!0}),x=null,l=c=>(x??=ye(d).units).find(g=>g.elStart===c)??null;return f.map(c=>{let g=tr(c?.ref);if(!g||g.slug!==p||typeof c.done!="boolean")return{reason:"ref"};let k=g.block?h.find(N=>N.block===g.block)??null:null;if(k&&k.text!==g.text)return{reason:"changed"};if(!k){let N=h.filter(S=>S.text===g.text&&er(S.path,g.path));if(g.version===b)k=N.find(S=>S.nth===g.nth)??null;else{if(N.length>1)return{reason:"ambiguous"};k=N[0]??null}}if(!k)return{reason:"changed"};let R=l(k.at);return R?{unit:R,done:k.done,want:c.done}:{reason:"locked"}})}function rn(p,u){let d=new Map,f=u.map(c=>{if(!c.unit)return!1;let g=d.has(c.unit.id)?d.get(c.unit.id):c.done;return d.set(c.unit.id,c.want),g!==c.want}),b=new Map;for(let c of u)c.unit&&d.get(c.unit.id)!==c.done&&b.set(c.unit.id,c);if(b.size===0)return{commit:null,changed:f};let h=[],x=[],l=new Map;for(let[c,g]of b){let k=`todo${h.length}`,R=g.unit.blockId?{key:k,id:g.unit.blockId}:{key:k,open:c,hash:we(p,g.unit)};h.push({key:k,unit:R,attribute:"data-checked",value:d.get(c)?"":null}),x.push(R),l.set(c,k)}return{commit:{units:h,touch:x,keys:l},changed:f}}import{EMPTY_STYLE as yr,emptyWordsScript as gr,showEmpty as kr}from"../browser/editor/components/placeholder.mjs";import{TOKENS as br}from"../browser/editor/page/look.mjs";import{MARGIN_STYLE as $r,earlyMarginScript as xr}from"../browser/editor/page/margin.mjs";var te=/^[a-f0-9]{16}$/,ne=2*1024*1024,Sr=ur,on=50,an=/^\d{8}T\d{6}Z-[a-f0-9]{16}\.html$/,vr=30,sn=3,cn=200,ft="\u6587\u4EF6\u4E00\u518D\u88AB\u4FEE\u6539\uFF08\u4F8B\u5982 AI \u6B63\u5728\u5199\u5165\uFF09\uFF0C\u7A0D\u540E\u518D\u540C\u6B65",Or="\u8FD9\u6B21\u7684\u4FEE\u6539\u592A\u5927\uFF0C\u4E00\u6B21\u5B58\u4E0D\u4E0B",jr=250,lt=Symbol("again"),Mr="/__gallery/edit/src/editor/page/editor.mjs",Ar=p=>new Promise(u=>setTimeout(u,p));function Nr(p,u=ne){return new Promise((d,f)=>{let b=[],h=0;p.on("data",x=>{h+=x.length,h>u?b.length=0:b.push(x)}),p.on("end",()=>h>u?f(new Error("too-large")):d(Buffer.concat(b).toString("utf8"))),p.on("error",f)})}function Tr(p){if(!p)return ee(16).toString("hex");let u=P.join(p,"token");try{let f=ir(u,"utf8").trim();if(/^[a-f0-9]{32}$/.test(f))return f}catch{}let d=ee(16).toString("hex");try{sr(p,{recursive:!0,mode:448}),cr(u,d,{mode:384})}catch{}return d}function zo({base:p="",token:u=null,reportsDirectory:d=dr,stateDirectory:f=null,write:b=Jt,ids:h=!0,finish:x=R=>R,log:l=null,settling:c={},reviewing:g={},onChanges:k=()=>{}}={}){let R=u??Tr(rr().data),N=Le(c),S=c.wait??Je,Q=new Map,L=async(t,n,e,o="reader")=>{let i=await b(t,n,e);if(i!==!1&&hr(P.basename(t))){let y=P.basename(P.dirname(t));N.wrote(y,n),Q.set(y,{hash:J(n),by:o})}return i},_=t=>wr(t,d),z=t=>Nt(_(t)).html,Z=new Map,U=f&&P.join(f,"snapshots"),D=Promise.resolve(),V=Promise.resolve(),st=async(t,n,e,{by:o="time"}={})=>{let i=(await H.readdir(t)).filter(m=>n.test(m));if(i.length<=e)return;let y=o==="name"?i.sort():(await Promise.all(i.map(async m=>({name:m,time:(await H.stat(P.join(t,m))).mtimeMs})))).sort((m,j)=>m.time-j.time).map(({name:m})=>m);await Promise.all(y.slice(0,y.length-e).map(m=>H.rm(P.join(t,m),{force:!0})))},s=(t,n)=>{U&&(D=D.then(async()=>{let e=P.join(U,`${t}.html`),o=new Date;try{await H.utimes(e,o,o);return}catch{}await H.mkdir(U,{recursive:!0}),await Jt(e,n),await st(U,/^[a-f0-9]{16}\.html$/,on)}).catch(()=>{}))},w=(t,n)=>{f&&(D=D.then(async()=>{let e=P.join(f,"history",t),o=J(n);if(await H.mkdir(e,{recursive:!0}),(await H.readdir(e)).filter(m=>an.test(m)).sort().at(-1)?.endsWith(`-${o}.html`))return;let y=new Date().toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z");await Jt(P.join(e,`${y}-${o}.html`),n),await st(e,an,vr,{by:"name"})}).catch(()=>{}))},r=new Map,a=t=>f&&P.join(f,"receipts",t),O=(t,n,e,o)=>{for(r.set(`${t} ${n}`,{digest:e,answer:o});r.size>cn*4;)r.delete(r.keys().next().value);let i=a(t);i&&(D=D.then(async()=>{await H.mkdir(i,{recursive:!0}),await Jt(P.join(i,`${n}.json`),JSON.stringify({digest:e,answer:o})),await st(i,{test:y=>y.endsWith(".json")&&Xt.test(y.slice(0,-5))},cn)}).catch(()=>{}))},v=async(t,n)=>{let e=r.get(`${t} ${n}`);if(e)return e;let o=a(t);if(!o)return null;await D;try{let i=JSON.parse(await H.readFile(P.join(o,`${n}.json`),"utf8"));return typeof i?.digest=="string"&&i.answer?.ok?i:null}catch{return null}},I=new Map,T=(t,n)=>{let e=new Date().toISOString();if(!f)return void I.set(t,[...I.get(t)??[],{time:e,changes:n}].slice(-20));D=D.then(()=>tn({stateDirectory:f,reportsDirectory:d,slug:t,time:e,changes:n})).catch(()=>{})},$=async t=>{if(!f){let n=I.get(t)??[];return I.delete(t),n}return await D,en({stateDirectory:f,reportsDirectory:d,slug:t})},M=(t,n)=>{for(Z.delete(t),Z.set(t,n);Z.size>on;)Z.delete(Z.keys().next().value);s(t,n)},A=async t=>{if(Z.has(t))return Z.get(t);if(!U||!te.test(t))return null;await D;let n=await H.readFile(P.join(U,`${t}.html`),"utf8").catch(()=>null);return n===null||J(n)!==t?null:(M(t,n),n)},tt=new Map,ot=t=>{let n=tt.get(t);if(n)return n;let e=je(t,{finish:x});for(tt.set(t,e);tt.size>8;)tt.delete(tt.keys().next().value);return e},$t=P.join(P.resolve(d),".gallery","pages"),C=Ce({...g,stateDirectory:f,shown:t=>ot(t).text,folderOf:_,log:l,isPage:t=>P.resolve(_(t)).startsWith($t+P.sep)}),ut=(t,n)=>n.then(e=>{e&&k(t)},e=>l?.(`${t}: the Agent's changes not kept (${e.message})`));async function Lt(t,n=void 0){if(typeof t!="string"||!rt.test(t))return null;let e=z(t),o=n!==void 0?n:await H.readFile(e,"utf8").catch(()=>null);if(o===null)return null;let{text:i,changes:y}=ot(o);return{file:e,source:o,text:i,version:J(i),changes:y}}async function it(t){if(typeof t!="string"||!rt.test(t))return{source:null,held:!1,signs:[],wait:0,own:!1};let n=z(t),e=await H.readFile(n,"utf8").catch(()=>null),o=(await H.stat(n).catch(()=>null))?.mtimeMs??0;return{source:e,...N.judge(t,{source:e,mtime:o})}}async function xt(t,n=Date.now()+S){for(;;){let e=await it(t);if(!e.held||Date.now()>=n)return e;await Ar(Math.max(0,Math.min(jr,n-Date.now())))}}async function _t(t,{wait:n=S}={}){let e=await xt(t,Date.now()+n),o=await Lt(t,e.held&&e.taken!==void 0?e.taken:e.source);return o&&{...o,held:e.held===!0}}function fn(t,n,{editor:e=Mr,kitTags:o=()=>[]}={}){let{html:i,map:y}=be(n);M(y.version,n);let m=me(),j=pe(m).map(({assets:B,...X})=>({...X,kit:o(B)})),E=`<script type="application/json" id="doc-edit-map" data-doc-dev>${JSON.stringify({slug:t,token:R,...y,components:j,hidden:m.settings.hidden}).replace(/</g,"\\u003c")}</script>
8
- <script data-doc-dev>document.currentScript.remove(); import(${JSON.stringify(e)});</script>`,W=`<style data-doc-dev>.doc-display { display: none; }</style>
9
- <style data-doc-dev data-ge-palette>${br}</style>
10
- <style data-doc-dev>${yr}</style>
11
- <script data-doc-dev>${gr()}</script>
12
- <script data-doc-dev>document.currentScript.remove(); document.documentElement.setAttribute("data-ge-order", "file");</script>
13
- <style data-doc-dev data-ge-margin-style>${$r}</style>
14
- <script data-doc-dev>document.currentScript.remove(); ${xr(nr(t,p),{notes:ar(P.join(_(t),fr))})}</script>`;return{html:kr(i),snippet:E,head:W}}let ln=t=>M(J(t),t);function re(t){if(t.method!=="POST")return[405,{ok:!1,reason:"method"}];let n=t.headers.host??"",e=t.socket.localPort;return n!==`127.0.0.1:${e}`&&n!==`localhost:${e}`?[403,{ok:!1,reason:"host"}]:t.headers.origin!==`http://${n}`?[403,{ok:!1,reason:"origin"}]:t.headers["x-gallery-token"]!==R?[403,{ok:!1,reason:"token"}]:null}async function dt(t,n=ne){let e=re(t);if(e)return{error:e};if(!/^application\/json\b/i.test(t.headers["content-type"]??""))return{error:[415,{ok:!1,reason:"type"}]};try{return{body:JSON.parse(await Nr(t,n))}}catch(o){return{error:o.message==="too-large"?[413,{ok:!1,reason:"body",message:Or}]:[400,{ok:!1,reason:"body"}]}}}async function Ut(t,n){let{slug:e,opening:o,known:i=null,texts:y=[],units:m=[],touch:j=[],pageIds:F=null,request:E=null,agent:W=!1}=t;if(typeof e!="string"||!rt.test(e)||![y,m,j].every(Array.isArray))return[400,{ok:!1,reason:"body"}];if(E!==null&&(typeof E!="string"||!Xt.test(E)))return[400,{ok:!1,reason:"body"}];let B=E===null?null:J(JSON.stringify([o??null,y,m,j])),X=await oe(t);if(X)return X;let K=nt=>(E!==null&&O(e,E,B,nt),[200,nt]),G=z(e),et=typeof o=="string"&&te.test(o)?await A(o):null,q=nt=>or("sha256",R).update(`${e}
15
- ${nt}`).digest("hex").slice(0,32);for(let nt=1;;nt++){let{source:at,held:It}=await it(e);if(at===null)return[404,{ok:!1,reason:"missing"}];if(It)return Date.now()<n?lt:[409,{ok:!1,reason:"busy",message:ft}];ut(e,C.look(e,at));let{text:jt,changes:zt}=ot(at),ce=[],Dt=xe({current:jt,opening:et,texts:y,units:m,touch:j,ids:h?()=>{let Ft=typeof h=="function"?h():Kt();return ce.push(Ft),Ft}:!1,seal:q,pageIds:F}),{title:fe,icon:le,...ue}=Dt,wt=Dt.text===jt?jt:x(Dt.text);wt!==Dt.text&&(ue.version=J(wt));let de={...ue,foreign:typeof i=="string"&&J(jt)!==i};if(wt===jt)return K({ok:!0,...de,wrote:!1,notes:[]});if(w(e,at),!await L(G,wt,{expect:at},W===!0?"agent":"reader")){if(nt===sn)return[409,{ok:!1,reason:"busy",message:ft}];continue}w(e,wt),ut(e,C.wrote(e,wt,Ft=>{let jn=0;return Ee(Ft,{opening:et,texts:y,units:m,touch:j,pageIds:F,seal:q,ids:h?()=>ce[jn++]??(typeof h=="function"?h():Kt()):!1})},{reader:W!==!0})),zt.length&&(l&&l(Gt(G,zt).join(`
16
- `)),T(e,zt));let On=[...fe?await Tt(P.dirname(G),fe):[],...le!==void 0?await Wt(P.dirname(G),le):[]];return K({ok:!0,...de,wrote:!0,notes:On})}}async function un(t,n){return typeof t!="string"||!rt.test(t)?[404,{ok:!1,reason:"missing",message:"\u627E\u4E0D\u5230\u8FD9\u4EFD\u6587\u6863"}]:!Array.isArray(n)||n.length===0||n.length>pr?[400,{ok:!1,reason:"body"}]:Bt({slug:t},async(e,o)=>{let{source:i,held:y}=await it(t);if(i===null)return[404,{ok:!1,reason:"missing",message:"\u627E\u4E0D\u5230\u8FD9\u4EFD\u6587\u6863"}];if(y)return Date.now()<o?lt:[409,{ok:!1,reason:"busy",message:ft}];let{text:m}=ot(i),j=nn(t,i,m,n),{commit:F,changed:E}=rn(m,j),W=j.map((q,nt)=>q.reason?{ok:!1,reason:q.reason}:{ok:!0,changed:E[nt],block:q.unit.blockId??null});if(!F)return[200,{ok:!0,results:W,wrote:!1}];let B=J(m);M(B,m);let X=await Ut({slug:t,opening:B,units:F.units,touch:F.touch},o);if(X===lt)return lt;let[K,G]=X;if(!G.ok)return[K,G];let et=new Map((G.units??[]).map(q=>[q.key,q]));return[200,{ok:!0,wrote:G.wrote===!0,results:W.map((q,nt)=>{if(!q.ok)return q;let at=F.keys.get(j[nt].unit.id);if(at===void 0)return q;let It=et.get(at);return It?.status!=="applied"?{ok:!1,reason:It?.reason==="ambiguous"?"ambiguous":"changed"}:{...q,block:G.ids?.[at]??q.block}})}]})}async function oe({slug:t,opening:n,texts:e=[],units:o=[],touch:i=[],request:y=null}){if(typeof t!="string"||!rt.test(t)||typeof y!="string"||!Xt.test(y)||![e,o,i].every(Array.isArray))return null;let m=await v(t,y);return m?m.digest===J(JSON.stringify([n??null,e,o,i]))?[200,{...m.answer,again:!0}]:[409,{ok:!1,reason:"request",message:"\u540C\u4E00\u6B21\u4FDD\u5B58\u7684\u5185\u5BB9\u4E0D\u4E00\u81F4"}]:null}async function dn(t,n){let{slug:e,opening:o,texts:i=[],units:y=[],instances:m=[],pageIds:j=null}=t;if(typeof e!="string"||!rt.test(e)||!Array.isArray(i)||!Array.isArray(y)||!Array.isArray(m))return[400,{ok:!1,reason:"body"}];let{source:F,held:E}=await it(e);if(E)return Date.now()<n?lt:[409,{ok:!1,reason:"busy",message:ft}];let W=await Lt(e,F);if(W===null)return[404,{ok:!1,reason:"missing"}];let{text:B,version:X}=W,K=typeof o=="string"&&te.test(o)?await A(o):null;return[200,{ok:!0,version:X,reverted:Oe({current:B,opening:K,texts:i,pageIds:j}),units:Se({current:B,units:y}),parts:ve({current:B,instances:m,pageIds:j})}]}let mn=600*1e3,St=new Map;async function ae(t,n){let e=_(t),o=null;try{o=JSON.parse(await H.readFile(Nt(e).json,"utf8"))}catch{}let{title:i,icon:y}=Ae(n,o);i&&typeof o?.title=="string"&&o.title!==i.to&&await Tt(e,{from:o.title,to:i.to,synced:!0}),y&&!y.missing&&await Wt(e,y.to)}async function pn(t,n){let{slug:e,action:o,stamp:i=null,undo:y=null}=t;if(typeof e!="string"||!rt.test(e)||!["accept","revert","undo"].includes(o))return[400,{ok:!1,reason:"body"}];let m=z(e),{source:j,held:F}=await it(e);if(j===null)return[404,{ok:!1,reason:"missing"}];if(F)return Date.now()<n?lt:[409,{ok:!1,reason:"busy",message:ft}];if(o==="undo"){for(let[G,et]of St)Date.now()-et.at>mn&&St.delete(G);let K=typeof y=="string"?St.get(y):null;return!K||K.slug!==e?[404,{ok:!1,reason:"gone",message:"\u64A4\u9500\u5DF2\u7ECF\u8FC7\u671F"}]:j!==K.after?[409,{ok:!1,reason:"moved-on",message:"\u64A4\u56DE\u4E4B\u540E\u6587\u6863\u53C8\u6539\u8FC7\u4E86\uFF0C\u6CA1\u6CD5\u64A4\u9500"}]:(w(e,j),await L(m,K.before,{expect:j})?(w(e,K.before),St.delete(y),await ae(e,K.before),await C.restore(e,K.saved),await C.wrote(e,K.before),k(e),[200,{ok:!0,version:J(ot(K.before).text)}]):[409,{ok:!1,reason:"busy",message:ft}])}await C.look(e,j);let E=await C.snapshot(e),W=E?.state?.base?`${E.state.since}|${E.state.writes}`:null;if(W===null)return[200,{ok:!0,none:!0}];if(W!==i)return[409,{ok:!1,reason:"changed",message:"Agent \u521A\u521A\u53C8\u6539\u4E86\u6587\u6863\uFF0C\u518D\u770B\u4E00\u773C"}];if(o==="accept")return await C.clear(e),k(e),[200,{ok:!0}];let B=E.base;if(w(e,j),!await L(m,B,{expect:j}))return[409,{ok:!1,reason:"busy",message:ft}];w(e,B),await ae(e,B);let X=ee(8).toString("hex");return St.set(X,{slug:e,before:j,after:B,saved:E,at:Date.now()}),await C.clear(e),await C.wrote(e,B),k(e),[200,{ok:!0,version:J(ot(B).text),undo:X}]}async function wn(t,n){let e=await dt(t);if(e.error)return Y(n,...e.error);let o=e.body??{};try{if(o.action!=="read")return Y(n,...await Bt(o,pn));if(typeof o.slug!="string"||!rt.test(o.slug))return Y(n,400,{ok:!1,reason:"body"});let i=await _t(o.slug,{wait:0});return i===null?Y(n,404,{ok:!1,reason:"missing"}):Y(n,200,{ok:!0,...await C.read(o.slug,i.source)})}catch(i){return Y(n,500,{ok:!1,reason:"write",message:i.message})}}async function Tt(t,{from:n,to:e,synced:o}){let i=["\u6807\u9898\u5DF2\u66F4\u65B0",...o?[]:["\u5355\u72EC\u6253\u5F00\u6216\u5BFC\u51FA\u65F6\u7684\u9875\u9762\u540D\u79F0\u539F\u672C\u5C31\u548C\u6807\u9898\u4E0D\u540C\uFF0C\u6CA1\u6709\u8DDF\u7740\u6539"]],y=Nt(t).json,m=await H.readFile(y,"utf8").catch(()=>""),j=null;try{j=JSON.parse(m)}catch{}if(j?.title!==n)return[...i,"\u641C\u7D22\u548C\u4FA7\u680F\u91CC\uFF08\u6CA1\u6253\u5F00\u8FD9\u4EFD\u6587\u6863\u65F6\uFF09\u7684\u6587\u6863\u540D\u539F\u672C\u5C31\u548C\u6807\u9898\u4E0D\u540C\uFF0C\u6CA1\u6709\u8DDF\u7740\u6539"];let F=new RegExp(`("title"\\s*:\\s*)${JSON.stringify(n).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}`),E=F.test(m)?m.replace(F,(W,B)=>B+JSON.stringify(e)):`${JSON.stringify({...j,title:e},null,2)}
17
- `;try{await L(y,E)}catch(W){return l?.(`${P.basename(y)}'s title was not written (${W.code??W.message}): ${y}`),[...i,"\u641C\u7D22\u548C\u4FA7\u680F\u91CC\uFF08\u6CA1\u6253\u5F00\u8FD9\u4EFD\u6587\u6863\u65F6\uFF09\u7684\u6587\u6863\u540D\u6CA1\u80FD\u8DDF\u7740\u6539"]}return i}async function Wt(t,n){let e=Nt(t).json,o=null;try{o=JSON.parse(await H.readFile(e,"utf8"))}catch{}if(!o||typeof o!="object")return l?.(`${P.basename(e)} could not be read, so its icon was not written: ${e}`),["\u9875\u9762\u56FE\u6807\u5DF2\u66F4\u6362\uFF0C\u4F46\u641C\u7D22\u548C\u4FA7\u680F\u91CC\uFF08\u6CA1\u6253\u5F00\u8FD9\u4EFD\u6587\u6863\u65F6\uFF09\u7684\u56FE\u6807\u6CA1\u80FD\u8DDF\u7740\u6362"];if((o.icon??null)===n)return[];let{icon:i,...y}=o,m=n===null?y:{...y,icon:n};try{await L(e,`${JSON.stringify(m,null,2)}
18
- `)}catch(j){return l?.(`${P.basename(e)}'s icon was not written (${j.code??j.message}): ${e}`),["\u9875\u9762\u56FE\u6807\u5DF2\u66F4\u6362\uFF0C\u4F46\u641C\u7D22\u548C\u4FA7\u680F\u91CC\uFF08\u6CA1\u6253\u5F00\u8FD9\u4EFD\u6587\u6863\u65F6\uFF09\u7684\u56FE\u6807\u6CA1\u80FD\u8DDF\u7740\u6362"]}return[]}async function hn(t,n){let e=typeof n=="string"?n.replace(/\s+/g," ").trim():"";if(!e)return{ok:!1,reason:"title",message:"\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A"};let o=z(t),i=await H.readFile(o,"utf8").catch(()=>null);if(i===null)return{ok:!1,reason:"missing"};ut(t,C.look(t,i));let y=he(i),m=ge(y).find(E=>E.kind==="title");if(!m)return{ok:!1,reason:"no-title",message:"\u8FD9\u4EFD\u6587\u6863\u6CA1\u6709\u6807\u9898"};let j=lr(e),F=$e({current:y,edits:[{id:m.id,parts:[{keep:!0,html:j}]}],ids:h});return F.ok?F.text!==i&&!await L(o,F.text,{expect:i})?{ok:!1,reason:"changed-again"}:(F.text!==i&&ut(t,C.wrote(t,F.text,E=>Re(E,j))),{ok:!0,title:e,notes:F.title?await Tt(P.dirname(o),F.title):[]}):{ok:!1,reason:"conflict"}}let vt=t=>(n,e)=>{let o=V.then(()=>t(n));return V=o.catch(()=>{}),o.then(([i,y])=>Y(e,i,y),i=>Y(e,500,{ok:!1,reason:"write",message:i.message}))},se=(t,{early:n=null}={})=>async(e,o)=>{let i=await dt(e);if(i.error)return Y(o,...i.error);let y=i.body??{};try{let m=n&&await n(y);return m?Y(o,...m):Y(o,...await Bt(y,t))}catch(m){return Y(o,500,{ok:!1,reason:"write",message:m.message})}};async function Bt(t,n){let e=Date.now()+S;for(;;){await xt(t.slug,e);let o=V.then(()=>n(t,e));V=o.catch(()=>{});let i=await o;if(i!==lt)return i}}async function Yt(t,{reader:n=!1}={}){if(typeof t!="string"||!rt.test(t))return{ok:!1,reason:"missing",message:"\u627E\u4E0D\u5230\u8FD9\u4EFD\u6587\u6863"};let e=_(t),{html:o,json:i}=Nt(e);for(let y=1;;y++){let{source:m,held:j}=n?await it(t):{source:await H.readFile(o,"utf8").catch(()=>null),held:!1};if(m===null)return{ok:!1,reason:"missing",message:"\u627E\u4E0D\u5230\u8FD9\u4EFD\u6587\u6863"};if(j)return{ok:!1,reason:"busy",message:"\u6587\u4EF6\u4E00\u518D\u88AB\u4FEE\u6539\uFF08\u4F8B\u5982 AI \u6B63\u5728\u5199\u5165\uFF09\uFF0C\u6CA1\u6709\u5199\u5165"};ut(t,C.look(t,m));let F=null;try{F=JSON.parse(await H.readFile(i,"utf8"))}catch{}let{text:E,changes:W,added:B,given:X,repeated:K,title:G,icon:et}=Me(m,{finish:x,next:typeof h=="function"?h:void 0,metadata:F});if(E!==m){if(w(t,m),!await L(o,E,{expect:m},n?"reader":"agent")){if(y===sn)return{ok:!1,reason:"busy",message:"\u6587\u4EF6\u4E00\u518D\u88AB\u4FEE\u6539\uFF08\u4F8B\u5982 AI \u6B63\u5728\u5199\u5165\uFF09\uFF0C\u6CA1\u6709\u5199\u5165"};continue}w(t,E),ut(t,C.wrote(t,E)),n&&W.length&&(l&&l(Gt(o,W).join(`
19
- `)),T(t,W))}return G&&typeof F?.title=="string"&&F.title!==G.to&&await Tt(e,{from:F.title,to:G.to,synced:G.page}),et&&!et.missing&&await Wt(e,et.to),{ok:!0,changes:E===m?[]:W,added:E===m?0:B,given:E===m?[]:X,repeated:K,written:E!==m,title:G,icon:et}}}let yn=async(t,{reader:n=!1}={})=>{n&&await xt(t);let e=V.then(()=>Yt(t,{reader:n}));return V=e.catch(()=>{}),e};async function Zt(t){let n=await dt(t);if(n.error)return{refused:n.error};let{slug:e,workspace:o}=n.body??{};return typeof e!="string"||!rt.test(e)||typeof o!="string"?{refused:[400,{ok:!1,reason:"body"}]}:mr(o,d)?{slug:e}:{refused:[409,{ok:!1,reason:"elsewhere",message:"\u8FD9\u4E2A\u9884\u89C8\u670D\u52A1\u5668\u7BA1\u7684\u662F\u53E6\u4E00\u4E2A\u76EE\u5F55\u7684\u6587\u6863"}]}}async function gn(t,n){try{let e=V.then(async()=>{let{slug:y,refused:m}=await Zt(t);if(m)return{answer:m};let j=await Yt(y);return{slug:j.ok?y:null,answer:[j.ok?200:j.reason==="missing"?404:409,j]}});V=e.catch(()=>{});let{slug:o,answer:i}=await e;return o&&await Et(o),Y(n,...i)}catch(e){return Y(n,500,{ok:!1,reason:"write",message:e.message})}}async function kn(t){let{slug:n,refused:e}=await Zt(t);return e||(await Et(n),[200,{ok:!0}])}async function ie(t){let{source:n}=await xt(t),{ended:e,moved:o}=await C.endDraft(t,n);return o&&k(t),e}async function bn(t){let{slug:n,refused:e}=await Zt(t);return e||[200,{ok:!0,ended:await ie(n)}]}let mt=Ie({reportsDirectory:d}),Ot=Ye({reportsDirectory:d,read:t=>_t(t,{wait:0}),write:L,dropped:(t,n)=>{let e=n.map(Qe);l&&l(qt(P.join(_(t),"annotations.json"),{items:e}).join(`
20
- `)),f&&(D=D.then(()=>Ve({stateDirectory:f,reportsDirectory:d,slug:t,time:new Date().toISOString(),items:e})).catch(()=>{}))}}),Ct=Promise.resolve(),Ht=t=>{let n=Ct.then(t);return Ct=n.catch(()=>{}),n},$n=t=>(n,e)=>Ht(()=>t(n)).then(([o,i])=>Y(e,o,i),o=>Y(e,500,{ok:!1,reason:"write",message:o.message})),xn=300,pt=new Map;async function Et(t){let n=pt.get(t);n&&(clearTimeout(n.timer),pt.delete(t));let e=Ht(()=>Ot.afterWrite(t));n&&e.then(n.resolve,n.reject),await e.catch(o=>l?.(`${t}: annotations not checked: ${o.message}`)),await D}let Sn=t=>{let n=t.headers.host??"",e=t.socket.localPort;return n!==`127.0.0.1:${e}`&&n!==`localhost:${e}`?[403,{ok:!1,reason:"host"}]:t.headers["x-gallery-token"]!==R?[403,{ok:!1,reason:"token"}]:null};async function vn(t){if(t.method==="GET"){let e=Sn(t);if(e)return e;let o=new URL(t.url??"/","http://localhost").searchParams;return o.get("as")==="copy"?Ot.copy(o.get("slug")):Ot.list(o.get("slug"))}let n=await dt(t);return n.error??Ot.change(n.body)}let Rt=(t,n=ne)=>async e=>{let o=await dt(e,n);return o.error??t(o.body)};return{token:R,preview:fn,opened:ln,check:dt,checkHeaders:re,upload:vt(Rt(mt.upload,Sr)),addEmoji:vt(Rt(mt.addEmoji)),unfurl:vt(Rt(mt.unfurl)),annotations:$n(vn),checkAnnotations(t){let n=pt.get(t);return n||(n={timer:0},n.done=new Promise((e,o)=>Object.assign(n,{resolve:e,reject:o})),pt.set(t,n)),clearTimeout(n.timer),n.timer=setTimeout(()=>{pt.delete(t),Ht(()=>Ot.afterWrite(t)).then(n.resolve,n.reject)},xn),n.done},frameable:vt(Rt(mt.frameable)),listEmojis:mt.listEmojis,readEmoji:mt.readEmoji,respond:vt,keepVersion:w,renameReport:hn,read:Lt,settled:it,writerOf:(t,n)=>typeof n=="string"&&Q.get(t)?.hash===J(n)?Q.get(t).by:null,whenTaken:xt,readTaken:_t,takeRewrites:$,handIn:yn,handInReport:Yt,handInRequest:gn,settleRequest:(t,n)=>kn(t).then(([e,o])=>Y(n,e,o),e=>Y(n,500,{ok:!1,reason:"write",message:e.message})),settleNotes:Et,roundRequest:(t,n)=>bn(t).then(([e,o])=>Y(n,e,o),e=>Y(n,500,{ok:!1,reason:"write",message:e.message})),beginRound:ie,commit:se(Ut,{early:oe}),handleCommit:Ut,setTodos:un,reverted:se(dn),changes:wn,noteTaken:(t,n)=>C.look(t,n),forgetChanges:t=>C.forget(t),drain:async()=>{await V,await Promise.all([...pt.keys()].map(Et)),await Ct,await C.idle(),await D},stored:async()=>{await C.idle(),await D}}}export{no as a,ro as b,en as c,fo as d,Mn as e,An as f,Nn as g,Tr as h,zo as i};
@@ -1,2 +0,0 @@
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,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y}from"./chunk-EURLTOTZ.mjs";import"./chunk-Q4UEPUWF.mjs";import"./chunk-5L7RYZCL.mjs";export{d as CACHE_FILE,e as FRESH,c as NEWER_LINE,a as PACKAGE,f as RETRY,b as SKILL_LINE,g as TIMEOUT,j as cacheDirectory,h as checkOff,r as claimCheck,o as latestUrl,w as newerLine,l as npmSettings,k as parseNpmrc,p as readCache,s as refreshCache,n as refreshEnv,m as registryOf,u as skillFolders,v as skillLine,x as skillLines,q as stale,t as startRefresh,y as versionNotes,i as viaNpx};
@@ -1,15 +0,0 @@
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 b}from"./chunk-2OHANJ6Q.mjs";import{c as L,d as F}from"./chunk-Q4UEPUWF.mjs";import{c as x,d as j,k as w}from"./chunk-4OZWXZE5.mjs";import"./chunk-5L7RYZCL.mjs";import l from"node:fs";import c from"node:path";import{pathToFileURL as K}from"node:url";import{projectRoot as p}from"../browser/shared/paths.mjs";import{sha256 as A}from"../browser/shared/files.mjs";var g=["SKILL.md","references/writing-html.md","references/building-blocks.md","references/block-script.md","references/pages-and-data.md","references/extensions.md","references/example-report.html","sdk","agents/openai.yaml"],u="## Before anything: the gallery command";function T(n){let[t,s]=n.split(/[.+-]/).map(Number);return{range:`^${n}`,takes:`${n} or a later ${t===0?`0.${s}`:t}.x`}}function N(n,t){let s=n.indexOf(`
3
- ${u}
4
- `);if(s<0)throw new Error(`SKILL.md has no section "${u}" (the version range of the command stands there)`);let e=n.indexOf(`
5
- ## `,s+u.length+1),i=e<0?n.length:e,{range:r,takes:o}=T(t),a=n.slice(s,i).replace(new RegExp(L.source,"g"),F(t)).replace(/\^\d+\.\d+\.\d+(?:-[\w.]+)?/g,r).replace(/\b\d+\.\d+\.\d+(?:-[\w.]+)? or a later \d+(?:\.\d+)?\.x\b/g,o);return n.slice(0,s)+a+n.slice(i)}function y(n=p){let t=g.filter(r=>!l.existsSync(c.join(n,r)));if(t.length)return t.map(r=>`the skill takes ${r}, which is not there`);let s=E(g,n),e=r=>l.readFileSync(c.join(n,r),"utf8"),i=P(s,e).map(r=>`${r}, which the skill does not hold: link only what it holds`);for(let r of s.filter(o=>o.startsWith("sdk/")&&o.endsWith(".ts")))for(let[,o]of e(r).matchAll(/\bfrom\s+["']([^"']+)["']|\bimport\(\s*["']([^"']+)["']\s*\)/g))o&&(!o.startsWith("./")||o.includes("/../"))&&i.push(`${r} imports ${o}, outside sdk/: write the types it needs in sdk/`);return i}function R(n,{root:t=p,version:s=JSON.parse(l.readFileSync(c.join(t,"package.json"),"utf8")).version}={}){let e=y(t);if(e.length)throw new Error(`The skill cannot be made:
6
- ${e.map(i=>` ${i}`).join(`
7
- `)}`);l.rmSync(n,{recursive:!0,force:!0});for(let i of E(g,t)){let r=c.join(n,i);l.mkdirSync(c.dirname(r),{recursive:!0}),i==="SKILL.md"?l.writeFileSync(r,N(l.readFileSync(c.join(t,i),"utf8"),s)):l.copyFileSync(c.join(t,i),r)}return k(n)}function k(n,t=""){let s=[];for(let e of l.readdirSync(n,{withFileTypes:!0}).sort((i,r)=>i.name.localeCompare(r.name))){let i=t?`${t}/${e.name}`:e.name;e.isDirectory()?s.push(...k(c.join(n,e.name),i)):e.isFile()&&s.push(i)}return s}function E(n,t=p){return n.flatMap(s=>{let e=c.join(t,s);return l.existsSync(e)?l.statSync(e).isDirectory()?k(e,s):[s]:[]})}function v(n){let t=null;return n.split(`
8
- `).map(s=>{let e=/^\s*(`{3,}|~{3,})(.*)$/.exec(s);return t?(e&&e[1][0]===t[0]&&e[1].length>=t.length&&!e[2].trim()&&(t=null),""):e&&!(e[1][0]==="`"&&e[2].includes("`"))?(t=e[1],""):s}).join(`
9
- `)}function z(n){let t=v(n).replace(/(`+)(?!`)(?:(?!\n[ \t]*\n)[\s\S])*?[^`]\1(?!`)/g,e=>" ".repeat(e.length));return[...[...t.matchAll(/\]\(\s*(?:<([^<>\n]*)>|((?:[^\s()<>]|\([^\s()<>]*\))+))(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^()\n]*\)))?\s*\)/g)].map(e=>[e.index,e[1]??e[2]]),...[...t.matchAll(/^ {0,3}\[(?!\^)[^\]\n]+\]:[ \t]*(?:<([^<>\n]*)>|(\S+))/gm)].map(e=>[e.index,e[1]??e[2]]),...[...t.matchAll(/<(?:a|img)\s[^>]*?\b(?:href|src)\s*=\s*(?:"([^"]*)"|'([^']*)')/gi)].map(e=>[e.index,e[1]??e[2]])].sort(([e],[i])=>e-i).map(([,e])=>e)}function C(n,t){if(/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(t))return null;let[,s,e=""]=/^([^?#]*)(?:\?[^#]*)?(?:#(.*))?$/s.exec(t),i=o=>{try{return decodeURIComponent(o)}catch{return o}};return{file:s?c.posix.normalize(c.posix.join(c.posix.dirname(n),i(s))).replace(/\/$/,""):n,anchor:i(e)}}function P(n,t){let s=new Set(n),e=new Set(n.flatMap(r=>r.split("/").slice(0,-1).map((o,a,f)=>f.slice(0,a+1).join("/")))),i=[];for(let r of n.filter(o=>/\.md$/i.test(o)))for(let o of z(t(r))){let a=C(r,o);!a||a.file===r||!s.has(a.file)&&!e.has(a.file)&&i.push(`${r} links ${o}`)}return i}function M(n,{root:t=p,version:s=JSON.parse(l.readFileSync(c.join(t,"package.json"),"utf8")).version}={}){let e=y(t);if(e.length)throw new Error(`The skill cannot be made:
10
- ${e.map(m=>` ${m}`).join(`
11
- `)}`);let i=c.join(n,"skill","gallery"),r=`gallery-skill-${s}.zip`,o=c.join(n,r);l.rmSync(c.join(n,"skill"),{recursive:!0,force:!0}),l.existsSync(c.join(n,"gallery","PACKAGE-MANIFEST.json"))&&l.rmSync(c.join(n,"gallery"),{recursive:!0,force:!0});for(let m of l.existsSync(n)?l.readdirSync(n):[])/^gallery-skill-.+\.zip(?:\.sha256)?$|^PACKAGE-MANIFEST\.json$/.test(m)&&l.rmSync(c.join(n,m),{force:!0});let a=R(i,{root:t,version:s}),f=a.map(m=>({name:`gallery/${m}`,data:l.readFileSync(c.join(i,m))})),h=b(f);l.writeFileSync(o,h);let S=A(h);l.writeFileSync(`${o}.sha256`,`${S} ${r}
12
- `);let{range:$}=T(s),I={name:"gallery",version:s,archive:r,holds:"The Agent's documents (SKILL.md, references/writing-html.md, references/building-blocks.md, references/block-script.md, references/pages-and-data.md, references/extensions.md, the example references/example-report.html), the SDK's types (sdk/) and Codex's display metadata (agents/openai.yaml). The tools are the npm package @heycys/gallery, which SKILL.md has the Agent check for and install (with the user's consent); gallery skill install writes this same skill.",skillEntrypoint:"SKILL.md",requires:`@heycys/gallery@${$}`,files:f.map(({name:m,data:d})=>({path:m.slice(8),bytes:d.byteLength,sha256:A(d)}))};l.writeFileSync(c.join(n,"PACKAGE-MANIFEST.json"),`${JSON.stringify(I,null,2)}
13
- `);let O=f.reduce((m,{data:d})=>m+d.byteLength,0);return{archive:o,skill:i,files:a,bytes:O,zipBytes:h.byteLength,sha256:S,range:$}}if(import.meta.url===K(process.argv[1]).href){let{positional:n}=await w(import.meta.url);n.length>0&&(console.error(j(x(import.meta.url),`Unknown argument: ${n[0]} (skill:package takes none: there is one skill).`)),process.exit(2));let t=y();t.length>0&&(console.error(`Not packaged:
14
- ${t.map(e=>` ${e}`).join(`
15
- `)}`),process.exit(1));let s=M(c.join(p,"release"));console.log(`Packaged ${s.archive} (${s.files.length} files, ${s.bytes.toLocaleString("en-US")} bytes; the ZIP ${s.zipBytes.toLocaleString("en-US")} bytes), for @heycys/gallery ${s.range}`),console.log(`The skill's folder: ${s.skill}`),console.log(`SHA-256 ${s.sha256}`)}export{u as BOOTSTRAP,g as SKILL_FILES,R as buildSkill,P as deadLinks,E as filesOf,C as linkTarget,z as linksOf,k as listFiles,M as packageSkill,y as skillProblems,T as skillRange,N as withRange,v as withoutSamples};
@@ -1,5 +0,0 @@
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(`
3
- `)[0]}`,null,`the console says ${p.text().split(`
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};
@@ -1,15 +0,0 @@
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 we,b as q,c as X,f as be,g as L,h as ke,i as Q,l as ye,m as xe}from"./chunk-3SKOU6OZ.mjs";import{a as gt}from"./chunk-ZTHICSSF.mjs";import{b as le,c as $t,e as K,f as de,i as fe,j as he,m as ue,n as pe,o as me,p as ge,q as $e,r as wt}from"./chunk-PLB7L22J.mjs";import{a as pt}from"./chunk-PAREWQGB.mjs";import{a as te,b as ee,c as oe,d as se,e as ne,f as ie,g as ae,h as re,l as ce}from"./chunk-BFJGHSQN.mjs";import{b as mt,c as Yt,d as qt,e as Xt,g as Qt}from"./chunk-U5XL7D6A.mjs";import{a as w,b as Vt,c as Zt}from"./chunk-HYMEEXKN.mjs";import{g as T,j as Kt,l as Gt,m as Jt}from"./chunk-TKWEX4FD.mjs";import{existsSync as bo,readFileSync as ki,readdirSync as yi}from"node:fs";import S from"node:fs/promises";import N from"node:path";function Se(t){if(!t||!Array.isArray(t.lines))throw new Error("diff: lines must be an array.");t.lines.forEach(e=>{if(!e||!["added","removed","unchanged"].includes(e.type)||typeof e.content!="string"||/[\r\n]/.test(e.content))throw new Error("diff: each line needs a valid type and single-line content.");if(e.lineNumber!=null&&(!Number.isInteger(e.lineNumber)||e.lineNumber<1))throw new Error("diff: lineNumber must be a positive integer.")})}import{BODY as kt,isInstance as Wo}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as Bo}from"../browser/shared/components/installed.mjs";import{attr as F,elementsOf as Ne,hasClass as Ho,walk as yt}from"../browser/shared/html-tree.mjs";import{CHART_DATA as Ko,CHART_KEY as Go,CHART_SOURCE as z,VIEW_FROM as tt,cellWords as Jo,rowsReading as ve,tableRows as Vo}from"../browser/shared/table-chart.mjs";var Zo=t=>t.tagName==="script"&&(F(t,"type")??"").trim().toLowerCase()==="application/json",Oe=t=>t.nodeName==="#text"?t.value:(t.childNodes??[]).map(Oe).join("");function Yo(t){let e=t;for(;e&&e.tagName!=="figure";)e=e.parentNode;let s=e?Ne(e).find(o=>/^h[2-4]$/.test(o.tagName)):null;return s?Jo(Oe(s)):""}function Ee(t,e,s=w(t)){let o=[];return yt(s,n=>{let i=e(n);if(i===void 0||!n.sourceCodeLocation)return;let a=n.childNodes.find(Zo);o.push({type:i,line:n.sourceCodeLocation.startLine,text:a?a.childNodes.map(c=>c.value??"").join(""):null,source:F(n,Ko),tag:n.tagName,holder:n.parentNode?.tagName,title:Yo(n)})},kt),o}var qo=t=>t.tagName==="ol"&&F(t,"data-doc-chart")==="flow",et=(t,e)=>Ee(t,s=>qo(s)?void 0:F(s,"data-doc-chart"),e),Xo=t=>Ee(t,e=>Ho(e,"doc-diff")?"diff":void 0);function G(t){let e=new Map;return yt(t,s=>{let o=F(s,z);if(o===void 0||!s.sourceCodeLocation)return;(e.get(o)??e.set(o,[]).get(o)).push({line:s.sourceCodeLocation.startLine,offset:s.sourceCodeLocation.startOffset,table:Ne(s).find(i=>i.tagName==="table")??null})},{...kt,inTemplates:!1}),e}function xt(t,e){let s=e.get(t)??[];if(s.length===0)return{error:`no table's frame carries ${z}="${t}", so the chart has nothing to draw: put the table back, or delete the card`};if(s.length>1)return{error:`${s.length} tables carry ${z}="${t}" (lines ${s.map(({line:c})=>c).join(", ")}): a key names one table (the chart draws the first); take it off the copies`};let[{line:o,table:n}]=s;if(!n)return{error:`the frame carrying ${z}="${t}" (line ${o}) holds no table`};let i=gt(n),a=Vo(i);return a.error?{error:`its table (line ${o}) ${a.error}`}:{...a,line:o,cells:i}}function St(t){let e=[t,...L(t).filter(({files:n})=>n.includes("kit.js")).map(n=>Q(n,"kit.js")??"")].join(`
3
- `),s=new Set([...e.matchAll(/DocCharts\.define\(\s*(["'`])([a-z][a-z0-9-]*)\1/g)].map(n=>n[2])),o=new Set([...e.matchAll(/DocCharts\.define\(\s*(["'`])([^"'`\n]*)\1/g)].map(n=>n[2]).filter(n=>!s.has(n)));return{defined:s,misnamed:o}}function Nt(t){let e=w(t),s=[],{defined:o,misnamed:n}=St(t),i=null;for(let{type:a,line:c,text:l,source:r,tag:d,holder:f}of et(t,e)){let h=`data-doc-chart="${a}" (line ${c})`;if(d==="table"){s.push(f==="figure"?`${h} is on a table inside a <figure>: the chart's card is a figure of its own, so write the table outside it, its <caption> the chart's title`:`${h} is on a table the tools leave as written (inside a whole block, an element with a class of the document's own, a cell): a chart is drawn from a table outside one`);continue}if(n.has(a)){s.push(`${h}: the document's script defines "${a}" with DocCharts.define, which refuses that name: a chart type's name is lowercase letters, digits and hyphens, a letter first ("interval", "ci-plot"); rename it in both places`);continue}if(!o.has(a)){s.push(`${h}: the document's script does not define "${a}": define it once in the document's <script> with DocCharts.define("${a}", ({ host, data, tokens, width, height }) => { \u2026 }) (references/writing-html.md, "Figures and charts")`);continue}if(r!==void 0){if(l!==null){s.push(`${h}: a chart drawn from a table takes its data from the table: take its <script type="application/json"> out`);continue}let u=xt(r,i??=G(e));u.error&&s.push(`${h}: ${u.error}`);continue}if(l===null){s.push(`${h} needs its data in a <script type="application/json"> child`);continue}try{JSON.parse(l)}catch(u){s.push(`${h}: its data is not valid JSON (${u.message})`)}}s.push(...Le(e,i??=G(e)).failures);for(let{line:a,text:c}of Xo(t)){if(c===null)continue;let l=`.doc-diff (line ${a})`;try{Se(JSON.parse(c))}catch(r){s.push(`${l}: ${r instanceof SyntaxError?`its options are not valid JSON (${r.message})`:r.message}`)}}return s}function Te(t,{written:e=t}={}){let s=w(t),o=[],{defined:n}=St(t),i=null,a=null;for(let{type:c,line:l,text:r,source:d,title:f,tag:h}of et(t,s)){if(d===void 0||h==="table"||r!==null||!n.has(c))continue;let u=`data-doc-chart="${c}" (line ${l})`;if(!f){a??=new Set(e===t?[]:et(e).map(k=>k.source).filter(k=>k!==void 0));let b=e!==t&&!a.has(d);o.push(`${u}: this chart card has no title: ${b?"write a <caption> on its table (the one with data-doc-chart), which becomes the card's h3":"write an h3 in the card's figure, before the chart"}`)}let m=xt(d,i??=G(s));if(m.error)continue;let{blank:p,twice:g}=ve(m.cells,m.data);p&&o.push(`${u}: its table's header (line ${m.line}) has a cell with no words, so that column's values are keyed "" in data: write the column's name there`),g.length>0&&o.push(`${u}: its table's header (line ${m.line}) names ${g.map(b=>`"${b}"`).join(", ")} twice, so data keeps the later column's value under it: give each column a name of its own`)}return o.push(...Le(s,i??=G(s)).notes),o}var bt=500;function Le(t,e){let s=[],o=[],n=T().packages;return yt(t,i=>{let a=F(i,tt);if(a===void 0||!i.sourceCodeLocation)return;let c=F(i,Bo),l=`${c??i.tagName} (line ${i.sourceCodeLocation.startLine})`;if(!Wo(i))return void s.push(`<${i.tagName}> (line ${i.sourceCodeLocation.startLine}) carries ${tt}="${a}", which only a view of a table carries: an instance of a custom block (<div data-doc-component="<scope>/<name>">) whose block's needs hold "tables"; take it off`);if(!Go.test(a))return void s.push(`${l}: ${tt}="${a}" is no key: a letter, then letters, digits, "_" or "-", 32 at most, as the table's frame writes it in ${z}`);let r=e.get(a)??[];if(r.length===0)return void s.push(`${l}: no table's frame carries ${z}="${a}", so the view has no table to read: put the table back, or delete the view`);if(r.length>1)return void s.push(`${l}: ${r.length} tables carry ${z}="${a}" (lines ${r.map(({line:g})=>g).join(", ")}): a key names one table (the view reads the first); take it off the copies`);let[{line:d,offset:f,table:h}]=r;if(!h)return void s.push(`${l}: the frame carrying ${z}="${a}" (line ${d}) holds no table`);i.sourceCodeLocation.startOffset<f&&o.push(`${l} stands before the table it reads (${z}="${a}", line ${d}): it works there, but each block's writing.md writes the table first and the view after it, as its example does: move the view below the table, unless the document is meant to open on it`);let u=n.get(c)?.needs;u&&!u.includes("tables")&&o.push(`${l} carries ${tt}="${a}", but its block's needs hold no "tables", so it reads no table: add "tables" to needs in its component.json, or take the key off`);let m=gt(h);m.merged&&o.push(`${l}: its table (line ${d}) has merged cells, which no view reads, so the view shows nothing of it: write each value in its own cell`);let p=m.names?m.rows.length:Math.max(0,m.rows.length-1);p>bt&&o.push(`${l}: its table (line ${d}) has ${p} rows: every view of a table reads it again as it is typed in, and past ${bt} rows that slows typing in it; split it, or keep what a view shows to ${bt} rows`)},kt),{failures:s,notes:o}}function Ae(t){let e=w(t),s=[],o=[],{defined:n}=St(t),i=null,a=(c,l)=>`${c} ${l}${c===1?"":"s"}`;for(let{type:c,line:l,text:r,source:d,tag:f}of et(t,e)){if(d===void 0||f==="table"||r!==null||!n.has(c))continue;let h=xt(d,i??=G(e));if(h.error)continue;let{rows:u,columns:m,foot:p,extra:g}=ve(h.cells,h.data),b=`data-doc-chart="${c}" (line ${l})`,k=[a(u,"row")];for(let{name:x,numbers:v,words:E,empty:H}of m){let R=v+E+H,Y=v===R&&R>0?"numbers":E===R&&R>0?"words":[v&&a(v,"number"),E&&`${E} as words`,H&&`${H} empty (null)`].filter(Boolean).join(", ")||"no rows";k.push(`"${x}": ${Y}`),v>0&&E>0&&o.push(`${b}: its table's column "${x}" (line ${h.line}) reads as numbers in ${a(v,"row")} and as words in ${E}: write each of its cells as one number (an empty cell, "\u2014" or "n/a" for none: null in data), or, for a column of words, data-sort-type="text" on its header cell`)}p>0&&o.push(`${b}: its table's <tfoot> (line ${h.line}) holds ${a(p,"row")} the chart leaves out, and a table with a <tfoot> has no table tools in the preview: keep a total out of a table you chart and say it in the text`),g>0&&o.push(`${b}: ${a(g,"row")} of its table (line ${h.line}) ${g===1?"has":"have"} cells past the header, which the chart does not read: give each column a header cell`),s.push(`${c} (line ${l}) reads its table (line ${h.line}): ${k.join("; ")}`)}return{readings:s,notes:o}}import{BODY as xi,componentOf as Si,matchesNode as ko}from"../browser/shared/components/index.mjs";import{FLOW as Ni}from"../browser/shared/components/list.mjs";import{attr as O,elementsOf as yo,walk as M}from"../browser/shared/html-tree.mjs";import{GLYPH_SETS as vi,ICON_COLORS as xo,glyphOf as Oi,glyphValue as Ei,iconKind as Pt,iconMarkup as Ti,iconValueOf as Li}from"../browser/shared/emoji/icon-value.mjs";import Qo from"node:vm";import{LINE_START as nt,lineStart as ts}from"../browser/shared/code-lines.mjs";import{BODY as De,COMPONENTS as es,FLOWS as os,instanceSlots as ss,instancesOf as ns,isInstance as D,isSlot as _e,matchesNode as P,ownSlots as is,partOf as Tt,vocabulary as as}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as C,INSTANCE as rs,PACKAGE_ID as it,SCHEMA as vt,SLOT as I,schemaAhead as cs}from"../browser/shared/components/installed.mjs";import{packageScript as ls}from"../browser/shared/export-wrap.mjs";import{asDocName as ds,kitNamespace as fs}from"../browser/shared/old-names.mjs";import{shortSheets as hs}from"../browser/shared/components/sheets.mjs";import{attr as y,curlyQuoted as us,hasClass as ps,walk as J}from"../browser/shared/html-tree.mjs";var{authoring:st,runtime:Ce}=as(),ms="input, select, textarea, button, details, table",at=t=>t.sourceCodeLocation?.startLine,$=t=>at(t)?` (line ${at(t)})`:"";function ze(t){let e=(o,n)=>{let i=Array.from({length:n.length+1},(a,c)=>c);for(let a=1;a<=o.length;a++){let c=i[0];i[0]=a;for(let l=1;l<=n.length;l++){let r=i[l];i[l]=Math.min(i[l]+1,i[l-1]+1,c+(o[a-1]===n[l-1]?0:1)),c=r}}return i[n.length]},[s]=[...st.keys()].filter(o=>o.startsWith(t.slice(0,7))).map(o=>[o,e(t,o)]).sort((o,n)=>o[1]-n[1]);return s&&s[1]<=3?` (${s[0]}?)`:""}function gs(t,e,s){let{part:o,property:n,min:i}=t.shares,a=new RegExp(`(?:^|;)\\s*${n}\\s*:\\s*([^;]*)`),c=s.map(f=>a.exec(y(f,"style")??"")?.[1].trim()??null),l=c.filter(f=>f!==null);if(l.length===0)return[];let r=`${t.id}${$(e)}`;return l.length<c.length?[`${r}: ${n} on ${l.length} of its ${c.length} ${o}: write it on every one of them, or on none (equal widths)`]:l.map(Number).some(f=>!Number.isFinite(f)||f<i-1e-9||f>1)?[`${r}: ${n} is a share of the row, a number from ${Math.round(i*1e3)/1e3} to 1 (${l.join(", ")})`]:[]}var ot={"doc-dialog-header":'a detail card has no header: its content region (<div class="doc-dialog-content">) stands alone in its panel',"doc-dialog-title":"a detail card's title is an ordinary heading (<h3>), first in its content region","doc-dialog-close":"a detail card has no close button: Esc and a press outside it close it","data-doc-dialog-close":"a detail card has no close button: Esc and a press outside it close it","doc-section-header":"a section's title is a plain heading (<h2>) with an ordinary paragraph below it for the line that says what the section is: no <div> goes around them","doc-grid":'a card row is now columns: <div class="doc-columns"> holding one <div class="doc-column"> per card',"doc-grid-3":'a card row is now columns: <div class="doc-columns"> holding three <div class="doc-column">',"doc-lede":`write the line under the title as a paragraph of the header (an ordinary <p>), or as small text, <p class="doc-note"): the header's lines read as the body's paragraphs`,"doc-source":`write the line under the title as a plain paragraph of the header (an ordinary <p>), or as small text (<p class="doc-note">): the header's lines read as the body's paragraphs`,"doc-prose":"write the text straight in its flow (the page, a Sheet panel, a section, a panel, a column\u2026): it reads the same there","doc-prose-h1":"write an h1","doc-prose-h2":"write an h2","doc-prose-h3":"write an h3","doc-prose-h4":"write an h4","doc-state-grid":'put the groups side by side in columns (<div class="doc-columns">)',"doc-state-group":"write the group's title as a heading and its controls as blocks of their own in a column","doc-state-status":'write the line as small text, <p class="doc-note">',"doc-code-block":'a code block is <div class="doc-code"> holding its title (<div class="doc-code-title">) and the <pre><code>',"doc-code-card":'a code block is <div class="doc-code"> holding its title and its <pre>; a diff is <div class="doc-diff">',"doc-code-header":'write the title as <div class="doc-code-title">: the kit draws the rest of the header',"data-doc-diff":'a diff is <div class="doc-diff"> holding its title and its options as JSON (sdk/doc-code.d.ts)',"data-doc-diff-stats":"the kit shows a diff's counts in its header: remove it","doc-code--wrap":"a code block wraps its long lines by itself: remove it (doc-code--nowrap scrolls them instead)"},$s={[nt]:'write it on its <div class="doc-code">',"data-start":`write ${nt} on its <div class="doc-code">`,"data-line-numbers":'write it on its <div class="doc-code">',"data-folded-lines":'write it on its <div class="doc-code">',"data-title":'write the title in its <div class="doc-code-title">',"data-wrap":'for long lines that scroll, write class="doc-code doc-code--nowrap" on its <div class="doc-code">'};function ws(t){let e=[],s=t.tagName==="pre"?t.parentNode:t.tagName==="code"&&t.parentNode?.tagName==="pre"?t.parentNode.parentNode:null;if(s?.tagName&&P(s,".doc-code"))for(let[n,i]of Object.entries($s))y(t,n)!==void 0&&e.push(`${n}${$(t)} on the <${t.tagName}> of a code block does nothing: ${i}`);let o=t.tagName==="div"&&P(t,".doc-code")?y(t,nt):void 0;return o!==void 0&&ts(o)===null&&e.push(`${nt}="${o}"${$(t)}: the number of a code block's first line is a whole number from 1`),e}var Ie=os.join(", "),bs=t=>P(t.parentNode,Ie)||t.parentNode?.tagName==="div"&&!y(t.parentNode,"class")&&P(t.parentNode.parentNode,Ie);function ks(t,e){let s=[];J(e,n=>s.push(...us(t,n)));let o=n=>n.replace(/=(\s*)[“”]/,'=$1"').replace(/[“”]$/,'"');return s.map(({written:n,line:i},a)=>a===0?`line ${i}: attribute ${n} uses curly quotes (U+201C/U+201D), which HTML reads as part of the value: write straight quotes, ${o(n)}; an editor keeping a file's \u201C\u2026\u201D style may change them`:`line ${i}: attribute ${n} uses curly quotes too: write ${o(n)}`)}var je={details:"write a plain <details> without the class (its <summary>, then what it holds): the export makes it the kit's"},ys="write a <section> of no attribute straight in it for each tab, starting with its heading (<h2>\u2013<h4>), the tab's name, the rest its blocks, and nothing else: the export makes the kit's tabs",xs='a bookmark written the short way is a paragraph in a flow holding only <a class="doc-bookmark" href="https://\u2026">its title</a> (a title attribute its description, nothing else on it, words alone in it): the export makes the card';function Me(t){let e=[];return J(t,s=>{y(s,C)!==void 0&&e.push(s)},De),e}var Ss=t=>{let e=t.parentNode;for(;e&&!(D(e)||_e(e));)e=e.parentNode;return e??null};function Ns(t,e){let s=[];return J(t,o=>{let n=y(o,I);if(n===void 0)return;if(D(o))return void s.push(`${I}="${n}"${$(o)} on the instance itself: a slot is an element inside it`);if(!_e(o))return void s.push(`${I}${$(o)} on a <${o.tagName}>: a slot is a block-level <div> or <section>`);let i=Ss(o),a=i&&D(i)?e?.get(y(i,C)):null;if(!i||!D(i)||a&&Pe(i,a,o))return void s.push(`${I}="${n}"${$(o)} stands outside any instance's own markup: a slot is a part of a component package's instance, written in its template`);y(o,"data-block-id")!==void 0&&s.push(`${I}="${n}"${$(o)}: a slot is no block: it carries no data-block-id`)}),s}var vs=(t,e)=>{for(let s=e.parentNode;s;s=s.parentNode)if(s===t)return!0;return!1},Pe=(t,e,s)=>Object.values(e.parts??{}).filter(({edit:o})=>o==="text"||o==="data").some(({at:o})=>Tt(t,o).some(n=>vs(n,s))),Re=(t,e)=>is(t).filter(s=>!Pe(t,e,s)),Os=t=>t.flatMap(e=>D(e)?it.test(y(e,C))?[]:[`${C}="${y(e,C)}"${$(e)} names no custom block: write <scope>/<name>, the id of a custom block of the workspace's components/ folder`]:[`${C}${$(e)} on a <${e.tagName}>: an instance of a component is a block-level <div> or <section>`]);function Ue(t){let e=Me(t).filter(o=>D(o)&&it.test(y(o,C))),s=e.length>0?T():null;return e.flatMap(o=>{let n=y(o,C),i=s.packages.get(n);if(i&&!cs(y(o,vt),i.schema))return[];if(i)return[`line ${at(o)}: <${o.tagName} ${C}="${n}">: ${vt}="${y(o,vt)}" is past the ${i.schema??1} its package's manifest reads (schema): nothing can write it back, and the block shows read-only until the package reads it`];let a=s.problems.get(n)?.problem,c=a?`package ${n} does not load (${Kt("en",a)})`:`no package ${n} in this workspace (components/${n}/component.json)`;return[`line ${at(o)}: <${o.tagName} ${C}="${n}">: ${c}: the block shows what it holds, read-only, and moves, copies and deletes whole`]})}function Ot(t,e){let s=[];for(let{name:o,value:n}of t.attrs){if(ot[o]&&!st.has(o)){s.push(`${o}${$(t)} is gone: ${ot[o]}`);continue}if(o.startsWith("data-doc-")&&!st.has(o)&&s.push(Ce.has(o)?`${o}${$(t)} is the kit's to set: remove it`:`${o}${$(t)} is no attribute of the kit's${ze(o)}`),o==="class"){for(let i of n.split(/\s+/).filter(e))if(!st.has(i)){if(ot[i]){s.push(`class ${i}${$(t)} is gone: ${ot[i]}`);continue}s.push(Ce.has(i)?`class ${i}${$(t)} is the kit's to set: remove it`:`class ${i}${$(t)} is no class of the kit's${ze(ds(i))}: give a class of the document's own a name of its own (not doc-\u2026)`)}}}return s}var Fe=t=>t.startsWith("doc-");function Es(t){try{return new Qo.Script(ls(t),{filename:"kit.js"}),null}catch(e){let s=/^kit\.js:(\d+)/.exec(e.stack??"")?.[1];return{message:e.message,line:s?Number(s):null}}}var Et=new Map;function Ts(t){if(!t.files.includes("kit.js"))return null;if(Et.get(t.folder)?.stamp!==t.stamp){let e=Q(t,"kit.js"),s=e===null?null:Es(e),o=e===null?`${t.id}: its kit.js cannot be read`:s&&`${t.id}: its kit.js does not run: ${s.message}${s.line?` (line ${s.line})`:""}`;Et.set(t.folder,{stamp:t.stamp,failure:o})}return Et.get(t.folder).failure}function Lt(t,e=w(t),s=null){let o=ks(t,e),n=Me(e);o.push(...Os(n));let i=n.length>0?s??T():null,a=i?[...i.packages.values()]:[];i&&o.push(...L(t,i,e).map(Ts).filter(Boolean));for(let r of[...es,...a].filter(d=>d.match&&(d.parts||d.pairs)))for(let d of ns(e,r)){if(r.empty&&!(d.childNodes??[]).some(u=>u.tagName||u.nodeName==="#text"&&u.value.trim()))continue;let f=r.id==="sheets"?hs(d):null;if(f){o.push(`${r.id}${$(d)} has no tabs and is no short form: ${f.why??"it stands where no block does (in a whole block or a figure)"}; ${ys}`);continue}if(je[r.id]&&Object.values(r.parts??{}).some(u=>Tt(d,u.at).length<(u.optional?0:u.min??1))){o.push(`${r.id}${$(d)} carries the kit's class without the kit's parts: ${je[r.id]}`);continue}let h={};for(let[u,m]of Object.entries(r.parts??{})){if(m.edit==="flow"&&it.test(r.id)){let b=Re(d,r).filter(k=>y(k,I)===u);b.length===0&&!m.optional&&o.push(`${r.id}${$(d)} has no ${u} (${I}="${u}")`);for(let k of b.slice(1))o.push(`${r.id}${$(k)}: slot "${u}" twice`);h[u]=b.slice(0,1);continue}h[u]=Tt(d,m.at);let p=m.optional?0:m.min??1,g=m.max??1/0;h[u].length<p?o.push(`${r.id}${$(d)} has ${h[u].length===0?"no":`${h[u].length} of`} ${u} (${m.at.replace(":scope > ","")})${h[u].length>0?`, at least ${p}`:""}`):h[u].length>g&&o.push(`${r.id}${$(d)} has ${h[u].length} of ${u}, at most ${g}`)}if(r.only){let u=new Set(r.only.flatMap(m=>h[m]));for(let m of(d.childNodes??[]).filter(p=>p.tagName&&!u.has(p)))o.push(`${r.id}${$(d)} holds a <${m.tagName}>${$(m)}: only its ${r.only.join(", ")} (${r.only.map(p=>r.parts[p].at.replace(":scope > ","")).join(", ")}) go in it`)}if(r.shares&&o.push(...gs(r,d,h[r.shares.part])),it.test(r.id)){let u=Object.entries(r.parts??{}).filter(([,m])=>m.edit==="flow").map(([m])=>m);for(let m of Re(d,r).filter(p=>!u.includes(y(p,I))))o.push(`${r.id}${$(m)}: slot "${y(m,I)}" is no part of its manifest edited as flow`)}for(let{a:u,attrA:m,b:p,attrB:g}of r.pairs??[]){let b=h[u].map(x=>y(x,m)),k=h[p].map(x=>y(x,g));for(let x of new Set(b.filter((v,E)=>b.indexOf(v)!==E)))o.push(`${r.id}${$(d)}: ${u} "${x}" twice`);for(let x of b.filter(v=>!k.includes(v)))o.push(`${r.id}${$(d)}: ${u.replace(/s$/,"")} "${x}" has no ${p.replace(/s$/,"")} (${g}="${x}")`);for(let x of k.filter(v=>!b.includes(v)))o.push(`${r.id}${$(d)}: ${p.replace(/s$/,"")} "${x}" has no ${u.replace(/s$/,"")} (${m}="${x}")`)}}o.push(...Ns(e,i?.packages));let c=new Set,l=[];J(e,r=>{if(D(r)){let h=new Set(ss(r));o.push(...Ot(r,Fe)),J(r,u=>o.push(...Ot(u,Fe)),{stop:u=>h.has(u)});return}r.tagName==="pre"&&bs(r)&&o.push(`<pre>${$(r)} straight in the text: a code block is <div class="doc-code"> holding its title (<div class="doc-code-title">) and the <pre>`),o.push(...ws(r)),r.tagName==="a"&&ps(r,"doc-bookmark")&&o.push(`<a class="doc-bookmark">${$(r)} is no bookmark: ${xs}`),o.push(...Ot(r,fs));let d=y(r,"data-doc-bind");d!==void 0&&(d.trim()?P(r,ms)?r.tagName==="button"&&y(r,"value")===void 0?o.push(`data-doc-bind${$(r)} on a button without a value: give it the value a click chooses`):c.add(d.trim()):o.push(`data-doc-bind${$(r)} on a ${r.tagName}: only inputs, selects, textareas, buttons with a value, details and tables hold a key`):o.push(`data-doc-bind${$(r)} names no key`));let f=y(r,"data-doc-show");f!==void 0&&l.push([r,f])},De);for(let[r,d]of l){let f=d.split(":")[0].trim();!f||!d.includes(":")?o.push(`data-doc-show="${d}"${$(r)}: write key:value`):c.has(f)||o.push(`data-doc-show="${d}"${$(r)}: nothing binds "${f}" (data-doc-bind="${f}")`)}return o.push(...js(t,e)),o}var Ls=/(?<![\\$])\$(?=[^\s$])([^$]*?[^\s$\\])\$(?![$\d])/g,As=/(?:(?<![A-Za-z0-9_])[A-Za-z]|[)\]}])_[A-Za-z0-9{]/,Cs=t=>/[\\^]/.test(t)||!t.startsWith("{")&&As.test(t),zs=new Set(["head","code","pre","kbd","samp","script","style","template","textarea","noscript","svg","math","title","iframe","object"]),Is=`.doc-math-inline, .doc-math-block, .doc-code, .doc-diff, [data-doc-math-dollar], [data-doc-chart], ${rs}`;function js(t,e){let s=[],o=n=>{for(let i of n.childNodes??[])if(i.nodeName==="#text"&&i.sourceCodeLocation&&i.value.includes("$")){let{startOffset:a,endOffset:c}=i.sourceCodeLocation;for(let l of t.slice(a,c).matchAll(Ls)){if(!Cs(l[1]))continue;let r=l[1].replace(/\s+/g," "),d=r.length>60?`${r.slice(0,59)}\u2026`:r;s.push(`line ${Zt(t,a+l.index)}: $${d}$ is not drawn as a formula (single dollars are off: they are money): write \\(${d}\\)`)}}else i.tagName&&!zs.has(i.tagName)&&!P(i,Is)&&o(i)};return o(e),s}import V from"node:fs";import W from"node:path";import{COLOR_NAMES as Hs}from"../browser/shared/colors.mjs";import{FOLD_DOTS as Ks}from"../browser/shared/code-folds.mjs";import{kitPublicDirectory as Gs,kitSourceDirectory as Js,release as Vs}from"../browser/shared/paths.mjs";import{FLOW_LABEL as Ua}from"../browser/shared/components/list.mjs";var Rs={"code-title":{zh:"\u4EE3\u7801\u5757",en:"Code"},"plain-text":{zh:"\u7EAF\u6587\u672C",en:"Plain text"},"fold-code":{zh:"\u6298\u53E0\u6216\u5C55\u5F00\u4EE3\u7801\u5757",en:"Collapse or expand the code block"},"copy-code":{zh:"\u590D\u5236\u4EE3\u7801",en:"Copy code"},copied:{zh:"\u5DF2\u590D\u5236",en:"Copied"},wrap:{zh:"\u81EA\u52A8\u6362\u884C",en:"Wrap lines"},"no-wrap":{zh:"\u53D6\u6D88\u81EA\u52A8\u6362\u884C",en:"Stop wrapping lines"},fold:{zh:"\u6298\u53E0",en:"Collapse"},unfold:{zh:"\u5C55\u5F00",en:"Expand"},line:{zh:"\u7B2C {0} \u884C",en:"Line {0}"},lines:{zh:"\u7B2C {0}\u2013{1} \u884C",en:"Lines {0}\u2013{1}"},"diff-counts":{zh:"\u65B0\u589E {0} \u884C\uFF0C\u5220\u9664 {1} \u884C",en:"Lines added: {0}, removed: {1}"}};var We="data-ge-language",Fs={"code-title":"--doc-word-code-title"};function Ds(t,e,s,...o){let n=t[s];if(!n)throw new Error(`The kit has no word "${s}" here (src/render/kit/words.js).`);let i=n[e]??n.zh;return o.length===0?i:i.replace(/\{(\d+)\}/g,(a,c)=>c<o.length?String(o[c]):a)}var _s=`:root[${We}="en"], :root:not([${We}])[lang|="en" i]`;function Be(){let t=e=>Object.entries(Fs).map(([s,o])=>`${o}: ${JSON.stringify(Ds(Rs,e,s))};`).join(" ");return`:root { ${t("zh")} }
4
- ${_s} { ${t("en")} }`}import{LOOK as At,LOOK_ATTRIBUTES as Ms,SERIF_FONT as He,SIZE_FACTOR as Ps,SPACING as Us,WIDTH as Ct}from"../browser/shared/document-look.mjs";var Ke=[["--doc-body-font-size","--doc-body-line-height"],["--doc-small-font-size","--doc-small-line-height"],["--doc-note-font-size","--doc-note-line-height"],["--doc-title-font-size","--doc-title-line-height"],["--doc-h1-font-size","--doc-h1-line-height"],["--doc-h2-font-size","--doc-h2-line-height"],["--doc-h3-font-size","--doc-h3-line-height"],["--doc-h4-font-size","--doc-h4-line-height"],["--doc-card-title-font-size","--doc-card-title-line-height"],["--doc-table-font-size","--doc-table-line-height"]],Ws=["--doc-component-gap","--doc-block-gap","--doc-media-gap","--doc-paragraph-gap","--doc-group-gap","--doc-list-gap"],zt="--doc-content-max-width";function Bs(t){let e=new Map;for(let[,s,o]of String(t).matchAll(/^\s*(--doc-[a-z0-9-]+):\s*([^;]+);/gm))e.has(s)||e.set(s,o.trim());return e}var rt=t=>`${Math.round(t)}px`;function ct(t,{size:e="default",spacing:s="default",width:o="default"}={}){let n=r=>{let d=/^(-?[0-9.]+)px$/.exec(t.get(r)??"");if(!d)throw new Error(`src/render/kit/styles/tokens.css: ${r} is no length in px (src/render/look-css.mjs reads it)`);return Number(d[1])},i=Ps[e],{leading:a,gaps:c}=Us[s],l={};if(e!=="default"||s!=="default")for(let[r,d]of Ke){let f=n(r)*i;e!=="default"&&(l[r]=rt(f)),l[d]=rt(Math.round(f)+(n(d)-n(r))*i*a)}if(s!=="default"){for(let r of Ws)l[r]=rt(n(r)*c);l["--doc-space"]=String(c)}if(o!=="default"){if(n(zt)!==Ct.default)throw new Error(`src/render/kit/styles/tokens.css: ${zt} is not \u9ED8\u8BA4 \u6B63\u6587\u5BBD\u5EA6's ${Ct.default}px (src/shared/document-look.mjs WIDTH)`);l[zt]=rt(Ct[o])}return l}var U=(t,e)=>`${t} { ${Object.entries(e).map(([s,o])=>`${s}: ${o};`).join(" ")} }`,_=(t,e)=>`[${Ms[t]}="${e}"]`;function Ge(t){let e=Bs(t),s=e.get("--doc-font");if(!s)throw new Error("src/render/kit/styles/tokens.css: no --doc-font (src/render/look-css.mjs keeps it as --doc-sans-font)");let o=[U(`:root${_("font","serif")}`,{"--doc-sans-font":s,"--doc-font":He}),U(`:root${_("font","mixed")}`,{"--doc-heading-font":He})],[,...n]=At.size,[,...i]=At.spacing,[,...a]=At.width;for(let c of n)o.push(U(`:root${_("size",c)}`,ct(e,{size:c})));for(let c of i)o.push(U(`:root${_("spacing",c)}`,ct(e,{spacing:c})));for(let c of a)o.push(U(`:root${_("width",c)}`,ct(e,{width:c})));for(let c of n)for(let l of i){let r=ct(e,{size:c,spacing:l});o.push(U(`:root${_("size",c)}${_("spacing",l)}`,Object.fromEntries(Ke.map(([,d])=>[d,r[d]]))))}return o.join(`
5
- `)}var Je=Object.fromEntries(K.filter(t=>t.file).map(t=>[t.file,t.build])),tr=Object.keys(Je),Z=t=>W.join(Js,t),Zs=(t,e,s)=>({entryPoints:[Z(t)],bundle:!0,write:!1,format:"iife",platform:"browser",target:"es2022",...typeof e=="function"?e():e,...s}),Ys=t=>{let e=Je[t];if(!e)throw new Error(`src/render/kit-build.mjs: no kit file "${t}"`);return e},lt=new Map;function qs(t,e){let s=[...e.matchAll(/^@import\s+"\.\/([a-z0-9-]+\.css)";\s*$/gm)].map(i=>i[1]),o=V.readdirSync(W.dirname(Z(t))).filter(i=>i.endsWith(".css")&&i!==W.basename(t)),n=[...o.filter(i=>!s.includes(i)).map(i=>`${i} is not listed`),...s.filter((i,a)=>!o.includes(i)||s.indexOf(i)!==a).map(i=>`${i} is listed but missing, or listed twice`)];if(n.length>0)throw new Error(`src/render/kit/${t}: ${n.join("; ")}`);return s.map(i=>W.join(W.dirname(t),i))}var Xs=t=>t.replace(/@(text|highlight)-colors\b/g,(e,s)=>Hs.map(o=>`.doc-${s}-${o}`).join(", ")),Qs=t=>{let e=Xs(t.join(`
6
- `)).replaceAll("@fold-dots",Ks).replace(/^@kit-words;$/m,()=>Be());return e.replace(/^@kit-look;$/m,()=>Ge(e))};function It(t,{fresh:e=!1}={}){let s=Ys(t);if(Vs)return V.promises.readFile(W.join(Gs,t),"utf8");if(s.read)return V.promises.readFile(Z(s.read),"utf8");if(s.styles)return V.promises.readFile(Z(s.styles),"utf8").then(o=>Promise.all(qs(s.styles,o).map(n=>V.promises.readFile(Z(n),"utf8")))).then(Qs);if(e||!lt.has(t)){let o=le(Zs(s.bundle,s.options)).then(n=>n.outputFiles[0].text);o.catch(()=>lt.delete(t)),lt.set(t,o)}return lt.get(t)}import{kitNamespace as tn}from"../browser/shared/old-names.mjs";import{attr as jt,hasClass as ft}from"../browser/shared/html-tree.mjs";var Ve=t=>t.tagName==="section"&&ft(t,"doc-section"),en=new Set(["section","header","footer","nav","script","style","template","dialog","link","meta"]),on=t=>!en.has(t.tagName),dt=t=>t.nodeName==="#text"?t.value:(t.childNodes??[]).map(dt).join("");function Ye(t,e=[]){for(let s of t.childNodes??[])s.tagName&&((s.tagName==="main"&&ft(s,"doc-page")||jt(s,"data-doc-sheet")!==void 0)&&e.push(s),Ye(s.tagName==="template"?s.content:s,e));return e}var sn=/^(p|li|h[1-4]|blockquote|ul|ol)$/,qe=["doc-summary","doc-panel","doc-note","doc-callout"],nn=t=>sn.test(t.tagName)||qe.some(e=>ft(t,e)),an=new Set(["none","auto","100%","inherit","initial","unset","revert"]),Ze=t=>[...t.matchAll(/(?:^|[;{\s])(?:max-)?width\s*:\s*([^;}]+)/gi)].some(([,e])=>!an.has(e.replace(/!important/i,"").trim().toLowerCase())),rn=t=>{let e=t.trim().split(/\s*[\s>+~]\s*/).at(-1)??"",s=/^(p|li|h[1-4]|blockquote|ul|ol)\b/.test(e)||qe.some(n=>e.includes(`.${n}`)),o=[...t.matchAll(/\.([\w-]+)/g)].some(([,n])=>!tn(n))||t.includes("#");return s&&!o};function cn(t){let e=[],s=(o,n)=>{for(let i of o.childNodes??[]){if(!i.tagName)continue;let a=n||i.tagName==="main"&&ft(i,"doc-page");if(a&&nn(i)&&Ze(jt(i,"style")??"")&&e.push(`<${i.tagName}> with style="${jt(i,"style").trim()}"`),i.tagName==="style"){let c=dt(i).replace(/\/\*[\s\S]*?\*\//g,"");for(let[,l,r]of c.matchAll(/([^{}]+)\{([^{}]*)\}/g))if(Ze(r))for(let d of l.split(","))rn(d)&&e.push(`"${d.trim()}" in the document's style`)}s(i.tagName==="template"?i.content:i,a)}};return s(t,!1),e}function Xe(t,{written:e=t}={}){let s=[],o=w(t),n=cn(o);n.length>0&&s.push(`body text given a width of its own (${n.slice(0,3).join("; ")}${n.length>3?`; ${n.length-3} more`:""}): its lines break before the reading column's edge, leaving an extra right margin; let body text fill the column`);for(let i of Ye(o)){let a=i.childNodes.filter(c=>c.tagName);a.forEach((c,l)=>{if(!Ve(c))return;let r=l+1;for(;r<a.length&&on(a[r]);)r++;let d=a.slice(l+1,r);if(d.length===0||!Ve(a[r]??{})||/^h[1-4]$/.test(d[0].tagName))return;let f=c.childNodes.map(g=>g.tagName?g:null).filter(Boolean).map(dt).find(g=>g.trim())?.replace(/\s+/g," ").trim().slice(0,40)??"",[h]=d,u=dt(h).replace(/\s+/g," ").trim(),m=`<${h.tagName}>${u?` "${u.length>30?`${u.slice(0,30)}\u2026`:u}"`:""}`,p=h.sourceCodeLocation?.startLine;s.push(`${d.length} block${d.length===1?"":"s"} of body text right after the section "${f}" stand outside it${p?` (line ${p})`:""}, ${d.length===1?`the ${m}`:`the first a ${m}`}, between two sections, with no heading of their own: fine if meant, otherwise they belong inside that section`)})}return s.push(...Te(t,{written:e})),s}import{attr as Qe,hasClass as ln}from"../browser/shared/html-tree.mjs";var to="Write instead where it came from, in words, or a path relative to materials/ (materials/data.csv)",dn=new Set(["script","style","template","noscript","textarea","pre","code","kbd","samp","var"]),fn=["doc-math-inline","doc-math-block"],hn=/\\\([\s\S]*?\\\)|\\\[[\s\S]*?\\\]|\$\$[\s\S]*?\$\$/g,un=/(?<!\\)\$(?:\\[\s\S]|[^\\$])+\$/g,pn=/[\s"'<>|()[\]{};,。;:、!?()《》「」『』“”‘’【】]/u,mn=/[^\s"'<>|()[\]{};,。;:、!?()《》「」『』“”‘’【】]+/gu,so=/^[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u,gn=/\.[A-Za-z0-9]{1,8}$/,$n=[/(?<![A-Za-z0-9_\\])[A-Za-z]:[\\/]/g,/(?<![A-Za-z0-9_.~:/\\-])\/(?:Users|home|root|tmp|private|mnt|opt|Volumes|var\/folders)\/(?=\S)/g,/(?<![A-Za-z0-9_.~:/\\-])~\/(?=\S)/g,/(?<![A-Za-z0-9_$\\])\$(?:HOME|\{HOME\})\/(?=\S)/g,/(?<![A-Za-z0-9_:\\])\\\\[A-Za-z0-9][\w.$-]*\\(?=[^\s\\])/g,/%(?:TEMP|TMP|APPDATA|LOCALAPPDATA|USERPROFILE)%/gi],wn=/(?:^|[\\/])(?:AppData|scratchpad)(?=[\\/]|$)/i,bn=/^(?:[A-Za-z]:|[\\/]|%[A-Za-z]+%)[\s\S]*[\\/](?:temp|tmp)(?=[\\/])/i,kn=t=>t.includes("://")&&!/^file:/i.test(t),eo=12;function oo(t,e){let s=e;for(;s<t.length&&!pn.test(t[s])&&!(so.test(t[s])&&gn.test(t.slice(e,s)));)s++;return t.slice(e,s).replace(/[.,;:!?]+$/,"")}function yn(t,e=!1){let s=c=>c.replace(/[^\n]/g," "),o=t.replace(hn,s),n=e?o.replace(un,s):o,i=[],a=(c,l)=>i.some(r=>r.at<=c+l.length&&c<=r.at+r.path.length);for(let c of $n)for(let l of n.matchAll(c)){let r=oo(n,l.index);r.length>=l[0].length+2&&!a(l.index,r)&&i.push({at:l.index,path:r})}for(let c of n.matchAll(mn)){let l=c.index;for(;l<c.index+c[0].length&&so.test(n[l]);)l++;let r=oo(n,l);/[\\/]/.test(r)&&(wn.test(r)||bn.test(r))&&!kn(r)&&!a(l,r)&&i.push({at:l,path:r})}return i.sort((c,l)=>c.at-l.at)}function no(t,e=w(t)){let s=[],o=(a,c)=>{for(let l of a.childNodes??[])if(l.nodeName==="#text"){if(!l.sourceCodeLocation)continue;for(let{at:r,path:d}of yn(l.value,c))s.push({line:l.sourceCodeLocation.startLine+(l.value.slice(0,r).match(/\n/g)?.length??0),path:d})}else l.tagName&&!dn.has(l.tagName)&&Qe(l,"hidden")===void 0&&!fn.some(r=>ln(l,r))&&o(l,c||Qe(l,"data-doc-math-dollar")!==void 0)};o(e,!1);let n=s.slice(0,eo).map(({line:a,path:c})=>`line ${a}: "${c.length>80?`${c.slice(0,77)}\u2026`:c}" is a path of this machine in the text a reader reads: a reader on another machine cannot open it. ${to}`),i=s.slice(eo);return i.length>0&&n.push(`${i.length} more path${i.length===1?"":"s"} of this machine in the text a reader reads, on line${new Set(i.map(({line:a})=>a)).size===1?"":"s"} ${[...new Set(i.map(({line:a})=>a))].join(", ")}. ${to}`),n}import{elementsOf as io}from"../browser/shared/html-tree.mjs";import{netSnapshot as xn}from"../browser/shared/net-cache.mjs";import{hostIn as Sn,netHostsOf as Nn}from"../browser/shared/net-policy.mjs";var vn=(t,e)=>`<script type="application/json" data-doc-snapshot data-at="${e}">${JSON.stringify(t).replace(/</g,"\\u003c")}</script>`,Rt=t=>t.some(({needs:e})=>Array.isArray(e)&&e.includes("workspace"));function ao(t,{slug:e,packages:s,root:o,at:n=new Date,workspace:i=null}){let a=s.flatMap(({needs:f})=>Nn(f)),c=a.length===0?null:xn(o,e,f=>{try{return Sn(new URL(f).hostname,a)!==null}catch{return!1}}),l={...i&&Rt(s)?i:{},...c?{net:c}:{}};if(Object.keys(l).length===0)return t;let r=io(io(w(t)).find(f=>f.tagName==="html")??{}).find(f=>f.tagName==="head"),d=r?.sourceCodeLocation?.endTag?.startOffset??r?.sourceCodeLocation?.startTag?.endOffset;return d===void 0?t:`${t.slice(0,d)} ${vn(l,n.toISOString())}
7
- ${t.slice(d)}`}import{MENTION as On,MENTION_ICON as En}from"../browser/shared/components/mention.mjs";import{escapeAttribute as Tn}from"../browser/shared/escape.mjs";import{attr as ro,elementsOf as Ln,hasClass as co,walk as An}from"../browser/shared/html-tree.mjs";import{addressOn as Cn,decoded as zn,fromFile as In,hosted as jn,pageAddress as Rn,workbenchHash as Fn}from"../browser/shared/page-address.mjs";function Dn(t,e,s){let o=In(t,e),n=Cn(o,s);return n||jn(t)?n:Rn(o)??(Fn(o)===null?null:{slug:null,block:null})}function _n(t,e,s,o){let n=w(t),i=new Set,a=[];An(n,r=>{let d=ro(r,"data-block-id");d!==void 0&&i.add(d),r.tagName==="a"&&ro(r,"href")!==void 0&&r.sourceCodeLocation?.startTag&&a.push(r)});let c=new Map,l=({startOffset:r,endOffset:d})=>c.set(r,[d,""]);for(let r of a){let{prefix:d,value:f}=r.attrs.find(({name:k})=>k==="href"),h=f.startsWith("#")?zn(f.slice(1)):null,u=h===null?f&&Dn(f,e,o):i.has(h)?{slug:e,block:h}:null;if(!u)continue;let m=s(u,f);if(m===f)continue;let{attrs:p,startTag:g,endTag:b}=r.sourceCodeLocation;if(m===null)l(g),b&&l(b),co(r,On)&&Ln(r).filter(k=>co(k,En)).forEach(k=>l(k.sourceCodeLocation));else{let k=d?`${d}:href`:"href";c.set(p[k].startOffset,[p[k].endOffset,`${k}="${Tn(m)}"`])}}return[...c].sort(([r],[d])=>d-r).reduce((r,[d,[f,h]])=>`${r.slice(0,d)}${h}${r.slice(f)}`,t)}function lo(t,e,s,{blocks:o=!0,links:n}){return _n(t,e,({slug:i,block:a})=>{let c=s(i);if(c===null)return null;if(!a||!o)return i===e&&a?null:c;let l=`#${encodeURIComponent(a)}`;return i===e?l:`${c}${l}`},n)}import ht from"node:fs";import Mn from"node:path";import{extensionOf as Pn,imageFile as Un,mediaTypeOf as Wn}from"../browser/shared/media.mjs";var _t=1024*1024,Bn=_t,ho=2400,Ft=2e3,Hn=.25,Kn=new Set(["png","gif"]),fo=.75;function Gn(t){if(t.length<16||t.toString("latin1",0,4)!=="RIFF"||t.toString("latin1",8,12)!=="WEBP")return!1;for(let e=12;e+8<=t.length;){let s=t.toString("latin1",e,e+4);if(s==="VP8L")return!0;if(s==="VP8 "||s==="ANMF")return!1;let o=t.readUInt32LE(e+4);e+=8+o+o%2}return!1}function Jn(t){let e=(s,o)=>s+o<=t.length;if(e(0,24)&&t.readUInt32BE(0)===2303741511&&t.toString("latin1",12,16)==="IHDR")return{width:t.readUInt32BE(16),height:t.readUInt32BE(20)};if(e(0,10)&&/^GIF8[79]a$/.test(t.toString("latin1",0,6)))return{width:t.readUInt16LE(6),height:t.readUInt16LE(8)};if(e(0,4)&&t[0]===255&&t[1]===216){for(let s=2;e(s,4);){if(t[s]!==255)return null;let o=t[s+1];if(o===255){s+=1;continue}if(o===216||o===1||o>=208&&o<=215){s+=2;continue}if(o>=192&&o<=207&&![196,200,204].includes(o))return e(s,9)?{width:t.readUInt16BE(s+7),height:t.readUInt16BE(s+5)}:null;if(o===217||o===218)return null;s+=2+t.readUInt16BE(s+2)}return null}if(e(0,30)&&t.toString("latin1",0,4)==="RIFF"&&t.toString("latin1",8,12)==="WEBP"){let s=t.toString("latin1",12,16);if(s==="VP8 ")return{width:t.readUInt16LE(26)&16383,height:t.readUInt16LE(28)&16383};if(s==="VP8L"){let o=t.readUInt32LE(21);return{width:(o&16383)+1,height:(o>>>14&16383)+1}}return s==="VP8X"?{width:t.readUIntLE(24,3)+1,height:t.readUIntLE(27,3)+1}:null}if(e(0,12)&&t.toString("latin1",4,8)==="ftyp"&&/avi[fs]/.test(t.toString("latin1",8,Math.min(t.length,t.readUInt32BE(0))))){let s=null;for(let o=t.indexOf("ispe",0,"latin1");o>=0&&e(o,16);o=t.indexOf("ispe",o+4,"latin1")){let n={width:t.readUInt32BE(o+8),height:t.readUInt32BE(o+12)};(!s||n.width*n.height>s.width*s.height)&&(s=n)}return s}return null}var Vn=_t;function Zn(t){let e;try{e=ht.openSync(t,"r");let{size:s}=ht.fstatSync(e),o=Buffer.alloc(Math.min(s,Vn));return ht.readSync(e,o,0,o.length,0),{length:s,head:o}}catch{return null}finally{e!==void 0&&ht.closeSync(e)}}var j=t=>`${Math.max(.1,t/_t).toFixed(1)} MB`;function Yn({bytes:t,width:e,height:s,extension:o,lossless:n}){let i=Math.max(e,s),a=Math.min(1,Ft/i),c=Math.min(t,e*s*a*a*Hn);if(i>ho){if(!n)return c<=t*fo?` \u2014 a ${Ft}px copy would be about ${j(c)}`:"";let l=t*a*a;return` \u2014 a ${Ft}px copy would be about ${j(l)}${o==="png"&&c<l/2?`, or ${j(c)} as a JPEG (for a photograph)`:""}`}return!n&&c<=t*fo?` \u2014 written again as a JPEG of quality about 82, it would be about ${j(c)}`:o==="png"&&c<t/2?` \u2014 as a JPEG (for a photograph) it would be about ${j(c)}`:""}var Dt=t=>t===2?"twice":`${t} times`;function uo({html:t,directory:e,tree:s=w(t)}){let{embedded:o,unserved:n}=re({html:t,directory:e,tree:s}),i=new Map,a=(l,r,d,f=!1)=>{let h=i.get(l)??i.set(l,{at:[],shows:0,served:d}).get(l);h.at.push(r),f||(h.shows+=1)};for(let{file:l,line:r,icon:d}of o)Un(l)&&a(l,r,!0,d);for(let{file:l,line:r}of n)Wn(l).startsWith("image/")&&a(l,r,!1);let c=[];for(let[l,{at:r,shows:d,served:f}]of[...i].sort(([,h],[,u])=>Math.min(...h.at)-Math.min(...u.at))){let h=Zn(Mn.join(e,l));if(!h)continue;let{length:u,head:m}=h,p=Jn(m),g=p?Math.max(p.width,p.height):0,b=u>Bn||g>ho,k=f&&d>1;if(!b&&!k)continue;let x=[...new Set(r)],v=`line${x.length===1?"":"s"} ${x.length>1?`${x.slice(0,-1).join(", ")} and ${x.at(-1)}`:x[0]}`,E=k?`shown ${Dt(d)}: the export embeds it ${Dt(d)}; show it once and refer back to it in words`:"";if(!b){c.push(`${l} (${v}): ${E} (${j(Math.ceil(u/3)*4*d)} as data: URLs)`);continue}let H=r.length===1||!f?"":`, ${Dt(r.length)}`,R=f?r.length:1,Y=`${j(Math.ceil(u/3)*4*R)} as ${R===1?"a data: URL":"data: URLs"}`,Po=p?`, ${p.width}\xD7${p.height}px`:"",Bt=Pn(l),Ht=p?Yn({bytes:u,...p,extension:Bt,lossless:Kn.has(Bt)||Gn(m)}):"",Uo=f?`the export embeds it as it is${H}, ${Y}${Ht}`:`its name keeps it out of the preview and the export (the failure at its line says why); copied into assets/ under a name they take, the export embeds it as it is, ${Y}${Ht}: copy it in at the size the page needs`;c.push(`${l} (${v}): ${j(u)}${Po}; ${Uo}${E?`; ${E}`:""}`)}return c}import{COMPONENTS as hi}from"../browser/shared/components/index.mjs";import{withLook as ui}from"../browser/shared/document-look.mjs";import{reportsDirectory as pi}from"../browser/shared/paths.mjs";import{documentLook as mi}from"../browser/shared/workspace-look.mjs";import po from"node:fs";import{MENTION as mo,MENTION_ICON as go}from"../browser/shared/components/mention.mjs";import{escapeAttribute as qn,escapeText as Xn}from"../browser/shared/escape.mjs";import{iconUrl as Qn,validIcon as ti}from"../browser/shared/emoji/icon-value.mjs";import{attr as ei,hasClass as oi,walk as si}from"../browser/shared/html-tree.mjs";import{fromFile as ni,isFileLink as ii,pageAddress as ai}from"../browser/shared/page-address.mjs";import{reportsDirectory as ri}from"../browser/shared/paths.mjs";import{documentDirectory as ci,documentFiles as li}from"../browser/shared/workspace.mjs";function di(t,e){let{html:s,json:o}=li(ci(t,e));if(!po.existsSync(s))return null;try{let{title:n,icon:i}=JSON.parse(po.readFileSync(o,"utf8"));return{title:n,icon:i}}catch{return{}}}function fi(t,e,s,o){if(s==="words"||typeof t!="string"||!ti(t))return null;if(s==="preview")return Qn(t,e,{tab:!0});let n=qt({value:t,slug:e,tab:!0,reportsDirectory:o});return n&&`data:${n.type};base64,${n.body.toString("base64")}`}function $o(t,{slug:e,mode:s="export",reportsDirectory:o=ri}){if(!t.includes(mo))return t;let n=new Map,i=c=>(n.has(c)||n.set(c,di(c,o)),n.get(c)),a=new Map;return si(w(t),c=>{let l=c.tagName==="a"&&oi(c,mo)?ei(c,"href"):void 0,{startTag:r,endTag:d}=c.sourceCodeLocation??{};if(!l||!ii(l)||!r||!d)return;let f=ai(ni(l,e))?.slug;if(!f)return;let h=i(f);if(!h)a.set(r.endOffset-1,[r.endOffset-1," data-doc-gone"]);else if(h.title){let u=fi(h.icon,f,s,o);a.set(r.endOffset,[d.startOffset,`${u?`<img class="${go}" src="${qn(u)}" alt="">`:`<span class="${go}"></span>`}${Xn(h.title)}`])}}),[...a].sort(([c],[l])=>l-c).reduce((c,[l,[r,d]])=>`${c.slice(0,l)}${d}${c.slice(r)}`,t)}var gi=/<script\b[^>]*\bdata-doc-kit="runtime"[^>]*><\/script>/;function $i(t,e,s){let o=Gt(e).filter(({id:n})=>!s.some(i=>i.id===n)).map(Jt).join(" ");return o?t.replace(gi,n=>`${n}
8
- <script data-doc-dev>${o}</script>`):t}var wo=/(<title\b[^>]*>)\s*(<\/title>)/i;function wi(t){if(!wo.test(t))return t;let e=/^en\b/i.test(/<html\b[^>]*\slang=["']?([^"'\s>]*)/i.exec(t)?.[1]??"");return t.replace(wo,(s,o,n)=>`${o}${e?"Untitled":"\u672A\u547D\u540D\u6587\u6863"}${n}`)}function Mt(t,{slug:e,mode:s="export",files:o=!0,reportsDirectory:n,kit:i,catalog:a}){let{html:c,removed:l}=bi(t,{reportsDirectory:n,kit:i,catalog:a,describe:s==="preview"}),r={slug:e,mode:s,...n?{reportsDirectory:n}:{}},d=Xt(ui(c,mi(e,n??pi)),r),f=o?ce(te(oe(ne(d,r),r),r),r):d;return{html:wi($o(f,r)),removed:l}}function bi(t,{reportsDirectory:e,kit:s,page:o=!1,describe:n=!1,catalog:i=T()}){let a=L(t,i),{html:c,removed:l,used:r}=fe(t,[...hi,...a]),d=ke(he(c,{used:r,page:o,...s?{href:s}:{}}),a);return{html:n?$i(d,i,a):d,removed:l,packages:a}}import{exportsDirectory as Ai,kitPublicDirectory as Ci,release as zi,reportsDirectory as A,vendorDirectory as Ii}from"../browser/shared/paths.mjs";import{referencedFile as ji}from"../browser/shared/media.mjs";import{decoded as Ri,fromFile as Fi,hashAddress as Di,hosted as Lo,pageAddress as _i,workbenchHash as Mi}from"../browser/shared/page-address.mjs";import{pageLinks as Pi}from"../browser/shared/page-links.mjs";import{layoutOf as Ao}from"../browser/shared/workspace.mjs";import{documentLinks as Ui,listReportSlugs as Wi}from"../browser/shared/reports.mjs";import{documentDirectory as B,documentFiles as Wt}from"../browser/shared/workspace.mjs";import{sha256 as ut}from"../browser/shared/files.mjs";import{EXPORT_CSP as Bi,GENERATOR as Hi,isolateUmd as Ki,packagesMeta as Gi,sourceMeta as Ji}from"../browser/shared/export-wrap.mjs";var So=/__REPORT_[A-Z_]+__/,No=1e6,vo=t=>t.length>1?`${t.slice(0,-1).join(", ")} and ${t.at(-1)}`:`${t[0]}`;function Vi(t){return t.map(({id:e,lines:s,columns:o})=>{let n=new Set(s).size<s.length,i=s.map((a,c)=>n?`${a}:${o[c]}`:`${a}`);return`data-block-id repeats: "${e}" on lines ${vo(i)}${n?" (line:column)":""}; each id names one block: remove it from the copy, which needs none (the later ${i.length>2?`ones, lines ${vo(i.slice(1))}`:`one, line ${i[1]}`}, unless the copy went before its original)`})}var Zi=({slug:t,htmlPath:e,metadataPath:s})=>{let o=e?{html:e,json:s??e.replace(/\.html$/,".json")}:Wt(B(t,A));return{htmlName:N.basename(o.html),jsonName:N.basename(o.json)}};function Yi({slug:t,html:e,metadata:s,htmlPath:o,metadataPath:n,tree:i=w(e)}){let a=[],{htmlName:c,jsonName:l}=Zi({slug:t,htmlPath:o,metadataPath:n}),r=/<h1\b[^>]*\bclass="[^"]*\bdoc-title\b[^"]*"[^>]*>\s*<\/h1>/i.test(e),d=[[/<meta\s+name=["']viewport["']/i,"missing viewport metadata"],[r?/<title>\s*<\/title>|<title>[^<]+<\/title>/i:/<title>[^<]+<\/title>/i,"missing document title"],[/<main(?:\s|>)/i,"missing semantic main element"],[/aria-label|aria-labelledby|<title>/i,"missing accessible labels"]];for(let[p,g]of d)p.test(e)||a.push(g);let f=Buffer.byteLength(e);f>No&&a.push(`the document's editable source is ${f.toLocaleString("en-US")} bytes, over the ${No.toLocaleString("en-US")}-byte limit: aggregate or sample the embedded data, or split the document`),So.test(e)&&a.push(`${c} still contains a starter placeholder such as __REPORT_TITLE__`);for(let[p,g]of Object.entries(s))typeof g=="string"&&So.test(g)&&a.push(`${l} "${p}" is still a starter placeholder such as __REPORT_TITLE__`);/<[a-z][^>]*\sdata-doc-placeholder\b/i.test(e)&&a.push("starter placeholder content ([data-doc-placeholder]) is still present; replace it with the document's content");let h=new Map;M(i,p=>{let g=O(p,"data-block-id"),b=p.sourceCodeLocation?.attrs?.["data-block-id"]??p.sourceCodeLocation;g!==void 0&&h.set(g,[...h.get(g)??[],{line:b?.startLine,column:b?.startCol}])});let u=[...h].filter(([,p])=>p.length>1);a.push(...Vi(u.map(([p,g])=>({id:p,lines:g.map(({line:b})=>b),columns:g.map(({column:b})=>b)}))));let m=null;if(M(i,p=>{!m&&p.tagName==="main"&&(m=p)},{inTemplates:!1}),m){let p=O(m,"data-doc-id");p===void 0?a.push(`main.doc-page needs data-doc-id="${t}"`):p!==t&&a.push(`main[data-doc-id] is "${p}": it must be the document's slug "${t}"`)}return a}var Co=t=>yo(yo(t).find(e=>e.tagName==="html")??{}).find(e=>e.tagName==="head")?.sourceCodeLocation?.startTag?.endOffset,Ut=new Set(["localStorage","sessionStorage"]);function zo(t){let e=[],s=[];return M(t,o=>{o.tagName==="script"&&O(o,"src")!==void 0&&e.push(O(o,"src")),(o.tagName==="link"?(O(o,"rel")??"").toLowerCase().split(/\s+/):[]).includes("stylesheet")&&O(o,"href")!==void 0&&s.push(O(o,"href"))}),{scripts:e,styles:s}}function Io({slug:t,html:e,directory:s=B(t,A),tree:o=w(e),uses:n=X(e,q,{tree:o}),catalog:i}){let a=[];Co(o)===void 0&&a.push("the page writes no <head> start tag, which an export puts its Content-Security-Policy right after: write <head> \u2026 </head> before <body>");let c=[];M(o,d=>{if(["script","link","img"].includes(d.tagName))for(let f of["src","href"]){let h=O(d,f)?.trim();h&&/^https?:\/\//i.test(h)&&c.push(h)}}),c.length>0&&a.push(`external resources are not portable: ${c.join(", ")}`);for(let{name:d,how:f,line:h,where:u}of n){if(!q.has(d))continue;let m={call:`calls ${d}(\u2026)`,new:`creates new ${d}(\u2026)`}[f]??`uses ${d}`;a.push(`line ${h}: ${u} ${m}: embed its data (inline JSON, DocState); the export blocks the network`)}let{scripts:l,styles:r}=zo(o);for(let d of l)ge.has(d)||a.push(`unsupported script dependency ${d}`);for(let d of r)$e.has(d)||a.push(`unsupported stylesheet dependency ${d}`);return a.push(...ie({html:e,directory:s,tree:o}),...se({html:e,directory:s,tree:o}),...ee({html:e,directory:s,tree:o}),...ae({html:e,directory:s,tree:o})),a.push(...ye(L(e,i,o))),[...new Set(a)]}var qi=[[/\bDocSheets\.mount\s*\(/,"Sheet areas start on their own: remove DocSheets.mount (an area keeps its tab under its data-doc-sheets name)"],[/\bDocCode\.(?:View|DiffView|DiffStats|enhance)\b/,'code blocks are highlighted on their own, and a diff is declared as <div class="doc-diff"> holding { path, lines } as JSON (sdk/doc-code.d.ts)'],[/\bDocTables\.(?:enhance|enhanceAll|makeSortable)\b/,"tables start on their own: remove the call"],[/\bDocDialogs\.(?:enhance|enhanceAll)\b/,"detail cards start on their own: remove the call"]];function Xi({html:t,tree:e=w(t),uses:s=X(t,Ut,{tree:e})}){let o=we(t,e),n=[...ue(t,e),...pe(t,e)];for(let[i,a]of qi)i.test(o)&&n.push(`${o.match(i)[0].replace(/\s*\($/,"")} is gone: ${a}`);for(let{name:i,line:a,where:c}of s)Ut.has(i)&&n.push(`line ${a}: ${c} uses ${i}: use DocState instead of direct browser storage`);return[...new Set(n)]}var Qi=(t,e)=>e.childNodes.find(s=>s.tagName||s.nodeName==="#text"&&s.value.trim())===t,ta=t=>ko(t,Si("highlight").match)||t.tagName==="li"&&ko(t.parentNode,`ol.${Ni}`),ea=`an icon is one of three kinds: an emoji, <div class="doc-icon">\u{1F3AF}</div>; an icon of Gallery's sets in one of ${xo.length} colors, <div class="doc-icon" data-icon="/icons/airplane_blue.svg"></div> (MingCute's names; Tabler's as /icons/tabler/plane_blue.svg; the colors ${xo.join(", ")}); or a picture of the document's folder, <div class="doc-icon"><img src="assets/logo.png" alt=""></div>`,jo=t=>t.nodeName==="#text"?t.value:(t.childNodes??[]).map(jo).join("");function Oo(t,e,s){let o=e.sourceCodeLocation?.attrs?.[s],n=o?t.slice(o.startOffset,o.endOffset):`${s}="${O(e,s)??""}"`;return n.length>72?`${n.slice(0,71)}\u2026`:n}function oa(t,e){let s=O(e,"data-icon");if(s!==void 0)return{held:Oo(t,e,"data-icon"),meant:Pt(s)==="glyph"?s:null};let o=null;if(M(e,i=>{o??=["img","svg"].includes(i.tagName)?i:null}),o?.tagName==="img"){let i=O(o,"src");return{held:`<img ${Oo(t,o,"src")}>`,meant:Pt(i)==="image"?i:null}}if(o)return{held:"an <svg>"};let n=jo(e).replace(/\s+/g," ").trim();return{held:n?`"${n.slice(0,40)}"`:"nothing"}}function sa({set:t,name:e,color:s}){let o=vi.find(a=>a!==t);if(mt(o).includes(e))return`; "${e}" is ${o==="tabler"?"Tabler":"MingCute"}'s: ${Ei(o,e,s)}`;let n=e.split("-").filter(a=>a.length>=3),i=mt(t).filter(a=>a.split("-").some(c=>n.includes(c))).slice(0,6);return i.length>0?`; names of its set near it: ${i.join(", ")}`:""}function na({html:t,tree:e=w(t)}){let{all:s,own:o}=Qt(e),n=[],i=a=>a.sourceCodeLocation?.startLine;o.length>1&&n.push(`line ${i(o[1])}: ${o.length} page icons (.doc-icon) in the header (the first at line ${i(o[0])}): a document has one, right before its title`);for(let a of s){let c=i(a),l=a.parentNode;!o.includes(a)&&!(ta(l)&&Qi(a,l))&&n.push(`line ${c}: an icon (.doc-icon) stands only right before the document's title, first in a highlight block (.doc-panel, .doc-summary), or first in a flowchart's step (ol.doc-flow > li, in its number's place)`);let r=Li(Vt(t,a)),{held:d,meant:f}=r?{}:oa(t,a);f?n.push(`line ${c}: an icon (.doc-icon) holds ${d}, an icon a page reads only in double quotes: write ${Ti(f)}`):r?Pt(r)==="glyph"&&!Yt(r)&&n.push(`line ${c}: the icon ${r} is none of the icon sets' (MingCute: /icons/<name>_<color>.svg, Tabler: /icons/tabler/<name>_<color>.svg; src/shared/emoji/data/icons.json lists the names of each)${sa(Oi(r))}`):n.push(`line ${c}: an icon (.doc-icon) holds no icon (it holds ${d}): ${ea}`)}return[...new Set(n)]}function Ro(t){let e=w(t.html),s={...t,tree:e,uses:X(t.html,new Set([...q,...Ut]),{tree:e})};return[...Yi(s),...Lt(t.html,e),...Xi(s),...na(s),...Io(s)]}function ia(t){let e=new Map(t.map(n=>[n.slug,[...Ro(n),...Nt(n.html)]])),s=new Map(t.map(n=>[N.resolve(n.htmlPath),n.slug])),o=new Map(t.map(n=>[N.resolve(n.htmlPath),n]));for(let n of t)n.scriptNotes=[];if(t.length>0)for(let{htmlPath:n,text:i,typeOnly:a,note:c}of be(t)){if(a){o.get(n)?.scriptNotes.push(c);continue}let l=n?[s.get(n)]:[...e.keys()];for(let r of l)e.get(r).push(n?i:`${i} (shared SDK declaration)`)}for(let[n,i]of e)i.length===0&&e.delete(n);return e}async function Rc(t=[],{prepare:e=null}={}){let{reports:s,failures:o}=await pt(t,{prepare:e});for(let n of s){let i=[...Ro(n),...Nt(n.html)];i.length&&o.set(n.slug,i)}return o}async function aa(t=[],{prepare:e=null,directory:s=A}={}){let{reports:o,failures:n}=await pt(t,{prepare:e,directory:s});for(let[i,a]of ia(o))n.set(i,a);return{reports:o,failures:n}}async function ra({fresh:t=!1,kit:e=Ci,vendor:s=Ii}={}){if(zi)return;let o=K.map(a=>[a,a.file?It(a.file,{fresh:t}):wt(a)]);await S.mkdir(e,{recursive:!0});let n=N.join(s,"katex","fonts");await S.mkdir(n,{recursive:!0});let i=(await S.readdir($t)).filter(a=>a.endsWith(".woff2"));await Promise.all(i.map(a=>S.copyFile(N.join($t,a),N.join(n,a)))),await Promise.all(o.map(async([a,c])=>S.writeFile(a.file?N.join(e,a.file):N.join(s,...a.vendor.path.split("/").slice(2)),await c)))}async function ca(t,e){let s=await S.readdir(t).catch(()=>[]);await Promise.all(s.filter(o=>o.endsWith(".html")&&!e.has(o.slice(0,-5))).map(o=>S.rm(N.join(t,o),{force:!0})))}async function la(t,e){let s=N.join(e,"reports.json"),o=await S.readFile(s,"utf8").then(JSON.parse,()=>[]),n=new Map(Array.isArray(o)?o.map(a=>[a.slug,a]):[]);for(let{entry:a}of t)n.set(a.slug,a);let i=[];for(let[a,c]of[...n].sort(([l],[r])=>l.localeCompare(r))){let l=N.join(e,`${a}.html`);await S.stat(l).then(()=>!0,()=>!1)&&i.push(c)}await S.writeFile(s,`${JSON.stringify(i,null,2)}
9
- `)}async function da(t=[],{prepare:e=null,directory:s=A}={}){let o=Ao(s).built,{reports:n,failures:i}=await aa(t,{prepare:e,directory:s});await ra(),await S.mkdir(o,{recursive:!0}),await ca(o,new Set(await Wi(s)));let a=[];for(let c of n){let l=`${c.slug}.html`,r=N.join(o,l);if(i.has(c.slug)){await S.rm(r,{force:!0});continue}let{html:d,removed:f}=Mt(c.html,{slug:c.slug,reportsDirectory:s});await S.writeFile(r,d),a.push({report:c,html:d,removed:f,entry:{slug:c.slug,...c.metadata,preview:`/generated/${l}`,sourceSha256:ut(c.html),outputSha256:ut(d)}})}return await la(a,o),{built:a,failures:i}}var fa=t=>t.replace(/<\/script/gi,"<\\/script");async function Fo(){return new Map(await Promise.all(K.map(async t=>{let e=await(t.file?It(t.file):wt(t,{inline:!0}));return de(t).endsWith(".css")||(e=fa(e)),[t.id,t.umd?Ki(e):e]})))}function ha(t,e,s=null,o=[]){let n=Co(w(e));if(n===void 0)throw new Error(`${t}: the page writes no <head> start tag, which the export's Content-Security-Policy goes right after`);let i=s?`
10
- ${Ji(s)}${o.length>0?`
11
- ${Gi(o)}`:""}`:"";return`${e.slice(0,n)}
12
- <meta name="generator" content="${Hi}">
13
- <meta http-equiv="Content-Security-Policy" content="${Bi}">${i}${e.slice(n)}`}function Do(t,e,s,o=null,n=T(),i=A,a=null){let c=L(e,n);e=ao(ha(t,e,o,c),{slug:t,packages:c,root:i,workspace:a}),e=me(xe(e,n),({id:d,element:f,attribute:h})=>{let u=s.get(d);if(typeof u!="string")throw new Error(`${t}: no inline source for the asset "${d}" (loadInlineSources in src/render/pipeline.mjs)`);return`<${f} ${h}="${d}-inline">${u}</${f}>`});let{scripts:l,styles:r}=zo(w(e));if(l.length+r.length>0)throw new Error(`${t}: export still contains a linked script or stylesheet`);return e}async function Eo(t,e=A,{components:s=!0,catalog:o=T()}={}){let n=B(t,e),i=await S.readFile(Wt(n).html),a=i.toString("utf8"),c=w(a);s||(o={packages:new Map});let l=[...s?Lt(a,c,o):[],...Io({slug:t,html:a,directory:n,tree:c,catalog:o})];if(l.length>0){let r=L(a,o,c).find(({id:d})=>l[0].startsWith(`${d}:`)||l[0].startsWith(`${d} (`))?.id;throw Object.assign(new Error(`${t}: ${l[0]}`),{reason:"check",slug:t,failures:l,...r?{component:r}:{}})}return{html:a,sha256:ut(i)}}async function Fc({directory:t=A,workspace:e=null,catalog:s=T()}={}){let o=await Fo(),n=async(i,{files:a=!0}={})=>{let c=await Eo(i,t,{catalog:s}),l=Mt(c.html,{slug:i,files:a,reportsDirectory:t,catalog:s}).html;return Do(i,l,o,c.sha256,s,t,await _o(e,i,l,s))};return n.check=async i=>{await Eo(i,t,{components:!1})},n}async function _o(t,e,s,o){return typeof t!="function"||!Rt(L(s,o))?null:await t(e).catch(()=>null)??null}async function Dc(t=[],{prepare:e=null,workspace:s=null,directory:o=A}={}){let n=Ao(o).exports,i=T(),{built:a,failures:c}=await da(t,{prepare:e,directory:o}),l=await Fo();await S.mkdir(n,{recursive:!0});let r=new Set(a.map(({report:h})=>h.slug)),{links:d}=await Ui(o),f=[];for(let{report:h,html:u}of a)try{let m=lo(u,h.slug,g=>r.has(g)?`${g}.html`:null,{links:d}),p=Do(h.slug,m,l,h.fileSha256,i,o,await _o(s,h.slug,m,i));await S.writeFile(N.join(n,`${h.slug}.html`),p),f.push({slug:h.slug,bytes:Buffer.byteLength(p),sha256:ut(p)})}catch(m){c.set(h.slug,[m.message])}return{built:a,exported:f,failures:c}}function To(t){let e=new Set;return M(t,s=>{for(let o of["id","data-block-id"])O(s,o)!==void 0&&e.add(O(s,o))}),e}function ua(t,e,s){if(Lo(t)||/^(?:[a-z][a-z0-9+.-]*:|\/)/i.test(t)||ji(t))return!1;let{pathname:o}=new URL(e);return!o.startsWith(`/${s}/`)||o.endsWith(".html")}function pa({slug:t,tree:e,directory:s}){let o=[],n=To(e),i=s===B(N.basename(s),A)?A:N.dirname(s),a=new Map([[t,n]]),c=d=>{if(!a.has(d)){let f=Wt(B(d,i));a.set(d,bo(f.html)?To(w(ki(f.html,"utf8"))):null)}return a.get(d)},l=null,r=(d,f)=>f===null?_i(d):Di(f,l??=Pi((bo(i)?yi(i):[]).map(h=>({slug:h}))));return M(e,d=>{let f=d.tagName==="a"?O(d,"href"):void 0;if(!f||f==="#"||f==="#top")return;let h=d.sourceCodeLocation?.startLine;if(f.startsWith("#")){n.has(Ri(f.slice(1)))||o.push(`the link to ${f} (line ${h}) names no block or element of this document`);return}let u=Fi(f,t),m=Mi(u),p=r(u,m);(p?!c(p.slug):m!==null)?Lo(f)||o.push(`the link to ${f} (line ${h}) names a document that is not there: gallery list has the slugs`):p?.block&&!c(p.slug).has(p.block)?o.push(`the link to ${f} (line ${h}) names a block document ${p.slug} does not hold`):u&&!p&&ua(f,u,t)&&o.push(`the link to ${f} (line ${h}) leads to no document: a link to one is ../<slug>/doc.html, gallery list has the slugs`)},xi),o}function Mo({slug:t,html:e,directory:s=B(t,A),written:o=e,scriptNotes:n=[]}){let i=w(e),a=Ae(e);return{fix:[...no(e,i),...uo({html:e,directory:s,tree:i})],notes:[...Xe(e,{written:o}),...Ue(i),...pa({slug:t,tree:i,directory:s}),...a.notes,...n],readings:a.readings}}function _c(t){let{fix:e,notes:s}=Mo(t);return[...e,...s]}function Mc(t){let e=t.map(s=>[s.slug,Mo(s)]);for(let[s,{fix:o}]of e)for(let n of o)console.log(`fix ${s}: ${n}`);for(let[s,{notes:o}]of e)for(let n of o)console.log(`note ${s}: ${n}`);for(let[s,{readings:o}]of e)for(let n of o)console.log(`chart ${s}: ${n}`)}async function ma(t,{exportNote:e=!1}={}){for(let[s,o]of t){console.error(`
14
- FAIL ${s}: ${o.length} problem${o.length===1?"":"s"}`);for(let i of o)console.error(` - ${i}`);let n=N.join(Ai,`${s}.html`);e&&await S.stat(n).then(()=>!0,()=>!1)&&console.error(` ${n} was not updated; it still holds an earlier export.`)}}function ga(t,{above:e=!1,allow:s=process.argv.includes("--allow-failures")}={}){t.size!==0&&(console.error(`
15
- ${t.size} document${t.size===1?"":"s"} failed: ${[...t.keys()].join(", ")}${e?" (the failures are listed first, above)":""}`),s||(process.exitCode=1))}async function Pc(t,{exportNote:e=!1,allow:s}={}){await ma(t,{exportNote:e}),ga(t,{allow:s})}export{Es as a,_n as b,lo as c,$o as d,Mt as e,bi as f,Vi as g,Io as h,Ro as i,ia as j,Rc as k,aa as l,ra as m,da as n,ha as o,Fc as p,Dc as q,Mo as r,_c as s,Mc as t,ma as u,ga as v,Pc as w};
@@ -1,2 +0,0 @@
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{$ as ha,A as I,B as J,C as K,D as L,E as M,F as N,G as O,H as P,I as Q,J as R,K as S,L as T,M as U,N as V,O as W,P as X,Q as Y,R as Z,S as _,T as $,U as aa,V as ba,W as ca,X as da,Y as ea,Z as fa,_ as ga,a as i,aa as ia,b as j,ba as ja,c as k,ca as ka,d as l,e as m,f as n,g as o,h as p,i as q,j as r,k as s,l as t,m as u,n as v,o as w,p as x,q as y,r as z,s as A,t as B,u as C,v as D,w as E,x as F,y as G,z as H}from"./chunk-MKIBJTJZ.mjs";import"./chunk-342HXE3Q.mjs";import"./chunk-2KAVXMKG.mjs";import"./chunk-XZCFPKGO.mjs";import"./chunk-PUOQ65NC.mjs";import{a,b,c,f as d,g as e,h as f,k as g,l as h}from"./chunk-6Q7ASAXJ.mjs";import"./chunk-S3SX3COT.mjs";import"./chunk-IA4PSIMD.mjs";import"./chunk-F4ZA6JRZ.mjs";import"./chunk-7M2BQQGZ.mjs";import"./chunk-6NLXUKAY.mjs";import"./chunk-VRPVVMRB.mjs";import"./chunk-4OZWXZE5.mjs";import"./chunk-USIHBCSW.mjs";import"./chunk-3SKOU6OZ.mjs";import"./chunk-ZTHICSSF.mjs";import"./chunk-PLB7L22J.mjs";import"./chunk-PAREWQGB.mjs";import"./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"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";export{_ as ADVICE,t as BLOCK_PICTURES,$ as CODE_SIDEWAYS,X as HAND_OVER,u as INK_MARGIN,i as KINDS,j as LEVELS,k as LOOKS,Y as LOOK_YOURSELF,W as MORE_PICTURES,M as MOSTLY_CHANGED,y as MOVED_PART,x as MOVED_WHOLE,w as NEIGHBOUR_EDGE,p as PICTURED_INFO,ca as SCROLLS,v as SCROLL_FRAMES,s as SCROLL_SLACK,ba as WARNED,l as WIDE,m as WIDTHS,f as adoptIdless,aa as adviceOf,e as baselineOf,L as baselineSaid,b as blocksOf,N as blocksToPicture,da as describeLooks,S as disclosuresSaid,g as exportBaselines,G as exportOf,ga as exportingFirst,Q as findingKey,q as findingLevel,O as inkOf,P as inventory,n as layoutNotesOf,o as levelOf,R as lookAt,J as missedWidths,V as morePictures,H as movedBlocks,z as movedClips,ha as namedBlocks,I as nextBaseline,ea as notPicturedLine,c as pageOf,r as picturedAt,T as picturesSaid,D as placeOf,h as previewBaseline,a as rankOf,d as readBaseline,ka as run,K as seenOf,C as sourceIndex,F as staleExport,Z as startFailure,E as timeOf,ia as unknownBlocks,ja as unknownBlocksSaid,U as unopenedSaid,A as urlName,fa as verdictOf,B as wordsOf};