graview 0.1.67 → 0.1.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/preview/{chunk.T2OUHRAA.js → chunk.26RYER7Y.js} +1 -1
- package/dist/preview/{chunk.XFLGSUYO.js → chunk.2AL26ZPJ.js} +1 -1
- package/dist/preview/chunk.2WFOKJB4.js +1 -0
- package/dist/preview/chunk.3D37E2G5.js +1 -0
- package/dist/preview/chunk.3PT3BU6K.js +1 -0
- package/dist/preview/{chunk.XSWSBTUO.js → chunk.3TKIZGC7.js} +1 -1
- package/dist/preview/{chunk.SFBHPYRD.js → chunk.3VNOTHA5.js} +1 -1
- package/dist/preview/{chunk.P2EKKKK2.js → chunk.3XTIYX6M.js} +1 -1
- package/dist/preview/chunk.447RWLS7.js +2 -0
- package/dist/preview/{chunk.6W6XMLSF.js → chunk.47VEV4BX.js} +1 -1
- package/dist/preview/{chunk.QZQCQWQG.js → chunk.4FJ4OPSJ.js} +1 -1
- package/dist/preview/{chunk.MAKCZ6B6.js → chunk.4O7WYLCK.js} +1 -1
- package/dist/preview/chunk.4R7H3GIL.js +4 -0
- package/dist/preview/{chunk.35KMZHB7.js → chunk.4RPKCW4J.js} +1 -1
- package/dist/preview/{chunk.RSQ432QN.js → chunk.523EFGHU.js} +1 -1
- package/dist/preview/chunk.5DU6FA5R.js +1 -0
- package/dist/preview/{chunk.EP6Q32WT.js → chunk.5MOXQUZH.js} +1 -1
- package/dist/preview/chunk.5TWRTGP6.js +1 -0
- package/dist/preview/{chunk.STPA7HBK.js → chunk.66TRDXYR.js} +1 -1
- package/dist/preview/{chunk.D7NWMXSX.js → chunk.6BNSDPZE.js} +3 -3
- package/dist/preview/chunk.6BR2SUAE.js +1 -0
- package/dist/preview/{chunk.7S6ZRMW4.js → chunk.6TDVNWFU.js} +1 -1
- package/dist/preview/{chunk.NKYWIGC7.js → chunk.6XBQDXT6.js} +1 -1
- package/dist/preview/{chunk.5AKZROMR.js → chunk.6ZFYFT5A.js} +1 -1
- package/dist/preview/{chunk.MSAYU25L.js → chunk.7L3I776Z.js} +1 -1
- package/dist/preview/chunk.7OLKVOS6.js +1 -0
- package/dist/preview/{chunk.NSOPYIT4.js → chunk.7T2P42VW.js} +1 -1
- package/dist/preview/chunk.AG7WJYM5.js +3 -0
- package/dist/preview/{chunk.V7H4BUEB.js → chunk.AHYMIVBX.js} +1 -1
- package/dist/preview/chunk.AMAOZVEO.js +1 -0
- package/dist/preview/chunk.AMV2ILR6.js +1 -0
- package/dist/preview/{chunk.YZPESGCP.js → chunk.AUNQNTKY.js} +1 -1
- package/dist/preview/{chunk.37RFCHSS.js → chunk.AZRICZKT.js} +1 -1
- package/dist/preview/{chunk.DWM7AR5Y.js → chunk.B422DSYN.js} +1 -1
- package/dist/preview/{chunk.NAXOXBOF.js → chunk.B5EFNTDA.js} +1 -1
- package/dist/preview/{chunk.TI5FR2QQ.js → chunk.BO32A3W5.js} +1 -1
- package/dist/preview/{chunk.BDNQMKDG.js → chunk.BQORHDAH.js} +1 -1
- package/dist/preview/chunk.BSQI3KM2.js +1 -0
- package/dist/preview/{chunk.7UHPHEH5.js → chunk.C6CT6F4C.js} +1 -1
- package/dist/preview/{chunk.LVOTLGJB.js → chunk.CA2SYEYE.js} +1 -1
- package/dist/preview/{chunk.BKYZSV2Y.js → chunk.CCCONK73.js} +1 -1
- package/dist/preview/{chunk.ZG5VGP5U.js → chunk.CDSHUWSK.js} +1 -1
- package/dist/preview/{chunk.GFLH7RCI.js → chunk.CKSRW3LA.js} +1 -1
- package/dist/preview/{chunk.EGPCVMDU.js → chunk.CLIC2QBA.js} +1 -1
- package/dist/preview/{chunk.EFVSZKB5.js → chunk.CLZYNFFH.js} +1 -1
- package/dist/preview/{chunk.A7GVTE5Y.js → chunk.CSVDBDRZ.js} +2 -2
- package/dist/preview/{chunk.UW52CMGJ.js → chunk.CUEIGKFG.js} +1 -1
- package/dist/preview/{chunk.GRFD42WM.js → chunk.CYEPHT7V.js} +1 -1
- package/dist/preview/{chunk.TTSGCNPT.js → chunk.D3SWJ7OS.js} +1 -1
- package/dist/preview/{chunk.FRQSLWP4.js → chunk.D5JZQZ74.js} +1 -1
- package/dist/preview/{chunk.ZEZUKRC6.js → chunk.DHPXRDT5.js} +5 -5
- package/dist/preview/{chunk.WALVW3KJ.js → chunk.DKUEZPGR.js} +1 -1
- package/dist/preview/chunk.DO3FQM6R.js +8 -0
- package/dist/preview/{chunk.UWS4RMM3.js → chunk.DRAPVGQZ.js} +1 -1
- package/dist/preview/{chunk.X226YATK.js → chunk.DU76ASS4.js} +1 -1
- package/dist/preview/{chunk.N4ZKZ4GM.js → chunk.EEUCRZA3.js} +1 -1
- package/dist/preview/{chunk.25QFDTCU.js → chunk.EK3JXEZL.js} +1 -1
- package/dist/preview/{chunk.YCD4JSXD.js → chunk.EL7XXGQY.js} +1 -1
- package/dist/preview/{chunk.SNHKYH72.js → chunk.EP7YT7LT.js} +1 -1
- package/dist/preview/{chunk.MJY4SLWA.js → chunk.EQZPEOIW.js} +1 -1
- package/dist/preview/{chunk.JU6UFWS3.js → chunk.F4CDJBDS.js} +1 -1
- package/dist/preview/{chunk.PZ7KY6XH.js → chunk.FE3SINPK.js} +1 -1
- package/dist/preview/{chunk.JQ63N4MZ.js → chunk.FIY4RUK5.js} +1 -1
- package/dist/preview/{chunk.A5PSEU3W.js → chunk.FWXW4T4I.js} +1 -1
- package/dist/preview/{chunk.F464JKHZ.js → chunk.G43YUGNW.js} +1 -1
- package/dist/preview/{chunk.JEC5FDKX.js → chunk.GF5CZPZ7.js} +1 -1
- package/dist/preview/{chunk.KX5ZBHMA.js → chunk.GPBHUIZQ.js} +1 -1
- package/dist/preview/{chunk.QF5QB5YR.js → chunk.GTF6EMVE.js} +1 -1
- package/dist/preview/chunk.GVFGS2HY.js +1 -0
- package/dist/preview/{chunk.B7KZBT27.js → chunk.HCX6KPRF.js} +1 -1
- package/dist/preview/{chunk.QXLJGHMC.js → chunk.HGH27XZG.js} +3 -3
- package/dist/preview/{chunk.AJMVRFYX.js → chunk.HMJXB6KC.js} +2 -2
- package/dist/preview/chunk.HTEQCRVP.js +1 -0
- package/dist/preview/{chunk.IDALEKIW.js → chunk.HU3KEWFO.js} +1 -1
- package/dist/preview/{chunk.Z27NSSYL.js → chunk.I4H2GS4O.js} +2 -2
- package/dist/preview/{chunk.UGQYMN4J.js → chunk.I7KN732Z.js} +1 -1
- package/dist/preview/{chunk.6NG76MDA.js → chunk.I7OFRF6N.js} +2 -2
- package/dist/preview/{chunk.OHAO6KKH.js → chunk.IAVIYJTL.js} +1 -1
- package/dist/preview/{chunk.LP2ZMAT2.js → chunk.IO5VFTXC.js} +1 -1
- package/dist/preview/{chunk.E5PYNAYT.js → chunk.IPKESOIU.js} +2 -2
- package/dist/preview/{chunk.IAEGJDF3.js → chunk.IRNEWNUB.js} +1 -1
- package/dist/preview/{chunk.2VUX54XH.js → chunk.ISZFRLNJ.js} +1 -1
- package/dist/preview/{chunk.Z3O2VZAJ.js → chunk.IY3DV52G.js} +1 -1
- package/dist/preview/{chunk.NRURQGXV.js → chunk.IYHY4VEC.js} +1 -1
- package/dist/preview/{chunk.MUSMNKE4.js → chunk.J2N7EKMX.js} +1 -1
- package/dist/preview/{chunk.3NSV3WKM.js → chunk.J7O23NKZ.js} +2 -2
- package/dist/preview/chunk.JDUA5PH2.js +1 -0
- package/dist/preview/{chunk.HJUZMOW2.js → chunk.JHAMSDAI.js} +1 -1
- package/dist/preview/{chunk.6UQFV53C.js → chunk.JN3WZGJY.js} +1 -1
- package/dist/preview/{chunk.O5VFKVZS.js → chunk.JPAE6K4E.js} +1 -1
- package/dist/preview/{chunk.GMLONS5L.js → chunk.JQEXH23N.js} +1 -1
- package/dist/preview/{chunk.FVQKSN33.js → chunk.KEGL6NBD.js} +1 -1
- package/dist/preview/{chunk.OCXY5DCD.js → chunk.KHKCTVHD.js} +1 -1
- package/dist/preview/{chunk.4EMKCKDB.js → chunk.KKFKSJUN.js} +1 -1
- package/dist/preview/{chunk.SY5ID44D.js → chunk.KLEKC4ZX.js} +1 -1
- package/dist/preview/chunk.KVQYOFDV.js +1 -0
- package/dist/preview/{chunk.CKDCTFLU.js → chunk.KW7PHJYX.js} +1 -1
- package/dist/preview/{chunk.77C556NM.js → chunk.LAVLPYSC.js} +1 -1
- package/dist/preview/{chunk.G5GVT6JY.js → chunk.LGNGFG5V.js} +1 -1
- package/dist/preview/{chunk.LRNFE3UK.js → chunk.LKM2R5UF.js} +1 -1
- package/dist/preview/{chunk.5R744JGZ.js → chunk.LMZ2WMGH.js} +1 -1
- package/dist/preview/{chunk.6SJEZWH3.js → chunk.MATUPDZ3.js} +1 -1
- package/dist/preview/{chunk.7BJRHPE3.js → chunk.MD3N26BC.js} +2 -2
- package/dist/preview/{chunk.SO6NT5K7.js → chunk.MH3AQO2R.js} +1 -1
- package/dist/preview/chunk.MHHNO3O2.js +1 -0
- package/dist/preview/{chunk.QAM76AXV.js → chunk.MKN7ADJB.js} +1 -1
- package/dist/preview/{chunk.HAOB6O72.js → chunk.ML5EHDZG.js} +1 -1
- package/dist/preview/{chunk.WEMUKZKH.js → chunk.MUWI54IP.js} +1 -1
- package/dist/preview/{chunk.MW7R5G3C.js → chunk.MV27WMNW.js} +1 -1
- package/dist/preview/{chunk.ZAQ4IDX6.js → chunk.N7A3T5QU.js} +1 -1
- package/dist/preview/{chunk.QNP5OR3P.js → chunk.NLZHNPDU.js} +2 -2
- package/dist/preview/{chunk.DZMIYEHQ.js → chunk.NRECR3NQ.js} +1 -1
- package/dist/preview/{chunk.FPHRAO3R.js → chunk.NSAGOOJW.js} +1 -1
- package/dist/preview/{chunk.264PB572.js → chunk.O7NYSO6F.js} +1 -1
- package/dist/preview/{chunk.O2OL6RQQ.js → chunk.OD5QZHRC.js} +1 -1
- package/dist/preview/{chunk.SJQPTDAT.js → chunk.P26ATAAI.js} +1 -1
- package/dist/preview/{chunk.GVT4UUQA.js → chunk.PJL3I2IW.js} +1 -1
- package/dist/preview/{chunk.NKLPL7QD.js → chunk.POKGLN4T.js} +1 -1
- package/dist/preview/{chunk.JQ2WNKDW.js → chunk.PZ3KM3TY.js} +1 -1
- package/dist/preview/{chunk.RJY7VJBH.js → chunk.QEBD7SC4.js} +1 -1
- package/dist/preview/{chunk.Z2XUVJAL.js → chunk.QK7EUIPL.js} +1 -1
- package/dist/preview/{chunk.4W57E7AX.js → chunk.QNC2OKLF.js} +1 -1
- package/dist/preview/{chunk.HN4ZJ4B4.js → chunk.QRNKGPAD.js} +1 -1
- package/dist/preview/{chunk.TXZQEJ5T.js → chunk.QVCKTDG3.js} +1 -1
- package/dist/preview/{chunk.LYEGRY77.js → chunk.R7POSVUK.js} +1 -1
- package/dist/preview/{chunk.UQIPEMJ5.js → chunk.RNAL35ID.js} +1 -1
- package/dist/preview/{chunk.AKJS2NUM.js → chunk.ROYCJXPE.js} +1 -1
- package/dist/preview/chunk.RZ73YG5K.js +1 -0
- package/dist/preview/{chunk.KFT7JIEH.js → chunk.S2NQRD6W.js} +1 -1
- package/dist/preview/{chunk.6N4PE3U5.js → chunk.SAWASNDO.js} +1 -1
- package/dist/preview/{chunk.QRQ5WPZI.js → chunk.SCVKHGO3.js} +1 -1
- package/dist/preview/chunk.SM37MNS2.js +1 -0
- package/dist/preview/{chunk.3GNT5MKP.js → chunk.T2BZBR7S.js} +1 -1
- package/dist/preview/{chunk.DKEIEH2D.js → chunk.T3PELB6I.js} +1 -1
- package/dist/preview/{chunk.ARWO4WOV.js → chunk.TAJBXG5U.js} +1 -1
- package/dist/preview/{chunk.RG5G6YQD.js → chunk.TLPCYKLW.js} +1 -1
- package/dist/preview/{chunk.EJ2EZL2G.js → chunk.TQQDUJLX.js} +1 -1
- package/dist/preview/{chunk.H6KIEDZN.js → chunk.TQRC5VAM.js} +1 -1
- package/dist/preview/chunk.U563J5IM.js +1 -0
- package/dist/preview/{chunk.FLJXYESX.js → chunk.UAEOCWSG.js} +1 -1
- package/dist/preview/{chunk.A4EZAGG7.js → chunk.UHJSZ2XZ.js} +1 -1
- package/dist/preview/{chunk.M7KXQGQL.js → chunk.UPOYRCKI.js} +1 -1
- package/dist/preview/{chunk.ZAPS4J6G.js → chunk.VBBH5R5T.js} +1 -1
- package/dist/preview/chunk.VBYJBW32.js +1 -0
- package/dist/preview/{chunk.7ARRVNUR.js → chunk.VEQIH7HR.js} +1 -1
- package/dist/preview/chunk.VHLL6VC6.js +1 -0
- package/dist/preview/{chunk.QWGWOEBZ.js → chunk.VQDL4EEP.js} +1 -1
- package/dist/preview/{chunk.R6JBA7UK.js → chunk.VQOYFBEV.js} +1 -1
- package/dist/preview/{chunk.ILJDLBPJ.js → chunk.VR553M6J.js} +1 -1
- package/dist/preview/{chunk.UDHPMVC4.js → chunk.VXPEXUQF.js} +1 -1
- package/dist/preview/{chunk.VBLQJVQ5.js → chunk.W3WXI5B3.js} +1 -1
- package/dist/preview/{chunk.Z4TY44CD.js → chunk.W43XWQRC.js} +1 -1
- package/dist/preview/{chunk.URQTF5SY.js → chunk.WFJCC6G3.js} +1 -1
- package/dist/preview/{chunk.J2OPIS3H.js → chunk.WJHLE73Y.js} +1 -1
- package/dist/preview/{chunk.G3GFDVO2.js → chunk.WQ7K5O2I.js} +1 -1
- package/dist/preview/{chunk.H3EGBDW2.js → chunk.WV6SP6IJ.js} +1 -1
- package/dist/preview/{chunk.J6HF7IRQ.js → chunk.YJ4PFOPC.js} +1 -1
- package/dist/preview/{chunk.JVB5KDSG.js → chunk.YZKHTBTC.js} +1 -1
- package/dist/preview/{chunk.6KJGRM7A.js → chunk.ZE5RSKXF.js} +1 -1
- package/dist/preview/{chunk.4UUJHLHR.js → chunk.ZQYHNFRZ.js} +1 -1
- package/dist/preview/{chunk.D4WJ7OM5.js → chunk.ZT3ZG52B.js} +1 -1
- package/dist/preview/{chunk.47XEJZ3O.js → chunk.ZU3RPI34.js} +1 -1
- package/dist/preview/index.html +55 -55
- package/dist/preview/page.js +2 -2
- package/package.json +6 -6
- package/dist/preview/chunk.2FHIINXG.js +0 -2
- package/dist/preview/chunk.3ENPWZBG.js +0 -1
- package/dist/preview/chunk.3ZODN6BW.js +0 -1
- package/dist/preview/chunk.55G4IPOO.js +0 -1
- package/dist/preview/chunk.5J6DVR7S.js +0 -1
- package/dist/preview/chunk.7WHQWLL6.js +0 -1
- package/dist/preview/chunk.B5SJMCTT.js +0 -7
- package/dist/preview/chunk.CTUJZ3IV.js +0 -1
- package/dist/preview/chunk.CY7FFKEZ.js +0 -1
- package/dist/preview/chunk.DEKRFTRN.js +0 -4
- package/dist/preview/chunk.EBKH3ILT.js +0 -1
- package/dist/preview/chunk.FOUBDGL3.js +0 -1
- package/dist/preview/chunk.HB5NWHFP.js +0 -3
- package/dist/preview/chunk.HVBKI5ZO.js +0 -1
- package/dist/preview/chunk.I3SDKMQS.js +0 -1
- package/dist/preview/chunk.J5OLYVZ4.js +0 -1
- package/dist/preview/chunk.JKFVNQY7.js +0 -1
- package/dist/preview/chunk.KGMSSXZL.js +0 -1
- package/dist/preview/chunk.NXZL5CA2.js +0 -1
- package/dist/preview/chunk.PSNMZBVS.js +0 -1
- package/dist/preview/chunk.R7CRBRD4.js +0 -1
- package/dist/preview/chunk.RR25BGWP.js +0 -1
- package/dist/preview/chunk.T27QKVKP.js +0 -1
- package/dist/preview/chunk.T3WCRS6M.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as O,b,c as w,d as R,e as V}from"./chunk.UGQYMN4J.js";import{h as d,i as S}from"./chunk.RG5G6YQD.js";import{Qa as $,Ra as F}from"./chunk.ZEZUKRC6.js";var E=["card","row","page"],j=["good","warn","bad","neutral","accent"],U=["money","percent","date","time","datetime","relative","count"],_=4,T=40,I=120,L=["number","money","percent"],B=["large"],C=["card","row"],M=1e3,ce=100;function X(e){let n=/^\s*(out|in)\(\s*['"]([A-Za-z][A-Za-z0-9_-]*)['"]\s*\)\s*$/.exec(e);return n?{edge:n[2],way:n[1]}:/^[A-Za-z][A-Za-z0-9_-]*$/.test(e)?{edge:e}:void 0}var v={title:[],headline:[],list:["sort","limit","group","empty","as"],text:["tone","lines"],badge:["tone"],field:["as","currency","label"],image:["as","label"],progress:["label"],group:["direction"],when:["show"],divider:[],figure:["as","currency","label","emphasis"]},Z=Object.keys(v),G=`{"title": "{name}"}, {"headline": "{count(all('offer'))} offers"}, {"figure": expr, "as"?: "number"|"money"|"percent", "currency"?, "label"?, "emphasis"?: "large"}, {"list": expr, "sort"?, "limit"?, "group"?, "empty"?, "as"?: "card"|"row"}, {"text": "\u2026", "tone"?, "lines"?: 0-12}, {"badge": "{status}", "tone"?}, {"field": "quote", "as"?, "currency"?, "label"?}, {"image": "photos", "as"?: "thumb"|"gallery"}, {"progress": {"value": expr, "max": expr}, "label"?}, {"group": [blocks], "direction"?: "row"|"column"}, {"when": expr, "show": [blocks]}, {"divider": true}, {"figure": true}`,Y=e=>/^(image|video|file)$/.test(e?.of??e?.type??"");function ge(e){return Object.fromEntries(Object.entries(e.views??{}).filter(([,n])=>!Array.isArray(n)))}function ye(e){let n=e.views?.home;return Array.isArray(n)?n:void 0}var q={field:()=>!1,relation:()=>!1,figure:!1},z=e=>e.kind??"the home",m=(e,n)=>e!==void 0&&Object.hasOwn(e,n),g=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function W(e,n,t){let s=O(e);for(let a of s.unknownFunctions)t.findings.push(d("unknown-function",n,`"${a}" is not a function the rule language knows`,"see docs/declaration-document.md#expression-language"));for(let a of s.names){if(t.kind===null){t.findings.push(d("view-name",n,`"${a}" names nothing here: these blocks are about no one record`,"reach records with all('<kind>'), like count(all('offer')) or first(all('party') where role == 'client').name"));continue}a==="id"||t.spec.field(a)||t.spec.relation(a)||t.findings.push(d("view-name",n,`${t.kind} has no field or relation called "${a}"`))}for(let a of s.edges)t.edges.has(a)||t.findings.push(d("view-edge",n,`"${a}" is not a relation any kind declares`));for(let a of s.sweeps)t.kinds.has(a)||t.findings.push(d("view-kind",n,`"${a}" is not a kind this document declares`))}function k(e,n,t){if(typeof e!="string"||e.length===0||e.length>2e3){t.findings.push(d("view-expression",n,`an expression is a line of the rule language, like "status == 'booked'"`));return}try{W(w(e),n,t)}catch(s){if(!(s instanceof b))throw s;t.findings.push(d("expression",n,`${s.sentence} (at character ${s.at+1})`))}}function A(e,n,t,s,a=!1){let l=s==="text";if(typeof e!="string"||e.length===0||e.length>300){t.findings.push(d("view-template",n,'a template is words with {field} in braces, like "{name}" or "{quote|money}", at most 300 characters'));return}let r;try{r=V(e)}catch(i){if(i instanceof R||i instanceof b){t.findings.push(d("template",n,i.sentence));return}throw i}for(let i of r)if(i.expr){if(W(i.expr,n,t),l&&!a&&!i.format&&i.expr.t==="ident"&&(t.slot==="card"||t.slot==="row")&&t.spec.prose?.(i.expr.name)){let o=i.expr.name;t.findings.push(S("view-whole-text",n,`${t.kind} ${t.slot} shows ${o} whole; it will be clamped. Use {${o}|excerpt} or move it to the page.`,`write {${o}|excerpt}, or {${o}|excerpt: 80} for fewer characters`))}if(s==="headline"&&!i.format&&i.expr.t==="ident"&&t.spec.prose?.(i.expr.name)){let o=i.expr.name;t.findings.push(S("view-headline-long",n,`${z(t)}${t.slot?` ${t.slot}`:""} heads it with ${o}, a long text, drawn at a headline's size; a headline is a few words.`,`say it in a text block, {"text": "{${o}}"}, or head it with {${o}|excerpt: 60}`))}}}var K=12;function J(e,n,t){typeof e=="number"&&Number.isInteger(e)&&e>=0&&e<=K||t.findings.push(d("view-lines",n,`lines is ${JSON.stringify(e)}, and a text block's lines is a whole number from 1 to ${K}, or 0 to show it whole`,'{"text": "{awards}", "lines": 6}, or "lines": 0 for no cut at all'))}function Q(e,n,t){if(typeof e=="string"){j.includes(e)||t.findings.push(d("view-tone",n,`"${e}" is not a tone`,`use one of ${j.join(", ")}, or {"expr": "if(status == 'booked', 'good', 'neutral')"}`));return}if(g(e)&&Object.keys(e).length===1&&"expr"in e){k(e.expr,`${n}.expr`,t);return}t.findings.push(d("view-tone",n,'a tone is a word or {"expr": \u2026}',`one of ${j.join(", ")}`))}function x(e,n,t,s){if(!Array.isArray(e)){s.findings.push(d("view-shape",n,"a view is a list of blocks"));return}if(t>_){s.findings.push(d("view-depth",n,`blocks nest at most ${_} deep`,"flatten a group or a condition"));return}e.forEach((a,l)=>ee(a,`${n}.${l}`,t,s))}function ee(e,n,t,s){if(t===1&&s.count++,s.all++,!g(e)){s.findings.push(d("view-block",n,"a block is an object naming what it shows",`one of ${G}`));return}let a=Object.keys(e),l=a.filter(o=>Z.includes(o)&&!(o==="group"&&a.includes("list")));if(l.length===0){s.findings.push(d("view-block",n,`${a.length>0?a.map(o=>`"${o}"`).join(", "):"an empty object"} is not a block Graview knows`,`one of ${G}`));return}if(l.length>1){s.findings.push(d("view-block",n,`a block is one thing, and this says ${l.map(o=>`"${o}"`).join(" and ")}`,"split it into two blocks"));return}let r=l[0];for(let o of a)o!==r&&o!="key"&&!v[r].includes(o)&&s.findings.push(d("unknown-key",`${n}.${o}`,`"${o}" is not part of a ${r} block`,v[r].length>0?`a ${r} block may also say ${v[r].map(f=>`"${f}"`).join(", ")}`:`a ${r} block says nothing else`));let i=e[r];switch(r){case"title":case"headline":case"text":case"badge":A(i,`${n}.${r}`,s,r==="text"||r==="headline"?r:void 0,r==="text"&&"lines"in e),"tone"in e&&Q(e.tone,`${n}.tone`,s),r==="text"&&"lines"in e&&J(e.lines,`${n}.lines`,s);return;case"image":case"field":{let o=r==="image";if(typeof i!="string"||!(o?s.spec.files?.(i):s.spec.field(i))){let u=typeof i=="string"&&s.spec.relation(i);s.findings.push(d(`view-${r}`,`${n}.${r}`,`${s.kind} has no ${o?"image, video or file ":""}field ${typeof i=="string"?`"${i}"`:"by that name"}`,u?`"${i}" is a relation; show it with {"text": "{${i}.name}"}`:void 0))}let f=o?["thumb","gallery"]:U;"as"in e&&!f.includes(e.as)&&s.findings.push(d("view-format",`${n}.as`,`"${String(e.as)}" is not a way to show ${o?"pictures":"a field"}`,`use one of ${f.join(", ")}`)),o||D(e,n,s,"field"),"label"in e&&oe(e.label,`${n}.label`,s);return}case"progress":{!g(i)||Object.keys(i).some(o=>o!=="value"&&o!=="max")||!("value"in i)||!("max"in i)?s.findings.push(d("view-progress",`${n}.progress`,'progress is {"value": expression, "max": expression}')):(k(i.value,`${n}.progress.value`,s),k(i.max,`${n}.progress.max`,s)),"label"in e&&A(e.label,`${n}.label`,s);return}case"group":"direction"in e&&e.direction!=="row"&&e.direction!=="column"&&s.findings.push(d("view-direction",`${n}.direction`,`a group runs "row" or "column", not "${String(e.direction)}"`)),x(i,`${n}.group`,t+1,s);return;case"when":k(i,`${n}.when`,s),"show"in e?x(e.show,`${n}.show`,t+1,s):s.findings.push(d("view-when",n,'a condition says what it shows: {"when": expr, "show": [blocks]}'));return;case"figure":if(typeof i=="string")return ne(e,n,s);for(let o of["as","currency","label","emphasis"])o in e&&s.findings.push(d("unknown-key",`${n}.${o}`,`"${o}" belongs to a figure that works a number out; {"figure": true} is the kind's picture`,`write {"figure": "count(all('offer'))", "as": "number"}`));i!==!0?s.findings.push(d("view-block",`${n}.figure`,`a figure is a number worked out, {"figure": "sum(all('offer'), net)", "as": "money"}, or the kind's picture, {"figure": true}`)):s.spec.figure||s.findings.push(d("view-figure",`${n}.figure`,`${z(s)} has no figure to show`,s.kind===null?`work a number out: {"figure": "count(all('offer'))"}`:'give the kind a "figure", or leave this block out'));return;case"list":return te(e,n,s);case"divider":i!==!0&&s.findings.push(d("view-block",`${n}.${r}`,`write {"${r}": true}`));return}}function ne(e,n,t){k(e.figure,`${n}.figure`,t),"as"in e&&!L.includes(e.as)&&t.findings.push(d("view-format",`${n}.as`,`"${String(e.as)}" is not a way to say a figure`,`use one of ${L.join(", ")}`)),D(e,n,t,"figure"),"label"in e&&A(e.label,`${n}.label`,t),"emphasis"in e&&!B.includes(e.emphasis)&&t.findings.push(d("view-emphasis",`${n}.emphasis`,`"${String(e.emphasis)}" is not how loudly a figure is said`,`use ${B.map(s=>`"${s}"`).join(", ")}, or leave it out for the figure's own size`))}function D(e,n,t,s){"currency"in e&&(typeof e.currency!="string"||!/^[A-Z]{3}$/.test(e.currency)?t.findings.push(d("view-currency",`${n}.currency`,'a currency is its three-letter code, like "USD" or "EUR"')):e.as!=="money"&&t.findings.push(d("view-currency",`${n}.currency`,`a currency belongs on a ${s} shown as money`,'add "as": "money"')))}function ie(e,n){let t=[...n.kinds],s=(l,r)=>{let i=new Set;for(let o of l){let f=n.vocabulary.namesOf(o)?.targets?.(r);if(f==="*")return t;for(let u of f??[])i.add(u)}return i.size>0?[...i]:void 0},a=l=>{switch(l.t){case"ident":return n.kind!==null&&n.spec.relation(l.name)?s([n.kind],l.name):void 0;case"member":{let r=a(l.object);return r?s(r,l.name):void 0}case"where":return a(l.set);case"call":{let r=l.args[0],i=r?.t==="lit"&&typeof r.value=="string"?r.value:void 0;if(l.fn==="all")return i!==void 0&&n.kinds.has(i)?[i]:void 0;let o=l.args.length===2&&l.args[1]?.t==="lit"&&typeof l.args[1].value=="string"?l.args[1].value:void 0;if(l.fn==="out"&&o!==void 0){let f=a(r);return f?s(f,o):void 0}if(l.fn==="out")return i!==void 0&&n.kind!==null?s([n.kind],i):void 0;if(l.fn==="in"){let f=o??i,u=o!==void 0?a(r):n.kind!==null?[n.kind]:void 0,c=f!==void 0?n.vocabulary.sources(f).filter(p=>{let y=n.vocabulary.namesOf(p)?.targets?.(f);return!u||y==="*"||u.some(h=>y?.includes(h))}):[];return c.length>0?c:void 0}if((l.fn==="sort"||l.fn==="first")&&r)return a(r);if(l.fn==="either"){let f=l.args.map(a);return f.every(u=>u!==void 0)?[...new Set(f.flatMap(u=>u??[]))]:void 0}return}default:return}};return a(e)}function N(e,n,t,s){let a;try{a=w(e)}catch(r){if(!(r instanceof b))throw r;s.findings.push(d("expression",n,`${r.sentence} (at character ${r.at+1})`));return}let l=O(a);for(let r of l.unknownFunctions)s.findings.push(d("unknown-function",n,`"${r}" is not a function the rule language knows`,"see docs/declaration-document.md#expression-language"));for(let r of l.edges)s.edges.has(r)||s.findings.push(d("view-edge",n,`"${r}" is not a relation any kind declares`));if(t)for(let r of l.names)r==="id"||t.some(i=>s.vocabulary.namesOf(i)?.field(r)||s.vocabulary.namesOf(i)?.relation(r))||s.findings.push(d("view-name",n,`${t.join(" and ")} ${t.length===1?"has":"have"} no field or relation called "${r}"`))}function te(e,n,t){let s=e.list;k(s,`${n}.list`,t);let a;if(typeof s=="string")try{a=ie(w(s),t)}catch{a=void 0}let l=i=>{if(!a)return[...t.kinds].map(f=>t.vocabulary.namesOf(f)?.choices?.(i)).find(f=>f!==void 0);let o=a.map(f=>t.vocabulary.namesOf(f)?.choices?.(i));return o.every(f=>f!==void 0)?[...new Set(o.flatMap(f=>f??[]))]:void 0},r=a?a.join(" and "):"any kind";if("sort"in e){let i=e.sort;if(typeof i=="string")N(i,`${n}.sort`,a,t);else if(g(i)&&typeof i.by=="string"&&Object.keys(i).every(o=>o==="by"||o==="direction")){let o=i.direction;o!==void 0&&o!=="asc"&&o!=="desc"&&o!=="choices"?t.findings.push(d("list-sort",`${n}.sort.direction`,`a list is sorted "asc", "desc" or "choices", not "${String(o)}"`,'"choices" puts a choice field in the order its choices are declared')):o==="choices"?l(i.by)===void 0&&t.findings.push(d("list-sort",`${n}.sort.by`,`"${i.by}" is not a choice field of ${r}, so it has no declared order`,'sort by a choice field, or say "asc" or "desc"')):N(i.by,`${n}.sort.by`,a,t)}else t.findings.push(d("list-sort",`${n}.sort`,'a sort is a key, like "net", or {"by": key, "direction": "asc" | "desc" | "choices"}'))}if("limit"in e){let i=e.limit;(typeof i!="number"||!Number.isInteger(i)||i<1||i>M)&&t.findings.push(d("list-limit",`${n}.limit`,`a limit is a whole number from 1 to ${M}`))}if("group"in e){let i=e.group,o=typeof i=="string"?i:g(i)&&typeof i.by=="string"?i.by:void 0;if(!(typeof i=="string"||g(i)&&Object.keys(i).every(u=>u==="by"||u==="headings"))||o===void 0)t.findings.push(d("list-group",`${n}.group`,'a group is a choice field, like "type", or {"by": "type", "headings": {"pain": "What hurts"}} \u2014 or a relation, like "inGenre", a heading per linked record'));else{let u=l(o),c=u===void 0?X(o):void 0,p=c!==void 0&&(c.way!==void 0?t.edges.has(c.edge):a?a.every(y=>t.vocabulary.namesOf(y)?.relation(c.edge)):t.edges.has(c.edge));if(u===void 0&&!p&&t.findings.push(d("list-group",`${n}.group`,`"${o}" is not a choice field or a relation of ${r}, so it has nothing to group by`,'group by a field whose type is enum, or by a relation of the kind listed, like "inGenre"')),g(i)&&"headings"in i){let y=i.headings;if(!g(y)||Object.values(y).some(h=>typeof h!="string"||h.length===0||h.length>80))t.findings.push(d("list-group",`${n}.group.headings`,'headings are words per choice, like {"pain": "What hurts"}, at most 80 characters each'));else if(u)for(let h of Object.keys(y))u.includes(h)||t.findings.push(d("list-group",`${n}.group.headings.${h}`,`"${h}" is not one of ${o}'s choices`,`use ${u.join(", ")}`))}}}"empty"in e&&(typeof e.empty!="string"||e.empty.length===0||e.empty.length>200)&&t.findings.push(d("list-empty",`${n}.empty`,"what an empty list says is a sentence, at most 200 characters")),"as"in e&&!C.includes(e.as)&&t.findings.push(d("list-as",`${n}.as`,`a list draws each record as its "card" or its "row", not "${String(e.as)}"`))}function oe(e,n,t){(typeof e!="string"||e.length===0||e.length>60)&&t.findings.push(d("view-label",n,"a label is a few words, at most 60 characters"))}function P(e,n,t,s,a,l,r){let i={kind:null,spec:q,kinds:s,edges:a,vocabulary:t,findings:l,count:0,all:0};Array.isArray(e)&&e.length===0&&l.push(d("view-shape",n,`${r} has no blocks`,'give it one: {"headline": "\u2026"}')),x(e,n,1,i),H(i,n,r,"show less")}function H(e,n,t,s){e.count>T?e.findings.push(d("view-size",n,`${t} has ${e.count} blocks at its top; a view has at most ${T} there, a group or a condition counting as one`,`${s}, or gather some into a group`)):e.all>I&&e.findings.push(d("view-size",n,`${t} has ${e.all} blocks counting the ones inside its groups and conditions; a view has at most ${I} in all`,s))}function se(e,n,t,s,a){Array.isArray(e)&&e.forEach((l,r)=>{if(!g(l)||l.name!=="blocks"||!g(l.options)||!("blocks"in l.options))return;let i=[];P(l.options.blocks,`lenses.${r}.options.blocks`,n,t,s,i,`the lens "${String(l.title??r)}"`);for(let o of i)a.push({...o,severity:"warning"})})}function re(e,n,t,s,a,l,r){let i=[];if(e===void 0)return i;if(!g(e))return i.push(d("view-shape",n,'views are an object of kinds, each with a "card", a "row" or a "page"')),i;for(let[o,f]of Object.entries(e)){if(o==="home"&&Array.isArray(f)){P(f,`${n}.home`,r,s,a,i,"the home");continue}let u=t(o);if(!u){i.push(d("view-kind",`${n}.${o}`,`"${o}" is not a kind this ${l} declares`));continue}if(!g(f)){i.push(d("view-shape",`${n}.${o}`,`a kind's views are {"card": [blocks], "row": [blocks], "page": [blocks]}`));continue}for(let c of Object.keys(f))E.includes(c)||i.push(d("view-slot",`${n}.${o}.${c}`,`"${c}" is not a place a view is drawn`,`use ${E.map(p=>`"${p}"`).join(", ")}`));for(let c of E){let p=f[c];if(p===void 0)continue;let y={kind:o,spec:u,kinds:s,edges:a,vocabulary:r,findings:i,count:0,all:0,slot:c};x(p,`${n}.${o}.${c}`,1,y),H(y,`${n}.${o}.${c}`,`this ${c}`,"show less, or move detail to the page")}}return i}function he(e){let n=new Set(Object.keys(e.kinds)),t=new Set(Object.values(e.kinds).flatMap(r=>Object.keys($(r.edges)))),s=r=>{let i=m(e.kinds,r)?e.kinds[r]:void 0;return i?{field:o=>m(i.fields,o)||m(i.computed,o)||F(i.edges).has(o),relation:o=>m($(i.edges),o),figure:i.figure!==void 0,files:o=>m(i.fields,o)&&Y(i.fields[o]),choices:o=>m(i.fields,o)&&i.fields[o].type==="enum"?i.fields[o].options:void 0,targets:o=>m($(i.edges),o)?i.edges[o].to:void 0,prose:o=>m(i.fields,o)&&i.fields[o].type==="text"}:void 0},a={namesOf:s,sources:r=>Object.keys(e.kinds).filter(i=>m(e.kinds[i].edges,r))},l=re(e.views,"views",s,n,t,"document",a);return se(e.lenses,a,n,t,l),l}export{j as a,U as b,L as c,B as d,M as e,ce as f,X as g,ge as h,ye as i,he as j};
|
|
1
|
+
import{a as O,b,c as w,d as R,e as V}from"./chunk.I7KN732Z.js";import{h as d,i as S}from"./chunk.TLPCYKLW.js";import{Qa as $,Ra as F}from"./chunk.DHPXRDT5.js";var E=["card","row","page"],j=["good","warn","bad","neutral","accent"],U=["money","percent","date","time","datetime","relative","count"],_=4,T=40,I=120,L=["number","money","percent"],B=["large"],C=["card","row"],M=1e3,ce=100;function X(e){let n=/^\s*(out|in)\(\s*['"]([A-Za-z][A-Za-z0-9_-]*)['"]\s*\)\s*$/.exec(e);return n?{edge:n[2],way:n[1]}:/^[A-Za-z][A-Za-z0-9_-]*$/.test(e)?{edge:e}:void 0}var v={title:[],headline:[],list:["sort","limit","group","empty","as"],text:["tone","lines"],badge:["tone"],field:["as","currency","label"],image:["as","label"],progress:["label"],group:["direction"],when:["show"],divider:[],figure:["as","currency","label","emphasis"]},Z=Object.keys(v),G=`{"title": "{name}"}, {"headline": "{count(all('offer'))} offers"}, {"figure": expr, "as"?: "number"|"money"|"percent", "currency"?, "label"?, "emphasis"?: "large"}, {"list": expr, "sort"?, "limit"?, "group"?, "empty"?, "as"?: "card"|"row"}, {"text": "\u2026", "tone"?, "lines"?: 0-12}, {"badge": "{status}", "tone"?}, {"field": "quote", "as"?, "currency"?, "label"?}, {"image": "photos", "as"?: "thumb"|"gallery"}, {"progress": {"value": expr, "max": expr}, "label"?}, {"group": [blocks], "direction"?: "row"|"column"}, {"when": expr, "show": [blocks]}, {"divider": true}, {"figure": true}`,Y=e=>/^(image|video|file)$/.test(e?.of??e?.type??"");function ge(e){return Object.fromEntries(Object.entries(e.views??{}).filter(([,n])=>!Array.isArray(n)))}function ye(e){let n=e.views?.home;return Array.isArray(n)?n:void 0}var q={field:()=>!1,relation:()=>!1,figure:!1},z=e=>e.kind??"the home",m=(e,n)=>e!==void 0&&Object.hasOwn(e,n),g=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function W(e,n,t){let s=O(e);for(let a of s.unknownFunctions)t.findings.push(d("unknown-function",n,`"${a}" is not a function the rule language knows`,"see docs/declaration-document.md#expression-language"));for(let a of s.names){if(t.kind===null){t.findings.push(d("view-name",n,`"${a}" names nothing here: these blocks are about no one record`,"reach records with all('<kind>'), like count(all('offer')) or first(all('party') where role == 'client').name"));continue}a==="id"||t.spec.field(a)||t.spec.relation(a)||t.findings.push(d("view-name",n,`${t.kind} has no field or relation called "${a}"`))}for(let a of s.edges)t.edges.has(a)||t.findings.push(d("view-edge",n,`"${a}" is not a relation any kind declares`));for(let a of s.sweeps)t.kinds.has(a)||t.findings.push(d("view-kind",n,`"${a}" is not a kind this document declares`))}function k(e,n,t){if(typeof e!="string"||e.length===0||e.length>2e3){t.findings.push(d("view-expression",n,`an expression is a line of the rule language, like "status == 'booked'"`));return}try{W(w(e),n,t)}catch(s){if(!(s instanceof b))throw s;t.findings.push(d("expression",n,`${s.sentence} (at character ${s.at+1})`))}}function A(e,n,t,s,a=!1){let l=s==="text";if(typeof e!="string"||e.length===0||e.length>300){t.findings.push(d("view-template",n,'a template is words with {field} in braces, like "{name}" or "{quote|money}", at most 300 characters'));return}let r;try{r=V(e)}catch(i){if(i instanceof R||i instanceof b){t.findings.push(d("template",n,i.sentence));return}throw i}for(let i of r)if(i.expr){if(W(i.expr,n,t),l&&!a&&!i.format&&i.expr.t==="ident"&&(t.slot==="card"||t.slot==="row")&&t.spec.prose?.(i.expr.name)){let o=i.expr.name;t.findings.push(S("view-whole-text",n,`${t.kind} ${t.slot} shows ${o} whole; it will be clamped. Use {${o}|excerpt} or move it to the page.`,`write {${o}|excerpt}, or {${o}|excerpt: 80} for fewer characters`))}if(s==="headline"&&!i.format&&i.expr.t==="ident"&&t.spec.prose?.(i.expr.name)){let o=i.expr.name;t.findings.push(S("view-headline-long",n,`${z(t)}${t.slot?` ${t.slot}`:""} heads it with ${o}, a long text, drawn at a headline's size; a headline is a few words.`,`say it in a text block, {"text": "{${o}}"}, or head it with {${o}|excerpt: 60}`))}}}var K=12;function J(e,n,t){typeof e=="number"&&Number.isInteger(e)&&e>=0&&e<=K||t.findings.push(d("view-lines",n,`lines is ${JSON.stringify(e)}, and a text block's lines is a whole number from 1 to ${K}, or 0 to show it whole`,'{"text": "{awards}", "lines": 6}, or "lines": 0 for no cut at all'))}function Q(e,n,t){if(typeof e=="string"){j.includes(e)||t.findings.push(d("view-tone",n,`"${e}" is not a tone`,`use one of ${j.join(", ")}, or {"expr": "if(status == 'booked', 'good', 'neutral')"}`));return}if(g(e)&&Object.keys(e).length===1&&"expr"in e){k(e.expr,`${n}.expr`,t);return}t.findings.push(d("view-tone",n,'a tone is a word or {"expr": \u2026}',`one of ${j.join(", ")}`))}function x(e,n,t,s){if(!Array.isArray(e)){s.findings.push(d("view-shape",n,"a view is a list of blocks"));return}if(t>_){s.findings.push(d("view-depth",n,`blocks nest at most ${_} deep`,"flatten a group or a condition"));return}e.forEach((a,l)=>ee(a,`${n}.${l}`,t,s))}function ee(e,n,t,s){if(t===1&&s.count++,s.all++,!g(e)){s.findings.push(d("view-block",n,"a block is an object naming what it shows",`one of ${G}`));return}let a=Object.keys(e),l=a.filter(o=>Z.includes(o)&&!(o==="group"&&a.includes("list")));if(l.length===0){s.findings.push(d("view-block",n,`${a.length>0?a.map(o=>`"${o}"`).join(", "):"an empty object"} is not a block Graview knows`,`one of ${G}`));return}if(l.length>1){s.findings.push(d("view-block",n,`a block is one thing, and this says ${l.map(o=>`"${o}"`).join(" and ")}`,"split it into two blocks"));return}let r=l[0];for(let o of a)o!==r&&o!="key"&&!v[r].includes(o)&&s.findings.push(d("unknown-key",`${n}.${o}`,`"${o}" is not part of a ${r} block`,v[r].length>0?`a ${r} block may also say ${v[r].map(f=>`"${f}"`).join(", ")}`:`a ${r} block says nothing else`));let i=e[r];switch(r){case"title":case"headline":case"text":case"badge":A(i,`${n}.${r}`,s,r==="text"||r==="headline"?r:void 0,r==="text"&&"lines"in e),"tone"in e&&Q(e.tone,`${n}.tone`,s),r==="text"&&"lines"in e&&J(e.lines,`${n}.lines`,s);return;case"image":case"field":{let o=r==="image";if(typeof i!="string"||!(o?s.spec.files?.(i):s.spec.field(i))){let u=typeof i=="string"&&s.spec.relation(i);s.findings.push(d(`view-${r}`,`${n}.${r}`,`${s.kind} has no ${o?"image, video or file ":""}field ${typeof i=="string"?`"${i}"`:"by that name"}`,u?`"${i}" is a relation; show it with {"text": "{${i}.name}"}`:void 0))}let f=o?["thumb","gallery"]:U;"as"in e&&!f.includes(e.as)&&s.findings.push(d("view-format",`${n}.as`,`"${String(e.as)}" is not a way to show ${o?"pictures":"a field"}`,`use one of ${f.join(", ")}`)),o||D(e,n,s,"field"),"label"in e&&oe(e.label,`${n}.label`,s);return}case"progress":{!g(i)||Object.keys(i).some(o=>o!=="value"&&o!=="max")||!("value"in i)||!("max"in i)?s.findings.push(d("view-progress",`${n}.progress`,'progress is {"value": expression, "max": expression}')):(k(i.value,`${n}.progress.value`,s),k(i.max,`${n}.progress.max`,s)),"label"in e&&A(e.label,`${n}.label`,s);return}case"group":"direction"in e&&e.direction!=="row"&&e.direction!=="column"&&s.findings.push(d("view-direction",`${n}.direction`,`a group runs "row" or "column", not "${String(e.direction)}"`)),x(i,`${n}.group`,t+1,s);return;case"when":k(i,`${n}.when`,s),"show"in e?x(e.show,`${n}.show`,t+1,s):s.findings.push(d("view-when",n,'a condition says what it shows: {"when": expr, "show": [blocks]}'));return;case"figure":if(typeof i=="string")return ne(e,n,s);for(let o of["as","currency","label","emphasis"])o in e&&s.findings.push(d("unknown-key",`${n}.${o}`,`"${o}" belongs to a figure that works a number out; {"figure": true} is the kind's picture`,`write {"figure": "count(all('offer'))", "as": "number"}`));i!==!0?s.findings.push(d("view-block",`${n}.figure`,`a figure is a number worked out, {"figure": "sum(all('offer'), net)", "as": "money"}, or the kind's picture, {"figure": true}`)):s.spec.figure||s.findings.push(d("view-figure",`${n}.figure`,`${z(s)} has no figure to show`,s.kind===null?`work a number out: {"figure": "count(all('offer'))"}`:'give the kind a "figure", or leave this block out'));return;case"list":return te(e,n,s);case"divider":i!==!0&&s.findings.push(d("view-block",`${n}.${r}`,`write {"${r}": true}`));return}}function ne(e,n,t){k(e.figure,`${n}.figure`,t),"as"in e&&!L.includes(e.as)&&t.findings.push(d("view-format",`${n}.as`,`"${String(e.as)}" is not a way to say a figure`,`use one of ${L.join(", ")}`)),D(e,n,t,"figure"),"label"in e&&A(e.label,`${n}.label`,t),"emphasis"in e&&!B.includes(e.emphasis)&&t.findings.push(d("view-emphasis",`${n}.emphasis`,`"${String(e.emphasis)}" is not how loudly a figure is said`,`use ${B.map(s=>`"${s}"`).join(", ")}, or leave it out for the figure's own size`))}function D(e,n,t,s){"currency"in e&&(typeof e.currency!="string"||!/^[A-Z]{3}$/.test(e.currency)?t.findings.push(d("view-currency",`${n}.currency`,'a currency is its three-letter code, like "USD" or "EUR"')):e.as!=="money"&&t.findings.push(d("view-currency",`${n}.currency`,`a currency belongs on a ${s} shown as money`,'add "as": "money"')))}function ie(e,n){let t=[...n.kinds],s=(l,r)=>{let i=new Set;for(let o of l){let f=n.vocabulary.namesOf(o)?.targets?.(r);if(f==="*")return t;for(let u of f??[])i.add(u)}return i.size>0?[...i]:void 0},a=l=>{switch(l.t){case"ident":return n.kind!==null&&n.spec.relation(l.name)?s([n.kind],l.name):void 0;case"member":{let r=a(l.object);return r?s(r,l.name):void 0}case"where":return a(l.set);case"call":{let r=l.args[0],i=r?.t==="lit"&&typeof r.value=="string"?r.value:void 0;if(l.fn==="all")return i!==void 0&&n.kinds.has(i)?[i]:void 0;let o=l.args.length===2&&l.args[1]?.t==="lit"&&typeof l.args[1].value=="string"?l.args[1].value:void 0;if(l.fn==="out"&&o!==void 0){let f=a(r);return f?s(f,o):void 0}if(l.fn==="out")return i!==void 0&&n.kind!==null?s([n.kind],i):void 0;if(l.fn==="in"){let f=o??i,u=o!==void 0?a(r):n.kind!==null?[n.kind]:void 0,c=f!==void 0?n.vocabulary.sources(f).filter(p=>{let y=n.vocabulary.namesOf(p)?.targets?.(f);return!u||y==="*"||u.some(h=>y?.includes(h))}):[];return c.length>0?c:void 0}if((l.fn==="sort"||l.fn==="first")&&r)return a(r);if(l.fn==="either"){let f=l.args.map(a);return f.every(u=>u!==void 0)?[...new Set(f.flatMap(u=>u??[]))]:void 0}return}default:return}};return a(e)}function N(e,n,t,s){let a;try{a=w(e)}catch(r){if(!(r instanceof b))throw r;s.findings.push(d("expression",n,`${r.sentence} (at character ${r.at+1})`));return}let l=O(a);for(let r of l.unknownFunctions)s.findings.push(d("unknown-function",n,`"${r}" is not a function the rule language knows`,"see docs/declaration-document.md#expression-language"));for(let r of l.edges)s.edges.has(r)||s.findings.push(d("view-edge",n,`"${r}" is not a relation any kind declares`));if(t)for(let r of l.names)r==="id"||t.some(i=>s.vocabulary.namesOf(i)?.field(r)||s.vocabulary.namesOf(i)?.relation(r))||s.findings.push(d("view-name",n,`${t.join(" and ")} ${t.length===1?"has":"have"} no field or relation called "${r}"`))}function te(e,n,t){let s=e.list;k(s,`${n}.list`,t);let a;if(typeof s=="string")try{a=ie(w(s),t)}catch{a=void 0}let l=i=>{if(!a)return[...t.kinds].map(f=>t.vocabulary.namesOf(f)?.choices?.(i)).find(f=>f!==void 0);let o=a.map(f=>t.vocabulary.namesOf(f)?.choices?.(i));return o.every(f=>f!==void 0)?[...new Set(o.flatMap(f=>f??[]))]:void 0},r=a?a.join(" and "):"any kind";if("sort"in e){let i=e.sort;if(typeof i=="string")N(i,`${n}.sort`,a,t);else if(g(i)&&typeof i.by=="string"&&Object.keys(i).every(o=>o==="by"||o==="direction")){let o=i.direction;o!==void 0&&o!=="asc"&&o!=="desc"&&o!=="choices"?t.findings.push(d("list-sort",`${n}.sort.direction`,`a list is sorted "asc", "desc" or "choices", not "${String(o)}"`,'"choices" puts a choice field in the order its choices are declared')):o==="choices"?l(i.by)===void 0&&t.findings.push(d("list-sort",`${n}.sort.by`,`"${i.by}" is not a choice field of ${r}, so it has no declared order`,'sort by a choice field, or say "asc" or "desc"')):N(i.by,`${n}.sort.by`,a,t)}else t.findings.push(d("list-sort",`${n}.sort`,'a sort is a key, like "net", or {"by": key, "direction": "asc" | "desc" | "choices"}'))}if("limit"in e){let i=e.limit;(typeof i!="number"||!Number.isInteger(i)||i<1||i>M)&&t.findings.push(d("list-limit",`${n}.limit`,`a limit is a whole number from 1 to ${M}`))}if("group"in e){let i=e.group,o=typeof i=="string"?i:g(i)&&typeof i.by=="string"?i.by:void 0;if(!(typeof i=="string"||g(i)&&Object.keys(i).every(u=>u==="by"||u==="headings"))||o===void 0)t.findings.push(d("list-group",`${n}.group`,'a group is a choice field, like "type", or {"by": "type", "headings": {"pain": "What hurts"}} \u2014 or a relation, like "inGenre", a heading per linked record'));else{let u=l(o),c=u===void 0?X(o):void 0,p=c!==void 0&&(c.way!==void 0?t.edges.has(c.edge):a?a.every(y=>t.vocabulary.namesOf(y)?.relation(c.edge)):t.edges.has(c.edge));if(u===void 0&&!p&&t.findings.push(d("list-group",`${n}.group`,`"${o}" is not a choice field or a relation of ${r}, so it has nothing to group by`,'group by a field whose type is enum, or by a relation of the kind listed, like "inGenre"')),g(i)&&"headings"in i){let y=i.headings;if(!g(y)||Object.values(y).some(h=>typeof h!="string"||h.length===0||h.length>80))t.findings.push(d("list-group",`${n}.group.headings`,'headings are words per choice, like {"pain": "What hurts"}, at most 80 characters each'));else if(u)for(let h of Object.keys(y))u.includes(h)||t.findings.push(d("list-group",`${n}.group.headings.${h}`,`"${h}" is not one of ${o}'s choices`,`use ${u.join(", ")}`))}}}"empty"in e&&(typeof e.empty!="string"||e.empty.length===0||e.empty.length>200)&&t.findings.push(d("list-empty",`${n}.empty`,"what an empty list says is a sentence, at most 200 characters")),"as"in e&&!C.includes(e.as)&&t.findings.push(d("list-as",`${n}.as`,`a list draws each record as its "card" or its "row", not "${String(e.as)}"`))}function oe(e,n,t){(typeof e!="string"||e.length===0||e.length>60)&&t.findings.push(d("view-label",n,"a label is a few words, at most 60 characters"))}function P(e,n,t,s,a,l,r){let i={kind:null,spec:q,kinds:s,edges:a,vocabulary:t,findings:l,count:0,all:0};Array.isArray(e)&&e.length===0&&l.push(d("view-shape",n,`${r} has no blocks`,'give it one: {"headline": "\u2026"}')),x(e,n,1,i),H(i,n,r,"show less")}function H(e,n,t,s){e.count>T?e.findings.push(d("view-size",n,`${t} has ${e.count} blocks at its top; a view has at most ${T} there, a group or a condition counting as one`,`${s}, or gather some into a group`)):e.all>I&&e.findings.push(d("view-size",n,`${t} has ${e.all} blocks counting the ones inside its groups and conditions; a view has at most ${I} in all`,s))}function se(e,n,t,s,a){Array.isArray(e)&&e.forEach((l,r)=>{if(!g(l)||l.name!=="blocks"||!g(l.options)||!("blocks"in l.options))return;let i=[];P(l.options.blocks,`lenses.${r}.options.blocks`,n,t,s,i,`the lens "${String(l.title??r)}"`);for(let o of i)a.push({...o,severity:"warning"})})}function re(e,n,t,s,a,l,r){let i=[];if(e===void 0)return i;if(!g(e))return i.push(d("view-shape",n,'views are an object of kinds, each with a "card", a "row" or a "page"')),i;for(let[o,f]of Object.entries(e)){if(o==="home"&&Array.isArray(f)){P(f,`${n}.home`,r,s,a,i,"the home");continue}let u=t(o);if(!u){i.push(d("view-kind",`${n}.${o}`,`"${o}" is not a kind this ${l} declares`));continue}if(!g(f)){i.push(d("view-shape",`${n}.${o}`,`a kind's views are {"card": [blocks], "row": [blocks], "page": [blocks]}`));continue}for(let c of Object.keys(f))E.includes(c)||i.push(d("view-slot",`${n}.${o}.${c}`,`"${c}" is not a place a view is drawn`,`use ${E.map(p=>`"${p}"`).join(", ")}`));for(let c of E){let p=f[c];if(p===void 0)continue;let y={kind:o,spec:u,kinds:s,edges:a,vocabulary:r,findings:i,count:0,all:0,slot:c};x(p,`${n}.${o}.${c}`,1,y),H(y,`${n}.${o}.${c}`,`this ${c}`,"show less, or move detail to the page")}}return i}function he(e){let n=new Set(Object.keys(e.kinds)),t=new Set(Object.values(e.kinds).flatMap(r=>Object.keys($(r.edges)))),s=r=>{let i=m(e.kinds,r)?e.kinds[r]:void 0;return i?{field:o=>m(i.fields,o)||m(i.computed,o)||F(i.edges).has(o),relation:o=>m($(i.edges),o),figure:i.figure!==void 0,files:o=>m(i.fields,o)&&Y(i.fields[o]),choices:o=>m(i.fields,o)&&i.fields[o].type==="enum"?i.fields[o].options:void 0,targets:o=>m($(i.edges),o)?i.edges[o].to:void 0,prose:o=>m(i.fields,o)&&i.fields[o].type==="text"}:void 0},a={namesOf:s,sources:r=>Object.keys(e.kinds).filter(i=>m(e.kinds[i].edges,r))},l=re(e.views,"views",s,n,t,"document",a);return se(e.lenses,a,n,t,l),l}export{j as a,U as b,L as c,B as d,M as e,ce as f,X as g,ge as h,ye as i,he as j};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{a as K}from"./chunk.NYLKG25K.js";import{c as O}from"./chunk.VR553M6J.js";import{G as Oe,W as Q}from"./chunk.FWXW4T4I.js";import{td as Z}from"./chunk.DHPXRDT5.js";import{b as L}from"./chunk.AJZBJBMO.js";function ht(e){let t=e.elements[0]?.getRootNode();return t?.host?.closest("[data-worker-view-place]")??t?.host?.parentElement??void 0}var Ee=["no","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"],G=e=>Ee[e]??String(e),ee=e=>e.replace(/\s+/g," ").trim(),x={li:["item","items"],a:["link","links"],button:["button","buttons"],img:["picture","pictures"],p:["paragraph","paragraphs"],ul:["list","lists"],ol:["list","lists"],table:["table","tables"],tr:["row","rows"],td:["cell","cells"],th:["column heading","column headings"],section:["section","sections"],article:["card","cards"],nav:["menu","menus"],form:["form","forms"],input:["field","fields"],label:["label","labels"]},je=new Set(["js","is","has","item","items","wrap","inner","outer","box","el","block","row","col","cell","card","pick","active","selected"]);function X(e){return e.split(/[-_]+/).filter(r=>/^[a-z]{3,}$/i.test(r)&&!je.has(r.toLowerCase())).at(-1)?.toLowerCase()}function Ne(e){if(e.length<2)return;let t=(r,n)=>Math.abs(r-n)<=6;if(e.every(r=>t(r.top,e[0].top)))return"columns";if(e.every(r=>t(r.left,e[0].left)))return"rows"}function ft(e){if(e.length===0)return"nothing";if(e.length===1){let[i]=e,l=/^h[1-6]$/.test(i.tag)?"heading":x[i.tag]?.[0]??i.classes.map(X).find(Boolean)??"part",g=ee(i.text);return g?`the ${l} \u201C${g.length>40?`${g.slice(0,39)}\u2026`:g}\u201D`:`the ${l}`}let r=e[0].classes.filter(i=>e.every(c=>c.classes.includes(i))).map(X).find(Boolean),n=new Set(e.map(i=>i.tag)),a=Ne(e.map(i=>i.box));if(r)return`the ${G(e.length)} ${r} ${a??(n.size===1&&x[e[0].tag]?x[e[0].tag][1]:"blocks")}`;if(n.size===1){let i=x[e[0].tag]?.[1]??(/^h[1-6]$/.test(e[0].tag)?"headings":a??"parts");return`the ${G(e.length)} ${i}`}let o=new Map;for(let i of e){let c=/^h[1-6]$/.test(i.tag)?"heading":x[i.tag]?.[0]??"part";o.set(c,(o.get(c)??0)+1)}let s=[...o].map(([i,c])=>c===1?`a ${i}`:`${G(c)} ${x[Object.keys(x).find(l=>x[l][0]===i)??""]?.[1]??`${i}s`}`);return s.length===1?s[0]:`${s.slice(0,-1).join(", ")} and ${s.at(-1)}`}function pt(e){return e.map(t=>`<${t.tag}${t.classes.length?` class="${t.classes.join(" ")}"`:""}> ${ee(t.text).slice(0,60)}`.trim())}function yt(e){if(e.length===1)for(let t of e){let r=t.matches("h1, h2, h3, h4, [role='heading']")?t:t.querySelector("h1, h2, h3, h4, [role='heading']");if(!r)continue;let n=r.cloneNode(!0);for(let o of n.querySelectorAll("span"))/^[\s·\d]+$/.test(o.textContent??"")&&o.remove();let a=(n.textContent??"").replace(/\s+/g," ").trim().replace(/^[▸▾]\s*/,"").replace(/\s*\d+$/,"");if(a)return a.length>60?`${a.slice(0,57)}\u2026`:a}}var ne=e=>e===void 0||e.off?void 0:e.fast??(e.decide?{model:e.name??"decide",decide:e.decide}:void 0),Me=/\b(look|looks|looking|nicer|prettier|cleaner|ugly|layout|laid out|lay it out|design|style|styled|theme|colou?rs?|font|bigger|smaller|larger|wider|narrower|taller|shorter|spacing|space|padding|margin|compact|dense|denser|roomier|columns?|grid|cards?|rows?|show (?:the )?\S+ (?:on|in) (?:each|every|the)|sort(?:ed)? by|order(?:ed)? by|group(?:ed)? by|readable|easier to read|at a glance|icons?|badges?|headings?|bold|highlight)\b/i;async function Ie(e,t,r){let n=t.trim(),a=ne(e);if(a&&n)try{let o=await a.decide({typed:n,on:r},{about:{type:"choice",instructions:`Somebody right-clicked \u201C${r}\u201D in an app and typed \u201C${n}\u201D. Is it about how \u201C${r}\u201D looks or is laid out, or about the records in it?`,criteria:{look:"How it looks or is laid out: making it look better, its style, size or spacing, what each row, card or page shows, its order or grouping",records:"The records themselves: changing, closing, assigning, adding, deleting or moving them, or a question about them"}}});e?.meter?.({tier:"fast",model:a.model,inputTokens:o.usage.inputTokens,outputTokens:o.usage.outputTokens,interaction:"menu"});let s=o.answers.about;if(s?.type==="choice"&&(s.choice==="look"||s.choice==="records"))return{about:s.choice,by:"fast",confidence:s.confidence}}catch{}return{about:Me.test(n)?"look":"records",by:"words"}}var Ce=/\b(colou?rs?|font|typeface|bigger|smaller|larger|wider|narrower|taller|spacing|padding|margin|border|shadow|rounded|corners?|columns? side by side|side by side|grid|chart|graph|picture of|animation|background|gradient|icons?|css|kanban|calendar)\b/i,re=.6;async function Le(e,t,r){let n=t.trim();if(!n)return{can:!0,by:"words"};let a=ne(e);if(a)try{let o=await a.decide({asked:n,on:r.name,page:r.slot},{can:{type:"choice",instructions:`Somebody asked of the page \u201C${r.name}\u201D: \u201C${n}\u201D. Can the app's view settings do it, or does it need drawing of its own?`,criteria:{spec:"The view settings can do it: which fields a card, a row or a page shows and in what order, a headline, a badge with a tone, a figure, a progress bar, a list of related records, how a list is sorted, grouped or filtered, a field's label or format",drawing:"It needs drawing the settings have no word for: colors, fonts, sizes, spacing, borders or shadows, a layout or columns side by side, a chart, a calendar, a board, or markup and styles of its own"}}});e?.meter?.({tier:"fast",model:a.model,inputTokens:o.usage.inputTokens,outputTokens:o.usage.outputTokens,interaction:"section"});let s=o.answers.can;if(s?.type==="choice"&&(s.choice==="spec"||s.choice==="drawing"))return{can:s.choice==="spec"||s.confidence<re,by:"fast",confidence:s.confidence}}catch{}return{can:!Ce.test(n),by:"words"}}var se=["set-view","set-glance","set-page-fields","arrange-pages","set-label","set-format"],Ke=new Set(["sort","group","filters"]);function ae(e){let t=[];e.length===0&&t.push("It changed nothing.");for(let r of e){let n=r?.op;if(typeof n!="string"||!se.includes(n)){t.push(`\u201C${String(n)}\u201D is not a change to how a page reads.`);continue}if(n==="arrange-pages")for(let a of Object.keys(r))a!=="op"&&!Ke.has(a)&&t.push(`arrange-pages may say only sort, group and filters here, not \u201C${a}\u201D.`);n==="set-label"&&r.field===void 0&&t.push("set-label may name only a field's label here, not a kind's.")}return t}var oe=["You change how one page of a Graview app reads, by editing its view spec: data that says what a kind's card, row and page show, and how a list opens. Nothing in it is code: no CSS, no markup, no colors or sizes of your own.","You are told the page (a kind's list, one group of it, a record's page, or the home), what was asked, the kind's fields and relations, and its spec as it stands.",'Answer with one JSON object and nothing else: {"edits": [...], "said": "<one sentence to the person saying what will change>"}. Or, where the spec has no word for it (colors, fonts, sizes, spacing, layout, a chart), answer {"cannot": "<one sentence saying what it would need>"}.',"The edits you may use, and no others:",`{"op":"set-view","kind":K,"slot":"card"|"row"|"page","blocks":[...]} \u2014 a kind's card, its row on a list, the blocks over its record page; {"op":"set-view","slot":"home","blocks":[...]} \u2014 the home. Blocks: {"title":"{name}"}, {"headline":"{count(out('rel'))} things"}, {"text":"{field}","lines":2}, {"badge":"{field}","tone":"good"|"warn"|"bad"|"neutral"|"accent"}, {"field":"due","as":"date"|"time"|"datetime"|"relative"|"money"|"percent"|"count","label":"Due"}, {"figure":"expr","as":"number"|"money"|"percent","label":"..."}, {"progress":{"value":"done","max":"total"},"label":"..."}, {"list":"out('rel')" or "all('kind')","as":"row"|"card","sort":{"by":"f","direction":"asc"|"desc"},"limit":5,"group":{"by":"f"},"empty":"None yet."}, {"group":[...blocks],"direction":"row"|"column"}, {"when":"rule expression","show":[...blocks]}, {"divider":true}. Templates say {field}; a row always leads with {"title":"{name}"} or the record's label field.`,`{"op":"set-glance","kind":K,"fields":[...]} \u2014 the few facts said beside a record's name on a list.`,`{"op":"set-page-fields","kind":K,"fields":[...],"groups":[{"title":"...","fields":[...]}]} \u2014 the order and groups of a record page's facts.`,`{"op":"arrange-pages","sort":{K:{"by":"f","direction":"asc"|"desc"}},"group":{K:{"by":"f"}},"filters":{K:["f"]}} \u2014 how a kind's list opens. A list sorts by one of its kind's fields or computed values, and groups only by a choice or a yes-or-no field of its own: grouping by a relation or by the record that holds it is not the spec's to say.`,'{"op":"set-label","kind":K,"field":F,"label":"..."}, {"op":"set-format","kind":K,"field":F,"format":"money"|"percent"|"duration"|null}.',"Name only fields and relations the kind has. Change only what the ask needs, on this page's kind. Keep every fact the page shows now unless asked to drop one.","Do what was asked or answer cannot: never something else in its place (grouping by another field than the one asked for, say)."].join(`
|
|
2
|
+
`);function E(e){let t=e.part.kind,r=e.document,n=t?r.kinds[t]:void 0,a=e.mode==="just"?"Make this page better: easier to read at a glance, the facts a person needs first. Change no data.":(e.words??"").trim();return JSON.stringify({page:{name:e.part.name,is:e.part.slot==="list"?"a kind's list":e.part.slot==="group"?`one group of a kind's list (\u201C${e.part.group}\u201D)`:e.part.slot==="record"?"a record's page (every record of the kind)":e.part.slot==="home"?"the home":"a place",...t?{kind:t}:{}},asked:a,...e.highlighted?.length?{pointed_at:e.highlighted}:{},...n?{fields:n.fields,relations:n.edges??n.relations,computed:n.computed,glance:n.glance,pageFields:n.pageFields}:{kinds:Object.keys(r.kinds)},now:{...t?{views:r.views?.[t]??null,list:r.pages?.lists?.[t]??null}:{home:r.views?.home??null}},...e.shows?{shows:e.shows.slice(0,1500)}:{},...e.findings?.length?{your_last_answer:e.last,what_broke:e.findings,repair:"Your last answer was refused as said in what_broke. Answer again, fixing each one \u2014 or, where the spec cannot do what was asked, answer cannot."}:{}})}function ie(e){let t=/```(?:json|js|javascript)?\s*([\s\S]*?)```/.exec(e)?.[1];for(let r of t?[t,e]:[e]){let n=r.indexOf("{"),a=r.lastIndexOf("}");if(!(n<0||a<=n))try{let o=JSON.parse(r.slice(n,a+1));if(o&&typeof o=="object"&&!Array.isArray(o))return o}catch{}}}function de(e){let t=ie(e);if(t){if(typeof t.cannot=="string"&&t.cannot.trim())return{cannot:t.cannot.trim()};if(Array.isArray(t.edits))return{edits:t.edits,said:typeof t.said=="string"&&t.said.trim()?t.said.trim():"Changed how this page reads."}}}function Ge(e){return async(t,r,n,a)=>{let o=Date.now();try{let s=await t.think({system:n,prompt:a,state:{},catalog:{candidates:[]}});return e.push({stage:r,model:t.model,ms:Date.now()-o,...s.usage?{usage:s.usage}:{}}),s.text}catch{e.push({stage:r,model:t.model,ms:Date.now()-o});return}}}async function ze(e){let t=[],r=e.ai.off?void 0:e.ai.light,n=O(e.ai),a=r??n;if(!a)return{ok:!1,refused:e.ai.withoutModel??"Changing a page needs AI, and none is on here.",stages:t};let o=Ge(t),s={part:e.part,document:e.document,mode:e.mode,...e.words?{words:e.words}:{},...e.highlighted?{highlighted:e.highlighted}:{},...e.shows?{shows:e.shows}:{}},i=async(h,k,v)=>{let f=await o(h,k,oe,v);return f===void 0?void 0:de(f)},c=await i(a,r?"light":"thinking",E(s));if(!c&&r&&(c=await i(r,"light",E(s))),!c)return{ok:!1,refused:"The model did not answer with a change to this page.",stages:t};if("cannot"in c)return{ok:!1,cannot:c.cannot,refused:c.cannot,stages:t};let l=async h=>{let k=ae(h);return k.length>0?k:[...await e.judge(h)]},g=await l(c.edits);if(g.length===0)return{ok:!0,edits:c.edits,said:c.said,repaired:!1,stages:t};let m=a;e.repairing?.(g);let y=await i(m,m===r?"light":"thinking",E({...s,findings:g,last:c}));return y&&"cannot"in y?{ok:!1,cannot:y.cannot,refused:y.cannot,stages:t}:y?(g=await l(y.edits),g.length>0?{ok:!1,refused:`It could not be changed so: ${g.join(" ")}`,stages:t}:{ok:!0,edits:y.edits,said:y.said,repaired:!0,stages:t}):{ok:!1,refused:`It could not be changed so: ${g.join(" ")}`,stages:t}}var te=e=>e.toLowerCase().normalize("NFKD").replace(/[̀-ͯ]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40)||"page";function Fe(e,t,r=[]){let n={...t.kinds.length?{kinds:[...t.kinds]}:{},...t.edges.length?{edges:[...t.edges]}:{}},a={...Object.keys(n).length>0?{reads:n}:{},...r.length>0?{acts:[...r]}:{}};if((e.slot==="list"||e.slot==="group")&&e.kind)return{name:`${te(e.kind)}-list`,attach:e.kind,cardinality:"many",replaces:"page",...a};if(e.slot==="record"&&e.kind)return{name:`${te(e.kind)}-page`,attach:e.kind,cardinality:"one",replaces:"page",...a};if(e.slot==="home")return{name:"home-page",attach:"home",cardinality:"many",...a}}var z=["You write a Graview worker view: one plain script, no imports and no build, that draws one page of an app through the global `graview`, in place of the page the app drew by itself.","The global: graview.style(css) a stylesheet; graview.onProps((props) => \u2026) on every push of what it is shown; graview.render(graview.html`\u2026`) draws markup, every ${value} escaped; graview.html`` nests: a list is ${items.map((one) => graview.html`<li>\u2026</li>`)}. Never build HTML as a string or with join(): a string is drawn as its words.","props.nodes holds the records a view of many is drawn for and those it reads; props.node the record a view of one is drawn for. A record is plain data: id, kind, label, and each field by name. props.edges are {kind, from, to}. props.choices[kind][field][option] is a choice's label.",'Link to a record with <a data-record="${node.id}">\u2026</a>. Give repeated rows data-key="${node.id}". Name each part a person would name with a heading inside a <section aria-labelledby="x-h"> whose heading has id="x-h"; never aria-label.',"The page draws its own title above your view: never draw the page's title again. Draw each other heading the page had, with the same words, and every record the page showed: each record still says what its row said (its status, its dates, its counts, in words) and stays under the heading it was under, unless what was asked changes that.",'Say things in words a person reads: a date as the page said it (\u201CSep 3\u201D), never as stored (2026-09-03). A date kept as YYYY-MM-DD is a day, not an instant: read it as new Date(`${value}T00:00`) \u2014 new Date(value) alone is midnight in London and the day before here \u2014 then .toLocaleDateString(props.locale, { month: "short", day: "numeric" }); never show a field\'s own name (order, done, holds), an id, true, false, null or undefined. Leave out a value the page did not show unless asked for it.',`CSS the host keeps: plain rules on your own classes and elements, one level, and @media. Give your outer element a class (class="pg") and style that: never :host, ::slotted or ::part, no url(), @import, @font-face, @keyframes or nesting. Colors, type and corners only through var(--graview-ink), var(--graview-ink-muted), var(--graview-panel), var(--graview-edge), var(--graview-accent), var(--graview-ground), var(--graview-radius). position may be static, relative, absolute or sticky. Set no height; lay it out well at a phone's width and at a desk's.`,"Never write the words import, export or require, nor <script>, <style>, or on\u2026= attributes.",'Answer with one JSON object and nothing else: {"source": "<the whole script>", "said": "<a few words on what you changed>"}.'].join(`
|
|
3
|
+
`);function F(e){return e.records.map(t=>{let r=e.says?.[t];return{record:t,...r?.id?{id:r.id}:{},...r?.shows?.length?{must_show:r.shows}:{},...r?.under?{under:r.under}:{}}})}function V(e){let[t,r]=e.record==="from"?["from","to"]:["to","from"];return`Group the records as the page did: each record sits under a heading that is the label of the ${e.kind} it is linked to \u2014 find the edge in props.edges with kind "${e.edge}" whose ${t} is the record's id; the ${e.kind} is props.nodes' node whose id is the edge's ${r}. Draw the headings in keep_these_headings' order; never guess a record's group from its fields.`}function W(e){let t=ie(e),r=t?.source,n=typeof r=="string"?r.trim().replace(/^```(?:js|javascript)?\s*/i,"").replace(/\s*```$/,"").replace(/^<script[^>]*>\s*/i,"").replace(/\s*<\/script>\s*$/i,""):void 0;if(!(typeof n!="string"||!/graview\.(render|onProps)/.test(n)))return{source:n,said:typeof t.said=="string"?t.said.trim():""}}var ue=["look","read","edit","draft","done","ask"],le=64e3,Ve=e=>e.length>80?`${e.slice(0,79)}\u2026`:e;function he(e,t,r){let n=[],a=e;return t.forEach((o,s)=>{let i=`Edit ${s+1}: \u201C${Ve(o.find)}\u201D`;if(!o.find)return void n.push(`${i} is no text to find: quote the text to change, exactly as it stands in ${r}.`);let c=0;for(let g=a.indexOf(o.find);g>=0&&c<2;g=a.indexOf(o.find,g+o.find.length))c+=1;if(c===0){let g=y=>y.replace(/\s+/g,""),m=g(o.find).length>0&&g(a).includes(g(o.find));return void n.push(`${i} is not in ${r}${m?" as written, but is there with other spacing":""}: quote it exactly as it stands there, spaces and quotes included.`)}if(c>1){let g=a.split(o.find).length-1;return void n.push(`${i} appears ${g} times in ${r}: quote more of the text around the place you mean, so it appears once.`)}let l=a.indexOf(o.find);a=`${a.slice(0,l)}${o.replace}${a.slice(l+o.find.length)}`}),n.length>0?{findings:n}:a===e?{findings:[`Your edits change nothing in ${r}: replace the text with something else, or say you are done.`]}:{source:a}}var fe=12,Y=[z.split(`
|
|
4
|
+
`).filter(e=>!e.startsWith("Answer with one JSON object")).join(`
|
|
5
|
+
`),"","You are Graview, redesigning one page of an app with the person who is looking at it. You work in steps, and each answer is ONE JSON object and nothing else:",'{"say": "<one short plain sentence the person reads: what you are doing or what you found>", "do": "look" | "read" | "edit" | "draft" | "done" | "ask", "edits": [{"find": "<text copied exactly from the script, there once>", "replace": "<what stands there instead>"}], "in": "page" | "draft", "source": "<the whole script>"}',"edits (and, if you like, in) only with edit; source only with draft.","You are shown, before your first step, what the page draws now (what_the_page_draws: its headings, each record's words and the heading it sits under, how they stand) and the records your view is handed (records_it_is_handed): edit or draft first.","- look: see what the page draws now again, as it stands.","- read: the records and fields your view is handed, again.",'- edit: change the script in place. Each find is text copied exactly from your_draft_on_the_page \u2014 or, with "in": "draft", from your_last_draft \u2014 long enough to be there once; replace is what stands there instead ("" takes it out). The code applies them in order, then draws and checks the result exactly as it does a draft; a find that is not there once is handed back to you. For a small change \u2014 a color, a corner, a size, a word, one rule, one part \u2014 answer with an edit, never the whole script again: "no rounded corners on the logo" is one edit of one declaration.',"- draft: for a redesign, or where there is no script on the page yet, your whole script, drawn where only you see it. You are told what the checks found (records, headings, dates, statuses or groups it lost; words it shows as the computer keeps them; a style the page will not keep, by its rule) and what it drew.",'With an edit or a draft, "say" is one sentence of what it does, as the person will read it once it is on the page ("Tasks are cards now, side by side, each with its status and date."). One the checks pass is shown to the person on the page, and your turn ends there.',"- done: you have finished this request; say in one sentence what you changed. Only once an edit or a draft passed, unless you must ask.","- ask: ask the person one short question, and wait for their answer.",`A control that changes a record is a press bound to one of the app's acts (acts_a_press_may_ask_for): <button data-act="finish" data-record="\${task.id}">Done</button> \u2014 the host runs the act for that record when it is pressed. A field the person types into is named for the act's argument, inside a fieldset with the press; data-prefill="field" fills it with the record's own text; data-save on a field saves it as it is typed. Never a checkbox, a toggle or a button bound to nothing, and never graview.act from your own click handler: it is refused. Every control on a record the page let a person press (marking it done, opening it) is kept, bound to the same act. A press that marks a record (an act with \`marks\`) shows what it marked from the record's own field: a record already marked says so and offers the act that undoes it (reopen), so a person sees the press land. The code presses every control headless and tells you what each one did.`,"Keep everything the page showed unless the person asked otherwise: every record, every heading, each record's words (its status, its dates, its counts) and its group. Fix what the checks found \u2014 with an edit where the fix is small \u2014 and keep going until one passes. Write to a person, never about code: no words like view, script, spec, host, CSS or stylesheet in what you say."].join(`
|
|
6
|
+
`);function H(e,t){let r=s=>s.length>le?`${s.slice(0,le)}
|
|
7
|
+
/* \u2026 the script goes on: quote only what you see */`:s,n=M(e.talk.filter(s=>s.who==="person").map(s=>s.said).join(" ")),a=n?e.rewordable??[]:[],o=e.keep&&a.length>0?{...e.keep,headings:e.keep.headings.filter(s=>!a.some(i=>i.trim().toLowerCase()===s.trim().toLowerCase()))}:e.keep;return JSON.stringify({page:e.part.name,view:{attach:e.manifest.attach,cardinality:e.manifest.cardinality,reads:e.manifest.reads??{}},conversation:e.talk.map(s=>({[s.who==="person"?"person":"you"]:s.said})),...e.about&&e.about.name!==e.part.name?{about:e.about.name,...e.about.lines?.length?{pointed_at:e.about.lines}:{}}:{},...e.acts?.length?{acts_a_press_may_ask_for:e.acts.map(s=>({act:s.act,title:s.title,record_goes_in:s.record,...s.toggle?{marks:s.toggle}:{}}))}:{},...e.pressed?.length?{the_controls_as_pressed:e.pressed,then:"The person says something does not work. This is what pressing every control of your draft found: fix what failed, with controls bound to acts."}:{},...e.section?{only_change:`Change only the part \u201C${e.section}\u201D of your_draft_on_the_page; keep every other part of the script as it is, byte for byte.`}:{},...o?{...o.title?{the_page_draws_its_title:o.title}:{},keep_these_headings:o.headings,records:F(o),...o.grouping?{grouping:V(o.grouping)}:{}}:{},...n?{you_may_reword:a.length>0?`The person asked for a heading's words to change: ${a.map(s=>`\u201C${s}\u201D`).join(", ")} may say new words, in the same place. Keep every other heading as it was.`:"The person asked for a heading's words to change: the heading they mean may say new words, in the same place. Keep every other heading as it was."}:{},...e.markup&&!e.current?{the_page_as_html:e.markup.slice(0,5e3)}:{},...e.current?{your_draft_on_the_page:r(e.current)}:{},...e.lastDraft!==void 0&&e.lastDraft!==e.current?{your_last_draft:r(e.lastDraft)}:{},your_steps:t.map((s,i)=>({said:s.said,did:s.did,...s.edits?{edits:s.edits}:{},...s.result!==void 0?{result:s.result}:{},...i<t.length-1&&(s.did==="draft"||s.did==="edit")?{note:s.did==="edit"?"an earlier edit":"an earlier draft"}:{}})),...t.length===0&&e.seen?{what_the_page_draws:e.seen.look,records_it_is_handed:e.seen.read}:{},next:t.length===0?e.current?"Edit or draft first, as one JSON object.":"Draft first, as one JSON object.":"Your next step, as one JSON object."})}function We(e){if(!Array.isArray(e)||e.length===0)return;let t=[];for(let r of e){let n=r?.find,a=r?.replace;if(typeof n!="string"||n.length===0||typeof a!="string")return;t.push({find:n,replace:a})}return t}function pe(e){let t=e.indexOf("{"),r=e.lastIndexOf("}");if(t<0||r<=t)return;let n;try{n=JSON.parse(e.slice(t,r+1))}catch{return}let a=ue.find(i=>i===n.do);if(!a)return;let o=typeof n.say=="string"?n.say.trim():"";if(a==="edit"){let i=We(n.edits),c=n.in==="draft"||n.in==="page"?n.in:void 0;return i?{say:o,do:"edit",...c?{in:c}:{},edits:i}:void 0}if(a!=="draft")return{say:o,do:a};let s=W(JSON.stringify({source:n.source,said:o}));return s?{say:o,do:"draft",source:s.source}:void 0}function Ye(e){let t=/^In “(.+?)”, /.exec(e)?.[1],r=/\((.+?) (?:is|are) kept\)/.exec(e)?.[1],n=/the (?:property|function) “([^”]+)”/i.exec(e)?.[1],a=n?/the function/i.test(e)?`${n}()`:n:/url\(\) is not allowed/.test(e)?"url()":/a value of “([^”]+)”/i.test(e)?`that value of ${/a value of “([^”]+)”/i.exec(e)[1]}`:void 0,o=/^The selector “([^”]+)” reaches outside/.exec(e)?.[1];if(o)return{short:`the selector \u201C${o}\u201D reaches outside the page`,still:`uses the selector \u201C${o}\u201D, which reaches outside the page`};let s=/^“(@[\w-]+)” is not allowed/.exec(e)?.[1];if(s)return{short:`${s} isn't allowed`,still:`uses ${s}, which isn't allowed`};if(/^The stylesheet is too long/.test(e))return{short:"the styles are too long to keep",still:"has styles too long to keep"};if(!a)return{short:"styles the page won't keep",still:"uses styles the page won't keep"};let i=t?` in \u201C${t}\u201D`:"";return{short:t&&r?`\u201C${t}\u201D keeps ${r}; ${a} isn't allowed`:`${a}${i} isn't allowed`,still:`uses ${a}${i}, which isn't allowed`}}function ye(e,t){let r=n=>n===1?`one of the ${t}`:`${n} ${t}`;switch(D(e)){case"fact-lost":{let n=/no longer says what it said: (.*?)(?: and (\d+) more)?\. Show/.exec(e),a=new Set([...(n?.[1]??"").matchAll(/” on “([^”]+)”/g)].map(i=>i[1])),o=[...(n?.[1]??"").matchAll(/“([^”]+)” on “/g)].some(i=>/\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*\.?\s+\d|\d{1,2}\s+(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i.test(i[1])),s=Math.max(1,a.size+Number(n?.[2]??0));return{short:`${o?"dates":"details"} lost on ${r(s)}`,still:`loses ${o?"the dates":"details"} on ${r(s)}`}}case"record-lost":{let n=/^It no longer shows (.*?)(?: and (\d+) more)?: show every record/.exec(e),a=Math.max(1,[...(n?.[1]??"").matchAll(/“/g)].length+Number(n?.[2]??0));return{short:`${r(a)} missing`,still:`leaves out ${r(a)}`}}case"record-twice":case"record-moved":return{short:`${t} in the wrong group`,still:`puts ${t} in the wrong group`};case"heading-lost":return{short:"headings missing",still:"drops headings the page had"};case"section-lost":{let n=/^“(.*)” is not drawn any more/.exec(e)?.[1]??"";return{short:`the part \u201C${n}\u201D missing`,still:`drops the part \u201C${n}\u201D`}}case"title-twice":return{short:"the title drawn twice",still:"draws the title twice"};case"computer-words":return{short:"words shown as the computer keeps them",still:"shows words as the computer keeps them"};case"did-not-draw":return{short:"it didn't draw",still:"doesn't draw"};case"style-refused":return Ye(e);case"edit-missed":{if(/^There is no script to edit/.test(e))return{short:"nothing to edit yet",still:"has nothing to edit"};if(/^Your edits change nothing/.test(e))return{short:"the edit changes nothing",still:"changes nothing"};let n=/appears (\d+) times/.exec(e)?.[1];return n?{short:`an edit's text appears ${n} times`,still:`quotes text that appears ${n} times`}:{short:"an edit's text isn't in the script",still:"quotes text that isn't in the script"}}case"unstyled":return{short:"a part left without its style",still:"leaves a part without its style"};case"control":return{short:"a control that doesn't work",still:"has a control that doesn't work"};default:{let n=(/^(.*?[.!?])(\s|$)/.exec(e.trim())?.[1]??e.trim()).replace(/[.!?]+$/,""),a=n.length>120?`${n.slice(0,119)}\u2026`:n;return{short:a,still:`fails a check: ${a}`}}}}function j(e,t="records"){return[...new Set(e.map(n=>ye(n,t).short))].slice(0,3).join(", ")}function we(e,t,r="records"){return`I tried twice, and the new design still ${ye(e,r).still}. ${t?"Keep it anyway, or stop?":"Say it another way, or stop?"}`}var ce=e=>{let t=D(e);return t==="other"?`other:${e}`:t};async function ge(e,t,r){if(t?.aborted)return"stopped";let n,a,o=await Promise.race([e.then(s=>({value:s})),...t?[new Promise(s=>t.addEventListener("abort",n=()=>s("stopped"),{once:!0}))]:[],...r!==void 0?[new Promise(s=>a=setTimeout(()=>s("late"),r))]:[]]);return n&&t?.removeEventListener("abort",n),a&&clearTimeout(a),o}async function He(e){let t=[],r=[],n=e.ai.off?void 0:e.ai.design??O(e.ai)??e.ai.light;if(!n)return{ended:"no-model",said:e.ai.withoutModel??"Changing how a page looks needs AI, and none is on here.",steps:r,stages:t};let a=h=>e.onEvent?.(h),o=e.noun??(e.part.slot==="record"?"parts":"records"),s,i,c=0,l=0,g=new Set,m=Math.max(2,e.steps??fe);a({kind:"look",text:`Looking at ${e.part.name}`});let y={look:e.host.look(),read:e.host.read()};for(let h=0;h<m;h++){let k=Date.now(),v=await ge((n.stream?n.stream({system:Y,prompt:H({...e,seen:y,...i?{lastDraft:i.source}:{}},r),state:{},catalog:{candidates:[]}},$=>a({kind:"streaming",text:me($)}),e.signal):n.think({system:Y,prompt:H({...e,seen:y,...i?{lastDraft:i.source}:{}},r),state:{},catalog:{candidates:[]}})).then($=>(t.push({stage:"thinking",model:n.model,ms:Date.now()-k,...$.usage?{usage:$.usage}:{}}),$.text),()=>{t.push({stage:"thinking",model:n.model,ms:Date.now()-k})}),e.signal,e.stepMs??10*6e4);if(v==="late")return{ended:"steps",said:s?"The model stopped answering; here is where it got to.":"The model didn't answer in time. Ask again, or say it another way.",...s?{passed:s}:{},...i?{last:i}:{},steps:r,stages:t};if(v==="stopped")return{ended:"stopped",said:"Stopped.",...s?{passed:s}:{},...i?{last:i}:{},steps:r,stages:t};let f=v.value===void 0?void 0:pe(v.value);if(!f){if(c+=1,c>=3)break;r.push({said:"",did:"look",result:{error:"Your answer was not one JSON object with say and do (with edits for an edit, the whole script in source for a draft). Answer again."}});continue}if(f.do==="look")a({kind:"look",text:`Looking at ${e.part.name}`}),r.push({said:f.say,did:"look",result:e.host.look()});else if(f.do==="read")a({kind:"read",text:`Reading what ${e.part.name} shows`}),r.push({said:f.say,did:"read",result:e.host.read()});else if(f.do==="draft"||f.do==="edit"){let $=f.source,P=f.edits??[];if(f.do==="edit"){a({kind:"edit",text:f.say?`Changing: ${f.say.replace(/\.$/,"")}`:"Changing it"});let S=f.in==="draft"?i?{script:i.source,where:"your last draft"}:void 0:e.current!==void 0?{script:e.current,where:"the script on the page"}:i?{script:i.source,where:"your last draft"}:void 0,_=S?he(S.script,P,S.where):{findings:[f.in==="draft"?"There is no script to edit yet: you have made no draft this turn, so edit the script on the page or draft the whole script.":"There is no script to edit yet: draft the whole script."]};if("findings"in _){a({kind:"check",text:`Check: ${j(_.findings,o)} \u2014 fixing`,findings:N(_.findings)}),r.push({said:f.say,did:"edit",edits:P,result:{findings:_.findings}});continue}$=_.source}else a({kind:"draft",text:f.say?`Drafting: ${f.say.replace(/\.$/,"")}`:"Drafting"});let T=f.do,A={said:f.say,did:T,...T==="edit"?{edits:P}:{}},d=q($,e.current!==void 0?{already:e.current}:{}),p=()=>e.host.draft($).catch(S=>({findings:[`The draft could not be judged: ${String(S instanceof Error?S.message:S).replace(/[.\s]+$/,"")}.`],drew:void 0})),w=d.length>0?{findings:d,drew:void 0}:await ge(p(),e.signal).then(S=>typeof S=="string"?void 0:S.value);if(!w)return{ended:"stopped",said:"Stopped.",...s?{passed:s}:{},...i?{last:i}:{},steps:r,stages:t};i={source:$,findings:w.findings},l+=1;let b=N(w.findings);try{e.ai.onDraftChecked?.({part:e.part.name,draft:l,passed:b.length===0,findings:b})}catch{}let C=w.findings.find(S=>g.has(ce(S)));if(g=new Set(w.findings.map(ce)),C!==void 0){let S=!w.findings.some(Pe=>D(Pe)==="did-not-draw"),_=we(C,S,o);return a({kind:"stuck",text:`Check: ${j([C],o)}, again`,findings:b}),r.push({...A,result:{findings:w.findings,drew:w.drew}}),{ended:"stuck",said:_,keepable:S,...s?{passed:s}:{},last:i,steps:r,stages:t}}if(w.findings.length===0)return s={source:$},a({kind:"passed",text:"Check: nothing lost \u2014 it's on the page"}),r.push({...A,result:{findings:[],drew:w.drew,shown:"It passed and is on the page now."}}),{ended:"done",said:f.say||"Here it is.",passed:s,last:i,steps:r,stages:t};a({kind:"check",text:`Check: ${j(w.findings,o)} \u2014 fixing`,findings:b}),r.push({...A,result:{findings:w.findings,drew:w.drew}})}else{if(f.do==="ask")return{ended:"ask",said:f.say||"What would you like it to look like?",...s?{passed:s}:{},...i?{last:i}:{},steps:r,stages:t};if(!s&&i&&i.findings.length>0&&h<m-2){r.push({said:f.say,did:"done",result:{not_yet:"No draft has passed the checks yet. Fix what the last check found with an edit or a draft, or ask the person."}});continue}return{ended:"done",said:f.say||(s?"Done.":"I stopped here."),...s?{passed:s}:{},...i?{last:i}:{},steps:r,stages:t}}}return{ended:"steps",said:s?"Here is where it got to.":"I haven't got it right yet. Tell me more, or ask me to keep going.",...s?{passed:s}:{},...i?{last:i}:{},steps:r,stages:t}}function me(e){let t=/"say"\s*:\s*"((?:[^"\\]|\\.)*)/.exec(e)?.[1],r="";if(t!==void 0)try{r=JSON.parse(`"${t.replace(/\\$/,"")}"`)}catch{r=t}let n=e.indexOf('"source"'),a=n>=0?e.slice(n).split("\\n").length:0,o=a>1?`writing it, ${a} lines so far`:"";return r&&o?`${r.replace(/\.$/,"")} \u2014 ${o}`:r||(o?`Writing the design, ${a} lines so far`:"Thinking\u2026")}function qe(e){return{headings:e.headings,records:e.records.map(t=>({record:t.label,says:t.facts??[],...t.under?{under:t.under}:{},at:{top:t.top,left:t.left},type_px:t.size}))}}function Se(e){let t=[];for(let r of e.matchAll(/graview\.style\(\s*([`"'])/g)){let n=r[1],a=r.index+r[0].length,o=a;for(;o<e.length&&e[o]!==n;)o+=e[o]==="\\"?2:1;o<e.length&&t.push({start:a,end:o,quote:n})}return t}var Et=["You revise one section of a view in a Graview app.","The view is a plain script: it draws HTML with graview.html`\u2026` templates and styles it with graview.style(css).","You are given the section's markup exactly as it stands in the script's template. It may hold ${\u2026} interpolations: keep each one you keep exactly as written, and never name a variable that is not already in them.","You are given the stylesheet rules that style only this section (you rewrite them), the rules it shares with the rest of the view (never restate or change those), the app's look (its scheme and the values of its --graview-* tokens), and the words the section shows now.",`Answer with one JSON object and nothing else: {"markup": "<the section's whole new markup>", "css": "<every rule that styles it now>", "said": "<one sentence to the person saying what you changed>"}.`,"Keep the same outer element, and keep its name \u2014 its label or its heading's words \u2014 so it is still found. Show the same data. Style every class the markup uses, or stop using it. Use var(--graview-\u2026) tokens for colors, type and corners, never colors of your own.","Never use import, export, require, <script>, <style>, or on\u2026= attributes."].join(" ");var u=e=>e.replace(/\s+/g," ").trim().toLowerCase(),J=["no","one","two","three","four","five","six","seven","eight","nine","ten"],et=e=>e.length<2?e[0]??"":`${e.slice(0,-1).join(", ")} and ${e.at(-1)}`;function tt({refusal:e,rule:t,kept:r}){let n=e.name?`\u201C${e.name}\u201D`:"",a=t?`In \u201C${t}\u201D, `:"",o=r&&r.length>0?` (${et(r)} ${r.length===1?"is":"are"} kept)`:"",s=i=>a?`${a}${i}`:i.charAt(0).toUpperCase()+i.slice(1);switch(e.reason){case"selector":return`The selector \u201C${/^(host|host-context)$/.test(e.name??"")?":":/^(slotted|part)$/.test(e.name??"")?"::":""}${e.name??""}\u201D reaches outside the view and is removed with its rule: give the view's outer element a class and style that instead.`;case"at-rule":return`${n||"An at-rule"} is not allowed and is removed with what it holds: use plain rules and @media only.`;case"property":return`${s(`the property ${n}`)} is not allowed and is removed${o}: use ordinary layout, color and type properties.`;case"function":return`${s(`the function ${n}()`)} is not allowed and is removed${o}: use var(--graview-\u2026), calc(), min(), max(), clamp() or repeat().`;case"url":return`${s("url()")} is not allowed and is removed${o}: draw nothing from an address.`;case"value":return`${s(`a value of ${n||"a property"}`)} is not allowed and is removed${o} (position may be static, relative, absolute or sticky).`;case"size":return"The stylesheet is too long and is removed whole: keep it short.";default:return`${s(`a rule ${n?`near ${n} `:""}`)}could not be read and is removed: write plain CSS, one rule at a time, no nesting.`}}function nt(e){let t=[],r=e.replace(/\/\*[\s\S]*?\*\//g,a=>" ".repeat(a.length)),n=0;for(;n<r.length;){let a=r.indexOf("{",n);if(a<0)break;let o=0,s=a;for(;s<r.length;s++)if(r[s]==="{")o+=1;else if(r[s]==="}"&&--o===0)break;t.push({head:r.slice(n,a).replace(/\s+/g," ").trim(),text:r.slice(n,s+1)}),n=s+1}return t}function rt(e){let t=e.indexOf("{");return t<0||e.trimStart().startsWith("@")?[]:[...new Set([...e.slice(t+1).matchAll(/(?:^|;)\s*(-{0,2}[a-zA-Z][\w-]*)\s*:/g)].map(r=>r[1]))]}function $e(e){let t=[];for(let r of Se(e)){let n=e.slice(r.start,r.end).replace(/\$\{(?:[^{}]|\{[^{}]*\})*\}/g,"0"),a=K(n).refused;if(a.length===0)continue;if(a.some(s=>s.reason==="size")){t.push({refusal:{reason:"size"}});continue}let o=[...a];for(let s of nt(n)){let i=K(s.text),c=rt(i.css);for(let l of i.refused){let g=o.findIndex(m=>m.reason===l.reason&&m.name===l.name);g<0||(o.splice(g,1),t.push({refusal:l,...s.head?{rule:s.head}:{},...c.length>0?{kept:c}:{}}))}}t.push(...o.map(s=>({refusal:s})))}return t}var xe=e=>`${e.refusal.reason}|${e.refusal.name??""}|${(e.rule??"").replace(/\s+/g,"")}`;function q(e,t={}){let r=t.already===void 0?new Set:new Set($e(t.already).map(xe)),n=new Set;for(let a of $e(e))r.has(xe(a))||n.add(tt(a));return[...n]}var _e=/\b\d{4}-\d{2}-\d{2}(?:T[\d:.]+Z?)?\b/,Re=/<\/?[a-z][a-z0-9-]*(?:\s[^<>]*)?>/i,st=/(?<![\w])(undefined|null|NaN|\[object Object\]|true|false)(?![\w])/g,at=["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"],B=/\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*\.?\s+(\d{1,2})\b|\b(\d{1,2})\s+(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*\b/,Ae=/\b(mon|tue|wed|thu|fri|sat|sun)[a-z]*\b|\b(today|tomorrow|yesterday)\b/;function ke(e,t){let r=u(e),n=u(t);if(!n||r.includes(n))return!0;let a=i=>i.replace(/[^\p{L}\p{N}]+/gu,"");if(a(n).length>=3&&a(r).includes(a(n)))return!0;let o=B.exec(n);if(o){let i=o[1]??o[4],c=Number(o[2]??o[3]);for(let l of r.matchAll(new RegExp(B.source,"g")))if((l[1]??l[4])===i&&Number(l[2]??l[3])===c)return!0;return at.every(l=>!r.includes(l))&&Ae.test(r)}let s=/^\D*(\d+(?:[.,]\d+)?)\D*$/.exec(n);if(s){if(new RegExp(`(^|\\D)${s[1].replace(/[.,]/g,"[.,]")}(\\D|$)`).test(r))return!0;let i=Number(s[1]);return i===0?/\b(no|none|zero|nothing|not any)\b/.test(r):Number.isInteger(i)&&i<J.length&&new RegExp(`\\b${J[i]}\\b`).test(r)}return!1}var ot=/\b(hide|hides|hiding|remove|drop|without|no more|less|fewer|only|just|minimal|simpler|declutter|strip)\b/i,De=/\b(group|groups|grouped|regroup|section|sections|categor\w*|split|move|moved|bucket\w*|by (status|date|day|list|owner|person))\b/i;function it(e,t){if(!e||!ot.test(e))return!1;let r=e.toLowerCase();return/\b(only|just)\b[^.]*\b(name|names|title|titles|label|labels)\b/.test(r)?!0:B.test(u(t))||Ae.test(u(t))?/\b(date|dates|due|day|days|when|deadline|deadlines)\b/.test(r):/^\D*\d/.test(t)?/\b(count|counts|number|numbers|how many|total|totals)\b/.test(r):/\b(status|statuses|state|tag|tags|chip|chips|badge|badges|label|labels|pill|pills|meta|details)\b/.test(r)||r.includes(u(t))}var dt=/\b(re-?word\w*|re-?name\w*|re-?title\w*|re-?phrase\w*|rewrite|shorten|shorter|longer|wording|words|call it|say|says)\b/i,lt=/\b(heading|headings|title|titles|header|headers|headline|headlines)\b/i;function M(e){return!!(e&&dt.test(e)&<.test(e))}function be(e,t){let r=new Map;if(e.length!==t.length)return r;let n=new Set(e.map(u)),a=new Set(t.map(u));return e.forEach((o,s)=>{let i=t[s];u(o)!==u(i)&&!a.has(u(o))&&!n.has(u(i))&&r.set(o,i)}),r}function ve(e,t,r,n){if(!M(n.asked))return[...e];let a=be(t,r),o=s=>!n.mayReword||n.mayReword.some(i=>u(i)===u(s));return e.filter(s=>!(a.has(s)&&o(s)))}function D(e){return/^Edit \d+: “|^There is no script to edit|^Your edits change nothing/.test(e)?"edit-missed":/no longer says what it said/.test(e)?"fact-lost":/^It no longer shows “/.test(e)?"record-lost":/more often than the page did/.test(e)?"record-twice":/moved to another group/.test(e)?"record-moved":/no longer shows the heading/.test(e)?"heading-lost":/” is not drawn any more\.?$/.test(e)?"section-lost":/drawn twice/.test(e)?"title-twice":/markup as words|a date as “|as the computer keeps it|a field's name/.test(e)?"computer-words":/is still drawn and no rule styles it/.test(e)?"unstyled":/can no longer be marked|no longer opens? (its|their) page/.test(e)?"control":/did not draw|did not start|threw while drawing|could not start/.test(e)?"did-not-draw":/not allowed|is removed|reaches outside/.test(e)?"style-refused":"other"}var N=e=>e.map(t=>({kind:D(t),words:t}));function Je(e,t,r={}){let n=[],a=u(t.text),o=e.records.map(d=>d.label).filter(d=>d&&!a.includes(u(d)));o.length>0&&n.push(`It no longer shows ${o.slice(0,4).map(d=>`\u201C${d}\u201D`).join(", ")}${o.length>4?` and ${o.length-4} more`:""}: show every record the page showed.`);let s=(d,p)=>d.split(u(p)).length-1,i=u(e.text),c=e.records.map(d=>d.label).filter(d=>d&&s(a,d)>s(i,d));c.length>0&&!(r.asked&&De.test(r.asked))&&n.push(`It shows ${c.slice(0,4).map(d=>`\u201C${d}\u201D`).join(", ")}${c.length>4?` and ${c.length-4} more`:""} more often than the page did: show each record where the page showed it, and nowhere else.`);let l=[],g=[];for(let d of e.records){let p=t.records.find(b=>u(b.label)===u(d.label));if(!p)continue;let w=`${p.row??""} ${p.under??""}`;for(let b of d.facts??[])!ke(w,b)&&!it(r.asked,b)&&l.push(`\u201C${b}\u201D on \u201C${d.label}\u201D`);d.under&&p.under&&u(d.under)!==u(p.under)&&t.headings.some(b=>u(b)===u(d.under))&&!(r.asked&&De.test(r.asked))&&g.push(`\u201C${d.label}\u201D is under \u201C${p.under}\u201D, and was under \u201C${d.under}\u201D`)}l.length>0&&n.push(`A record no longer says what it said: ${l.slice(0,4).join(", ")}${l.length>4?` and ${l.length-4} more`:""}. Show on each record what the page showed on it (its status, its dates, its counts), in words.`),g.length>0&&n.push(`A record moved to another group: ${g.slice(0,3).join("; ")}${g.length>3?` and ${g.length-3} more`:""}. Keep each record under the heading it was under.`);let m=ve(e.headings.filter(d=>d&&!a.includes(u(d))),e.headings,t.headings,r);m.length>0&&n.push(`It no longer shows the heading${m.length>1?"s":""} ${m.map(d=>`\u201C${d}\u201D`).join(", ")}: keep each heading the page had.`);let y=new Map;for(let d of t.headings)d.trim()&&y.set(u(d),(y.get(u(d))??0)+1);let h=[...y].filter(([,d])=>d>1).map(([d])=>t.headings.find(p=>u(p)===d)),k=e.headings.filter(d=>!h.some(p=>u(p)===u(d)));h.length>0&&n.push(`The heading${h.length>1?"s":""} ${h.map(d=>`\u201C${d}\u201D`).join(", ")} ${h.length>1?"are":"is"} drawn twice: the page already draws its title above the view, so leave it out${k.length>0?` \u2014 and keep every other heading as it was: ${k.map(d=>`\u201C${d}\u201D`).join(", ")}`:""}.`);let v=Re.exec(t.text);v&&!Re.test(e.text)&&n.push(`It shows its own markup as words (\u201C${v[0].slice(0,40)}\u201D): build it with graview.html\`\u2026\`, nesting graview.html for each list, never a string of HTML.`);let f=_e.exec(t.text);f&&!_e.test(e.text)&&n.push(`It shows a date as \u201C${f[0]}\u201D: say dates in words, as the page did (\u201CSep 3\u201D).`);let $=Object.values(r.values??{}).flat().filter(d=>typeof d=="string").join(`
|
|
8
|
+
`),T=[...t.text.matchAll(st)].map(d=>d[1]).find(d=>{let p=new RegExp(`(^|[^\\w])${d.replace(/[[\]]/g,"\\$&")}([^\\w]|$)`);return!p.test(e.text)&&(d==="[object Object]"||!p.test($))});T&&n.push(`It shows \u201C${T}\u201D, which is a value as the computer keeps it, not words for a person: say it in words or leave it out.`);let A=d=>d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");for(let d of r.fields??[]){if(d.length<3||["label","name","title"].includes(d))continue;let p=(r.values?.[d]??[]).map(b=>A(String(b))).filter(b=>b.length>0&&b.length<=40),w=/[A-Z]/.test(d)?new RegExp(`\\b${d}\\b`):r.values?p.length>0?new RegExp(`(?:^|[^\\w])${d}(?:\\s*[:=]\\s*|\\s+)(?:${p.join("|")})(?![\\w])`):void 0:new RegExp(`(?:^|[^\\w])${d}\\s*[:=]\\s*(?:\\d|true\\b|false\\b|null\\b|undefined\\b)`);if(w&&w.test(t.text)&&!w.test(e.text)){n.push(`It shows \u201C${d}\u201D, a field's name, not words for a person: say what it means, or leave it out.`);break}}return n}function Te(e){let t=new Map;for(let r of e){let n=[...t.keys()].find(a=>Math.abs(a-r.top)<=6)??r.top;t.set(n,(t.get(n)??0)+1)}return Math.max(0,...t.values())}function Be(e,t,r){let n=[],a=Te(t.records),o=Te(r.records);o>1&&o!==a?n.push(`side by side, ${J[o]??o} to a line`):o===1&&a>1&&n.push("one under another");let s=h=>h.length?h.reduce((k,v)=>k+v.size,0)/h.length:0,i=s(t.records)>0?s(r.records)/s(t.records):1;i>=1.12?n.push("in bigger type"):i<=.89&&n.push("in smaller type");let c=(h,k)=>h.map(v=>u(v.label)).filter(v=>k.has(v)),l=new Set(t.records.map(h=>u(h.label)).filter(h=>r.records.some(k=>u(k.label)===h)));c(t.records,l).join("|")!==c(r.records,l).join("|")&&n.push("in a new order");let g=new Set(t.records.map(h=>u(h.label))),m=r.headings.filter(h=>h.trim()&&!t.headings.some(k=>u(k)===u(h))&&u(h)!==u(e)&&!g.has(u(h)));if(m.length>0&&n.push(`under ${m.length===1?"a new heading":"new headings"}: ${m.slice(0,3).map(h=>`\u201C${h}\u201D`).join(", ")}`),n.length===0)return;let y=/s$/i.test(e.trim());return`${e} now ${y?"show":"shows"} ${n.length===1?n[0]:`${n.slice(0,-1).join(", ")} and ${n.at(-1)}`}.`}var R=(e,t)=>new RegExp(`\\s${t}="([^"]*)"`).exec(e)?.[1];function Ue(e,t,r,n="record"){let a=e.problems.slice(0,5).map(l=>`${l.control}: ${l.says}`),o=l=>e.controls.some(g=>g.ok&&g.does==="act"&&R(g.element,"data-record")===l&&r.includes(R(g.element,"data-act")??"")),s=l=>e.controls.some(g=>g.ok&&g.does==="link"&&R(g.element,"data-record")===l),i=r.length>0?t.filter(l=>l.presses&&!o(l.id)):[];i.length>0&&a.push(`${i.slice(0,3).map(l=>`\u201C${l.label}\u201D`).join(", ")}${i.length>3?` and ${i.length-3} more`:""} can no longer be marked as the page let a person mark ${i.length===1?"it":"them"}: give each ${n} a press bound to ${r.map(l=>`\u201C${l}\u201D`).join(" or ")}, e.g. <button data-act="${r[0]}" data-record="${i[0].id}">\u2026</button>.`);let c=t.filter(l=>l.opens&&!s(l.id));return c.length>0&&a.push(`${c.slice(0,3).map(l=>`\u201C${l.label}\u201D`).join(", ")}${c.length>3?` and ${c.length-3} more`:""} no longer ${c.length===1?"opens its":"open their"} page: link each with data-record="its id".`),a}function Ze(e,t,r="records"){let n=[];for(let o of t){let s=new Set(e.controls.filter(i=>i.ok&&i.does==="act"&&R(i.element,"data-act")===o.act).map(i=>R(i.element,"data-record")??i.control));s.size>0&&n.push(`${o.title.replace(/[.…]+$/,"")} works on ${s.size===1?"one of the":`${s.size}`} ${r}`)}let a=new Set(e.controls.filter(o=>o.ok&&o.does==="link"&&R(o.element,"data-record")).map(o=>R(o.element,"data-record")));if(a.size>0&&n.push(`${a.size} open${a.size===1?"s its":" their"} page${a.size===1?"":"s"}`),n.length!==0)return`Pressing each control checked it: ${n.length<2?n[0]:`${n.slice(0,-1).join(", ")} and ${n.at(-1)}`}.`}var Qe=/\b(check ?box(es)?|button|click|tap|press|toggle|mark(ed|s|ing)?|complet(e|ed|ing)|finish(ed|es|ing)?|persist|sav(e|es|ed|ing)|updat(e|es|ed|ing)|works?|working|data)\b/i,Xe=/\b(does(n'?t| not)|did(n'?t| not)|can'?t|cannot|won'?t|not)\s+(work|working|persist|save|stick|change|update|do anything|mark|finish|complete|click|press)|\bfake\b|\bbroken\b|\bstill (broken|not)\b/i;var I=L(Oe(),1),U=L(Q(),1);function ct(e){let t=null;for(let r of e){if(!r.isConnected)continue;let n=r.getBoundingClientRect();n.width===0&&n.height===0||(t=t?{left:Math.min(t.left,n.left),top:Math.min(t.top,n.top),right:Math.max(t.right,n.right),bottom:Math.max(t.bottom,n.bottom)}:{left:n.left,top:n.top,right:n.right,bottom:n.bottom})}return t?new DOMRect(t.left,t.top,t.right-t.left,t.bottom-t.top):null}function Ft({elements:e,label:t}){let r=(0,I.useRef)(null);return(0,I.useEffect)(()=>{let n=0,a=()=>{let o=ct(e),s=r.current;s&&(s.style.display=o?"block":"none",o&&(s.style.left=`${Math.round(o.left-3)}px`,s.style.top=`${Math.round(o.top-3)}px`,s.style.width=`${Math.round(o.width+6)}px`,s.style.height=`${Math.round(o.height+6)}px`)),n=requestAnimationFrame(a)};return a(),()=>cancelAnimationFrame(n)},[e]),(0,U.jsx)("div",{ref:r,"aria-hidden":"true","data-testid":"section-outline",style:gt,children:t?(0,U.jsx)("span",{style:ut,children:t}):null})}var gt={position:"fixed",display:"none",boxSizing:"border-box",border:"2px dashed var(--graview-accent)",borderRadius:8,pointerEvents:"none",zIndex:Z("popover")},ut={position:"absolute",top:-11,left:8,padding:"0 6px",fontSize:"0.6875rem",lineHeight:"18px",borderRadius:999,color:"var(--graview-accent-ink, #fff)",background:"var(--graview-accent)"};export{ht as a,ft as b,pt as c,yt as d,ve as e,Je as f,Be as g,Ue as h,Ze as i,Qe as j,Xe as k,Ie as l,Le as m,ze as n,Fe as o,He as p,qe as q,ct as r,Ft as s};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as Z}from"./chunk.JO2X52D4.js";import{a as K,b as J,d as X,e as Y,f as H,g as D,h as Q,i as W}from"./chunk.M5FP4Y4Q.js";import{Oc as z,Pc as G,Qc as j}from"./chunk.ZEZUKRC6.js";import"./chunk.FQLNBIQ5.js";import"./chunk.AJZBJBMO.js";var le={r:255,g:255,b:255,a:1},ue={r:18,g:18,b:18,a:1},M=t=>t.parentElement??t.getRootNode().host??null,C;function B(t,i){if(t==="transparent")return{r:0,g:0,b:0,a:0};let[a]=z(t);if(a)return a;if(C===void 0&&(C=i.createElement("canvas").getContext("2d",{willReadFrequently:!0})),!C)return;C.clearRect(0,0,1,1),C.fillStyle="#000",C.fillStyle=t,C.fillRect(0,0,1,1);let[n,c,r,u]=C.getImageData(0,0,1,1).data;return{r:n,g:c,b:r,a:u/255}}function ee(t){let i=t.ownerDocument,a=i.defaultView,n=[];for(let r=t;r;r=M(r)){let u=a.getComputedStyle(r);if(u.backgroundImage&&u.backgroundImage!=="none")return;let f=B(u.backgroundColor,i);if(!f)return;if(f.a>0&&n.push(f),f.a>=1)break}let c=a.getComputedStyle(i.documentElement).colorScheme.includes("dark")&&a.matchMedia?.("(prefers-color-scheme: dark)").matches;return n.reverse().reduce((r,u)=>G(u,r),c?ue:le)}var te=t=>`${Math.floor(t*100)/100}:1`;function ae(t,i){let a={},n=s=>a[s]=(a[s]??0)+1,c=t.filter(s=>typeof s.getBoundingClientRect=="function"),r=c[0];if(!r)return{unmeasured:a,measured:{contrast:0,"focus-visible":0}};let u=r.ownerDocument,f=u.defaultView,p=s=>{let N=s.getBoundingClientRect();return N.width>1&&N.height>1},l=0;for(let s of c){if(l>=i.limit)break;if(!Array.from(s.childNodes).some(d=>d.nodeType===3&&(d.textContent??"").trim()!=="")||s.namespaceURI!=="http://www.w3.org/1999/xhtml"||s.hasAttribute("disabled")||s.getAttribute("aria-disabled")==="true")continue;let E=f.getComputedStyle(s);if(E.visibility!=="visible"||E.display==="none"||!p(s))continue;l+=1;let m=B(E.color,u),x=ee(s);if(!m||!x){n("contrast");continue}let v=j(G(m,x),x),$=Number.parseFloat(E.fontSize),O=Number.parseInt(E.fontWeight,10),e=$>=24||$>=18.66&&O>=700,o=e?3:4.5;v+.005<o&&i.say("contrast",s,"serious",`Its words are at ${te(v)} against their ground; ${o}:1 is the least ${e?"large ":""}text may be.`,"Give it a color further from its ground: --graview-ink and --graview-ink-muted are held to the app's grounds.")}let w=u.activeElement,S=0;for(let s of c){if(S>=i.limit)break;if(!i.tabbable(s)||!p(s))continue;if(S+=1,s.focus({preventScroll:!0,focusVisible:!0}),s.getRootNode().activeElement!==s||!s.matches(":focus-visible")){n("focus-visible");continue}let m=f.getComputedStyle(s),x=Number.parseFloat(m.outlineWidth)||0,v=!1;for(let o=s;o;o=M(o))o.hasAttribute("data-graview-view-root")&&(v=!0);if(m.outlineStyle==="auto"){n("focus-visible");continue}if(m.outlineStyle==="none"||x===0){m.boxShadow&&m.boxShadow!=="none"?n("focus-visible"):i.say("focus-visible",s,"serious","It shows no ring when it has the keyboard: a person cannot see where they are.","Leave the outline on :focus-visible (in a view the host draws it; restyle it with --graview-focus-color).","2.4.7",v);continue}if(x+.01<2){i.say("focus-visible",s,"serious",`Its ring is ${x}px: at least 2px is seen.`,"Give the outline 2px or more (--graview-focus-width in a view).","2.4.7",v);continue}let $=B(m.outlineColor,u),O=M(s)?ee(M(s)):void 0;if(!$||!O){n("focus-visible");continue}let e=j(G($,O),O);e+.005<3&&i.say("focus-visible",s,"serious",`Its ring is at ${te(e)} against what is around it; 3:1 is the least a ring may be.`,"Give the ring a color at 3:1 against the ground (--graview-focus-color in a view; the app's accent is held to it).","1.4.11",v)}S>0&&(u.activeElement?.blur?.(),w&&w!==u.body&&w.focus?.({preventScroll:!0}));for(let s of c){let N=f.getComputedStyle(s);if(!(/(auto|scroll)/.test(N.overflowX)||/(auto|scroll)/.test(N.overflowY)))continue;let m=s;(m.scrollHeight>m.clientHeight+1||m.scrollWidth>m.clientWidth+1)&&i.scrollsOnPage(s)}return{unmeasured:a,measured:{contrast:l,"focus-visible":S}}}var q={keyboard:{wcag:"2.1.1",says:"What a person can click is reached by the keyboard.",needs:"structure"},role:{wcag:"4.1.2",says:"What takes the keyboard says what it is.",needs:"structure"},name:{wcag:"4.1.2",says:"Every control and link has a name.",needs:"structure"},"toggle-state":{wcag:"4.1.2",says:"A toggle says whether it is on, open or chosen.",needs:"structure"},"nested-interactive":{wcag:"4.1.2",says:"No control or link is inside another.",needs:"structure"},"img-alt":{wcag:"1.1.1",says:'Every image says what it shows, or says it is decoration (alt="").',needs:"structure"},"svg-name":{wcag:"1.1.1",says:'A picture drawn in SVG that means something is role="img" with a name; one that does not is hidden.',needs:"structure"},"scroll-region":{wcag:"2.1.1",says:"A box that scrolls by itself takes the keyboard and has a name.",needs:"structure"},"focus-visible":{wcag:"2.4.7",says:"Whatever has the keyboard shows a ring at least 2px wide, at 3:1 against its ground.",needs:"layout"},contrast:{wcag:"1.4.3",says:"Text is at 4.5:1 against its ground, 3:1 when large.",needs:"layout"},"keyboard-trap":{wcag:"2.1.2",says:"Tab leaves the view: the keyboard is never held inside it.",needs:"keys"}};var se="http://www.w3.org/1999/xhtml",U="http://www.w3.org/2000/svg",b=(t,...i)=>t.namespaceURI===se&&i.includes(t.localName),oe=t=>t.nodeType===1,T=t=>Array.from(t.childNodes).filter(oe),de=new Set(["button","link","checkbox","switch","radio","tab","menuitem","menuitemcheckbox","menuitemradio","option","slider","spinbutton","textbox","searchbox","combobox","treeitem"]),ce=new Set(["button","link","checkbox","switch","radio","tab","menuitem","menuitemcheckbox","menuitemradio","option","img","slider","progressbar","scrollbar","separator"]),he={checkbox:"aria-checked",switch:"aria-checked",radio:"aria-checked",menuitemcheckbox:"aria-checked",menuitemradio:"aria-checked",tab:"aria-selected",option:"aria-selected"},ie=new Set(["true","false","mixed"]),be=/^(show|hide|expand|collapse)?\s*(more|less|all|details|everything)?$/i;function I(t){let i=[],a=n=>{for(let c of T(n))i.push(c),a(c)};return a(t),i}function ne(t){for(let i=t;i;i=i.parentElement)if(i.getAttribute("aria-hidden")==="true"||i.hasAttribute("hidden"))return!0;return!1}var P=t=>t.getAttribute("role")?.trim().split(/\s+/)[0]?.toLowerCase()??null,fe=t=>{let i=t.getAttribute("tabindex");if(i===null)return;let a=Number.parseInt(i,10);return Number.isNaN(a)?void 0:a},me=t=>t.hasAttribute("disabled")||t.getAttribute("aria-disabled")==="true",R=t=>b(t,"input")&&(t.getAttribute("type")??"").toLowerCase()==="hidden"||b(t,"button","input","select","textarea")&&t.hasAttribute("disabled")?!1:H(t)&&(fe(t)??0)>=0,F=t=>b(t,"button","select","textarea","summary")||b(t,"input")&&(t.getAttribute("type")??"").toLowerCase()!=="hidden"||t.localName==="a"&&t.hasAttribute("href"),re=t=>F(t)||t.hasAttribute("data-graview-link")||t.hasAttribute("data-graview-press")?!0:de.has(P(t)??""),ge=t=>t.hasAttribute("role")||!D(t);function Ae(t){let i=[],a=n=>JSON.stringify(n);for(let n=t;n&&!n.hasAttribute("data-graview-view-root");n=n.parentElement){let c=n.getAttribute("data-key");if(c!==null){i.unshift(`[data-key=${a(c)}]`);break}let r=n.getAttribute("id");if(r){i.unshift(`[id=${a(r)}]`);break}let u=n.getAttribute("class")?.trim().split(/\s+/)[0],f=`${n.localName}${u?`.${u}`:""}`,p=n.parentElement;if(p){let l=T(p).filter(w=>w.localName===n.localName);l.length>1&&(f+=`:nth-of-type(${l.indexOf(n)+1})`)}i.unshift(f)}return i.join(" > ")}var ye=t=>{for(let i=t;i;i=i.parentElement){let a=i.getAttribute("data-key");if(a!==null)return a}};function k(t){if(t.nodeType===3)return t.textContent??"";if(!oe(t)||t.getAttribute("aria-hidden")==="true"||t.hasAttribute("hidden"))return"";let i=t.getAttribute("aria-label")?.trim();if(i)return` ${i} `;if(t.localName==="img")return` ${t.getAttribute("alt")??""} `;if(t.namespaceURI===U&&t.localName==="svg"){let a=T(t).find(n=>n.localName==="title");return a?` ${k(a)} `:""}return b(t,"input","select","textarea")?"":Array.from(t.childNodes).map(k).join("")}var A=t=>t.replace(/\s+/g," ").trim();function we(t,i,a){let n=t.getAttribute("aria-labelledby");if(n){let r=A(n.split(/\s+/).map(u=>i.get(u)?k(i.get(u)):"").join(" "));if(r)return r}let c=A(t.getAttribute("aria-label")??"");if(c)return c;if(b(t,"input","select","textarea")){let r=(t.getAttribute("type")??"").toLowerCase();if(b(t,"input")&&["submit","reset","button"].includes(r))return A(t.getAttribute("value")??(r==="submit"?"Submit":r==="reset"?"Reset":""));if(b(t,"input")&&r==="image")return A(t.getAttribute("alt")??"");let u=t.getAttribute("id"),f=u?a.find(l=>l.getAttribute("for")===u):void 0;if(f&&A(k(f)))return A(k(f));for(let l=t.parentElement;l;l=l.parentElement)if(b(l,"label")&&A(k(l)))return A(k(l));let p=A(t.getAttribute("placeholder")??"");return p||A(t.getAttribute("title")??"")}return t.localName==="img"?A(t.getAttribute("alt")??t.getAttribute("title")??""):A(k(t))||A(t.getAttribute("title")??"")}function pe(t){let i=I(t);for(let a of i){let n=I(a).some(K);if(!Q(a,n)||(a.setAttribute("data-graview-link",""),W(a,I(a))))continue;let c=a.localName==="a";if(!a.hasAttribute("role")&&(c||D(a))&&a.setAttribute("role","link"),b(a,"tr")){let r=T(a).find(u=>u.localName==="td"||u.localName==="th");r&&!r.hasAttribute("tabindex")&&r.setAttribute("tabindex","0");continue}!b(a,"button")&&!a.hasAttribute("tabindex")&&a.setAttribute("tabindex","0")}for(let a of i){let n=X(a)&&!J(a)&&!b(a,"input","select","textarea"),c=!n&&Y(a);!n&&!c||(H(a)||a.setAttribute("tabindex","0"),n&&D(a)&&a.setAttribute("role","button"),a.setAttribute("data-graview-press",""))}for(let a of i.filter(n=>n.namespaceURI===U&&n.localName==="svg")){let n=a.hasAttribute("role")||a.hasAttribute("aria-label")||a.hasAttribute("aria-labelledby")||T(a).some(r=>r.localName==="title"),c=[a,...I(a)].some(r=>r.hasAttribute("tabindex")||r.hasAttribute("data-graview-link")||r.hasAttribute("data-graview-press")||r.localName==="a");!n&&!c&&!a.hasAttribute("aria-hidden")&&a.setAttribute("aria-hidden","true")}}function ve(t,i){let a=t;return typeof a.querySelectorAll!="function"?[]:i.flatMap(n=>{try{return Array.from(a.querySelectorAll(n))}catch{return[]}})}function _(t){for(let i of T(t)){if(R(i)||_(i))return!0;let a=i.shadowRoot;if(a&&_(a))return!0}return!1}function ke(t){let i=t.ownerDocument?.defaultView;if(!i||typeof i.getComputedStyle!="function")return!1;let n=(t.host??t).getBoundingClientRect?.();return!!(n&&(n.width>0||n.height>0))}function Oe(t,i={}){i.host==="pending"&&pe(t);let a=I(t),n=new Map(a.flatMap(e=>e.getAttribute("id")?[[e.getAttribute("id"),e]]:[])),c=a.filter(e=>b(e,"label")),r=i.clicked?Array.from(i.clicked):[...Z(t)??[]],u=new Set([...r.filter(e=>typeof e=="object"),...ve(t,r.filter(e=>typeof e=="string"))]),f=i.chrome===!0,p=[],l=(e,o,d,g,h,y=!1,L=q[e].wcag)=>{let V=ye(o);p.push({rule:e,wcag:L,impact:d,at:Ae(o),...V!==void 0?{key:V}:{},says:g,fix:h,automatic:y||f})},w=a.filter(e=>!ne(e)),S=e=>we(e,n,c)!=="",s=new Set(w.filter(e=>e.hasAttribute("data-graview-link")&&W(e,I(e))));for(let e of w){if(me(e))continue;let o=e.hasAttribute("data-graview-link"),d=e.hasAttribute("data-graview-press"),g=u.has(e);if(!o&&!d&&!g||F(e)&&R(e)||s.has(e)&&!g||b(e,"tr")&&T(e).some(y=>(y.localName==="td"||y.localName==="th")&&R(y)))continue;if(!(R(e)||g&&I(e).some(y=>R(y)&&(F(y)||y.hasAttribute("data-graview-press")||y.hasAttribute("data-graview-link"))))){o||d?l("keyboard",e,"serious","It is a link or a press the host makes, and Tab does not reach it.","The host gives it the keyboard when it draws the view; audit the view as the host drew it.",!0):l("keyboard",e,"serious",`A <${e.localName}> the view hears a click on, which Tab does not reach: a mouse can press it and a keyboard cannot.`,'Draw it as a <button type="button"> (the host resets its look), or give it role="button" and the host gives it the keyboard, Enter and Space.');continue}R(e)&&!ge(e)&&!(e.localName==="a"&&e.hasAttribute("href"))&&l("role",e,"serious",`A <${e.localName}> that takes the keyboard says nothing of what it is: a screen reader says "group" or nothing.`,'Draw it as a <button type="button">, or give it role="button" (or role="link" when it goes somewhere).',o||d)}for(let e of w){if(!re(e)||s.has(e)||S(e))continue;let o=P(e),d=b(e,"button")||o==="button"||e.hasAttribute("data-graview-press"),g=b(e,"input","select","textarea")||["textbox","searchbox","combobox","slider","spinbutton"].includes(o??""),h=g?"field":d?"button":e.hasAttribute("data-graview-link")||e.localName==="a"||o==="link"?"link":"control";l("name",e,d||g?"critical":"serious",`A ${h} with no name: a screen reader says only "${h}".`,g?'Give it a <label for> or aria-label="\u2026".':'Put words in it \u2014 a .graview-sr span when it shows only an icon \u2014 or aria-label="\u2026".')}for(let e of w){let o=P(e),d=o&&!b(e,"input")?he[o]:void 0;if(d&&!e.hasAttribute(d)){l("toggle-state",e,"serious",`It is role="${o}" and says no ${d}: a screen reader cannot say whether it is ${d==="aria-checked"?"on":"chosen"}.`,`Give it ${d}="true" or "false", and draw it again as it changes.`);continue}for(let[h,y]of[["aria-checked",ie],["aria-pressed",ie],["aria-expanded",new Set(["true","false"])],["aria-selected",new Set(["true","false"])]]){let L=e.getAttribute(h);L!==null&&!y.has(L)&&l("toggle-state",e,"serious",`${h}="${L}" is no state a screen reader can say.`,`Give ${h} "true" or "false"${y.has("mixed")?' (or "mixed")':""}.`)}!(b(e,"button")||o==="button"||e.hasAttribute("data-graview-press"))||e.hasAttribute("aria-expanded")||e.hasAttribute("aria-pressed")||(e.hasAttribute("aria-controls")?l("toggle-state",e,"serious","A button that says what it controls (aria-controls) and not whether that is open.",'Give it aria-expanded="true" or "false", and draw it again as it opens and closes.'):u.has(e)&&A(k(e))!==""&&be.test(A(k(e)))&&l("toggle-state",e,"moderate",`A button the view hears that reads "${A(k(e))}" \u2014 it opens and closes something \u2014 and says no state.`,'Give it aria-expanded="true" or "false" (or aria-pressed for a toggle), and draw it again as it changes.'))}for(let e of w){let o=P(e)??(b(e,"button")?"button":e.localName==="a"&&e.hasAttribute("href")?"link":null);if(!o||!ce.has(o)||o==="img")continue;let d=I(e).find(h=>!ne(h)&&(R(h)||re(h)));if(!d)continue;let g=e.hasAttribute("data-graview-link")&&!b(e,"a");l("nested-interactive",e,"serious",`A ${o} holds a <${d.localName}> a person presses on its own: a screen reader reads the ${o} as one thing and never reaches what is inside.`,g?"Put an <a> to the card's own record or place on its heading: the card is then a bigger target for a pointer, and the <a> the keyboard's way in.":`Move the <${d.localName}> out of the ${o}, beside it.`)}for(let e of w){if(e.localName==="img"&&e.namespaceURI===se){if(e.hasAttribute("alt")||e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby")||["none","presentation"].includes(P(e)??""))continue;l("img-alt",e,"critical","An image with no alt: a screen reader reads its address, or nothing.",'Give it alt="what it shows", or alt="" when it is decoration.');continue}if(e.namespaceURI!==U||e.localName!=="svg"||e.parentElement?.namespaceURI===U||[e,...I(e)].some(h=>R(h)||h.hasAttribute("data-graview-link")||h.hasAttribute("data-graview-press")||h.localName==="a"))continue;let d=P(e);if(d==="none"||d==="presentation")continue;let g=S(e)&&(e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby")||T(e).some(h=>h.localName==="title"));!d&&!g?l("svg-name",e,"minor","An SVG that says nothing, which a screen reader still meets.","The host hides an SVG that says nothing when it draws the view.",!0):d!=="img"&&d!=="graphics-document"?l("svg-name",e,"minor","An SVG with a name and no role: some screen readers skip it.",'Give it role="img" beside its aria-label.'):g||l("svg-name",e,"serious",'An SVG that is role="img" with no name: a screen reader says "image" and nothing more.','Give it aria-label="what it shows", or a <title> first inside it.')}let N=e=>/overflow(-[xy])?\s*:\s*(auto|scroll)/i.test(e.getAttribute("style")??""),E=e=>{R(e)&&S(e)||_(e)||l("scroll-region",e,"serious","A box that scrolls by itself and holds nothing Tab reaches: the keyboard cannot scroll it, and what is past its edge is out of reach.",'Give it tabindex="0", role="region" and aria-label="what it holds", or let it flow with the page.')},m=i.measure!==!1&&ke(t);if(!m)for(let e of w)N(e)&&E(e);let x=["keyboard","role","name","toggle-state","nested-interactive","img-alt","svg-name","scroll-region"],v=[],$={},O={};if(m){let e=ae(w,{limit:i.limit??400,tabbable:R,scrollsOnPage:E,say:(o,d,g,h,y,L,V)=>l(o,d,g,h,y,V===!0,L)});x.push("focus-visible","contrast"),Object.assign($,e.unmeasured),Object.assign(O,e.measured)}else{let e=i.measure===!1?"Asked not to measure.":"Nothing here is laid out (a headless run, or a DOM with no layout): it needs a browser's styles and boxes.";v.push({rule:"focus-visible",why:e},{rule:"contrast",why:e})}return v.push({rule:"keyboard-trap",why:"It needs keys pressed in a browser: a harness's Tab walk presses them (pnpm verify a11y)."}),{problems:p,ran:x,skipped:v,unmeasured:$,measured:O}}export{q as AUDIT_RULES,Oe as auditView,pe as markAsTheHost};
|
|
1
|
+
import{b as Z}from"./chunk.JO2X52D4.js";import{a as K,b as J,d as X,e as Y,f as H,g as D,h as Q,i as W}from"./chunk.M5FP4Y4Q.js";import{Oc as z,Pc as G,Qc as j}from"./chunk.DHPXRDT5.js";import"./chunk.FQLNBIQ5.js";import"./chunk.AJZBJBMO.js";var le={r:255,g:255,b:255,a:1},ue={r:18,g:18,b:18,a:1},M=t=>t.parentElement??t.getRootNode().host??null,C;function B(t,i){if(t==="transparent")return{r:0,g:0,b:0,a:0};let[a]=z(t);if(a)return a;if(C===void 0&&(C=i.createElement("canvas").getContext("2d",{willReadFrequently:!0})),!C)return;C.clearRect(0,0,1,1),C.fillStyle="#000",C.fillStyle=t,C.fillRect(0,0,1,1);let[n,c,r,u]=C.getImageData(0,0,1,1).data;return{r:n,g:c,b:r,a:u/255}}function ee(t){let i=t.ownerDocument,a=i.defaultView,n=[];for(let r=t;r;r=M(r)){let u=a.getComputedStyle(r);if(u.backgroundImage&&u.backgroundImage!=="none")return;let f=B(u.backgroundColor,i);if(!f)return;if(f.a>0&&n.push(f),f.a>=1)break}let c=a.getComputedStyle(i.documentElement).colorScheme.includes("dark")&&a.matchMedia?.("(prefers-color-scheme: dark)").matches;return n.reverse().reduce((r,u)=>G(u,r),c?ue:le)}var te=t=>`${Math.floor(t*100)/100}:1`;function ae(t,i){let a={},n=s=>a[s]=(a[s]??0)+1,c=t.filter(s=>typeof s.getBoundingClientRect=="function"),r=c[0];if(!r)return{unmeasured:a,measured:{contrast:0,"focus-visible":0}};let u=r.ownerDocument,f=u.defaultView,p=s=>{let N=s.getBoundingClientRect();return N.width>1&&N.height>1},l=0;for(let s of c){if(l>=i.limit)break;if(!Array.from(s.childNodes).some(d=>d.nodeType===3&&(d.textContent??"").trim()!=="")||s.namespaceURI!=="http://www.w3.org/1999/xhtml"||s.hasAttribute("disabled")||s.getAttribute("aria-disabled")==="true")continue;let E=f.getComputedStyle(s);if(E.visibility!=="visible"||E.display==="none"||!p(s))continue;l+=1;let m=B(E.color,u),x=ee(s);if(!m||!x){n("contrast");continue}let v=j(G(m,x),x),$=Number.parseFloat(E.fontSize),O=Number.parseInt(E.fontWeight,10),e=$>=24||$>=18.66&&O>=700,o=e?3:4.5;v+.005<o&&i.say("contrast",s,"serious",`Its words are at ${te(v)} against their ground; ${o}:1 is the least ${e?"large ":""}text may be.`,"Give it a color further from its ground: --graview-ink and --graview-ink-muted are held to the app's grounds.")}let w=u.activeElement,S=0;for(let s of c){if(S>=i.limit)break;if(!i.tabbable(s)||!p(s))continue;if(S+=1,s.focus({preventScroll:!0,focusVisible:!0}),s.getRootNode().activeElement!==s||!s.matches(":focus-visible")){n("focus-visible");continue}let m=f.getComputedStyle(s),x=Number.parseFloat(m.outlineWidth)||0,v=!1;for(let o=s;o;o=M(o))o.hasAttribute("data-graview-view-root")&&(v=!0);if(m.outlineStyle==="auto"){n("focus-visible");continue}if(m.outlineStyle==="none"||x===0){m.boxShadow&&m.boxShadow!=="none"?n("focus-visible"):i.say("focus-visible",s,"serious","It shows no ring when it has the keyboard: a person cannot see where they are.","Leave the outline on :focus-visible (in a view the host draws it; restyle it with --graview-focus-color).","2.4.7",v);continue}if(x+.01<2){i.say("focus-visible",s,"serious",`Its ring is ${x}px: at least 2px is seen.`,"Give the outline 2px or more (--graview-focus-width in a view).","2.4.7",v);continue}let $=B(m.outlineColor,u),O=M(s)?ee(M(s)):void 0;if(!$||!O){n("focus-visible");continue}let e=j(G($,O),O);e+.005<3&&i.say("focus-visible",s,"serious",`Its ring is at ${te(e)} against what is around it; 3:1 is the least a ring may be.`,"Give the ring a color at 3:1 against the ground (--graview-focus-color in a view; the app's accent is held to it).","1.4.11",v)}S>0&&(u.activeElement?.blur?.(),w&&w!==u.body&&w.focus?.({preventScroll:!0}));for(let s of c){let N=f.getComputedStyle(s);if(!(/(auto|scroll)/.test(N.overflowX)||/(auto|scroll)/.test(N.overflowY)))continue;let m=s;(m.scrollHeight>m.clientHeight+1||m.scrollWidth>m.clientWidth+1)&&i.scrollsOnPage(s)}return{unmeasured:a,measured:{contrast:l,"focus-visible":S}}}var q={keyboard:{wcag:"2.1.1",says:"What a person can click is reached by the keyboard.",needs:"structure"},role:{wcag:"4.1.2",says:"What takes the keyboard says what it is.",needs:"structure"},name:{wcag:"4.1.2",says:"Every control and link has a name.",needs:"structure"},"toggle-state":{wcag:"4.1.2",says:"A toggle says whether it is on, open or chosen.",needs:"structure"},"nested-interactive":{wcag:"4.1.2",says:"No control or link is inside another.",needs:"structure"},"img-alt":{wcag:"1.1.1",says:'Every image says what it shows, or says it is decoration (alt="").',needs:"structure"},"svg-name":{wcag:"1.1.1",says:'A picture drawn in SVG that means something is role="img" with a name; one that does not is hidden.',needs:"structure"},"scroll-region":{wcag:"2.1.1",says:"A box that scrolls by itself takes the keyboard and has a name.",needs:"structure"},"focus-visible":{wcag:"2.4.7",says:"Whatever has the keyboard shows a ring at least 2px wide, at 3:1 against its ground.",needs:"layout"},contrast:{wcag:"1.4.3",says:"Text is at 4.5:1 against its ground, 3:1 when large.",needs:"layout"},"keyboard-trap":{wcag:"2.1.2",says:"Tab leaves the view: the keyboard is never held inside it.",needs:"keys"}};var se="http://www.w3.org/1999/xhtml",U="http://www.w3.org/2000/svg",b=(t,...i)=>t.namespaceURI===se&&i.includes(t.localName),oe=t=>t.nodeType===1,T=t=>Array.from(t.childNodes).filter(oe),de=new Set(["button","link","checkbox","switch","radio","tab","menuitem","menuitemcheckbox","menuitemradio","option","slider","spinbutton","textbox","searchbox","combobox","treeitem"]),ce=new Set(["button","link","checkbox","switch","radio","tab","menuitem","menuitemcheckbox","menuitemradio","option","img","slider","progressbar","scrollbar","separator"]),he={checkbox:"aria-checked",switch:"aria-checked",radio:"aria-checked",menuitemcheckbox:"aria-checked",menuitemradio:"aria-checked",tab:"aria-selected",option:"aria-selected"},ie=new Set(["true","false","mixed"]),be=/^(show|hide|expand|collapse)?\s*(more|less|all|details|everything)?$/i;function I(t){let i=[],a=n=>{for(let c of T(n))i.push(c),a(c)};return a(t),i}function ne(t){for(let i=t;i;i=i.parentElement)if(i.getAttribute("aria-hidden")==="true"||i.hasAttribute("hidden"))return!0;return!1}var P=t=>t.getAttribute("role")?.trim().split(/\s+/)[0]?.toLowerCase()??null,fe=t=>{let i=t.getAttribute("tabindex");if(i===null)return;let a=Number.parseInt(i,10);return Number.isNaN(a)?void 0:a},me=t=>t.hasAttribute("disabled")||t.getAttribute("aria-disabled")==="true",R=t=>b(t,"input")&&(t.getAttribute("type")??"").toLowerCase()==="hidden"||b(t,"button","input","select","textarea")&&t.hasAttribute("disabled")?!1:H(t)&&(fe(t)??0)>=0,F=t=>b(t,"button","select","textarea","summary")||b(t,"input")&&(t.getAttribute("type")??"").toLowerCase()!=="hidden"||t.localName==="a"&&t.hasAttribute("href"),re=t=>F(t)||t.hasAttribute("data-graview-link")||t.hasAttribute("data-graview-press")?!0:de.has(P(t)??""),ge=t=>t.hasAttribute("role")||!D(t);function Ae(t){let i=[],a=n=>JSON.stringify(n);for(let n=t;n&&!n.hasAttribute("data-graview-view-root");n=n.parentElement){let c=n.getAttribute("data-key");if(c!==null){i.unshift(`[data-key=${a(c)}]`);break}let r=n.getAttribute("id");if(r){i.unshift(`[id=${a(r)}]`);break}let u=n.getAttribute("class")?.trim().split(/\s+/)[0],f=`${n.localName}${u?`.${u}`:""}`,p=n.parentElement;if(p){let l=T(p).filter(w=>w.localName===n.localName);l.length>1&&(f+=`:nth-of-type(${l.indexOf(n)+1})`)}i.unshift(f)}return i.join(" > ")}var ye=t=>{for(let i=t;i;i=i.parentElement){let a=i.getAttribute("data-key");if(a!==null)return a}};function k(t){if(t.nodeType===3)return t.textContent??"";if(!oe(t)||t.getAttribute("aria-hidden")==="true"||t.hasAttribute("hidden"))return"";let i=t.getAttribute("aria-label")?.trim();if(i)return` ${i} `;if(t.localName==="img")return` ${t.getAttribute("alt")??""} `;if(t.namespaceURI===U&&t.localName==="svg"){let a=T(t).find(n=>n.localName==="title");return a?` ${k(a)} `:""}return b(t,"input","select","textarea")?"":Array.from(t.childNodes).map(k).join("")}var A=t=>t.replace(/\s+/g," ").trim();function we(t,i,a){let n=t.getAttribute("aria-labelledby");if(n){let r=A(n.split(/\s+/).map(u=>i.get(u)?k(i.get(u)):"").join(" "));if(r)return r}let c=A(t.getAttribute("aria-label")??"");if(c)return c;if(b(t,"input","select","textarea")){let r=(t.getAttribute("type")??"").toLowerCase();if(b(t,"input")&&["submit","reset","button"].includes(r))return A(t.getAttribute("value")??(r==="submit"?"Submit":r==="reset"?"Reset":""));if(b(t,"input")&&r==="image")return A(t.getAttribute("alt")??"");let u=t.getAttribute("id"),f=u?a.find(l=>l.getAttribute("for")===u):void 0;if(f&&A(k(f)))return A(k(f));for(let l=t.parentElement;l;l=l.parentElement)if(b(l,"label")&&A(k(l)))return A(k(l));let p=A(t.getAttribute("placeholder")??"");return p||A(t.getAttribute("title")??"")}return t.localName==="img"?A(t.getAttribute("alt")??t.getAttribute("title")??""):A(k(t))||A(t.getAttribute("title")??"")}function pe(t){let i=I(t);for(let a of i){let n=I(a).some(K);if(!Q(a,n)||(a.setAttribute("data-graview-link",""),W(a,I(a))))continue;let c=a.localName==="a";if(!a.hasAttribute("role")&&(c||D(a))&&a.setAttribute("role","link"),b(a,"tr")){let r=T(a).find(u=>u.localName==="td"||u.localName==="th");r&&!r.hasAttribute("tabindex")&&r.setAttribute("tabindex","0");continue}!b(a,"button")&&!a.hasAttribute("tabindex")&&a.setAttribute("tabindex","0")}for(let a of i){let n=X(a)&&!J(a)&&!b(a,"input","select","textarea"),c=!n&&Y(a);!n&&!c||(H(a)||a.setAttribute("tabindex","0"),n&&D(a)&&a.setAttribute("role","button"),a.setAttribute("data-graview-press",""))}for(let a of i.filter(n=>n.namespaceURI===U&&n.localName==="svg")){let n=a.hasAttribute("role")||a.hasAttribute("aria-label")||a.hasAttribute("aria-labelledby")||T(a).some(r=>r.localName==="title"),c=[a,...I(a)].some(r=>r.hasAttribute("tabindex")||r.hasAttribute("data-graview-link")||r.hasAttribute("data-graview-press")||r.localName==="a");!n&&!c&&!a.hasAttribute("aria-hidden")&&a.setAttribute("aria-hidden","true")}}function ve(t,i){let a=t;return typeof a.querySelectorAll!="function"?[]:i.flatMap(n=>{try{return Array.from(a.querySelectorAll(n))}catch{return[]}})}function _(t){for(let i of T(t)){if(R(i)||_(i))return!0;let a=i.shadowRoot;if(a&&_(a))return!0}return!1}function ke(t){let i=t.ownerDocument?.defaultView;if(!i||typeof i.getComputedStyle!="function")return!1;let n=(t.host??t).getBoundingClientRect?.();return!!(n&&(n.width>0||n.height>0))}function Oe(t,i={}){i.host==="pending"&&pe(t);let a=I(t),n=new Map(a.flatMap(e=>e.getAttribute("id")?[[e.getAttribute("id"),e]]:[])),c=a.filter(e=>b(e,"label")),r=i.clicked?Array.from(i.clicked):[...Z(t)??[]],u=new Set([...r.filter(e=>typeof e=="object"),...ve(t,r.filter(e=>typeof e=="string"))]),f=i.chrome===!0,p=[],l=(e,o,d,g,h,y=!1,L=q[e].wcag)=>{let V=ye(o);p.push({rule:e,wcag:L,impact:d,at:Ae(o),...V!==void 0?{key:V}:{},says:g,fix:h,automatic:y||f})},w=a.filter(e=>!ne(e)),S=e=>we(e,n,c)!=="",s=new Set(w.filter(e=>e.hasAttribute("data-graview-link")&&W(e,I(e))));for(let e of w){if(me(e))continue;let o=e.hasAttribute("data-graview-link"),d=e.hasAttribute("data-graview-press"),g=u.has(e);if(!o&&!d&&!g||F(e)&&R(e)||s.has(e)&&!g||b(e,"tr")&&T(e).some(y=>(y.localName==="td"||y.localName==="th")&&R(y)))continue;if(!(R(e)||g&&I(e).some(y=>R(y)&&(F(y)||y.hasAttribute("data-graview-press")||y.hasAttribute("data-graview-link"))))){o||d?l("keyboard",e,"serious","It is a link or a press the host makes, and Tab does not reach it.","The host gives it the keyboard when it draws the view; audit the view as the host drew it.",!0):l("keyboard",e,"serious",`A <${e.localName}> the view hears a click on, which Tab does not reach: a mouse can press it and a keyboard cannot.`,'Draw it as a <button type="button"> (the host resets its look), or give it role="button" and the host gives it the keyboard, Enter and Space.');continue}R(e)&&!ge(e)&&!(e.localName==="a"&&e.hasAttribute("href"))&&l("role",e,"serious",`A <${e.localName}> that takes the keyboard says nothing of what it is: a screen reader says "group" or nothing.`,'Draw it as a <button type="button">, or give it role="button" (or role="link" when it goes somewhere).',o||d)}for(let e of w){if(!re(e)||s.has(e)||S(e))continue;let o=P(e),d=b(e,"button")||o==="button"||e.hasAttribute("data-graview-press"),g=b(e,"input","select","textarea")||["textbox","searchbox","combobox","slider","spinbutton"].includes(o??""),h=g?"field":d?"button":e.hasAttribute("data-graview-link")||e.localName==="a"||o==="link"?"link":"control";l("name",e,d||g?"critical":"serious",`A ${h} with no name: a screen reader says only "${h}".`,g?'Give it a <label for> or aria-label="\u2026".':'Put words in it \u2014 a .graview-sr span when it shows only an icon \u2014 or aria-label="\u2026".')}for(let e of w){let o=P(e),d=o&&!b(e,"input")?he[o]:void 0;if(d&&!e.hasAttribute(d)){l("toggle-state",e,"serious",`It is role="${o}" and says no ${d}: a screen reader cannot say whether it is ${d==="aria-checked"?"on":"chosen"}.`,`Give it ${d}="true" or "false", and draw it again as it changes.`);continue}for(let[h,y]of[["aria-checked",ie],["aria-pressed",ie],["aria-expanded",new Set(["true","false"])],["aria-selected",new Set(["true","false"])]]){let L=e.getAttribute(h);L!==null&&!y.has(L)&&l("toggle-state",e,"serious",`${h}="${L}" is no state a screen reader can say.`,`Give ${h} "true" or "false"${y.has("mixed")?' (or "mixed")':""}.`)}!(b(e,"button")||o==="button"||e.hasAttribute("data-graview-press"))||e.hasAttribute("aria-expanded")||e.hasAttribute("aria-pressed")||(e.hasAttribute("aria-controls")?l("toggle-state",e,"serious","A button that says what it controls (aria-controls) and not whether that is open.",'Give it aria-expanded="true" or "false", and draw it again as it opens and closes.'):u.has(e)&&A(k(e))!==""&&be.test(A(k(e)))&&l("toggle-state",e,"moderate",`A button the view hears that reads "${A(k(e))}" \u2014 it opens and closes something \u2014 and says no state.`,'Give it aria-expanded="true" or "false" (or aria-pressed for a toggle), and draw it again as it changes.'))}for(let e of w){let o=P(e)??(b(e,"button")?"button":e.localName==="a"&&e.hasAttribute("href")?"link":null);if(!o||!ce.has(o)||o==="img")continue;let d=I(e).find(h=>!ne(h)&&(R(h)||re(h)));if(!d)continue;let g=e.hasAttribute("data-graview-link")&&!b(e,"a");l("nested-interactive",e,"serious",`A ${o} holds a <${d.localName}> a person presses on its own: a screen reader reads the ${o} as one thing and never reaches what is inside.`,g?"Put an <a> to the card's own record or place on its heading: the card is then a bigger target for a pointer, and the <a> the keyboard's way in.":`Move the <${d.localName}> out of the ${o}, beside it.`)}for(let e of w){if(e.localName==="img"&&e.namespaceURI===se){if(e.hasAttribute("alt")||e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby")||["none","presentation"].includes(P(e)??""))continue;l("img-alt",e,"critical","An image with no alt: a screen reader reads its address, or nothing.",'Give it alt="what it shows", or alt="" when it is decoration.');continue}if(e.namespaceURI!==U||e.localName!=="svg"||e.parentElement?.namespaceURI===U||[e,...I(e)].some(h=>R(h)||h.hasAttribute("data-graview-link")||h.hasAttribute("data-graview-press")||h.localName==="a"))continue;let d=P(e);if(d==="none"||d==="presentation")continue;let g=S(e)&&(e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby")||T(e).some(h=>h.localName==="title"));!d&&!g?l("svg-name",e,"minor","An SVG that says nothing, which a screen reader still meets.","The host hides an SVG that says nothing when it draws the view.",!0):d!=="img"&&d!=="graphics-document"?l("svg-name",e,"minor","An SVG with a name and no role: some screen readers skip it.",'Give it role="img" beside its aria-label.'):g||l("svg-name",e,"serious",'An SVG that is role="img" with no name: a screen reader says "image" and nothing more.','Give it aria-label="what it shows", or a <title> first inside it.')}let N=e=>/overflow(-[xy])?\s*:\s*(auto|scroll)/i.test(e.getAttribute("style")??""),E=e=>{R(e)&&S(e)||_(e)||l("scroll-region",e,"serious","A box that scrolls by itself and holds nothing Tab reaches: the keyboard cannot scroll it, and what is past its edge is out of reach.",'Give it tabindex="0", role="region" and aria-label="what it holds", or let it flow with the page.')},m=i.measure!==!1&&ke(t);if(!m)for(let e of w)N(e)&&E(e);let x=["keyboard","role","name","toggle-state","nested-interactive","img-alt","svg-name","scroll-region"],v=[],$={},O={};if(m){let e=ae(w,{limit:i.limit??400,tabbable:R,scrollsOnPage:E,say:(o,d,g,h,y,L,V)=>l(o,d,g,h,y,V===!0,L)});x.push("focus-visible","contrast"),Object.assign($,e.unmeasured),Object.assign(O,e.measured)}else{let e=i.measure===!1?"Asked not to measure.":"Nothing here is laid out (a headless run, or a DOM with no layout): it needs a browser's styles and boxes.";v.push({rule:"focus-visible",why:e},{rule:"contrast",why:e})}return v.push({rule:"keyboard-trap",why:"It needs keys pressed in a browser: a harness's Tab walk presses them (pnpm verify a11y)."}),{problems:p,ran:x,skipped:v,unmeasured:$,measured:O}}export{q as AUDIT_RULES,Oe as auditView,pe as markAsTheHost};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as Ae}from"./chunk.BJUUSIQY.js";import{a as X}from"./chunk.
|
|
1
|
+
import{a as Ae}from"./chunk.BJUUSIQY.js";import{a as X}from"./chunk.ZE5RSKXF.js";import{Dd as $e,Jb as be,fc as we,ga as B,la as he,oa as W,pc as Q,ra as ke,rc as Se,ua as _}from"./chunk.DHPXRDT5.js";import{j as H}from"./chunk.FQLNBIQ5.js";var M=e=>e.trim().toLowerCase(),U=e=>e.charAt(0).toUpperCase()+e.slice(1),le=e=>/^(?:[aeio]|u(?![sn]i|se|ser))/i.test(e),ee=e=>`${le(e)?"an":"a"} ${e}`,xe=e=>M(e).replace(/[^a-z0-9]+([a-z0-9])/g,(n,r)=>r.toUpperCase()).replace(/[^A-Za-z0-9]/g,""),se=e=>M(e).replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),ae=new Set(["person","people","someone","somebody","user","users","member","members"]);function de(e,n){let r=M(n);return Object.entries(e.kinds).find(([f,d])=>[f,d.noun,d.plural].some(c=>c!==void 0&&M(c)===r))?.[0]}function K(e,n){if(!e(n))return n;for(let r=2;;r++)if(!e(`${n}${r}`))return`${n}${r}`}function Fe(e,n){let r=e.acts??{},f=m=>m in r;if("link"in n){let m=de(e,n.link.on);if(!m)return{refused:`This app has no ${n.link.on} to give it to.`};let k=e.kinds[m],C=M(k.noun??m),v=M(n.link.called)||"linked to",u=de(e,n.link.to)??(ae.has(M(n.link.to))?(Object.entries(e.kinds).find(([,T])=>T.people)??Object.entries(e.kinds).find(([T,P])=>[T,P.noun,P.plural].some(t=>t!==void 0&&ae.has(M(t)))))?.[0]:void 0),A=[],j=[],$,F=u===void 0;if(!u){let T=M(n.link.to)||"person",P=ae.has(T),t=P?"person":T.replace(/s$/,""),a=P?"people":`${t}s`;u=K(b=>b in e.kinds,se(t)),A.push({op:"add-kind",kind:u,noun:t,plural:a,fields:{name:{type:"string",required:!0}},label:"{name}"}),$=K(f,`add-${u}`),j.push(`Add ${ee(U(a))} list.`)}let i=u in e.kinds?e.kinds[u]:A[0],y=M(i.noun??u),S=K(T=>T in(k.edges??{})||T in(k.fields??{}),xe(v)||"linkedTo");A.push({op:"add-relation",kind:m,relation:S,to:[u],cardinality:"one",description:U(v)});let R=K(f,`set-${se(v)}`);return A.push({op:"add-act",act:R,title:`Set \u201C${U(v)}\u201D`,on:m,connects:S,description:`Say who ${ee(C)} is ${v}.`}),j.push(`Give each ${C} ${le(v)?"an":"a"} \u201C${U(v)}\u201D field that points to ${ee(y)}.`),{edits:A,steps:j,on:m,relation:S,to:u,made:F,act:R,arg:"to",...$?{makes:$}:{},called:v}}let d=de(e,n.field.on);if(!d)return{refused:`This app has no ${n.field.on} to give it to.`};let c=e.kinds[d],g=M(c.noun??d),p=M(n.field.called)||"note",l=n.field.type??"string",s=K(m=>m in(c.fields??{})||m in(c.edges??{}),xe(p)||"note"),o=K(f,`set-${se(p)}`);return{edits:[{op:"add-field",kind:d,field:s,spec:{type:l}},{op:"add-act",act:o,title:`Set \u201C${U(p)}\u201D`,on:d,args:{value:{type:l,required:!0}},sets:{[s]:"$value"},description:`Say ${ee(g)}'s ${p}.`}],steps:[`Give each ${g} ${le(p)?"an":"a"} \u201C${U(p)}\u201D field.`],on:d,field:s,act:o,arg:"value",called:p}}var Re=["search-miss","unanswered","refused","tool-invalid"];var qe=new RegExp("[\\u0000-\\u001f\\u007f-\\u009f\\u200b-\\u200f\\u2028-\\u202e\\u2066-\\u2069]","g");var G=e=>e.onBehalfOf?G(e.onBehalfOf):e.id!==void 0?`${e.kind}:${e.id}`:`${e.kind}:?`,ce=e=>e.toLowerCase().replace(/\s+/g," ").replace(/^[\s\p{P}]+|[\s\p{P}]+$/gu,"");var Ce=new Set("a an and are at be by can do does for from has have how i in is it me my of on or our the their there this to was we what when where which who why will with you your".split(" "));function J(e,n,r,f,d){let c=new Map;for(let g of e){let p=n(g);if(p===void 0)continue;let l=c.get(p)??{first:g,people:new Set,times:0,last:g};l.people.add(G(g.by)),l.times+=1,l.last=g,c.set(p,l)}return[...c.entries()].filter(([,g])=>g.people.size>=f).sort(([g,p],[l,s])=>s.people.size-p.people.size||s.times-p.times||g.localeCompare(l)).slice(0,d).map(([g,p])=>({...r(p.last,g),people:p.people.size,times:p.times}))}function je(e,n={}){let r=Math.max(1,n.minPeople??2),f=n.most??12,d=n.reader?G(n.reader):void 0,c=e.filter(s=>!$e(s.by)&&(d===void 0||G(s.by)!==d)),g=Object.fromEntries(Re.map(s=>{let o=c.filter(m=>m.type===s);return[s,{events:o.length,people:new Set(o.map(m=>G(m.by))).size}]})),p=[],l=new Map;for(let s of c){let o=s.type==="search-miss"?s.words:s.type==="unanswered"?s.question:void 0;if(o!==void 0)for(let m of new Set(ce(o).split(/[^\p{L}\p{N}]+/u))){if(m.length<3||Ce.has(m))continue;let k={...s,id:`${s.id}:${m}`};p.push(k),l.set(k,m)}}return{events:c.length,people:new Set(c.map(s=>G(s.by))).size,byType:g,searches:J(c,s=>s.type==="search-miss"&&ce(s.words)||void 0,(s,o)=>({words:o}),r,f),questions:J(c,s=>s.type==="unanswered"&&ce(s.question)||void 0,(s,o)=>({question:o,...s.lacks?{lacks:s.lacks}:{}}),r,f),words:J(p,s=>l.get(s),(s,o)=>({word:o}),r,f),refusals:J(c,s=>s.type==="refused"?`${s.act}|${s.code}`:void 0,s=>({act:s.act,code:s.code}),r,f),tools:J(c,s=>s.type==="tool-invalid"?`${s.tool}|${s.act??""}`:void 0,s=>{let o=s;return{tool:o.tool,...o.act?{act:o.act}:{},...o.then?{then:o.then}:{}}},1,f)}}var ve=e=>e.length>3&&e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e;function Ee(e){let n=new Set,r=f=>{for(let d of f.toLowerCase().split(/[^\p{L}\p{N}]+/u))d.length>0&&n.add(ve(d))};for(let f of e.kinds){let d=e.tryDefinition(f);r(f),r(_(d,f)),r(W(e,f));for(let c of[...d?.aliases??[],...Object.values(d?.fieldAliases??{}).flat()])r(c);for(let c of Object.keys(d?.fields?.shape??{}))r(c),r(B(c))}return n}function Oe(e,n,r={}){let f=je(e,{most:8,...r}),d=Ee(n),c=f.searches.filter(o=>!o.words.split(/[^\p{L}\p{N}]+/u).some(m=>m.length>0&&d.has(ve(m)))).map(o=>({words:o.words,people:o.people})),g=f.questions.map(o=>({question:o.question,people:o.people,...o.lacks?{lacks:o.lacks}:{}})),p=f.tools.map(o=>({tool:o.tool,...o.act?{act:o.act}:{},...o.then?{then:o.then}:{},times:o.times})),l=o=>`${o} ${o===1?"person":"people"}`;return{said:[...c.length>0?[`Searched for, found nothing, and nothing here is called it: ${c.map(o=>`\u201C${o.words}\u201D (${l(o.people)})`).join(", ")}.`]:[],...g.length>0?[`Asked and not answered: ${g.map(o=>`\u201C${o.question}\u201D (${l(o.people)}${o.lacks?`; ${o.lacks.replace(/[.!]$/,"")}`:""})`).join(", ")}.`]:[],...p.length>0?[`Tool calls refused as invalid: ${p.map(o=>`${o.tool}${o.act?` (${o.act})`:""} ${o.times===1?"once":`${o.times} times`}${o.then?`, then worked as ${o.then}`:""}`).join("; ")}.`]:[]].join(`
|
|
2
2
|
`),unknownWords:c,questions:g,toolMistakes:p}}var Te=e=>/^(?:aggregate|kind):([^,]+)$/.exec(e)?.[1];function Ze(e,n){let r=e.about??[];if(e.field!==void 0&&e.on!==void 0&&n(e.on))return{on:"field",id:e.on,field:e.field};let f=r.filter(n);if(f.length>1)return{on:"selection",ids:f};if(e.on!==void 0&&n(e.on))return{on:"record",id:e.on};if(f.length===1)return{on:"record",id:f[0]};let d=[e.on,...r].map(c=>c===void 0?void 0:Te(c)).find(c=>c!==void 0);return e.place!==void 0?{on:"lens",place:e.place,...d?{kind:d}:{}}:d!==void 0?{on:"list",kind:d}:{on:"place",place:"home"}}var ne=e=>e.on==="record"||e.on==="field"?[e.id]:e.on==="selection"?e.ids:e.on==="act"&&e.id!==void 0?[e.id]:[],te=(e,n)=>e.tryDefinition(n)?.fields?.shape??{},Y=(e,n)=>e.tryDefinition(n)?.edges??{},ie=(e,n)=>new Set(e.tryDefinition(n)?.display?.hide??[]),N=(e,n)=>he(e.tryDefinition(n.kind),n),fe=(e,n,r)=>ke(e.tryDefinition(n),r)||B(r),ye=e=>typeof e=="boolean"?e?"yes":"no":String(e);function oe(e,n){let r=e.kindsKeptFrom(n);return new Set(e.schema.kinds.filter(f=>!r.has(f)))}function pe(e,n,r,f){if(!e.permits(n,r).ok)return!1;if(!f)return!0;try{return e.previewAll([n],{author:r}).ops.length>0}catch{return!1}}function Qe(e,n,r){let f=e,{principal:d}=r,c=r.each??8,g=H(f)?.store??f,p=g.seenBy(d),l=g.schema,s=oe(g,d),o=t=>{let a=p.graph.getNode(t);return a&&s.has(a.kind)?a:void 0},m=g.allMutations(),k=new Map(m.map(t=>[t.name,t])),C=[],v=new Set,u=t=>{v.has(t.id)||(v.add(t.id),C.push(t))},A=t=>t.slice(0,c),j=ne(n).filter(t=>o(t)!==void 0);if(ne(n).length>0&&j.length===0)return{target:n,candidates:[]};let $=j.length===1?o(j[0]):void 0,F=$?.kind??(n.on==="list"?n.kind:n.on==="lens"?n.kind??r.places?.find(t=>t.as===n.place)?.kind:void 0)??(n.on==="selection"?o(j[0])?.kind:void 0);if(F!==void 0&&!s.has(F))return{target:n,candidates:[]};let i=(t,a)=>`act:${t}${Object.keys(a).length>0?`:${Object.values(a).map(b=>String(b)).join(",")}`:""}`,y=(t,a,b,O,h)=>{t.destructive||Object.values(a).some(I=>typeof I=="string"&&g.graph.has(I)&&o(I)===void 0)||pe(g,{name:t.name,args:{...a}},d,O.length===0)&&u({type:"act",id:i(t.name,a),label:b,description:h??t.description??b,mutation:t.name,args:a,asks:O})};if(n.on!=="place"||r.acts)if(r.acts)for(let t of r.acts){let a=k.get(t.mutation);!a||t.destructive||n.on==="act"&&t.mutation!==n.act||y(a,t.args,t.label,(t.open??[]).filter(b=>!b.optional).map(b=>b.name),t.why)}else{let t=$?[$]:[];for(let a of m){if(n.on==="act"&&a.name!==n.act)continue;let b=a.input.shape??{},O=h=>Object.entries(b).filter(([I,w])=>I!==h&&w.safeParse?.(void 0).success===!1).map(([I])=>I);if(a.subject)for(let h of t)Q(l,a).includes(h.kind)&&y(a,{[a.subject.arg]:h.id},`${a.title??B(a.name)}: ${N(l,h)}`,O(a.subject.arg));else F!==void 0&&(a.creates??[]).includes(F)&&y(a,{},a.title??B(a.name),O(void 0))}}let S=C.filter(t=>t.type==="act");C.splice(0,C.length,...A(S));let R=(t,a)=>{let b=Se(l,m).get(t.kind),O=te(l,t.kind),h=ie(l,t.kind),I=[];for(let[w,D]of Object.entries(O)){if(a!==void 0?w!==a:h.has(w)||t[w]!==void 0)continue;let z=X(D),q=z?.type==="enum"&&!z.multiple?z.options??[]:z?.type==="boolean"?[!0,!1]:[];if(q.length===0)continue;let L=(b?.get(w)??[]).map(E=>k.get(E)).find(E=>E?.subject!==void 0&&pe(g,{name:E.name,args:{[E.subject.arg]:t.id,[w]:q.find(re=>re!==t[w])??q[0]}},d,!0));if(L?.subject)for(let E of q)t[w]!==E&&I.push({type:"fill",id:`fill:${t.id}:${w}:${ye(E)}`,label:`${fe(l,t.kind,w)}: ${ye(E)}`,description:`Set ${fe(l,t.kind,w).toLowerCase()} of ${N(l,t)} to ${ye(E)}`,record:t.id,field:w,value:E,call:{name:L.name,args:{[L.subject.arg]:t.id,[w]:E}}})}for(let[w,D]of Object.entries(Y(l,t.kind))){if(a!==void 0&&w!==a)continue;let z=D.to==="*"?[...s]:D.to.filter(x=>s.has(x)),q=new Set(p.graph.out(t.id,w).map(x=>x.id)),L=m.find(x=>(x.connects??[]).includes(w)&&x.subject!==void 0&&Q(l,x).includes(t.kind));if(!L?.subject)continue;let E=we(L.input).find(x=>x.name!==L.subject.arg);if(!E)continue;let re=z.flatMap(x=>E.kinds.length===0||E.kinds.includes(x)?p.graph.nodesOfKind(x):[]).filter(x=>x.id!==t.id&&!q.has(x.id)&&o(x.id)!==void 0);for(let x of A(re)){let me={name:L.name,args:{[L.subject.arg]:t.id,[E.name]:x.id}};pe(g,me,d,!0)&&I.push({type:"fill",id:`fill:${t.id}:${w}:${x.id}`,label:`${B(w)}: ${N(l,x)}`,description:`Link ${N(l,t)} to ${N(l,x)}${D.description?` as ${D.description}`:""}`,record:t.id,field:w,value:x.id,call:me})}}return I};if(n.on==="field"&&$)for(let t of R($,n.field))u(t);else if($&&n.on==="record")for(let t of A(R($)))u(t);let T=t=>{let a=W(l,t).toLowerCase(),b=[{type:"panel",id:`panel:${t}:list`,label:`A list of ${a}`,description:`Every ${_(l.tryDefinition(t),t).toLowerCase()} this viewer may see, as a list`,panel:{lens:"blocks",kind:t}}],O=ie(l,t);for(let[h,I]of Object.entries(te(l,t))){if(O.has(h))continue;let w=X(I),D=fe(l,t,h).toLowerCase();if(w?.type==="enum")b.push({type:"panel",id:`panel:${t}:group:${h}`,label:`${V(a)} by ${D}`,description:`A list of ${a} grouped by ${D}`,panel:{lens:"blocks",kind:t,group:h}}),b.push({type:"panel",id:`panel:${t}:columns:${h}`,label:`Columns of ${a} by ${D}`,description:`${V(a)} in a column for each ${D}`,panel:{lens:"columns",kind:t,column:h}});else if(w?.type==="number"||w?.type==="integer"||w?.type==="date"||w?.type==="datetime"){let z=w.type==="date"||w.type==="datetime";b.push({type:"panel",id:`panel:${t}:sort:${h}`,label:`${V(a)} by ${D}`,description:`A list of ${a}, the ${z?"latest":"highest"} ${D} first`,panel:{lens:"blocks",kind:t,sort:{by:h,direction:"desc"}}}),z&&b.push({type:"panel",id:`panel:${t}:calendar:${h}`,label:`A calendar of ${a}`,description:`${V(a)} on a calendar by ${D}`,panel:{lens:"calendar",kind:t,start:h}})}}return b},P=n.on==="place"?[...s]:F!==void 0?[F]:[];for(let t of P)for(let a of A(T(t)))u(a);for(let t of A((r.places??[]).filter(a=>a.kind===void 0?n.on==="place":s.has(a.kind)&&(n.on==="place"||a.kind===F))))n.on==="lens"&&t.as===n.place||u({type:"place",id:`place:${t.as}`,label:t.title,description:`Go to ${t.title}`,place:t.as});if($){let t=[];for(let[a,b]of Object.entries(Y(l,$.kind)))for(let O of p.graph.out($.id,a))o(O.id)&&t.push({type:"record",id:`record:${O.id}`,label:N(l,O),description:`${V(b.description??B(a))}: ${N(l,O)}`,record:O.id,relation:a});for(let a of l.kinds)for(let[b,O]of Object.entries(Y(l,a)))if(!(O.to!=="*"&&!O.to.includes($.kind)))for(let h of p.graph.in($.id,b))h.kind===a&&o(h.id)&&t.push({type:"record",id:`record:${h.id}`,label:N(l,h),description:`${V(O.inverse??B(b))}: ${N(l,h)}`,record:h.id,relation:b});for(let a of A(t))u(a)}else if(n.on==="list"||n.on==="lens")for(let t of A(F!==void 0?p.graph.nodesOfKind(F):[]))o(t.id)&&u({type:"record",id:`record:${t.id}`,label:N(l,t),description:`Open ${N(l,t)}`,record:t.id});else if(n.on==="selection")for(let t of j){let a=o(t);u({type:"record",id:`record:${t}`,label:N(l,a),description:`Open ${N(l,a)}`,record:t})}return{target:n,candidates:C}}var V=e=>e&&`${e[0].toUpperCase()}${e.slice(1)}`,Pe={columns:["board","kanban","column","lane","pipeline","stage","funnel"],board:["board","map","floor","layout","seat","slot"],calendar:["calendar","schedule","date","due","month","week","agenda","deadline","day"],timeline:["timeline","gantt","schedule","roadmap","span"],coverage:["coverage","matrix","grid","gap"],plan:["plan","floor","map","region","area"],blocks:["list","table","summary","overview","dashboard","card"]},De=new Set(["a","an","the","of","for","my","our","me","us","to","with","and","in","on","by","that","which","i","we","want","need","show","open","go","draw","make","new","view","views","panel","panels","page","lens","please","all","every","some","see","can","could","would","like","one","what","is","are","do","does","here","there","how","it","this","these","those"]),Z=e=>e.length>3&&e.endsWith("ies")?`${e.slice(0,-3)}y`:e.length>3&&e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e,ue=e=>e.toLowerCase().normalize("NFKD").replace(/[̀-ͯ]/g,"").split(/[^a-z0-9]+/).filter(Boolean);function Xe(e,n,r){let f=e,d=H(f)?.store??f,c=d.schema,g=oe(d,r.principal),p=d.seenBy(r.principal),l=ne(n),s=new Set;for(let i of l){let y=p.graph.getNode(i)?.kind;y!==void 0&&g.has(y)&&s.add(y)}if(l.length>0&&s.size===0)return[];if(n.on==="list"&&s.add(n.kind),n.on==="lens"){let i=n.kind??r.places.find(y=>y.as===n.place)?.kind;i!==void 0&&s.add(i)}let o=new Map;for(let i of c.kinds){if(!g.has(i))continue;let y=c.tryDefinition(i);for(let S of[i,_(y,i),W(c,i)])for(let R of ue(S))o.set(Z(R),i)}let m=ue(r.said??"").filter(i=>!De.has(i)),k=new Set,C=[];for(let i of m){let y=o.get(Z(i));y!==void 0?k.add(y):C.push(Z(i))}let v=k.size>0?k:s;if((r.said??"").trim()!==""&&m.length===0)return[];if(v.size===0&&m.length===0)return[];let u=[];r.places.forEach((i,y)=>{if(i.hidden||n.on==="lens"&&i.as===n.place)return;let S=i.over??(i.kind!==void 0?[i.kind]:[]);if(S.length>0&&!S.some(P=>g.has(P)))return;let R=S.some(P=>v.has(P)),T=!R&&(i.reads??[]).some(P=>v.has(P));v.size>0&&!R&&!T||u.push({place:i,own:R,reads:T,at:y})});let A=i=>new Set(ue(i.title).map(Z)),j=new Set(C.filter(i=>u.some(({place:y})=>A(y).has(i)))),$=[];for(let{place:i,own:y,reads:S,at:R}of u){let T=A(i),P=new Set((Pe[i.lens??""]??[]).map(Z)),t=C.filter(h=>T.has(h)||P.has(h)&&!j.has(h)).length,a=C.length-t;if(C.length>0&&t===0)continue;let b=!S&&a===0?"full":"partial",O=(y?4:S?2:1)+t*2-a+(b==="full"?1:0);$.push({view:{place:i.as,title:i.title,...i.kind!==void 0?{kind:i.kind}:{},fit:b},score:O,at:R})}return $.filter((i,y)=>!$.slice(0,y).some(S=>S.view.place===i.view.place&&S.view.title===i.view.title)).sort((i,y)=>y.score-i.score||i.at-y.at).slice(0,r.most??3).map(i=>i.view)}var ge=new WeakMap;function Ne(e){let n=2166136261;for(let r=0;r<e.length;r++)n^=e.charCodeAt(r),n=Math.imul(n,16777619)>>>0;return n.toString(36)}function Ie(e,n){let r=e,f=H(r)?.store??r,d=f.schema,c=oe(f,n),p=f.allMutations().filter(u=>!u.destructive&&f.permits({name:u.name,args:{}},n).ok!==!1),l=`${[...c].join(",")}|${p.map(u=>u.name).join(",")}`,s=ge.get(d)?.get(l);if(s)return s;let o=[...c].map(u=>{let A=ie(d,u),j={};for(let[y,S]of Object.entries(te(d,u))){if(A.has(y))continue;let R=X(S);R&&(j[y]=R.type==="enum"?`enum:${(R.options??[]).join("|")}`:R.type)}let $={};for(let[y,S]of Object.entries(Y(d,u)))$[y]=S.to==="*"?[...c]:S.to.filter(R=>c.has(R));let F=d.tryDefinition(u),i=Object.entries(F?.fieldAliases??{}).filter(([y,S])=>y in j&&S.length>0);return{kind:u,noun:_(d.tryDefinition(u),u),plural:W(d,u),fields:j,relations:$,...F?.aliases&&F.aliases.length>0?{aliases:F.aliases}:{},...i.length>0?{fieldAliases:Object.fromEntries(i)}:{}}}),m=p.map(u=>({name:u.name,title:u.title??B(u.name),...u.subject?{on:Q(d,u).filter(A=>c.has(A))}:{}})),k={kinds:o,acts:m},C={version:Ne(JSON.stringify(k)),...k},v=ge.get(d)??new Map;return v.set(l,C),ge.set(d,v),C}var Me=e=>e.name??e.id??e.kind;function en(e,n,r){let f=e,{principal:d}=r,c=H(f)?.store??f,g=c.seenBy(d),p=c.schema,l=oe(c,d),s=i=>{let y=g.graph.getNode(i);return y&&l.has(y.kind)?y:void 0},o=i=>({id:i.id,kind:i.kind,label:N(p,i)}),m=ne(n),k=m.length===1?s(m[0]):void 0,C=k?Object.fromEntries(Object.keys(te(p,k.kind)).filter(i=>!ie(p,k.kind).has(i)&&k[i]!==void 0&&i!=="label").map(i=>[i,k[i]])):{},v={on:n.on,...k?{record:{...o(k),fields:C}}:{},...n.on==="field"&&k?{field:n.field}:{},...n.on==="list"&&l.has(n.kind)?{kind:n.kind}:{},...n.on==="lens"?{place:n.place,...n.kind&&l.has(n.kind)?{kind:n.kind}:{}}:{},...n.on==="place"?{place:n.place}:{},...n.on==="act"?{act:n.act}:{}},u=[...new Set([...n.on==="selection"?n.ids:[],...r.selection??[]])].flatMap(i=>{let y=s(i);return y?[o(y)]:[]}),A=[];if(k){for(let i of Object.keys(Y(p,k.kind)))for(let y of g.graph.out(k.id,i))s(y.id)&&A.push({...o(y),relation:i,direction:"out"});for(let i of p.kinds)for(let y of Object.keys(Y(p,i)))for(let S of g.graph.in(k.id,y))S.kind===i&&s(S.id)&&A.push({...o(S),relation:y,direction:"in"})}let j=g.batches().filter(i=>!i.ops.every(be)).slice(-(r.recent??6)).reverse().map(i=>({intent:i.intent,at:i.at,by:Me(i.author)})),$=(r.purpose?.jobs??[]).filter(i=>Ae(i,d.roles)&&l.has(i.kind)).map(i=>({name:i.name,ask:i.ask,kind:i.kind})),F=r.purpose&&(r.purpose.for!==void 0||$.length>0)?{...r.purpose.for!==void 0?{for:r.purpose.for}:{},jobs:$}:void 0;return{...r.place!==void 0?{place:r.place}:{},target:v,selection:u,neighbors:A.slice(0,24),recent:j,schema:Ie(c,d),...F?{purpose:F}:{},...r.friction?{friction:Oe(r.friction,p,{reader:d})}:{}}}export{Fe as a,Ze as b,ne as c,Qe as d,Xe as e,en as f};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as z,j as D,k as H}from"./chunk.
|
|
1
|
+
import{i as z,j as D,k as H}from"./chunk.HMJXB6KC.js";import{a as P,b as A,c as p,d as W}from"./chunk.Q355UPFG.js";import"./chunk.JQEXH23N.js";import"./chunk.I7OFRF6N.js";import"./chunk.4RPKCW4J.js";import"./chunk.IRNEWNUB.js";import"./chunk.AUNQNTKY.js";import"./chunk.KLEKC4ZX.js";import"./chunk.PJL3I2IW.js";import"./chunk.LMZ2WMGH.js";import"./chunk.OD5QZHRC.js";import"./chunk.YJ4PFOPC.js";import"./chunk.LKM2R5UF.js";import{a as C,b as O}from"./chunk.MB7LKKUD.js";import"./chunk.26RYER7Y.js";import"./chunk.CYEPHT7V.js";import"./chunk.5MOXQUZH.js";import"./chunk.MKN7ADJB.js";import"./chunk.I4H2GS4O.js";import"./chunk.FE3SINPK.js";import"./chunk.MUWI54IP.js";import"./chunk.3D37E2G5.js";import"./chunk.WVUJXDXZ.js";import"./chunk.B422DSYN.js";import"./chunk.ZE5RSKXF.js";import"./chunk.DKUEZPGR.js";import"./chunk.EP7YT7LT.js";import"./chunk.I7KN732Z.js";import"./chunk.TLPCYKLW.js";import"./chunk.MIE4TJRW.js";import"./chunk.SCVKHGO3.js";import"./chunk.RD2FSSLV.js";import"./chunk.AZRICZKT.js";import"./chunk.MH3AQO2R.js";import"./chunk.J2N7EKMX.js";import"./chunk.P26ATAAI.js";import"./chunk.FIY4RUK5.js";import"./chunk.IY3DV52G.js";import"./chunk.NLZHNPDU.js";import"./chunk.QNC2OKLF.js";import{G as B,Va as k,W as L}from"./chunk.FWXW4T4I.js";import"./chunk.SDO3U72B.js";import{td as R}from"./chunk.DHPXRDT5.js";import"./chunk.FQLNBIQ5.js";import{b as E}from"./chunk.AJZBJBMO.js";var r=E(B(),1);var s=E(L(),1);function M(c){let e=document.activeElement;if(e!==null&&e!==document.body&&e!==document.documentElement&&e.isConnected)return;let n=c??document,o=n.querySelector("main")??n.querySelector("[data-graview-page]")??null,t=n.querySelector("[data-graview-page-title]")??o?.querySelector("h1, h2")??o;t instanceof HTMLElement&&(t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1"),t.focus({preventScroll:!0}))}var I=1500;function N(c,e,n){let{store:o,principal:t}=c,l=z(o),g=(0,r.useMemo)(()=>P(o,t),[o,t,l]),w=(0,r.useRef)(n),[b,d]=(0,r.useState)(),[y,u]=(0,r.useState)("");(0,r.useEffect)(()=>{let a=A(o,t,w.current);w.current=o.batches().length,a&&(d({batch:a.batch,at:e,when:Date.now()}),u(""))},[o,t,l]),(0,r.useEffect)(()=>{d(a=>!a||a.at===e?a:Date.now()-a.when<I?{...a,at:e}:void 0)},[e]);let[x,i]=(0,r.useState)(null),v=(0,r.useCallback)(()=>{d(void 0),i(null)},[]),f=(0,r.useCallback)(()=>{i(null);try{let a=W(o,t);a&&u(`Took back \u201C${a.intent}\u201D`)}catch(a){i(a instanceof Error?a.message:String(a))}},[o,t]),S=g&&b?.batch===g.batch&&b.at===e?g:void 0;return{change:g,offered:S,close:v,takeBack:f,refused:x,said:y}}function ee({context:c,docked:e,at:n,since:o,compact:t=!1,className:l,size:g}){let{change:w,offered:b,close:d,takeBack:y,refused:u,said:x}=N(c,n,o),i=e?b:w,v=(0,r.useRef)(null),f=e&&(i!==void 0||u!==null);j(v,f),(0,r.useEffect)(()=>{if(!f)return;let m,h=()=>m=setTimeout(()=>v.current?.matches(":hover, :focus-within")?h():d(),1e4);return h(),()=>clearTimeout(m)},[f,i?.batch,u,d]);let S=x||(e&&i?p(i):""),a=e?{position:"fixed",inset:"auto",margin:0,padding:0,border:"none",background:"none",overflow:"visible",zIndex:R("toast"),width:"max-content",height:"auto",bottom:"calc(16px + env(safe-area-inset-bottom, 0px))",left:16,justifyItems:"start",color:"var(--graview-ink)",...f?{}:{display:"none"}}:{},T=i?(0,s.jsxs)("button",{type:"button","data-testid":"page-undo",title:`${p(i)} \u2014 \u2318Z or Ctrl+Z`,"aria-keyshortcuts":"Meta+Z Control+Z",onClick:m=>{let h=m.currentTarget.closest("[data-graview-face]");y(),requestAnimationFrame(()=>M(h))},...e?{style:U}:{className:H("graview-undo",l),...D(g),...t?{"data-compact":"","aria-label":p(i)}:{}},children:[(0,s.jsx)("span",{"aria-hidden":"true",children:"\u21B6"}),e?(0,s.jsx)("span",{style:K,children:p(i)}):(0,s.jsx)("span",{className:"graview-undo-words",children:t?"Undo":p(i)})]}):null;return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("span",{role:"status","aria-live":"polite",style:V,children:S}),(0,s.jsxs)("div",{ref:v,...e?{popover:"manual","data-graview-foot":"","data-graview-offstage":""}:{},"data-testid":e?"face-undo-dock":"page-undo-place",...e?{style:{...F,...a}}:{className:"graview-undo-place"},children:[e?null:(0,s.jsx)("style",{children:q}),e&&i?(0,s.jsxs)("div",{"data-testid":"page-undo-notice",style:Z,children:[T,(0,s.jsx)("button",{type:"button","data-testid":"page-undo-dismiss","aria-label":`Dismiss: ${p(i)}`,title:"Dismiss",onClick:m=>{let h=m.currentTarget.closest("[data-graview-face]");d(),requestAnimationFrame(()=>M(h))},style:$,children:"\xD7"})]}):T,u?(0,s.jsx)("span",{"data-testid":"page-undo-refused",role:"alert",className:"graview-undo-refused",...e?{style:{fontSize:"0.8125rem",lineHeight:1.4,color:"var(--graview-warn)",borderRadius:6,background:"var(--graview-float)",padding:"4px 8px"}}:{},children:u}):null]})]})}function j(c,e){(0,r.useLayoutEffect)(()=>{let n=c.current;if(!n||!e)return;if(typeof n.showPopover=="function"&&!k(n))try{n.showPopover()}catch{}let o=()=>n.parentElement?.closest("[data-embed-content]")??null,t=()=>{O(n,o()),dispatchEvent(new Event(C))};t(),addEventListener("resize",t),addEventListener("scroll",t,!0);let l=typeof ResizeObserver=="function"?new ResizeObserver(t):null;return l?.observe(n),()=>{if(l?.disconnect(),removeEventListener("resize",t),removeEventListener("scroll",t,!0),n.isConnected&&k(n))try{n.hidePopover()}catch{}dispatchEvent(new Event(C))}},[c,e])}var q=`:where(.graview-undo-place){display:grid;justify-items:end;gap:4px;max-width:100%;min-width:0}
|
|
2
2
|
:where(.graview-undo){box-sizing:border-box;display:inline-flex;align-items:center;gap:6px;min-height:var(--graview-control-height,36px);max-width:min(100%,var(--graview-undo-widest,18rem));min-width:0;padding:0 14px;border-radius:999px;border:1px solid var(--graview-edge);background:var(--graview-float);color:var(--graview-ink);font:inherit;font-size:.875rem;cursor:pointer}
|
|
3
3
|
:where(.graview-undo[data-size=sm]){--graview-control-height:30px}
|
|
4
4
|
:where(.graview-undo[data-compact]){padding:0 10px}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as K}from"./chunk.4UUJHLHR.js";import{Fb as h,Gb as v,Hc as $,Ic as N,Nb as V,h as P,k as R,pc as Y,q as I,qb as G,qc as X,tc as B,ua as q,x as _}from"./chunk.ZEZUKRC6.js";import{a as T,c as C,h as L}from"./chunk.FQLNBIQ5.js";import"./chunk.AJZBJBMO.js";var te=Symbol.for("@graview/core:markdown"),ne=500;function ie(e){let n=e;for(let i=0;i<6;i++){let t=N(n);if(!t)return!1;if(t[$]!==void 0)return t[$]===1;if(t[te]===1)return!0;if(t.type==="string")return(t.checks??[]).some(s=>{let f=N(s);return f?.check==="max_length"&&(f.maximum??0)>ne});if(t.innerType===void 0)return!1;n=t.innerType}return!1}function O(e,n,i){if(n===void 0||i==="id"||i==="kind")return!1;let t=e.tryDefinition(n)?.fields?.shape;return!!t&&Object.prototype.hasOwnProperty.call(t,i)&&ie(t[i])}var re=e=>e>=55296&&e<=56319,oe=e=>e>=56320&&e<=57343;function S(e,n){let i=Math.min(e.length,n.length),t=0;for(;t<i&&e.charCodeAt(t)===n.charCodeAt(t);)t++;t>0&&re(e.charCodeAt(t-1))&&t--;let s=0;for(;s<i-t&&e.charCodeAt(e.length-1-s)===n.charCodeAt(n.length-1-s);)s++;return s>0&&oe(e.charCodeAt(e.length-s))&&s--,{at:t,removed:e.slice(t,e.length-s),inserted:n.slice(t,n.length-s)}}var w=e=>e.at+e.removed.length;function H(e){let n=S(e.removed,e.inserted);return{...n,at:e.at+n.at}}function U(e,n,i){if(w(e)<n.at)return e;if(e.at>w(n))return{...e,at:e.at+n.inserted.length-n.removed.length};let t=Math.min(e.at,n.at),s=w(e)-w(n),f=e.removed.slice(0,n.at-t)+n.inserted+(s>0?e.removed.slice(e.removed.length-s):""),r=n.at<e.at||n.at===e.at&&i;return H({at:t,removed:f,inserted:r?n.inserted+e.inserted:e.inserted+n.inserted})}function b(e,n){return[U(e,n,!1),U(n,e,!0)]}function D(e,n){let i=e.at+e.inserted.length;if(w(n)<e.at||n.at>i)return;let t=Math.min(e.at,n.at),s=w(n)-i,f=n.removed.slice(0,e.at-t),r=s>0?n.removed.slice(n.removed.length-s):"",l=T(f+e.inserted+r,{...n,at:n.at-t});return H({at:t,removed:f+e.removed+r,inserted:l})}function M(e,n,i){switch(e.op){case"patch-node":return e.id===n&&Object.prototype.hasOwnProperty.call(e.after,i);case"add-node":case"remove-node":return e.node.id===n;default:return!1}}function j(e,n,i){if(e.op!=="patch-node"||e.id!==n||!Object.prototype.hasOwnProperty.call(e.after,i))return;let t=e.before[i],s=e.after[i];return typeof s=="string"&&(t===void 0||t===""||C(t))?{at:0,removed:"",inserted:s}:void 0}var J=(e,n,i)=>e.flatMap(t=>t.op==="splice-text"&&t.id===n&&t.field===i?[t]:[]);function E(e,n,i,t,s,f){if(typeof f!="string"||s<n-1)return;let r=[];for(let o of e)if(!(o.seq<=s))for(let p of o.primitives){let a=j(p,i,t);if(a){r.push(a);continue}if(M(p,i,t))return;p.op==="splice-text"&&p.id===i&&p.field===t&&r.push(p)}let l=f;try{for(let o=r.length-1;o>=0;o--){let p=r[o];l=T(l,{at:p.at,removed:p.inserted,inserted:p.removed})}}catch{return}return{then:l,since:r}}function A(e,n){let i=e;for(let t of n)i=b(t,i)[1];return{at:i.at,removed:i.removed,inserted:i.inserted}}function Q(e,n,i){let t=i?A(S(i.then,n),i.since):S(e,n);return t.removed===""&&t.inserted===""?void 0:t}function Z(e){let n=e.schema,i=t=>{throw new V(t,"invalid")};return{name:h,title:"Type text",input:I({node:P(),field:P(),at:R(),remove:R(),insert:P(),rev:_(R())}),subject:{kinds:"*",arg:"node"},writes:[],describe:(t,s)=>{let{node:f,field:r,insert:l,remove:o}=t;return K({node:f,field:r,inserted:[...String(l??"")].length,removed:Number(o)||0},n,s)},apply(t,s){let{node:f,field:r,at:l,remove:o,insert:p,rev:a}=s;(![l,o,a??0].every(k=>Number.isInteger(k)&&k>=-1)||l<0||o<0)&&i("at and remove are whole numbers, none below 0, and rev a revision");let d=t.graph.getNode(f);if(!d)throw new G(f,"\u201CType text\u201D names a record that is not there.");if(O(n,d.kind,r)||i(`${q(n.tryDefinition(d.kind),d.kind)}'s "${r}" is not text typed together: write it whole, as its edit does`),o===0&&p==="")return;let c=d[r];if(typeof c!="string"||c===""){t.patchNode(f,{[r]:p});return}let g=e.graph.getNode(f)?.[r],m=a===void 0?{then:c,since:[]}:E(e.log.all(),e.log.horizon,f,r,Math.max(a,-1),g);m||i(`${r} was written whole since revision ${a}: read it again and type over what it holds now`);let{then:u,since:y}=m;l+o>u.length&&i(`${r} held ${u.length} characters at revision ${a??"now"}, so there is nothing at ${l}${o>0?`\u2013${l+o}`:""} to type over`);let x=A({at:l,removed:u.slice(l,l+o),inserted:p},y);x.removed===""&&x.inserted===""||t.emit({op:"splice-text",id:f,field:r,...x})}}}function ee(e,n,i,t,s=()=>!0){let f=i===void 0?void 0:e.tryDefinition(i);if(!f||typeof t!="string")return[];let r=new Set;for(let l of n)if(!(l.name===h||!Y(e,l).includes(i)||!X(l,f).includes(t))&&s(l)){r.add(l.name);for(let o of B(e,n,l)??[])r.add(o)}return[...r]}function se(e,n,i){if(!n.some(r=>r.op==="patch-node"))return[...n];let t=new Set,s=new Set,f=[];for(let r of n){if(r.op==="add-node"&&t.add(r.node.id),r.op!=="patch-node"||t.has(r.id)){r.op==="splice-text"&&s.add(`${r.id}\0${r.field}`),f.push(r);continue}let l=e.graph.getNode(r.id),o={},p={},a=[];for(let[d,c]of Object.entries(r.after)){let g=l?.[d],m=`${r.id}\0${d}`;if(typeof c=="string"&&typeof g=="string"&&g!==""&&!s.has(m)&&O(e.schema,l?.kind,d)){let u=i?.find(x=>x.node===r.id&&x.field===d),y=Q(g,c,u?E(e.log.all(),e.log.horizon,r.id,d,u.rev,g):void 0);if(y){a.push({op:"splice-text",id:r.id,field:d,...y}),s.add(m);continue}}o[d]=r.before[d],p[d]=c,s.add(m)}Object.keys(p).length>0&&f.push(a.length>0?{op:"patch-node",id:r.id,before:o,after:p}:r),f.push(...a)}return f}function de(e,n){let i=[];return[...n].sort((t,s)=>s.seq-t.seq).map(t=>{let s=L(t);if(!s.some(o=>o.op==="splice-text"))return i.push(...s),{op:t,primitives:s};let f=e.filter(o=>o.seq>t.seq).flatMap(o=>o.primitives),r=t.primitives.length,l=[];return s.forEach((o,p)=>{if(o.op!=="splice-text")return void l.push(o);let a=A(o,J([...t.primitives.slice(r-p),...f,...i,...l],o.id,o.field));(a.removed!==""||a.inserted!=="")&&l.push({op:"splice-text",id:o.id,field:o.field,...a})}),i.push(...l),{op:t,primitives:l}})}function ae(e,n){let i=(t,s)=>e.some(f=>M(f,t,s));return n.undoes!==void 0&&n.primitives.length===0&&e.some(t=>t.op==="splice-text")||n.primitives.length>0&&n.primitives.every(t=>t.op==="splice-text"&&!i(t.id,t.field))?!0:e.flatMap(t=>t.op==="splice-text"&&n.primitives.some(s=>M(s,t.id,t.field))?[t.id]:[])}function le(e,n,i){let t=new Map,s=[],f=new Set;for(let a of e){let d=a.primitives[0],c=a.mutation?.args,g=a.mutation?.name!==h||a.primitives.length!==1||!d?void 0:d.op==="splice-text"?d:j(d,String(c?.node),String(c?.field));g?s.push({batch:a.batch,node:String(c?.node),field:String(c?.field),splice:g}):f.add(a.batch)}if(s.length===0)return t;let r=a=>`${a.node}\0${a.field}`,l=new Set,o=new Set(e.map(a=>a.batch).filter(a=>!i.includes(a))),p=s;for(let a of n){if(o.has(a.batch)){p=p.filter(d=>d.batch!==a.batch);continue}for(let d of a.primitives){if(d.op==="add-edge"||d.op==="remove-edge")continue;let c=d.op==="add-node"||d.op==="remove-node"?d.node.id:d.id;for(let g of new Set(p.filter(m=>m.node===c).map(m=>m.field))){let m=d.op==="splice-text"?d.field===g?d:void 0:j(d,c,g);for(let u of p)u.node!==c||u.field!==g||(m?[m,u.splice]=b(m,u.splice):M(d,u.node,u.field)&&l.add(r(u)))}}}p.forEach((a,d)=>{if(!o.has(a.batch))return;let c={at:a.splice.at,removed:a.splice.inserted,inserted:a.splice.removed};for(let g of p.slice(d+1))r(g)===r(a)&&([c,g.splice]=b(c,g.splice))});for(let a of i){let d=p.filter(c=>c.batch===a);d.length===0||f.has(a)||d.some(c=>l.has(r(c)))||t.set(a,d.map(c=>({name:h,args:{node:c.node,field:c.field,at:c.splice.at,remove:c.splice.removed.length,insert:c.splice.inserted}})))}return t}v.typeText=Z;v.via=ee;v.collaborative=O;v.asSplices=se;v.undone=de;v.aside=ae;v.carried=le;function Ye(e){let{store:n,author:i,pending:t,provisional:s,asked:f}=e,r=new Map,l=(o,p)=>{r.get(o)?.(p),r.delete(o)};return{store:n,apply:(o,p)=>e.appliedAll(o,{...i?{author:i}:{},...p!==void 0?{batch:p}:{}}),hold(o){t.push(o),s.add(o),e.answers.set(o,new Promise(p=>r.set(o,p)))},ask:(o,p)=>void f.set(o,{calls:p}),send(o,p){f.set(o,{calls:p});let a=e.sent(o,p),d=()=>l(o,a);return a.then(c=>{Array.isArray(c?.ops)&&c.ops.length===0&&e.letGo.add(o),d()},d),a},drop(o){e.letGo.add(o),e.settle(o),f.delete(o),e.land([],[o]),l(o)},seen:e.seen,gone:e.gone,ahead(o,p,a){let d=t.indexOf(o),c=n.log.all(),g=m=>c.some(u=>u.batch===m&&u.primitives.some(y=>y.op==="splice-text"&&y.id===p&&y.field===a||y.op==="patch-node"&&y.id===p&&a in y.after));return t.slice(0,Math.max(0,d)).flatMap(m=>{let u=e.answers.get(m);return u&&g(m)?[{batch:m,answer:u}]:[]})}}}var ce=400,pe=/[\s.,;:!?)\]}]$/u,W=e=>typeof e=="string"?e:"";function z(e,n,i,t){let s=e.log.all(),f=s.findIndex(o=>o.batch===n);if(f<0)return;let r=W(e.graph.getNode(i)?.[t]),l;for(let o=s.length-1;o>=f;o--){let p=s[o];p.batch===n&&l===void 0&&(l=r);for(let a=p.primitives.length-1;a>=0;a--){let d=p.primitives[a];d.op==="splice-text"&&d.id===i&&d.field===t?r=T(r,{at:d.at,removed:d.inserted,inserted:d.removed}):d.op==="patch-node"&&d.id===i&&t in d.after&&(r=C(d.before[t])?"":W(d.before[t]))}}if(!(l===void 0||l===r))return S(r,l)}function Xe(e,n,i){let t,s=[],f,r,l=!1,o=new Set,p=c=>({name:h,args:{node:e,field:n,at:c.at,remove:c.removed.length,insert:c.inserted,rev:i.seen()}}),a=()=>{r&&clearTimeout(r),r=void 0,t!==void 0&&s.push(t),t=void 0,d()},d=()=>{if(f!==void 0||l||i.gone())return;let c=s.shift();if(c===void 0)return;let g=i.ahead(c,e,n).filter(u=>!o.has(u.batch));if(g.length>0){s.unshift(c),l=!0,Promise.allSettled(g.map(u=>u.answer)).then(()=>{for(let u of g)o.add(u.batch);l=!1,d()});return}let m=z(i.store,c,e,n);if(!m)return i.drop(c),d();f=c,i.send(c,[p(m)]).finally(()=>{f=void 0,d()})};return{splice(c,g,m){if(i.gone())return;let u=W(i.store.graph.getNode(e)?.[n]),y={at:c,removed:u.slice(c,c+g),inserted:m};if(t!==void 0){let F=z(i.store,t,e,n);(!F||!D(F,y))&&a()}let x=i.apply([{name:h,args:{node:e,field:n,at:c,remove:g,insert:m}}],t);if(x.ops.length===0)return;t===void 0&&(t=x.batch,i.hold(t));let k=z(i.store,t,e,n);if(k&&i.ask(t,[p(k)]),pe.test(m))return a();r&&clearTimeout(r),r=setTimeout(a,ce),r.unref?.()},flush:a,waiting:()=>s.length+(t!==void 0?1:0)+(f!==void 0?1:0)}}function Be(e,n){let i=n.find(l=>l.name===h)?.args;if(typeof i?.node!="string"||typeof i.field!="string")return;let{node:t,field:s}=i,f=()=>e.graph.getNode(t)?.[s],r=f();return{node:t,field:s,yours:r,over:l=>{let o=f();return{name:h,args:{node:t,field:s,at:0,remove:typeof o=="string"?o.length:0,insert:typeof r=="string"?r:"",rev:l}}}}}export{ce as TYPING_IDLE_MS,z as runSplice,Xe as typingOf,Ye as wireOf,Be as yoursOf};
|
|
1
|
+
import{d as K}from"./chunk.ZQYHNFRZ.js";import{Fb as h,Gb as v,Hc as $,Ic as N,Nb as V,h as P,k as R,pc as Y,q as I,qb as G,qc as X,tc as B,ua as q,x as _}from"./chunk.DHPXRDT5.js";import{a as T,c as C,h as L}from"./chunk.FQLNBIQ5.js";import"./chunk.AJZBJBMO.js";var te=Symbol.for("@graview/core:markdown"),ne=500;function ie(e){let n=e;for(let i=0;i<6;i++){let t=N(n);if(!t)return!1;if(t[$]!==void 0)return t[$]===1;if(t[te]===1)return!0;if(t.type==="string")return(t.checks??[]).some(s=>{let f=N(s);return f?.check==="max_length"&&(f.maximum??0)>ne});if(t.innerType===void 0)return!1;n=t.innerType}return!1}function O(e,n,i){if(n===void 0||i==="id"||i==="kind")return!1;let t=e.tryDefinition(n)?.fields?.shape;return!!t&&Object.prototype.hasOwnProperty.call(t,i)&&ie(t[i])}var re=e=>e>=55296&&e<=56319,oe=e=>e>=56320&&e<=57343;function S(e,n){let i=Math.min(e.length,n.length),t=0;for(;t<i&&e.charCodeAt(t)===n.charCodeAt(t);)t++;t>0&&re(e.charCodeAt(t-1))&&t--;let s=0;for(;s<i-t&&e.charCodeAt(e.length-1-s)===n.charCodeAt(n.length-1-s);)s++;return s>0&&oe(e.charCodeAt(e.length-s))&&s--,{at:t,removed:e.slice(t,e.length-s),inserted:n.slice(t,n.length-s)}}var w=e=>e.at+e.removed.length;function H(e){let n=S(e.removed,e.inserted);return{...n,at:e.at+n.at}}function U(e,n,i){if(w(e)<n.at)return e;if(e.at>w(n))return{...e,at:e.at+n.inserted.length-n.removed.length};let t=Math.min(e.at,n.at),s=w(e)-w(n),f=e.removed.slice(0,n.at-t)+n.inserted+(s>0?e.removed.slice(e.removed.length-s):""),r=n.at<e.at||n.at===e.at&&i;return H({at:t,removed:f,inserted:r?n.inserted+e.inserted:e.inserted+n.inserted})}function b(e,n){return[U(e,n,!1),U(n,e,!0)]}function D(e,n){let i=e.at+e.inserted.length;if(w(n)<e.at||n.at>i)return;let t=Math.min(e.at,n.at),s=w(n)-i,f=n.removed.slice(0,e.at-t),r=s>0?n.removed.slice(n.removed.length-s):"",l=T(f+e.inserted+r,{...n,at:n.at-t});return H({at:t,removed:f+e.removed+r,inserted:l})}function M(e,n,i){switch(e.op){case"patch-node":return e.id===n&&Object.prototype.hasOwnProperty.call(e.after,i);case"add-node":case"remove-node":return e.node.id===n;default:return!1}}function j(e,n,i){if(e.op!=="patch-node"||e.id!==n||!Object.prototype.hasOwnProperty.call(e.after,i))return;let t=e.before[i],s=e.after[i];return typeof s=="string"&&(t===void 0||t===""||C(t))?{at:0,removed:"",inserted:s}:void 0}var J=(e,n,i)=>e.flatMap(t=>t.op==="splice-text"&&t.id===n&&t.field===i?[t]:[]);function E(e,n,i,t,s,f){if(typeof f!="string"||s<n-1)return;let r=[];for(let o of e)if(!(o.seq<=s))for(let p of o.primitives){let a=j(p,i,t);if(a){r.push(a);continue}if(M(p,i,t))return;p.op==="splice-text"&&p.id===i&&p.field===t&&r.push(p)}let l=f;try{for(let o=r.length-1;o>=0;o--){let p=r[o];l=T(l,{at:p.at,removed:p.inserted,inserted:p.removed})}}catch{return}return{then:l,since:r}}function A(e,n){let i=e;for(let t of n)i=b(t,i)[1];return{at:i.at,removed:i.removed,inserted:i.inserted}}function Q(e,n,i){let t=i?A(S(i.then,n),i.since):S(e,n);return t.removed===""&&t.inserted===""?void 0:t}function Z(e){let n=e.schema,i=t=>{throw new V(t,"invalid")};return{name:h,title:"Type text",input:I({node:P(),field:P(),at:R(),remove:R(),insert:P(),rev:_(R())}),subject:{kinds:"*",arg:"node"},writes:[],describe:(t,s)=>{let{node:f,field:r,insert:l,remove:o}=t;return K({node:f,field:r,inserted:[...String(l??"")].length,removed:Number(o)||0},n,s)},apply(t,s){let{node:f,field:r,at:l,remove:o,insert:p,rev:a}=s;(![l,o,a??0].every(k=>Number.isInteger(k)&&k>=-1)||l<0||o<0)&&i("at and remove are whole numbers, none below 0, and rev a revision");let d=t.graph.getNode(f);if(!d)throw new G(f,"\u201CType text\u201D names a record that is not there.");if(O(n,d.kind,r)||i(`${q(n.tryDefinition(d.kind),d.kind)}'s "${r}" is not text typed together: write it whole, as its edit does`),o===0&&p==="")return;let c=d[r];if(typeof c!="string"||c===""){t.patchNode(f,{[r]:p});return}let g=e.graph.getNode(f)?.[r],m=a===void 0?{then:c,since:[]}:E(e.log.all(),e.log.horizon,f,r,Math.max(a,-1),g);m||i(`${r} was written whole since revision ${a}: read it again and type over what it holds now`);let{then:u,since:y}=m;l+o>u.length&&i(`${r} held ${u.length} characters at revision ${a??"now"}, so there is nothing at ${l}${o>0?`\u2013${l+o}`:""} to type over`);let x=A({at:l,removed:u.slice(l,l+o),inserted:p},y);x.removed===""&&x.inserted===""||t.emit({op:"splice-text",id:f,field:r,...x})}}}function ee(e,n,i,t,s=()=>!0){let f=i===void 0?void 0:e.tryDefinition(i);if(!f||typeof t!="string")return[];let r=new Set;for(let l of n)if(!(l.name===h||!Y(e,l).includes(i)||!X(l,f).includes(t))&&s(l)){r.add(l.name);for(let o of B(e,n,l)??[])r.add(o)}return[...r]}function se(e,n,i){if(!n.some(r=>r.op==="patch-node"))return[...n];let t=new Set,s=new Set,f=[];for(let r of n){if(r.op==="add-node"&&t.add(r.node.id),r.op!=="patch-node"||t.has(r.id)){r.op==="splice-text"&&s.add(`${r.id}\0${r.field}`),f.push(r);continue}let l=e.graph.getNode(r.id),o={},p={},a=[];for(let[d,c]of Object.entries(r.after)){let g=l?.[d],m=`${r.id}\0${d}`;if(typeof c=="string"&&typeof g=="string"&&g!==""&&!s.has(m)&&O(e.schema,l?.kind,d)){let u=i?.find(x=>x.node===r.id&&x.field===d),y=Q(g,c,u?E(e.log.all(),e.log.horizon,r.id,d,u.rev,g):void 0);if(y){a.push({op:"splice-text",id:r.id,field:d,...y}),s.add(m);continue}}o[d]=r.before[d],p[d]=c,s.add(m)}Object.keys(p).length>0&&f.push(a.length>0?{op:"patch-node",id:r.id,before:o,after:p}:r),f.push(...a)}return f}function de(e,n){let i=[];return[...n].sort((t,s)=>s.seq-t.seq).map(t=>{let s=L(t);if(!s.some(o=>o.op==="splice-text"))return i.push(...s),{op:t,primitives:s};let f=e.filter(o=>o.seq>t.seq).flatMap(o=>o.primitives),r=t.primitives.length,l=[];return s.forEach((o,p)=>{if(o.op!=="splice-text")return void l.push(o);let a=A(o,J([...t.primitives.slice(r-p),...f,...i,...l],o.id,o.field));(a.removed!==""||a.inserted!=="")&&l.push({op:"splice-text",id:o.id,field:o.field,...a})}),i.push(...l),{op:t,primitives:l}})}function ae(e,n){let i=(t,s)=>e.some(f=>M(f,t,s));return n.undoes!==void 0&&n.primitives.length===0&&e.some(t=>t.op==="splice-text")||n.primitives.length>0&&n.primitives.every(t=>t.op==="splice-text"&&!i(t.id,t.field))?!0:e.flatMap(t=>t.op==="splice-text"&&n.primitives.some(s=>M(s,t.id,t.field))?[t.id]:[])}function le(e,n,i){let t=new Map,s=[],f=new Set;for(let a of e){let d=a.primitives[0],c=a.mutation?.args,g=a.mutation?.name!==h||a.primitives.length!==1||!d?void 0:d.op==="splice-text"?d:j(d,String(c?.node),String(c?.field));g?s.push({batch:a.batch,node:String(c?.node),field:String(c?.field),splice:g}):f.add(a.batch)}if(s.length===0)return t;let r=a=>`${a.node}\0${a.field}`,l=new Set,o=new Set(e.map(a=>a.batch).filter(a=>!i.includes(a))),p=s;for(let a of n){if(o.has(a.batch)){p=p.filter(d=>d.batch!==a.batch);continue}for(let d of a.primitives){if(d.op==="add-edge"||d.op==="remove-edge")continue;let c=d.op==="add-node"||d.op==="remove-node"?d.node.id:d.id;for(let g of new Set(p.filter(m=>m.node===c).map(m=>m.field))){let m=d.op==="splice-text"?d.field===g?d:void 0:j(d,c,g);for(let u of p)u.node!==c||u.field!==g||(m?[m,u.splice]=b(m,u.splice):M(d,u.node,u.field)&&l.add(r(u)))}}}p.forEach((a,d)=>{if(!o.has(a.batch))return;let c={at:a.splice.at,removed:a.splice.inserted,inserted:a.splice.removed};for(let g of p.slice(d+1))r(g)===r(a)&&([c,g.splice]=b(c,g.splice))});for(let a of i){let d=p.filter(c=>c.batch===a);d.length===0||f.has(a)||d.some(c=>l.has(r(c)))||t.set(a,d.map(c=>({name:h,args:{node:c.node,field:c.field,at:c.splice.at,remove:c.splice.removed.length,insert:c.splice.inserted}})))}return t}v.typeText=Z;v.via=ee;v.collaborative=O;v.asSplices=se;v.undone=de;v.aside=ae;v.carried=le;function Ye(e){let{store:n,author:i,pending:t,provisional:s,asked:f}=e,r=new Map,l=(o,p)=>{r.get(o)?.(p),r.delete(o)};return{store:n,apply:(o,p)=>e.appliedAll(o,{...i?{author:i}:{},...p!==void 0?{batch:p}:{}}),hold(o){t.push(o),s.add(o),e.answers.set(o,new Promise(p=>r.set(o,p)))},ask:(o,p)=>void f.set(o,{calls:p}),send(o,p){f.set(o,{calls:p});let a=e.sent(o,p),d=()=>l(o,a);return a.then(c=>{Array.isArray(c?.ops)&&c.ops.length===0&&e.letGo.add(o),d()},d),a},drop(o){e.letGo.add(o),e.settle(o),f.delete(o),e.land([],[o]),l(o)},seen:e.seen,gone:e.gone,ahead(o,p,a){let d=t.indexOf(o),c=n.log.all(),g=m=>c.some(u=>u.batch===m&&u.primitives.some(y=>y.op==="splice-text"&&y.id===p&&y.field===a||y.op==="patch-node"&&y.id===p&&a in y.after));return t.slice(0,Math.max(0,d)).flatMap(m=>{let u=e.answers.get(m);return u&&g(m)?[{batch:m,answer:u}]:[]})}}}var ce=400,pe=/[\s.,;:!?)\]}]$/u,W=e=>typeof e=="string"?e:"";function z(e,n,i,t){let s=e.log.all(),f=s.findIndex(o=>o.batch===n);if(f<0)return;let r=W(e.graph.getNode(i)?.[t]),l;for(let o=s.length-1;o>=f;o--){let p=s[o];p.batch===n&&l===void 0&&(l=r);for(let a=p.primitives.length-1;a>=0;a--){let d=p.primitives[a];d.op==="splice-text"&&d.id===i&&d.field===t?r=T(r,{at:d.at,removed:d.inserted,inserted:d.removed}):d.op==="patch-node"&&d.id===i&&t in d.after&&(r=C(d.before[t])?"":W(d.before[t]))}}if(!(l===void 0||l===r))return S(r,l)}function Xe(e,n,i){let t,s=[],f,r,l=!1,o=new Set,p=c=>({name:h,args:{node:e,field:n,at:c.at,remove:c.removed.length,insert:c.inserted,rev:i.seen()}}),a=()=>{r&&clearTimeout(r),r=void 0,t!==void 0&&s.push(t),t=void 0,d()},d=()=>{if(f!==void 0||l||i.gone())return;let c=s.shift();if(c===void 0)return;let g=i.ahead(c,e,n).filter(u=>!o.has(u.batch));if(g.length>0){s.unshift(c),l=!0,Promise.allSettled(g.map(u=>u.answer)).then(()=>{for(let u of g)o.add(u.batch);l=!1,d()});return}let m=z(i.store,c,e,n);if(!m)return i.drop(c),d();f=c,i.send(c,[p(m)]).finally(()=>{f=void 0,d()})};return{splice(c,g,m){if(i.gone())return;let u=W(i.store.graph.getNode(e)?.[n]),y={at:c,removed:u.slice(c,c+g),inserted:m};if(t!==void 0){let F=z(i.store,t,e,n);(!F||!D(F,y))&&a()}let x=i.apply([{name:h,args:{node:e,field:n,at:c,remove:g,insert:m}}],t);if(x.ops.length===0)return;t===void 0&&(t=x.batch,i.hold(t));let k=z(i.store,t,e,n);if(k&&i.ask(t,[p(k)]),pe.test(m))return a();r&&clearTimeout(r),r=setTimeout(a,ce),r.unref?.()},flush:a,waiting:()=>s.length+(t!==void 0?1:0)+(f!==void 0?1:0)}}function Be(e,n){let i=n.find(l=>l.name===h)?.args;if(typeof i?.node!="string"||typeof i.field!="string")return;let{node:t,field:s}=i,f=()=>e.graph.getNode(t)?.[s],r=f();return{node:t,field:s,yours:r,over:l=>{let o=f();return{name:h,args:{node:t,field:s,at:0,remove:typeof o=="string"?o.length:0,insert:typeof r=="string"?r:"",rev:l}}}}}export{ce as TYPING_IDLE_MS,z as runSplice,Xe as typingOf,Ye as wireOf,Be as yoursOf};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as u}from"./chunk.
|
|
1
|
+
import{b as u}from"./chunk.FIY4RUK5.js";import{na as l}from"./chunk.DHPXRDT5.js";function a(e,n){let s=new Map;for(let o of e){let t=n(o.from),i=n(o.to);if(t===void 0||i===void 0)continue;let d=`${o.kind}|${t}|${i}`,r=s.get(d);r||s.set(d,r={edge:o.kind,from:t,to:i,links:0,froms:new Set,tos:new Set}),r.links+=1,r.froms.add(o.from),r.tos.add(o.to)}return[...s.entries()].sort(([o],[t])=>o<t?-1:o>t?1:0).map(([o,t])=>({key:o,edge:t.edge,from:t.from,to:t.to,links:t.links,fromCount:t.froms.size,toCount:t.tos.size}))}function m(e,n,s){let o=[],t=[];for(let d of e){let r=f(d);if(r!==null){o.includes(r)||o.push(r);continue}s(d)!==void 0&&t.push(d)}let i=n.overview&&n.focusId!==null?f(n.focusId):null;return n.beside&&n.overview&&i===null&&n.focusId!==null&&t.length===0&&o.length===0&&s(n.focusId)!==void 0&&t.push(n.focusId),{districts:o,records:t,lens:i}}function f(e){return e.startsWith("kind:")?e.slice(5)||null:e.startsWith("aggregate:")&&!e.includes("|")&&e.slice(10)||null}function y(e,n){let s=u(e,n.from,n.edge,"out"),o=n.from===n.to?" of their own":"";return`${l(e,n.from,n.fromCount)} \u2192 ${l(e,n.to,n.toCount)}${o}, ${s}`}export{a,m as b,f as c,y as d};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as a}from"./chunk.
|
|
1
|
+
import{g as a}from"./chunk.I7KN732Z.js";import{c as l}from"./chunk.TLPCYKLW.js";import{Oa as d}from"./chunk.DHPXRDT5.js";function m(n){let r=new Map;for(let i of n.kinds){let e=n.tryDefinition(i),o=a(e),s=d(e);r.set(i,{fields:new Set(Object.keys(e?.fields?.shape??{})),edges:new Map(Object.entries(e?.edges??{}).map(([p,y])=>[p,y.cardinality??"many"])),...o?{computed:o}:{},...s.size>0?{linked:s}:{}})}let t=a(n);return t&&r.set(l,{computed:t}),r}export{m as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as m}from"./chunk.
|
|
1
|
+
import{c as m}from"./chunk.I7KN732Z.js";import{ga as c,la as u,ma as p,oa as f,ta as h,ua as l}from"./chunk.DHPXRDT5.js";function M(t,e){let n=t.schema.kinds,r="kind"in e?e.kind:void 0;if(r!==void 0&&!n.includes(r))return`There is no kind "${r}" in this app. Its kinds are: ${n.join(", ")}.`;if(e.on==="act"&&e.act!==void 0&&t.allMutations&&!t.allMutations().some(i=>i.name===e.act))return`There is no act "${e.act}" in this app.`;let o="record"in e?e.record:void 0;if(o!==void 0&&t.graph&&!t.graph.getNode(o))return`No record "${o}" is here to be told about.`;if(o!==void 0&&r!==void 0&&t.graph&&t.graph.getNode(o)?.kind!==r)return`\u201C${o}\u201D is not ${h(r)}.`;if(e.on==="changed"&&e.kind===void 0&&e.record===void 0)return"Say which kind, or which record, to be told about.";if(e.on==="reaches"){if(e.condition.trim()==="")return"Say what it should reach: a condition like done == true.";try{m(e.condition)}catch(i){return`The condition does not read: ${i instanceof Error?i.message:String(i)}.`}}}function d(t,e){let n=t.graph?.getNode(e);return n?u(t.schema.tryDefinition(n.kind),n):e}function g(t,e){let n=t.allMutations?.().find(r=>r.name===e);return n?p(n):c(e)}function v(t,e){let{when:n}=e,r=e.alsoMine?"anyone":"someone else",o=s=>l(t.schema.tryDefinition(s),s),i=s=>{let a=o(s);return`${/^[aeiou]/i.test(a)?"an":"a"} ${a}`};switch(n.on){case"act":{let s=n.act!==void 0?`\u201C${g(t,n.act)}\u201D`:"an act";return`When ${r} runs ${s}${n.record!==void 0?` on \u201C${d(t,n.record)}\u201D`:""}`}case"created":return`When ${r} adds ${i(n.kind)}`;case"changed":return n.record!==void 0?`When ${r} changes \u201C${d(t,n.record)}\u201D`:`When ${r} changes any of the ${f(t.schema,n.kind)}`;case"reaches":return`When ${n.record!==void 0?`\u201C${d(t,n.record)}\u201D`:i(n.kind)} reaches ${n.condition}${e.alsoMine?"":" (by someone else)"}`}}export{M as a,v as b};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as v,b as w,c as x}from"./chunk.MB7LKKUD.js";import"./chunk.
|
|
1
|
+
import{a as v,b as w,c as x}from"./chunk.MB7LKKUD.js";import"./chunk.NLZHNPDU.js";import"./chunk.QNC2OKLF.js";import{G as R,Va as g,W as y,Xa as h}from"./chunk.FWXW4T4I.js";import"./chunk.SDO3U72B.js";import{lb as b,td as m}from"./chunk.DHPXRDT5.js";import"./chunk.FQLNBIQ5.js";import{b as p}from"./chunk.AJZBJBMO.js";var c=p(R(),1);var r=p(y(),1);function W({notices:e,anchor:n,board:a,report:i}){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(k,{notices:e.filter(s=>s.kind==="banner"),at:"top",anchor:n,board:a,report:i}),(0,r.jsx)(k,{notices:e.filter(s=>s.kind==="toast"),at:"foot",anchor:n,board:a,report:i})]})}var E={info:"var(--graview-accent)",good:"var(--graview-good)",warn:"var(--graview-warn)",bad:"var(--graview-bad)"},C={info:"i",good:"\u2713",warn:"!",bad:"!"};function k({notices:e,at:n,anchor:a,board:i,report:s}){let l=(0,c.useRef)(null),t=e.length>0;return(0,c.useLayoutEffect)(()=>{let o=l.current;if(!t||!o)return;if(typeof o.showPopover=="function"&&!g(o))try{o.showPopover()}catch{}let d=()=>(n==="top"?x:w)(o,a());d(),n==="foot"&&i.hold?.(()=>o.matches(":hover")||o.contains(document.activeElement));let N=h(o);addEventListener("resize",d),addEventListener("scroll",d,!0),n==="foot"&&addEventListener(v,d);let u=typeof ResizeObserver=="function"?new ResizeObserver(d):null;return u?.observe(o),()=>{if(N(),u?.disconnect(),removeEventListener("resize",d),removeEventListener("scroll",d,!0),removeEventListener(v,d),o.isConnected&&g(o))try{o.hidePopover()}catch{}}},[t,n,a,i]),t?(0,r.jsx)("div",{ref:l,popover:"manual",role:"region","aria-label":n==="top"?"Notices":"Messages","data-testid":n==="top"?"notices-banners":"notices-toasts","data-graview-offstage":"",style:{position:"fixed",inset:"auto",margin:0,padding:0,border:"none",background:"none",overflow:"visible",zIndex:m("toast"),width:"max-content",height:"auto",maxWidth:"min(560px, calc(100vw - 32px))",display:"grid",gap:8,color:"var(--graview-ink)"},children:e.map(o=>(0,r.jsx)(O,{notice:o,board:i,report:s},o.id))}):null}var T=e=>e.split(/\s+/).filter(Boolean).map(n=>n.replace(/^Meta\+/,"\u2318").replace(/^Control\+/,"Ctrl+").replace(/^Alt\+/,"Alt+")).join(" or "),H=e=>/^.*?[.!?](?=\s|$)/.exec(e.trim())?.[0]??e.trim(),L=e=>e.from==="framework"&&(e.tone==="bad"||e.tone==="warn");function O({notice:e,board:n,report:a}){let i=e.tone??"info",s=[...e.action?[e.action]:[],...e.actions??[]],l=()=>n.dismiss(e.id);return(0,r.jsxs)("div",{"data-testid":"notice","data-kind":e.kind,"data-tone":i,style:{boxSizing:"border-box",display:"flex",flexWrap:"wrap",alignItems:"center",gap:"8px 12px",padding:e.kind==="banner"?"8px 10px 8px 12px":"10px 12px 10px 12px",borderRadius:"var(--graview-radius, 12px)",border:"1px solid var(--graview-edge)",background:"var(--graview-float)",boxShadow:"var(--graview-lift-high)",fontSize:"0.875rem",lineHeight:1.45},children:[(0,r.jsx)("span",{"aria-hidden":"true","data-testid":"notice-chip",style:{width:20,height:20,borderRadius:"var(--graview-radius-sm, 6px)",flex:"0 0 auto",display:"inline-grid",placeItems:"center",fontSize:"0.75rem",fontWeight:700,lineHeight:1,color:"var(--graview-ink)",background:`color-mix(in srgb, ${E[i]} 22%, transparent)`},children:C[i]}),(0,r.jsx)("span",{"data-testid":"notice-sentence",style:{flex:"1 1 16rem",minWidth:0},children:e.sentence}),s.length>0?(0,r.jsx)("span",{style:{display:"flex",flexWrap:"wrap",gap:6},children:s.map((t,o)=>t.href!==void 0?(0,r.jsx)("a",{href:t.href,...t.target?{target:t.target,rel:"noopener"}:{},"data-testid":"notice-action",onClick:()=>{t.onSelect?.(),l()},style:{...f,...o===0?S:{}},children:t.label},t.label):(0,r.jsx)("button",{type:"button","data-testid":"notice-action",...t.keys?{"aria-keyshortcuts":t.keys,title:`${t.label} \u2014 ${T(t.keys)}`}:{},onClick:()=>{l(),t.onSelect?.()},style:{...f,...o===0?S:{}},children:t.label},t.label))}):null,a&&L(e)?(0,r.jsx)("button",{type:"button","data-testid":"notice-report","aria-label":`Report this: ${H(e.sentence)}`,onClick:()=>a.tell({message:e.sentence,...e.code?{code:e.code}:{},...a.where(),version:b}),style:f,children:"Report this"}):null,(0,r.jsx)("button",{type:"button","data-testid":"notice-dismiss","aria-label":`Dismiss: ${e.sentence}`,title:"Dismiss",onClick:l,style:z,children:"\xD7"})]})}var f={display:"inline-flex",alignItems:"center",minHeight:28,padding:"2px 12px",borderRadius:9,border:"1px solid var(--graview-edge)",background:"var(--graview-panel)",color:"var(--graview-ink)",font:"inherit",fontWeight:500,textDecoration:"none",cursor:"pointer"},S={background:"var(--graview-accent)",borderColor:"var(--graview-accent)",color:"var(--graview-accent-ink)"},z={minWidth:28,minHeight:28,padding:0,border:"none",background:"none",boxShadow:"none",color:"var(--graview-ink-muted)",fontSize:"1rem",cursor:"pointer"};export{W as NoticeStacks,H as firstSentenceOf,L as reportable};
|