hyper-html-api 0.13.0 → 0.14.0
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/README.md +4 -1
- package/conformance/MANIFEST.json +2 -2
- package/conformance/cases/all-matches-read-quoted.expected.json +3 -0
- package/conformance/cases/all-matches-read-quoted.html +5 -0
- package/conformance/cases/all-matches-read-quoted.meta +7 -0
- package/conformance/cases/all-matches-read-quoted.parsed.json +3 -0
- package/conformance/cases/all-matches-read.expected.json +3 -0
- package/conformance/cases/all-matches-read.html +6 -0
- package/conformance/cases/all-matches-read.meta +7 -0
- package/conformance/cases/all-matches-read.parsed.json +3 -0
- package/conformance/cases/write-all-matches-attr.after.html +1 -0
- package/conformance/cases/write-all-matches-attr.after.json +3 -0
- package/conformance/cases/write-all-matches-attr.data.json +1 -0
- package/conformance/cases/write-all-matches-attr.html +1 -0
- package/conformance/cases/write-all-matches-attr.meta +6 -0
- package/conformance/cases/write-all-matches-attr.write.json +4 -0
- package/conformance/cases/write-all-matches-group.after.html +1 -0
- package/conformance/cases/write-all-matches-group.after.json +3 -0
- package/conformance/cases/write-all-matches-group.data.json +1 -0
- package/conformance/cases/write-all-matches-group.html +1 -0
- package/conformance/cases/write-all-matches-group.meta +6 -0
- package/conformance/cases/write-all-matches-group.write.json +4 -0
- package/conformance/cases/write-all-matches-text.after.html +1 -0
- package/conformance/cases/write-all-matches-text.after.json +3 -0
- package/conformance/cases/write-all-matches-text.data.json +1 -0
- package/conformance/cases/write-all-matches-text.html +1 -0
- package/conformance/cases/write-all-matches-text.meta +6 -0
- package/conformance/cases/write-all-matches-text.write.json +4 -0
- package/conformance/cases/write-all-matches-unmatched.data.json +1 -0
- package/conformance/cases/write-all-matches-unmatched.error.json +14 -0
- package/conformance/cases/write-all-matches-unmatched.html +1 -0
- package/conformance/cases/write-all-matches-unmatched.meta +6 -0
- package/dist/hyper-html-api.engine.esm.js +1 -1
- package/dist/hyper-html-api.engine.min.js +1 -1
- package/dist/hyper-html-api.min.js +8 -8
- package/dist/hyper-html-api.upgrade.min.js +2 -2
- package/package.json +3 -2
- package/src/engine/apply.js +6 -7
- package/src/engine/extract.js +6 -3
- package/src/engine/round-trip.js +9 -1
- package/src/engine/rule-syntax.js +13 -3
- package/src/engine/write-plan.js +2 -3
- package/src/page.js +15 -5
- package/src/site.js +164 -0
- package/src/upgrade/migrate.js +2 -1
- package/src/upgrade/shape-match.js +32 -13
- package/src/write.js +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var hyperHtmlApiUpgrade=(()=>{var fe=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var pt=Object.getOwnPropertyNames;var ht=Object.prototype.hasOwnProperty;var Pe=(e,t)=>{for(var n in t)fe(e,n,{get:t[n],enumerable:!0})},mt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of pt(t))!ht.call(e,r)&&r!==n&&fe(e,r,{get:()=>t[r],enumerable:!(o=dt(t,r))||o.enumerable});return e};var yt=e=>mt(fe({},"__esModule",{value:!0}),e);var ln={};Pe(ln,{default:()=>cn,engine:()=>Se,upgrade:()=>ut});var G=["textContent","innerText","innerHTML","outerHTML","value","checked","selected","disabled","readOnly","type","tagName","nodeName","nodeType","nodeValue","childElementCount","id","className","classList","baseURI","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","dataset","currentSrc","duration","paused","title","documentURI","contentType"],Z=new Set(G),ue=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),Q=new Set(["tagName","nodeName","nodeType","nodeValue","childElementCount","classList","baseURI","documentURI","contentType","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","currentSrc","duration","paused","dataset"]),Me=new Set(["checked","selected","disabled","readOnly","paused"]);function ae(e,t){return t==null?Me.has(e)?!1:"":Me.has(e)?t==="false"?!1:!!t:t}var ne={};Pe(ne,{EmptyListInsert:()=>P,MAX_RULE_DEPTH:()=>D,MaxRuleDepthExceeded:()=>k,NoRulesTag:()=>de,RuleTargetReadOnly:()=>H,RulesParseError:()=>_,ShapeMismatch:()=>U,UnknownRulesVersion:()=>M,WriteNotRoundTripped:()=>te,WriteRefused:()=>ee,WriteRejected:()=>pe});var _=class extends Error{constructor(t,n){super(t),this.name="RulesParseError",this.cause=n}},M=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},D=20,k=class extends Error{constructor(t){super(`rule depth exceeded ${D} at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},U=class extends Error{constructor(t){super(`shape mismatch: ${t.length} field(s) failed validation`),this.name="ShapeMismatch",this.mismatches=t}},P=class extends Error{constructor(t,n){super(n?`cannot add items to empty list at "${t.join(".")}" \u2014 ${n}`:`cannot add items to empty list at "${t.join(".")}" \u2014 no sibling to clone as template. Seed the list with a hidden item first.`),this.name="EmptyListInsert",this.path=t}},H=class extends Error{constructor(t){super(`cannot write to read-only DOM property "${t}"`),this.name="RuleTargetReadOnly",this.target=t}},ee=class extends Error{constructor(t){super(`write refused: ${t.length} write(s) broke the content-only policy`),this.name="WriteRefused",this.refusals=t}};function gt(e){return e.reduce((n,o)=>typeof o=="number"?`${n}[${o}]`:n?`${n}.${o}`:String(o),"")||"(root)"}var te=class extends Error{constructor(t){super(`write did not round-trip at "${gt(t)}"`),this.name="WriteNotRoundTripped",this.path=t}},de=class extends Error{constructor(t){super(`no <script data-rules-name~="${t}"> rules tag in this document`),this.name="NoRulesTag",this.token=t}},pe=class extends Error{constructor(t,n){super(`write rejected: ${t.length} unknown key(s), ${n.length} rule(s) with no matching element`),this.name="WriteRejected",this.unknownKeys=t,this.unmatched=n}};function S(e){let t=0,n=null,o=-1;for(let r=0;r<e.length;r++){let i=e[r];i==="\\"?r++:n?i===n&&(n=null):i==='"'||i==="'"?n=i:i==="["||i==="("?t++:i==="]"||i===")"?t>0&&t--:i==="@"&&t===0&&(o=r)}return o}function he(e){let t=S(e);return t===-1?{selector:e,prop:null}:{selector:e.slice(0,t),prop:e.slice(t+1)||null}}function me(e){let t=0,n=null,o=-1,r=!1;for(let i=0;i<e.length;i++){let s=e[i];s==="\\"?i++:n?s===n&&(n=null):s==='"'||s==="'"?n=s:s==="["||s==="("?t++:s==="]"||s===")"?t>0&&t--:t===0&&s===">"?o=i:t===0&&s===","&&(r=!0)}return r||o===-1||!At(e,o+1)?null:e.slice(0,o).trim()||null}function At(e,t){let n=t,o=e.replace(/\s+$/,"").length;for(;n<o&&/\s/.test(e[n]);)n++;let r=0,i=null;for(;n<o;n++){let s=e[n];if(s==="\\")n++;else if(i)s===i&&(i=null);else if(s==='"'||s==="'")i=s;else if(s==="["||s==="(")r++;else if(s==="]"||s===")")r>0&&r--;else if(r===0&&(s==="+"||s==="~"||/\s/.test(s)))return!1}return!0}var wt=/^--[A-Za-z0-9_-]+$/;function I(e){return typeof e=="string"&&wt.test(e)}function ke(e){let t=[],n=[],o=null,r=0;for(let i=0;i<e.length;i++){let s=e[i];if(o){s==="\\"?i++:s===o&&(o=null);continue}if(s==="/"&&e[i+1]==="*"){let c=e.indexOf("*/",i+2);i=c===-1?e.length:c+1;continue}s==='"'||s==="'"?o=s:s==="("?n.push(")"):s==="["?n.push("]"):s==="{"?n.push("}"):(s===")"||s==="]"||s==="}")&&n[n.length-1]===s?n.pop():s===";"&&n.length===0&&(t.push(e.slice(r,i)),r=i+1)}return t.push(e.slice(r)),t}function Tt(e){let t="",n=null;for(let o=0;o<e.length;o++){let r=e[o];if(n){t+=r,r==="\\"&&o+1<e.length?t+=e[++o]:r===n&&(n=null);continue}if(r==="/"&&e[o+1]==="*"){let i=e.indexOf("*/",o+2);o=i===-1?e.length:i+1,t+=" ";continue}(r==='"'||r==="'")&&(n=r),t+=r}return t}function Ie(e){e=Tt(e);let t=e.indexOf(":");if(t===-1)return null;let n=e.slice(0,t).trim(),o=e.slice(t+1).trim(),r=/!\s*important\s*$/i.exec(o);return r&&(o=o.slice(0,r.index).trim()),{name:n,value:o,important:!!r}}function q(e,t){if(e==null)return null;let n=null;for(let o of ke(String(e))){let r=Ie(o);!r||r.name!==t||(!n||r.important||!n.important)&&(n=r)}return n?n.value:null}function Le(e,t,n){let o=e==null?"":String(e),r=n==null||n==="",i=ke(o),s=i.map(Ie),c=s.some(h=>h&&h.name===t&&h.important),l=[],u=!1;i.forEach((h,m)=>{let T=s[m];if(!T||T.name!==t){l.push(h);return}if(r||u)return;let f=/^\s*/.exec(h)[0];l.push(`${f}${t}: ${n}${c?" !important":""}`),u=!0});let d=l.join(";");if(!r&&!u){let h=d.trimEnd();d=h===""?`${t}: ${n}`:`${h}${h.endsWith(";")?" ":"; "}${t}: ${n}`}return d.trim()===""?null:d}function ye(e,t,n,o){let r=e.attr(t,"style");if((q(r,n)??"")===o)return;let i=Le(r,n,o);i==null?e.removeAttr(t,"style"):e.attr(t,"style",i)}function N(e,t,n,o={}){if(Object.prototype.hasOwnProperty.call(o,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");return ge(e,t,n,{depth:0,path:[]},o)}function ge(e,t,n,o,r){if(o.depth>D)throw new k(o.path);if(typeof n=="string")return xt(e,t,n,o,r);if(Array.isArray(n)){let[i,s]=n,c=e.find(t,i,r);return $e(r,o,c),c.map((l,u)=>ge(e,l,s,{depth:o.depth+1,path:[...o.path,u]},r))}if(typeof n=="object"&&n!==null){let i={};for(let[s,c]of Object.entries(n))i[s]=ge(e,t,c,{depth:o.depth+1,path:[...o.path,s]},r);return i}return null}function xt(e,t,n,o,r){if(n.endsWith("[]")){let c=n.slice(0,-2),l=e.find(t,c,r);return $e(r,o,l),l.map(u=>e.text(u))}if(n.startsWith("@"))return je(e,t,n.slice(1));let i=S(n);if(i!==-1){let c=n.slice(0,i),l=n.slice(i+1),u=c?e.find(t,c,r):[t];return u.length===0?null:je(e,u[0],l)}if(n===".")return e.text(t);let s=e.find(t,n,r);return s.length===0?null:e.text(s[0])}function $e(e,t,n){if(typeof e.onRowsRead=="function")try{e.onRowsRead(t.path.slice(),n)}catch(o){console.warn(`[hyper-html-api] onRowsRead threw at "${t.path.join(".")||"(root)"}"`,o)}}function je(e,t,n){if(I(n))return q(e.attr(t,"style"),n);if(Z.has(n)){let r=e.prop(t,n);return r==null?null:String(r)}let o=e.attr(t,n);return o??null}function ve(e,t,n,o){let r=e.length,i=t.length,s=new Array(r).fill(-1);if(o){let a=new Set;for(let y=0;y<r;y++){let A=o[y];!(A>=0&&A<i)||a.has(A)||(s[y]=A,a.add(A))}}if(r===0||i===0)return s;let c=e.map(a=>_e(a,n)),l=t.map(a=>_e(a,n)),u=new Array(i).fill(!1);for(let a of s)a>=0&&(u[a]=!0);let d=new Map;l.forEach((a,y)=>{u[y]||d.set(a,d.has(a)?-1:y)});let h=new Map;c.forEach((a,y)=>{s[y]>=0||h.set(a,(h.get(a)||0)+1)}),c.forEach((a,y)=>{if(s[y]>=0||h.get(a)!==1)return;let A=d.get(a);A===void 0||A===-1||u[A]||(s[y]=A,u[A]=!0)});let m=[];for(let a=0;a<r;a++)s[a]<0&&m.push(a);let T=[];for(let a=0;a<i;a++)u[a]||T.push(a);if(m.length===0||T.length===0)return s;let f=r*i+1,p=Ot(e,t,n),g=(a,y)=>p(a,y)*f+Math.abs(a-y);for(let[a,y]of Et(m,T,g))s[a]=y;return s}var We=e=>typeof e=="object"&&e!==null;function _e(e,t){if(!We(t))return e==null?" null":String(e);let n=Object.keys(t);return JSON.stringify(n.map(o=>{let r=JSON.stringify(e?.[o]);return r===void 0?" undef":r}))}function Ot(e,t,n){if(!We(n))return(c,l)=>e[c]===t[l]?0:1;let o=Object.keys(n),r=c=>o.map(l=>JSON.stringify(c?.[l])),i=e.map(r),s=t.map(r);return(c,l)=>{let u=i[c],d=s[l],h=0;for(let m=0;m<o.length;m++)u[m]!==d[m]&&h++;return h}}function Et(e,t,n){return e.length<=t.length?De(e,t,n,!1):De(t,e,(o,r)=>n(r,o),!0)}function De(e,t,n,o){let r=e.length,i=t.length,s=[];for(let h=0;h<=r;h++)s.push(new Float64Array(i+1).fill(1/0));let c=[];for(let h=0;h<=r;h++)c.push(new Uint8Array(i+1));for(let h=0;h<=i;h++)s[r][h]=0;for(let h=r-1;h>=0;h--)for(let m=i-1;m>=0;m--){let T=n(e[h],t[m])+s[h+1][m+1],f=s[h][m+1];T<=f?(s[h][m]=T,c[h][m]=1):s[h][m]=f}let l=[],u=0,d=0;for(;u<r&&d<i;)c[u][d]&&(l.push(o?[t[d],e[u]]:[e[u],t[d]]),u++),d++;return l}function we(e,t,n,o,r,i,s,c={}){let l=e.find(t,n,c);if(r.length===0){l.forEach(w=>e.remove(w)),Ae(c,"onRowsApplied",i.path,[]);return}let u=r.length>l.length,d=l[0]||null;if(u&&!d&&(d=Nt(e,t,n,c),!d))throw new P(i.path);let h=l.map(w=>Rt(e,w,o,c)),m=null;if(u&&d){m=e.clone(d),c.templateAttr&&e.removeAttr(m,c.templateAttr);let w=e.stripIds(m);w>0&&console.warn(`[hyper-html-api] stripped ${w} id attribute(s) from cloned template at "${i.path.join(".")||"(root)"}"`)}let T=ve(r,h,o,bt(e,l,r,i,c)),f=l.length>0?e.parent(l[0]):kt(e,t,n,d,i,c),p=l.length>0?Be(e,f,l[0]):0,g=jt(e,l),a=new Set,y=[],A=r.map((w,b)=>{let O=T[b];if(O>=0)return a.add(O),y.push(!1),l[O];y.push(!0);let x=e.clone(m);return e.stripIds(x),x});l.forEach((w,b)=>{a.has(b)||e.remove(w)}),g?Lt(e,f,p,A,y):$t(e,A,y,f,p),St(e,A,o,r,i,s,c),Ae(c,"onRowsApplied",i.path,A)}function Ae(e,t,n,o){if(typeof e[t]=="function")try{return e[t](n.slice(),o)}catch(r){console.warn(`[hyper-html-api] ${t} threw at "${n.join(".")||"(root)"}"`,r);return}}function bt(e,t,n,o,r){let i=Ae(r,"identifyRows",o.path,n);if(!Array.isArray(i))return null;let s=new Array(n.length).fill(-1),c=new Set,l=new Map(t.map((u,d)=>[e.identity(u),d]));for(let u=0;u<n.length;u++){if(!i[u])continue;let d=l.get(e.identity(i[u]));d===void 0||c.has(d)||(s[u]=d,c.add(d))}return s}function St(e,t,n,o,r,i,s){t.forEach((c,l)=>{if(n===null){let u=o[l],d=u==null?"":String(u);e.text(c)!==d&&e.text(c,d)}else{let u=i(e,c,n,o[l],{depth:r.depth+1,path:[...r.path,l]},s);u&&u!==c&&(t[l]=u)}})}function Rt(e,t,n,o){return n===null?e.text(t):N(e,t,n,o.onRowsRead?{...o,onRowsRead:void 0}:o)}function Be(e,t,n){let o=e.children(t);for(let r=0;r<o.length;r++)if(e.sameNode(o[r],n))return r;return-1}function Nt(e,t,n,o){if(!o.templateAttr)return null;let r=/^\s*:scope\s*>\s*/.test(n),i=new RegExp(":not\\(\\["+o.templateAttr.replace(/[.*+?^${}()|[\]\\-]/g,"\\$&")+"\\]\\)","g"),s=n.replace(/^\s*:scope\s*>\s*/,"").replace(i,""),c=r?Ct(s):0,l=me(s),u=t;for(;u;){let d=e.find(u,s,{includeRulesTag:!1,templateAttr:null});for(let h of d)if(e.attr(h,o.templateAttr)!=null&&!(r&&!Mt(e,t,h,c))&&!(l&&!e.matches(e.parent(h),l)))return h;u=e.parent(u)}return null}function Ct(e){let t=0,n=null,o=1;for(let r=0;r<e.length;r++){let i=e[r];if(i==="\\")r++;else if(n)i===n&&(n=null);else if(i==='"'||i==="'")n=i;else if(i==="["||i==="(")t++;else if(i==="]"||i===")")t>0&&t--;else if(t===0&&i===">")o++;else{if(t===0&&(i==="+"||i==="~"))return null;if(t===0&&/\s/.test(i)){if(!Pt(e,r))return null;for(;r+1<e.length&&/\s/.test(e[r+1]);)r++}}}return o}function Pt(e,t){let n=t;for(;n<e.length&&/\s/.test(e[n]);)n++;let o=t>0?e[t-1]:"",r=n<e.length?e[n]:"";return Ue(o)||Ue(r)}function Ue(e){return e===">"||e==="+"||e==="~"}function Mt(e,t,n,o){if(o===null)return!0;let r=n;for(let l=0;l<o;l++)if(r=e.parent(r),!r)return!1;let i=e.prop(t,"tagName");if(!i)return!0;let s=e.prop(r,"tagName");if(!s||String(s).toLowerCase()!==String(i).toLowerCase())return!1;let c=new Set(He(e,r));return He(e,t).every(l=>c.has(l))}function He(e,t){let n=e.attr(t,"class");return n?String(n).split(/\s+/).filter(Boolean):[]}function kt(e,t,n,o,r,i){let s=e.parent(o);if(s&&It(e,t,s)&&!Ve(e,s,i))return s;let c=me(n);if(!c)throw new P(r.path,`the list selector "${n}" names no container to hold the new rows \u2014 write it as "container > row" (for example "ol.comments > li") so the cloned row lands in the list`);let u=(c===":scope"?e.prop(t,"tagName")?[t]:[]:e.find(t,c,i)).filter(d=>!Ve(e,d,i));if(u.length===0)throw new P(r.path,`no container matching "${c}" inside this context to hold the new rows`);if(u.length>1)throw new P(r.path,`"${c}" matches ${u.length} containers inside this context, so the new rows have no single destination`);return u[0]}function It(e,t,n){let o=n;for(;o;){if(e.sameNode(o,t))return!0;o=e.parent(o)}return e.parent(t)?!1:e.find(t,"*",{includeRulesTag:!0,templateAttr:null}).some(r=>e.sameNode(r,n))}var qe=["no-data","editor-ui"];function Ve(e,t,n){let o=t;for(;o;){if(n.templateAttr&&e.attr(o,n.templateAttr)!=null||qe.some(i=>e.attr(o,i)!=null))return!0;let r=e.attr(o,"clay");if(r&&r.split(/\s+/).some(i=>qe.includes(i)))return!0;o=e.parent(o)}return!1}function Lt(e,t,n,o,r){let i=e.children(t),s=i.map(l=>e.identity(l)),c=!1;o.forEach((l,u)=>{let d=e.identity(l),h=n+u;if(s[h]===d)return;if(!r[u]){let T=s.indexOf(d);T!==-1&&(s.splice(T,1),i.splice(T,1))}let m=Math.min(h,i.length);m<i.length?e.insertBefore(i[m],l):i.length?c?e.insertAfter(i[i.length-1],l):(e.insertAt(t,l,h),c=!0):e.insertAt(t,l,0),s.splice(m,0,d),i.splice(m,0,l)})}function jt(e,t){if(t.length<=1)return!0;let n=e.parent(t[0]);if(!n)return!1;let o=new Map(e.children(n).map((i,s)=>[e.identity(i),s])),r=[];for(let i of t){let s=o.get(e.identity(i));if(s===void 0)return!1;r.push(s)}return r.sort((i,s)=>i-s),r[r.length-1]-r[0]===r.length-1}function $t(e,t,n,o,r){let i=null,s=r;for(let c=0;c<t.length;c++){if(!n[c]){i=t[c];continue}let l=i?e.parent(i):o;if(!l)continue;let u=i?Be(e,l,i)+1:s++;e.insertAt(l,t[c],u),i=t[c]}}function L(e,t,n,o,r={}){if(Object.prototype.hasOwnProperty.call(r,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");let i=[];if(Te(n,o,[],i),i.length)throw new U(i);re(e,t,n,o,{depth:0,path:[]},r)}function re(e,t,n,o,r,i={}){if(r.depth>D)throw new k(r.path);if(o===void 0)return t;if(typeof n=="string")return _t(e,t,n,o,r,i);if(Array.isArray(n)){let[s,c]=n;return we(e,t,s,c,o,r,re,i),t}if(typeof n=="object"&&n!==null){for(let[s,c]of Object.entries(n)){let l=re(e,t,c,o==null?o:o[s],{depth:r.depth+1,path:[...r.path,s]},i);l&&l!==t&&(t=l)}return t}return t}function _t(e,t,n,o,r,i){if(n.endsWith("[]")){let l=n.slice(0,-2);return we(e,t,l,null,o,r,re,i),t}if(n.startsWith("@"))return Fe(e,t,n.slice(1),o);let s=S(n);if(s!==-1){let l=n.slice(0,s),u=n.slice(s+1),d=l?e.find(t,l,i):[t];return d.length===0||Fe(e,d[0],u,o),t}if(n===".")return ze(e,t,o),t;let c=e.find(t,n,i);return c.length===0||ze(e,c[0],o),t}function ze(e,t,n){let o=n==null?"":String(n);e.text(t)!==o&&e.text(t,o)}function Dt(e,t,n,o){if(e.styleVar){e.styleVar(t,n,o);return}ye(e,t,n,o)}function Fe(e,t,n,o){if(I(n))return Dt(e,t,n,o==null?"":String(o).trim()),t;if(Q.has(n)){let r=e.prop(t,n);if(r===o||r!=null&&o!=null&&String(r)===String(o))return t;throw new H(n)}if(n==="outerHTML"){let r=o==null?"":String(o);return e.replaceWith(t,r)}if(ue.has(n)){let r=ae(n,o);return e.prop(t,n)!==r&&e.prop(t,n,r),t}if(o==null)e.attr(t,n)!=null&&e.removeAttr(t,n);else{let r=String(o);e.attr(t,n)!==r&&e.attr(t,n,r)}return t}function Te(e,t,n,o){if(t!==void 0){if(typeof e=="string"){if(e.endsWith("[]")){Array.isArray(t)?t.forEach((r,i)=>{typeof r=="object"&&r!==null&&o.push({path:B([...n,i]),expected:"scalar",got:V(r)})}):o.push({path:B(n),expected:"array",got:V(t)});return}t!==null&&typeof t=="object"&&o.push({path:B(n),expected:"scalar",got:V(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){o.push({path:B(n),expected:"array",got:V(t)});return}let r=e[1];t.forEach((i,s)=>Te(r,i,[...n,s],o));return}if(typeof e=="object"&&e!==null){if(t===null||Array.isArray(t)||typeof t!="object"){o.push({path:B(n),expected:"object",got:V(t)});return}for(let[r,i]of Object.entries(e))Te(i,t[r],[...n,r],o)}}}function V(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function B(e){return e.join(".")}function xe(e){try{return JSON.parse(e)}catch(t){throw new _(`Invalid strict JSON: ${t.message}`,t)}}function j(e){try{return JSON.parse(e)}catch{}let t={BRACE_OPEN:"{",BRACE_CLOSE:"}",BRACKET_OPEN:"[",BRACKET_CLOSE:"]",COLON:":",COMMA:",",STRING:"STRING",SELECTOR:"SELECTOR",IDENTIFIER:"IDENTIFIER",NUMBER:"NUMBER",BOOLEAN:"BOOLEAN"};function n(r){let i=[],s=0;for(;s<r.length;){let c=r[s];if(/\s/.test(c)){s++;continue}if("{}".includes(c)){i.push({type:c,value:c}),s++;continue}if(c==="["){let h=!1,m=s+1;for(;m<r.length&&/\s/.test(r[m]);)m++;if(m<r.length&&/[a-zA-Z_]/.test(r[m])&&(h=!0),!h){i.push({type:c,value:c}),s++;continue}}if(c==="]"){i.push({type:c,value:c}),s++;continue}if(c===":"){i.push({type:t.COLON,value:c}),s++;continue}if(c===","){i.push({type:t.COMMA,value:c}),s++;continue}if(c==='"'||c==="'"){let h=c,m=s+1;for(;m<r.length&&r[m]!==h;)r[m]==="\\"&&m++,m++;i.push({type:t.STRING,value:r.substring(s+1,m),quoted:!0,sourceQuote:h}),s=m+1;continue}let l=s,u;for(;l<r.length&&!/[{},]/.test(r[l]);)if(r[l]===":"){let h=[":first",":last",":nth-child",":nth-of-type",":first-child",":last-child",":first-of-type",":last-of-type",":only-child",":only-of-type",":hover",":focus",":active",":visited",":disabled",":enabled",":checked",":empty",":root",":target",":not",":before",":after",":nth-last-child",":nth-last-of-type"],m=!1;for(let T of h){let f=T.substring(1);if(r.substring(l+1,l+1+f.length)===f){m=!0,l+=f.length;break}}if(!m)break}else if(r[l]==="["){for(l++;l<r.length&&r[l]!=="]";){if(r[l]==='"'||r[l]==="'"){let h=r[l];for(l++;l<r.length&&r[l]!==h;)r[l]==="\\"&&l++,l++}l++}l<r.length&&r[l]==="]"&&l++}else l++;u=r.substring(s,l);let d=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(u)?d=t.NUMBER:u==="true"||u==="false"||u==="null"?d=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(u)&&(d=t.SELECTOR),i.push({type:d,value:u,quoted:!1}),s=l}return i}function o(r){let i="";for(let s=0;s<r.length;s++){let c=r[s];if("{}".includes(c.type)||"[]".includes(c.type)){i+=c.value;continue}if(c.type===t.COLON){i+=c.value;continue}if(c.type===t.COMMA){let l=r[s+1];if(l&&(l.type==="}"||l.type==="]"))continue;i+=c.value;continue}if(c.type===t.STRING&&c.quoted){let l=c.value;c.sourceQuote==="'"&&(l=l.replace(/\\'/g,"'"),l=l.replace(/(\\*)"/g,(u,d)=>d.length%2===0?d+'\\"':u)),i+=`"${l}"`;continue}if(c.type===t.NUMBER||c.type===t.BOOLEAN){i+=c.value;continue}if(c.type===t.SELECTOR||c.type===t.IDENTIFIER){i+=`"${c.value}"`;continue}i+=`"${c.value}"`}return i}try{let r=n(e),i=o(r);return JSON.parse(i)}catch(r){throw new _("Invalid extraction rules syntax: "+r.message,r)}}var Oe="1",Ke=/^[a-zA-Z0-9_-]+$/;function z(e,t,n){let o;if(n===void 0)o="script[data-rules-name]";else{if(typeof n!="string"||!Ke.test(n))throw new Error(`hyper-html-api: invalid rules token ${JSON.stringify(n)} (must match ${Ke})`);o=`script[data-rules-name~="${n}"]`}let r=e.find(t,o,{includeRulesTag:!0});if(r.length===0)return null;n!==void 0&&r.length>1&&console.warn(`hyper-html-api: ${r.length} rules tags match data-rules-name~="${n}"; using the first.`);let i=r[0],s=e.attr(i,"data-rules-version");if(s!==Oe)throw new M(s);return{rules:j(e.text(i)),tagNode:i}}var oe=Object.freeze({data:Object.freeze({tokens:["no-data"],bundles:["editor-ui"]}),save:Object.freeze({tokens:["no-save"],bundles:["editor-ui"]}),snapshot:Object.freeze({tokens:["no-snapshot"],bundles:["editor-ui"]}),watch:Object.freeze({tokens:["no-watch"],bundles:["editor-ui"]}),undo:Object.freeze({tokens:["no-undo"],bundles:["editor-ui"]}),history:Object.freeze({tokens:[],bundles:["editor-ui"]})}),vt=Object.freeze({"editor-ui":Object.freeze(["no-data","no-save","no-snapshot","no-watch","no-undo"])}),Je=Object.freeze(["no-save","no-snapshot","no-trigger-autosave","no-dirty","no-watch","no-undo","no-data","freeze","editor-ui","live"]);function F(e,t){if(!e||e.nodeType!==1)return!1;let n=e.getAttribute?.("clay");return!!(n&&n.split(/\s+/).includes(t)||e.hasAttribute?.(t))}function Ee(e,t){if(F(e,t))return!0;for(let[n,o]of Object.entries(vt))if(o.includes(t)&&F(e,n))return!0;return!1}function K(e){let t=oe[e];if(!t)throw new Error(`Unknown region capability: ${e}`);return[...t.tokens,...t.bundles].flatMap(n=>[`[clay~="${n}"]`,`[${n}]`]).join(", ")}function Wt(e,t){let n=e&&e.nodeType===1?e:e?.parentElement;for(;n&&n.nodeType===1;){let o=oe[t];if(!o)throw new Error(`Unknown region capability: ${t}`);if(o.tokens.some(r=>Ee(n,r))||o.bundles.some(r=>F(n,r)))return n;n=n.parentElement}return null}function Ye(e,t){return!!Wt(e,t)}var Ut=Object.freeze({refusedRuleForms:["innerHTML","outerHTML"],refusedTargets:["script","style","template","noscript","iframe","object","embed","xmp","plaintext","noembed","noframes","meta","link","base","animate","set","animatemotion","animatetransform"],refusedAttributes:["style","srcdoc","is","http-equiv","sandbox","allow","nonce","integrity","charset","htmlclaytoken","htmlclayid","data-rules-name","data-rules-version","clay","contenteditable",...Je],refusedAttributePrefixes:["on"],urlAttributes:["href","src","srcset","action","formaction","poster","cite","data","ping","background","longdesc","usemap","xlink:href","manifest","codebase","icon"],refusedSchemes:["javascript","vbscript","data"],customPropertyValues:Object.freeze({maxLength:200,refusedCharacters:[";","{","}","<",">","\\"],refusedFunctions:["url","src","image","image-set","-webkit-image-set","cross-fade","element","expression","paint"]})});function be(e,t,n){if(n&&typeof n=="object")return{rules:n,tagNode:null};if(typeof n=="string"){let o=t&&t.ownerDocument?t.ownerDocument:t;return z(e,o,n)}return null}var Bt=/:(?:focus(?:-within|-visible)?|hover|active|visited|defined)\b/i;function zt(e,t){if(!/^(INPUT|TEXTAREA|SELECT|OPTION)$/.test(e.tagName||""))return;let n=(e.getAttribute?.("type")||"").toLowerCase();"value"in e&&"value"in t&&e.tagName!=="OPTION"&&n!=="checkbox"&&n!=="radio"&&n!=="file"&&(t.value=e.value),e.tagName==="INPUT"&&(n==="checkbox"||n==="radio")&&(t.checked=e.checked),e.tagName==="OPTION"&&(t.selected=e.selected),"indeterminate"in e&&"indeterminate"in t&&(t.indeterminate=e.indeterminate)}function Xe(e,t,n,o){if(o)return!!e.closest?.(t);let r=e;for(;r?.nodeType===1;){if(r.matches(t))return!0;if(r===n)break;r=r.parentElement}return!1}function Ge(e,t,n,o,r,i){return(i?Ye(e,t):Xe(e,n,r,!1))||!!(o&&(i&&e!==r?e.matches(o):Xe(e,o,r,i)))}function Ft(e,t){let n=oe[t];return n.tokens.some(o=>Ee(e,o))||n.bundles.some(o=>F(e,o))}var Kt=new Set(["INPUT","TEXTAREA","SELECT","OPTION"]);function Ze(e,t,n,o){if(e.nodeType===1&&o(e)){n.dropped.push(t);return}n.cloneToLive.set(t,e),n.liveToClone.set(e,t);let r=e,i=t;if(e.nodeType===1){if(Kt.has(e.tagName)&&n.controls.push(e,t),e.tagName==="TEMPLATE"){for(;t.firstChild;)t.removeChild(t.firstChild);r=e.content,i=t.content,n.cloneToLive.set(i,r),n.liveToClone.set(r,i)}}else if(e.nodeType!==11)return;let s=i.firstChild;for(let c=r.firstChild;c&&s;c=c.nextSibling)Ze(c,s,n,o),s=s.nextSibling}function J(e,{capability:t="data",exclude:n=null,inherit:o=!0,provenance:r=null}={}){if(!e)throw new TypeError("createContentView requires a DOM context");let i=e.nodeType===9?e:e.ownerDocument;if(!i?.implementation?.createHTMLDocument)throw new TypeError("createContentView requires an HTML DOM implementation");let s=i.implementation.createHTMLDocument(""),c=r||new WeakMap,l=new WeakMap,u=e.nodeType===9?e.documentElement:e;n&&s.documentElement.matches(n);let d=K(t),h=o?f=>Ft(f,t)||!!(n&&f.matches(n)):f=>Ge(f,t,d,n,u,!1),m=null;if(u.nodeType!==1||!Ge(u,t,d,n,u,o)){m=s.importNode(u,!0);let f={cloneToLive:c,liveToClone:l,dropped:[],controls:[]};Ze(u,m,f,h);for(let p of f.dropped)p.remove();for(let p=0;p<f.controls.length;p+=2)zt(f.controls[p],f.controls[p+1])}e.nodeType===9&&m&&(s.replaceChild(m,s.documentElement),l.set(e,s),c.set(s,e));let T=f=>{if(Bt.test(f))throw new Error(`Filtered content queries do not support stateful selector: ${f}`)};return{root:m,document:s,capability:t,selector:K(t),cloneToLive:c,liveToClone:l,original(f){return c.get(f)||null},cloneOf(f){return l.get(f)||null},query(f,p=m){return T(f),Array.from(p.querySelectorAll(f),g=>c.get(g)||g)},text(f=m){return(f===m?m:l.get(f))?.textContent||""},html(f=m){return(f===m?m:l.get(f))?.innerHTML??""},clone(f=m){let p=f===m?m:l.get(f);return p?s.importNode(p,!0):null}}}function et(e){return e&&e.nodeType===1&&e.tagName==="SCRIPT"&&e.hasAttribute&&e.hasAttribute("data-rules-name")}function Jt(e){return e?(e.nodeType===9||e.nodeType===11,e):null}function Qe(e,t,n){!e||e.nodeType!==1||(t==="value"&&e.tagName==="INPUT"?e.value=n===null?"":n:t==="checked"&&e.tagName==="INPUT"?e.checked=n!==null:t==="selected"&&e.tagName==="OPTION"&&(e.selected=n!==null))}function tt(e,t){e&&e.tagName==="TEXTAREA"&&(e.value=t)}function nt(e){if(!e||e.nodeType!==1)return;let t=[e,...e.querySelectorAll?e.querySelectorAll("textarea, input, option"):[]];for(let n of t)if(n.tagName==="TEXTAREA")n.value=n.defaultValue;else if(n.tagName==="INPUT"){let o=n.type;o!=="file"&&o!=="checkbox"&&o!=="radio"&&(n.value=n.defaultValue),n.checked=n.defaultChecked}else n.tagName==="OPTION"&&(n.selected=n.defaultSelected)}var E={semanticExclude:!0,find(e,t,n={}){let o=Jt(e);if(!o||!o.querySelectorAll)return[];let r=Array.from(o.querySelectorAll(t));n.includeRulesTag||(r=r.filter(c=>!et(c)));let i=[];n.skip&&i.push(n.skip);let s=n.templateAttr===null?null:n.templateAttr||"cms-template";if(s&&i.push("["+s+"]"),i.length){let c=i.join(", ");r=r.filter(l=>!l.closest||!l.closest(c))}return r},parent(e){return e?e.parentElement:null},children(e){return e?Array.from(e.children):[]},matches(e,t){return!!(e&&e.matches)&&e.matches(t)},text(e,t){if(t===void 0)return(e.textContent||"").trim();e.textContent=t,tt(e,t)},attr(e,t,n){if(n===void 0)return e.hasAttribute&&e.hasAttribute(t)?e.getAttribute(t):null;e.setAttribute(t,n),Qe(e,t,n)},removeAttr(e,t){e&&e.removeAttribute&&e.removeAttribute(t),Qe(e,t,null)},prop(e,t,n){if(n===void 0){let o=e?e[t]:void 0;return o!==void 0?o:null}e[t]=n},clone(e){let t=e.cloneNode(!0);return nt(t),t},insertAt(e,t,n){let o=e.children[n]||null;e.insertBefore(t,o)},insertBefore(e,t){e.parentNode.insertBefore(t,e)},insertAfter(e,t){e.parentNode.insertBefore(t,e.nextSibling)},identity(e){return e||null},remove(e){e&&e.parentNode&&e.parentNode.removeChild(e)},replaceWith(e,t){if(!e||!e.parentNode)throw new Error("dom.replaceWith: node has no parent");let o=e.ownerDocument.createElement("template");o.innerHTML=t;let r=o.content.firstElementChild;if(!r)throw new Error("dom.replaceWith: html did not parse to an element");return e.parentNode.replaceChild(r,e),r},stripIds(e){let t=0;return e.id&&(e.removeAttribute("id"),t++),(e.querySelectorAll?e.querySelectorAll("[id]"):[]).forEach(o=>{o.removeAttribute("id"),t++}),t},sameNode(e,t){return e===t}};function Y(e,t={}){if(t.exclude===null)return E;let n=[K("data"),t.exclude].filter(Boolean).join(", "),o=e.nodeType===9?e:e.ownerDocument||e,r=e.nodeType===9?e.documentElement:e;if(!t._write&&!r?.matches?.(n)&&!r?.querySelector?.(n)&&!o?.querySelector?.(n))return E;let i=e.nodeType===9||!e.isConnected?e:e.ownerDocument,s=e.nodeType===9?e:e.ownerDocument,c=null,l=()=>c||(c=J(i,{capability:"data",exclude:t.exclude||null})),u=f=>{let p=l();return f===e?p.cloneOf(e):p.cloneOf(f)||f},d=f=>c?.original(f)||f,h=(f,p)=>{l().liveToClone.set(f,p),l().cloneToLive.set(p,f);let g=f.childNodes||[],a=p.childNodes||[];for(let y=0;y<Math.min(g.length,a.length);y++)h(g[y],a[y])},m=(f,p,g,a)=>{let y=Array.from(f.childNodes).filter(x=>c.cloneOf(x)),w=y[0];for(;w&&y.includes(w);)w=w.nextSibling;for(let x of y)x.remove();if(g==="innerHTML"){let x=s.createElement("template");x.innerHTML=a;for(let W of Array.from(x.content.childNodes))f.insertBefore(W,w||null)}else f.insertBefore(s.createTextNode(a),w||null),tt(f,a);let b=J(f,{capability:"data",exclude:t.exclude||null});p.replaceChildren(...Array.from(b.root?.childNodes||[]));let O=x=>{let W=b.original(x);W&&(c.liveToClone.set(W,x),c.cloneToLive.set(x,W));for(let at of Array.from(x.childNodes||[]))O(at)};for(let x of Array.from(p.childNodes))O(x)},T={...E,find(f,p,g={}){let a=u(f);if(!a?.querySelectorAll)return[];let y=l().query(p,a);g.includeRulesTag||(y=y.filter(b=>!et(b)));let A=[];g.skip&&A.push(g.skip);let w=g.templateAttr===null?null:g.templateAttr||"cms-template";if(w&&A.push(`[${w}]`),A.length){let b=A.join(", ");y=y.filter(O=>!O.closest?.(b))}return y},parent(f){let p=u(f)?.parentElement;return p?d(p):null},children(f){return Array.from(u(f)?.children||[],d)},text(f,p){if(p===void 0){let y=d(f);return!y?.matches?.(n)&&!y?.querySelector?.(n)?E.text(y):(u(f)?.textContent||"").trim()}let g=d(f);if(!g?.matches?.(n)&&!g?.querySelector?.(n)&&!c){E.text(g,p);return}let a=l().cloneOf(g);a?m(g,a,"textContent",p):E.text(g,p)},attr(f,p,g){let a=d(f);if(g===void 0)return E.attr(a,p);E.attr(a,p,g);let y=c?.cloneOf(a);y&&(E.attr(y,p,g),J(a,{capability:"data",exclude:t.exclude||null}).root===null&&(y.remove(),c.liveToClone.delete(a),c.cloneToLive.delete(y)))},removeAttr(f,p){let g=d(f);E.removeAttr(g,p);let a=c?.cloneOf(g);a&&E.removeAttr(a,p)},prop(f,p,g){let a=d(f);if(g===void 0)return p==="innerHTML"||p==="outerHTML"||p==="textContent"||p==="innerText"?E.prop(u(a),p):E.prop(a,p);let y=p==="innerHTML"||p==="textContent"||p==="innerText",A=y?l().cloneOf(a):c?.cloneOf(a);A&&y?m(a,A,p,g):(E.prop(a,p,g),A&&E.prop(A,p,g))},clone(f){let p=u(f);if(p===f)return E.clone(f);let g=s.importNode(p,!0);return nt(g),g},insertAt(f,p,g){let a=d(f),A=T.children(a)[g]||(()=>{for(let O=a.children.length-1;O>=0;O--){let x=a.children[O];if(l().cloneOf(x))return x.nextElementSibling}return a.firstElementChild})(),w=d(p);a.insertBefore(w,A||null);let b=l().cloneOf(a);if(b){let O=l().cloneOf(w);O||(O=s.importNode(w,!0),h(w,O));let x=Array.from(b.children);b.insertBefore(O,x[g]||null)}},insertBefore(f,p){let g=d(f),a=d(p);g.parentNode.insertBefore(a,g);let y=l().cloneOf(g.parentNode);if(y){let A=l().cloneOf(a);A||(A=s.importNode(a,!0),h(a,A));let w=l().cloneOf(g);w?w.before(A):y.appendChild(A)}},insertAfter(f,p){let g=d(f),a=d(p);g.parentNode.insertBefore(a,g.nextSibling);let y=l().cloneOf(g.parentNode);if(y){let A=l().cloneOf(a);A||(A=s.importNode(a,!0),h(a,A));let w=l().cloneOf(g);w?w.after(A):y.appendChild(A)}},identity(f){return d(f)||null},remove(f){let p=d(f),g=l().cloneOf(p);E.remove(p),g&&E.remove(g)},replaceWith(f,p){let g=d(f),a=l().cloneOf(g),y=E.replaceWith(g,p);if(a){let A=J(y,{capability:"data",exclude:t.exclude||null});if(!A.root)a.remove();else{a.replaceWith(A.root);let w=b=>{let O=A.original(b);O&&(c.liveToClone.set(O,b),c.cloneToLive.set(b,O));for(let x of Array.from(b.childNodes||[]))w(x)};w(A.root)}}return y}};return T}var R=E;var Se={extract:(e,t,n={})=>N(Y(e,n),e,t,n),apply:(e,t,n,o={})=>L(Y(e,{...o,_write:!0}),e,t,n,o),findRulesIn:(e,t)=>z(R,e,t),findRules:(e,t)=>be(R,e,t),bind:(e,t,n={})=>{let o=be(R,e,t);if(!o){let r=typeof t=="string"?`data-rules-name~="${t}"`:"the provided rules object";throw new Error(`hyper-html-api: could not resolve rules for ${r}`)}return{...o,get:()=>N(Y(e,n),e,o.rules,n),set:r=>L(Y(e,{...n,_write:!0}),e,o.rules,r,n)}},parseStrict:xe,parseRelaxed:j,ruleAttrIndex:S,splitRule:he,errors:ne,DOM_PROPERTIES:G};var Yt="hha:upgrade-check:";function C(e,t){let n=e.querySelector(`meta[name="${t}"]`),o=n?n.getAttribute("content"):null;return o&&o.trim()?o.trim():null}function rt(e){if(typeof e!="string")return null;let t=e.trim().replace(/^v/,"");return/^\d+(\.\d+)*$/.test(t)?t.split(".").map(Number):null}function Xt(e,t){let n=rt(e),o=rt(t);if(!n||!o)return!1;let r=Math.max(n.length,o.length);for(let i=0;i<r;i++){let s=n[i]||0,c=o[i]||0;if(s!==c)return s>c}return!1}function Gt(e){try{let t=globalThis.localStorage.getItem(e);return t?JSON.parse(t):null}catch{return null}}function Zt(e,t){try{globalThis.localStorage.setItem(e,JSON.stringify(t))}catch{}}async function ot({force:e=!1,doc:t,loc:n,fetchFn:o,now:r,ttlMs:i=864e5}={}){if(t=t||(typeof document<"u"?document:null),n=n||(typeof location<"u"?location:null),o=o||(m=>fetch(m)),r=r??Date.now(),!t)return null;let s=C(t,"hyper-source");if(!s)return null;let c=C(t,"hyper-version"),l;try{l=new URL(s,n?n.href:void 0)}catch{return null}if(n&&l.origin===n.origin&&l.pathname===n.pathname)return null;let u=`${Yt}${l.href}:${c||"none"}`,d,h=e?null:Gt(u);if(h&&typeof h.checkedAt=="number"&&r-h.checkedAt<i)d=h.sourceVersion;else{try{let m=await o(l.href);if(!m.ok)throw new Error(`HTTP ${m.status}`);let T=await m.text(),f=new DOMParser().parseFromString(T,"text/html");d=C(f,"hyper-version")}catch{d=null}Zt(u,{checkedAt:r,sourceVersion:d})}return d?{available:Xt(d,c||"0.0.0"),currentVersion:c,sourceVersion:d,sourceUrl:l.href}:null}var Qt="script[data-rules-name]";function en(e){return typeof e=="string"?e.trim().replace(/\s+/g," "):""}function ie(e,t){let n=e.find(t,Qt,{includeRulesTag:!0}),o=new Set,r=[];for(let i of n){let s=en(e.attr(i,"data-rules-name"));if(!s)continue;if(o.has(s)){console.warn(`hyper-html-api: duplicate rules tag name "${s}"; using the first.`);continue}let c=e.attr(i,"data-rules-version");if(c!==Oe)throw new M(c);o.add(s),r.push({name:s,rules:j(e.text(i))})}return r}function Re(e,t){let n={};for(let{name:o,rules:r}of ie(e,t))n[o]=N(e,t,r);return n}function it(e){let t=e||document,n=t.nodeType===9?t:t.ownerDocument||t;return{dataByName:Re(R,t),version:C(n,"hyper-version")}}var X=class extends Error{constructor(t,n){super(`could not fetch upgrade source: ${t}`),this.name="UpgradeSourceUnreachable",this.sourceUrl=t,this.cause=n}},se=class extends Error{constructor(t){super(`upgrade source has no rules tags; refusing to drop all existing data: ${t}`),this.name="UpgradeSourceHasNoRules",this.sourceUrl=t}},$=class extends Error{constructor(t,n){super(t),this.name="UpgradeTransformInvalid",this.cause=n}},ce=class extends Error{constructor(t){super(`found ${t} script[type="text/hyper-upgrade"] tags; only one is allowed per document.`),this.name="UpgradeMultipleTransforms",this.count=t}};var tn="text/hyper-upgrade";function st(e,t){let n=e.find(t,`script[type="${tn}"]`);if(n.length===0)return null;if(n.length>1)throw new ce(n.length);return e.text(n[0])||null}var nn=new Function("url","return import(url)");async function ct(e){let t=new Blob([e],{type:"text/javascript"}),n=URL.createObjectURL(t),o;try{o=await nn(n)}catch(r){throw new $(`transform failed to load: ${r&&r.message?r.message:r}`,r)}finally{URL.revokeObjectURL(n)}if(typeof o.default!="function")throw new $("transform must `export default` a function");return o.default}function le(e,t){let n={carriedOver:0,discarded:0,listItems:0},o=Ne(t,e,n);return Ce(t,e,n),{data:o,summary:n}}function Ne(e,t,n){if(typeof e=="string")return e.endsWith("[]")?Array.isArray(t)?(n.listItems+=t.length,n.carriedOver+=t.length,t):void 0:t==null||typeof t=="object"?void 0:(n.carriedOver++,t);if(Array.isArray(e)){let[,o]=e;return Array.isArray(t)?(n.listItems+=t.length,t.map(r=>Ne(o,r,n))):void 0}if(typeof e=="object"&&e!==null){let o={};for(let[r,i]of Object.entries(e)){let s=Ne(i,t?.[r],n);s!==void 0&&(o[r]=s)}return o}}function Ce(e,t,n){if(t!=null){if(typeof e=="object"&&e!==null&&!Array.isArray(e)){if(typeof t!="object"||Array.isArray(t))return;let o=new Set(Object.keys(e));for(let r of Object.keys(t))o.has(r)?Ce(e[r],t[r],n):n.discarded+=v(t[r]);return}if(Array.isArray(e)&&Array.isArray(t)){let o=e[1];t.forEach(r=>Ce(o,r,n));return}typeof e=="string"&&!e.endsWith("[]")&&typeof t=="object"&&t!==null&&(n.discarded+=v(t))}}function v(e){return e==null?0:Array.isArray(e)?e.reduce((t,n)=>t+v(n),0):typeof e=="object"?Object.values(e).reduce((t,n)=>t+v(n),0):1}function lt(e,t,n){let o=ie(e,t),r={carriedOver:0,discarded:0,listItems:0},i={},s=new Set;for(let{name:c,rules:l}of o){if(s.add(c),!Object.prototype.hasOwnProperty.call(n,c)){i[c]={carriedOver:0,discarded:0,listItems:0};continue}let{data:u,summary:d}=le(n[c],l);L(e,t,l,u),i[c]=d,r.carriedOver+=d.carriedOver,r.discarded+=d.discarded,r.listItems+=d.listItems}for(let c of Object.keys(n))s.has(c)||(r.discarded+=v(n[c]));return{totals:r,byName:i,rulesTagCount:o.length}}async function ft({sourceUrl:e,dataByName:t,fromVersion:n,doc:o,loc:r,fetchFn:i}={}){if(o=o||(typeof document<"u"?document:null),r=r||(typeof location<"u"?location:null),i=i||(a=>fetch(a)),!o)throw new Error("upgrade.run requires a document context");if(e=e||C(o,"hyper-source"),!e)throw new Error("upgrade.run: no sourceUrl given and no hyper-source meta tag found");let s=new URL(e,r?r.href:void 0);n=n!==void 0?n:C(o,"hyper-version"),t=t||Re(R,o);let c;try{c=await i(s.href)}catch(a){throw new X(s.href,a)}if(!c.ok)throw new X(s.href,new Error(`HTTP ${c.status}`));let l=await c.text(),u=new DOMParser().parseFromString(l,"text/html"),d=C(u,"hyper-version"),h=t,m=!1,T=st(R,u);if(T){let y=await(await ct(T))(h,{fromVersion:n,toVersion:d});if(!y||typeof y!="object"||Array.isArray(y))throw new $("transform must return a plain object map of { rulesName: data }");h=y,m=!0}let{totals:f,byName:p,rulesTagCount:g}=lt(R,u,h);if(g===0&&Object.keys(h).length>0)throw new se(s.href);return{html:on(u),fromVersion:n,toVersion:d,summary:{transformApplied:m,totals:f,byName:p}}}function rn(e){for(let t of e.querySelectorAll("input")){let n=(t.getAttribute("type")||"").toLowerCase();n!=="file"&&(n==="checkbox"||n==="radio"?t.checked!==t.hasAttribute("checked")&&t.toggleAttribute("checked",t.checked):t.value!==(t.getAttribute("value")??"")&&t.setAttribute("value",t.value))}for(let t of e.querySelectorAll("textarea"))t.value!==t.textContent&&(t.textContent=t.value);for(let t of e.querySelectorAll("select")){let n=[...t.options];if(!t.multiple){let o=n.findIndex(r=>r.hasAttribute("selected"));if(t.selectedIndex===o||o===-1&&t.selectedIndex<=0)continue}for(let o of n)o.selected!==o.hasAttribute("selected")&&o.toggleAttribute("selected",o.selected)}}function on(e){return rn(e),`<!DOCTYPE ${e.doctype&&e.doctype.name?e.doctype.name:"html"}>
|
|
2
|
-
`+e.documentElement.outerHTML}var
|
|
1
|
+
var hyperHtmlApiUpgrade=(()=>{var ue=Object.defineProperty;var pt=Object.getOwnPropertyDescriptor;var ht=Object.getOwnPropertyNames;var mt=Object.prototype.hasOwnProperty;var Pe=(e,t)=>{for(var n in t)ue(e,n,{get:t[n],enumerable:!0})},yt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ht(t))!mt.call(e,r)&&r!==n&&ue(e,r,{get:()=>t[r],enumerable:!(o=pt(t,r))||o.enumerable});return e};var gt=e=>yt(ue({},"__esModule",{value:!0}),e);var un={};Pe(un,{default:()=>fn,engine:()=>Re,upgrade:()=>at});var Q=["textContent","innerText","innerHTML","outerHTML","value","checked","selected","disabled","readOnly","type","tagName","nodeName","nodeType","nodeValue","childElementCount","id","className","classList","baseURI","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","dataset","currentSrc","duration","paused","title","documentURI","contentType"],ee=new Set(Q),ae=new Set(["textContent","innerText","innerHTML","value","checked","selected","disabled","readOnly","type","id","className","title"]),D=new Set(["tagName","nodeName","nodeType","nodeValue","childElementCount","classList","baseURI","documentURI","contentType","offsetWidth","offsetHeight","clientWidth","clientHeight","scrollWidth","scrollHeight","currentSrc","duration","paused","dataset"]),ke=new Set(["checked","selected","disabled","readOnly","paused"]);function de(e,t){return t==null?ke.has(e)?!1:"":ke.has(e)?t==="false"?!1:!!t:t}var re={};Pe(re,{EmptyListInsert:()=>P,MAX_RULE_DEPTH:()=>W,MaxRuleDepthExceeded:()=>I,NoRulesTag:()=>pe,RuleTargetReadOnly:()=>V,RulesParseError:()=>v,ShapeMismatch:()=>q,UnknownRulesVersion:()=>k,WriteNotRoundTripped:()=>ne,WriteRefused:()=>te,WriteRejected:()=>he});var v=class extends Error{constructor(t,n){super(t),this.name="RulesParseError",this.cause=n}},k=class extends Error{constructor(t){super(`unknown rules version: ${t}. Library supports "1".`),this.name="UnknownRulesVersion",this.version=t}},W=20,I=class extends Error{constructor(t){super(`rule depth exceeded ${W} at path: ${t.join(".")}`),this.name="MaxRuleDepthExceeded",this.path=t}},q=class extends Error{constructor(t){super(`shape mismatch: ${t.length} field(s) failed validation`),this.name="ShapeMismatch",this.mismatches=t}},P=class extends Error{constructor(t,n){super(n?`cannot add items to empty list at "${t.join(".")}" \u2014 ${n}`:`cannot add items to empty list at "${t.join(".")}" \u2014 no sibling to clone as template. Seed the list with a hidden item first.`),this.name="EmptyListInsert",this.path=t}},V=class extends Error{constructor(t){super(`cannot write to read-only DOM property "${t}"`),this.name="RuleTargetReadOnly",this.target=t}},te=class extends Error{constructor(t){super(`write refused: ${t.length} write(s) broke the content-only policy`),this.name="WriteRefused",this.refusals=t}};function At(e){return e.reduce((n,o)=>typeof o=="number"?`${n}[${o}]`:n?`${n}.${o}`:String(o),"")||"(root)"}var ne=class extends Error{constructor(t){super(`write did not round-trip at "${At(t)}"`),this.name="WriteNotRoundTripped",this.path=t}},pe=class extends Error{constructor(t){super(`no <script data-rules-name~="${t}"> rules tag in this document`),this.name="NoRulesTag",this.token=t}},he=class extends Error{constructor(t,n){super(`write rejected: ${t.length} unknown key(s), ${n.length} rule(s) with no matching element`),this.name="WriteRejected",this.unknownKeys=t,this.unmatched=n}};function S(e){let t=0,n=null,o=-1;for(let r=0;r<e.length;r++){let i=e[r];i==="\\"?r++:n?i===n&&(n=null):i==='"'||i==="'"?n=i:i==="["||i==="("?t++:i==="]"||i===")"?t>0&&t--:i==="@"&&t===0&&(o=r)}return o}var Ie="[*]";function R(e){let t=S(e),n=t===-1?e:e.slice(0,t),o=n.endsWith(Ie),r={selector:o?n.slice(0,-Ie.length):n,prop:t===-1?null:e.slice(t+1)||null};return o&&(r.all=!0),r}function me(e){let t=0,n=null,o=-1,r=!1;for(let i=0;i<e.length;i++){let s=e[i];s==="\\"?i++:n?s===n&&(n=null):s==='"'||s==="'"?n=s:s==="["||s==="("?t++:s==="]"||s===")"?t>0&&t--:t===0&&s===">"?o=i:t===0&&s===","&&(r=!0)}return r||o===-1||!wt(e,o+1)?null:e.slice(0,o).trim()||null}function wt(e,t){let n=t,o=e.replace(/\s+$/,"").length;for(;n<o&&/\s/.test(e[n]);)n++;let r=0,i=null;for(;n<o;n++){let s=e[n];if(s==="\\")n++;else if(i)s===i&&(i=null);else if(s==='"'||s==="'")i=s;else if(s==="["||s==="(")r++;else if(s==="]"||s===")")r>0&&r--;else if(r===0&&(s==="+"||s==="~"||/\s/.test(s)))return!1}return!0}var Tt=/^--[A-Za-z0-9_-]+$/;function L(e){return typeof e=="string"&&Tt.test(e)}function Le(e){let t=[],n=[],o=null,r=0;for(let i=0;i<e.length;i++){let s=e[i];if(o){s==="\\"?i++:s===o&&(o=null);continue}if(s==="/"&&e[i+1]==="*"){let c=e.indexOf("*/",i+2);i=c===-1?e.length:c+1;continue}s==='"'||s==="'"?o=s:s==="("?n.push(")"):s==="["?n.push("]"):s==="{"?n.push("}"):(s===")"||s==="]"||s==="}")&&n[n.length-1]===s?n.pop():s===";"&&n.length===0&&(t.push(e.slice(r,i)),r=i+1)}return t.push(e.slice(r)),t}function xt(e){let t="",n=null;for(let o=0;o<e.length;o++){let r=e[o];if(n){t+=r,r==="\\"&&o+1<e.length?t+=e[++o]:r===n&&(n=null);continue}if(r==="/"&&e[o+1]==="*"){let i=e.indexOf("*/",o+2);o=i===-1?e.length:i+1,t+=" ";continue}(r==='"'||r==="'")&&(n=r),t+=r}return t}function je(e){e=xt(e);let t=e.indexOf(":");if(t===-1)return null;let n=e.slice(0,t).trim(),o=e.slice(t+1).trim(),r=/!\s*important\s*$/i.exec(o);return r&&(o=o.slice(0,r.index).trim()),{name:n,value:o,important:!!r}}function B(e,t){if(e==null)return null;let n=null;for(let o of Le(String(e))){let r=je(o);!r||r.name!==t||(!n||r.important||!n.important)&&(n=r)}return n?n.value:null}function $e(e,t,n){let o=e==null?"":String(e),r=n==null||n==="",i=Le(o),s=i.map(je),c=s.some(p=>p&&p.name===t&&p.important),l=[],a=!1;i.forEach((p,h)=>{let T=s[h];if(!T||T.name!==t){l.push(p);return}if(r||a)return;let f=/^\s*/.exec(p)[0];l.push(`${f}${t}: ${n}${c?" !important":""}`),a=!0});let u=l.join(";");if(!r&&!a){let p=u.trimEnd();u=p===""?`${t}: ${n}`:`${p}${p.endsWith(";")?" ":"; "}${t}: ${n}`}return u.trim()===""?null:u}function ye(e,t,n,o){let r=e.attr(t,"style");if((B(r,n)??"")===o)return;let i=$e(r,n,o);i==null?e.removeAttr(t,"style"):e.attr(t,"style",i)}function C(e,t,n,o={}){if(Object.prototype.hasOwnProperty.call(o,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");return Ae(e,t,n,{depth:0,path:[]},o)}function Ae(e,t,n,o,r){if(o.depth>W)throw new I(o.path);if(typeof n=="string")return Ot(e,t,n,o,r);if(Array.isArray(n)){let[i,s]=n,c=e.find(t,i,r);return _e(r,o,c),c.map((l,a)=>Ae(e,l,s,{depth:o.depth+1,path:[...o.path,a]},r))}if(typeof n=="object"&&n!==null){let i={};for(let[s,c]of Object.entries(n))i[s]=Ae(e,t,c,{depth:o.depth+1,path:[...o.path,s]},r);return i}return null}function Ot(e,t,n,o,r){if(n.endsWith("[]")){let a=n.slice(0,-2),u=e.find(t,a,r);return _e(r,o,u),u.map(p=>e.text(p))}if(n.startsWith("@"))return ge(e,t,n.slice(1));let i=S(n);if(i!==-1){let{selector:a,all:u}=R(n),p=n.slice(i+1),h=a?e.find(t,a,r):[t];return u&&r.allMatches?h.map(T=>ge(e,T,p)):h.length===0?null:ge(e,h[0],p)}if(n===".")return e.text(t);let{selector:s,all:c}=R(n),l=e.find(t,s,r);return c&&r.allMatches?l.map(a=>e.text(a)):l.length===0?null:e.text(l[0])}function _e(e,t,n){if(typeof e.onRowsRead=="function")try{e.onRowsRead(t.path.slice(),n)}catch(o){console.warn(`[hyper-html-api] onRowsRead threw at "${t.path.join(".")||"(root)"}"`,o)}}function ge(e,t,n){if(L(n))return B(e.attr(t,"style"),n);if(ee.has(n)){let r=e.prop(t,n);return r==null?null:String(r)}let o=e.attr(t,n);return o??null}function We(e,t,n,o){let r=e.length,i=t.length,s=new Array(r).fill(-1);if(o){let d=new Set;for(let y=0;y<r;y++){let A=o[y];!(A>=0&&A<i)||d.has(A)||(s[y]=A,d.add(A))}}if(r===0||i===0)return s;let c=e.map(d=>De(d,n)),l=t.map(d=>De(d,n)),a=new Array(i).fill(!1);for(let d of s)d>=0&&(a[d]=!0);let u=new Map;l.forEach((d,y)=>{a[y]||u.set(d,u.has(d)?-1:y)});let p=new Map;c.forEach((d,y)=>{s[y]>=0||p.set(d,(p.get(d)||0)+1)}),c.forEach((d,y)=>{if(s[y]>=0||p.get(d)!==1)return;let A=u.get(d);A===void 0||A===-1||a[A]||(s[y]=A,a[A]=!0)});let h=[];for(let d=0;d<r;d++)s[d]<0&&h.push(d);let T=[];for(let d=0;d<i;d++)a[d]||T.push(d);if(h.length===0||T.length===0)return s;let f=r*i+1,m=Et(e,t,n),g=(d,y)=>m(d,y)*f+Math.abs(d-y);for(let[d,y]of bt(h,T,g))s[d]=y;return s}var Ue=e=>typeof e=="object"&&e!==null;function De(e,t){if(!Ue(t))return e==null?" null":String(e);let n=Object.keys(t);return JSON.stringify(n.map(o=>{let r=JSON.stringify(e?.[o]);return r===void 0?" undef":r}))}function Et(e,t,n){if(!Ue(n))return(c,l)=>e[c]===t[l]?0:1;let o=Object.keys(n),r=c=>o.map(l=>JSON.stringify(c?.[l])),i=e.map(r),s=t.map(r);return(c,l)=>{let a=i[c],u=s[l],p=0;for(let h=0;h<o.length;h++)a[h]!==u[h]&&p++;return p}}function bt(e,t,n){return e.length<=t.length?ve(e,t,n,!1):ve(t,e,(o,r)=>n(r,o),!0)}function ve(e,t,n,o){let r=e.length,i=t.length,s=[];for(let p=0;p<=r;p++)s.push(new Float64Array(i+1).fill(1/0));let c=[];for(let p=0;p<=r;p++)c.push(new Uint8Array(i+1));for(let p=0;p<=i;p++)s[r][p]=0;for(let p=r-1;p>=0;p--)for(let h=i-1;h>=0;h--){let T=n(e[p],t[h])+s[p+1][h+1],f=s[p][h+1];T<=f?(s[p][h]=T,c[p][h]=1):s[p][h]=f}let l=[],a=0,u=0;for(;a<r&&u<i;)c[a][u]&&(l.push(o?[t[u],e[a]]:[e[a],t[u]]),a++),u++;return l}function Te(e,t,n,o,r,i,s,c={}){let l=e.find(t,n,c);if(r.length===0){l.forEach(w=>e.remove(w)),we(c,"onRowsApplied",i.path,[]);return}let a=r.length>l.length,u=l[0]||null;if(a&&!u&&(u=Ct(e,t,n,c),!u))throw new P(i.path);let p=l.map(w=>Nt(e,w,o,c)),h=null;if(a&&u){h=e.clone(u),c.templateAttr&&e.removeAttr(h,c.templateAttr);let w=e.stripIds(h);w>0&&console.warn(`[hyper-html-api] stripped ${w} id attribute(s) from cloned template at "${i.path.join(".")||"(root)"}"`)}let T=We(r,p,o,St(e,l,r,i,c)),f=l.length>0?e.parent(l[0]):It(e,t,n,u,i,c),m=l.length>0?ze(e,f,l[0]):0,g=$t(e,l),d=new Set,y=[],A=r.map((w,b)=>{let O=T[b];if(O>=0)return d.add(O),y.push(!1),l[O];y.push(!0);let x=e.clone(h);return e.stripIds(x),x});l.forEach((w,b)=>{d.has(b)||e.remove(w)}),g?jt(e,f,m,A,y):_t(e,A,y,f,m),Rt(e,A,o,r,i,s,c),we(c,"onRowsApplied",i.path,A)}function we(e,t,n,o){if(typeof e[t]=="function")try{return e[t](n.slice(),o)}catch(r){console.warn(`[hyper-html-api] ${t} threw at "${n.join(".")||"(root)"}"`,r);return}}function St(e,t,n,o,r){let i=we(r,"identifyRows",o.path,n);if(!Array.isArray(i))return null;let s=new Array(n.length).fill(-1),c=new Set,l=new Map(t.map((a,u)=>[e.identity(a),u]));for(let a=0;a<n.length;a++){if(!i[a])continue;let u=l.get(e.identity(i[a]));u===void 0||c.has(u)||(s[a]=u,c.add(u))}return s}function Rt(e,t,n,o,r,i,s){t.forEach((c,l)=>{if(n===null){let a=o[l],u=a==null?"":String(a);e.text(c)!==u&&e.text(c,u)}else{let a=i(e,c,n,o[l],{depth:r.depth+1,path:[...r.path,l]},s);a&&a!==c&&(t[l]=a)}})}function Nt(e,t,n,o){return n===null?e.text(t):C(e,t,n,o.onRowsRead?{...o,onRowsRead:void 0}:o)}function ze(e,t,n){let o=e.children(t);for(let r=0;r<o.length;r++)if(e.sameNode(o[r],n))return r;return-1}function Ct(e,t,n,o){if(!o.templateAttr)return null;let r=/^\s*:scope\s*>\s*/.test(n),i=new RegExp(":not\\(\\["+o.templateAttr.replace(/[.*+?^${}()|[\]\\-]/g,"\\$&")+"\\]\\)","g"),s=n.replace(/^\s*:scope\s*>\s*/,"").replace(i,""),c=r?Mt(s):0,l=me(s),a=t;for(;a;){let u=e.find(a,s,{includeRulesTag:!1,templateAttr:null});for(let p of u)if(e.attr(p,o.templateAttr)!=null&&!(r&&!kt(e,t,p,c))&&!(l&&!e.matches(e.parent(p),l)))return p;a=e.parent(a)}return null}function Mt(e){let t=0,n=null,o=1;for(let r=0;r<e.length;r++){let i=e[r];if(i==="\\")r++;else if(n)i===n&&(n=null);else if(i==='"'||i==="'")n=i;else if(i==="["||i==="(")t++;else if(i==="]"||i===")")t>0&&t--;else if(t===0&&i===">")o++;else{if(t===0&&(i==="+"||i==="~"))return null;if(t===0&&/\s/.test(i)){if(!Pt(e,r))return null;for(;r+1<e.length&&/\s/.test(e[r+1]);)r++}}}return o}function Pt(e,t){let n=t;for(;n<e.length&&/\s/.test(e[n]);)n++;let o=t>0?e[t-1]:"",r=n<e.length?e[n]:"";return He(o)||He(r)}function He(e){return e===">"||e==="+"||e==="~"}function kt(e,t,n,o){if(o===null)return!0;let r=n;for(let l=0;l<o;l++)if(r=e.parent(r),!r)return!1;let i=e.prop(t,"tagName");if(!i)return!0;let s=e.prop(r,"tagName");if(!s||String(s).toLowerCase()!==String(i).toLowerCase())return!1;let c=new Set(qe(e,r));return qe(e,t).every(l=>c.has(l))}function qe(e,t){let n=e.attr(t,"class");return n?String(n).split(/\s+/).filter(Boolean):[]}function It(e,t,n,o,r,i){let s=e.parent(o);if(s&&Lt(e,t,s)&&!Be(e,s,i))return s;let c=me(n);if(!c)throw new P(r.path,`the list selector "${n}" names no container to hold the new rows \u2014 write it as "container > row" (for example "ol.comments > li") so the cloned row lands in the list`);let a=(c===":scope"?e.prop(t,"tagName")?[t]:[]:e.find(t,c,i)).filter(u=>!Be(e,u,i));if(a.length===0)throw new P(r.path,`no container matching "${c}" inside this context to hold the new rows`);if(a.length>1)throw new P(r.path,`"${c}" matches ${a.length} containers inside this context, so the new rows have no single destination`);return a[0]}function Lt(e,t,n){let o=n;for(;o;){if(e.sameNode(o,t))return!0;o=e.parent(o)}return e.parent(t)?!1:e.find(t,"*",{includeRulesTag:!0,templateAttr:null}).some(r=>e.sameNode(r,n))}var Ve=["no-data","editor-ui"];function Be(e,t,n){let o=t;for(;o;){if(n.templateAttr&&e.attr(o,n.templateAttr)!=null||Ve.some(i=>e.attr(o,i)!=null))return!0;let r=e.attr(o,"clay");if(r&&r.split(/\s+/).some(i=>Ve.includes(i)))return!0;o=e.parent(o)}return!1}function jt(e,t,n,o,r){let i=e.children(t),s=i.map(l=>e.identity(l)),c=!1;o.forEach((l,a)=>{let u=e.identity(l),p=n+a;if(s[p]===u)return;if(!r[a]){let T=s.indexOf(u);T!==-1&&(s.splice(T,1),i.splice(T,1))}let h=Math.min(p,i.length);h<i.length?e.insertBefore(i[h],l):i.length?c?e.insertAfter(i[i.length-1],l):(e.insertAt(t,l,p),c=!0):e.insertAt(t,l,0),s.splice(h,0,u),i.splice(h,0,l)})}function $t(e,t){if(t.length<=1)return!0;let n=e.parent(t[0]);if(!n)return!1;let o=new Map(e.children(n).map((i,s)=>[e.identity(i),s])),r=[];for(let i of t){let s=o.get(e.identity(i));if(s===void 0)return!1;r.push(s)}return r.sort((i,s)=>i-s),r[r.length-1]-r[0]===r.length-1}function _t(e,t,n,o,r){let i=null,s=r;for(let c=0;c<t.length;c++){if(!n[c]){i=t[c];continue}let l=i?e.parent(i):o;if(!l)continue;let a=i?ze(e,l,i)+1:s++;e.insertAt(l,t[c],a),i=t[c]}}function j(e,t,n,o,r={}){if(Object.prototype.hasOwnProperty.call(r,"exclude")&&e.semanticExclude===!1)throw new Error("This adapter does not support semantic exclude queries; omit exclude or use the DOM adapter.");let i=[];if(xe(n,o,[],i),i.length)throw new q(i);oe(e,t,n,o,{depth:0,path:[]},r)}function oe(e,t,n,o,r,i={}){if(r.depth>W)throw new I(r.path);if(o===void 0)return t;if(typeof n=="string")return Dt(e,t,n,o,r,i);if(Array.isArray(n)){let[s,c]=n;return Te(e,t,s,c,o,r,oe,i),t}if(typeof n=="object"&&n!==null){for(let[s,c]of Object.entries(n)){let l=oe(e,t,c,o==null?o:o[s],{depth:r.depth+1,path:[...r.path,s]},i);l&&l!==t&&(t=l)}return t}return t}function Dt(e,t,n,o,r,i){if(n.endsWith("[]")){let u=n.slice(0,-2);return Te(e,t,u,null,o,r,oe,i),t}if(n.startsWith("@"))return Ke(e,t,n.slice(1),o);let s=S(n);if(s!==-1){let{selector:u,all:p}=R(n),h=n.slice(s+1),T=u?e.find(t,u,i):[t];for(let f of p?T:T.slice(0,1))Ke(e,f,h,o);return t}if(n===".")return Fe(e,t,o),t;let{selector:c,all:l}=R(n),a=e.find(t,c,i);for(let u of l?a:a.slice(0,1))Fe(e,u,o);return t}function Fe(e,t,n){let o=n==null?"":String(n);e.text(t)!==o&&e.text(t,o)}function vt(e,t,n,o){if(e.styleVar){e.styleVar(t,n,o);return}ye(e,t,n,o)}function Ke(e,t,n,o){if(L(n))return vt(e,t,n,o==null?"":String(o).trim()),t;if(D.has(n)){let r=e.prop(t,n);if(r===o||r!=null&&o!=null&&String(r)===String(o))return t;throw new V(n)}if(n==="outerHTML"){let r=o==null?"":String(o);return e.replaceWith(t,r)}if(ae.has(n)){let r=de(n,o);return e.prop(t,n)!==r&&e.prop(t,n,r),t}if(o==null)e.attr(t,n)!=null&&e.removeAttr(t,n);else{let r=String(o);e.attr(t,n)!==r&&e.attr(t,n,r)}return t}function xe(e,t,n,o){if(t!==void 0){if(typeof e=="string"){if(e.endsWith("[]")){Array.isArray(t)?t.forEach((r,i)=>{typeof r=="object"&&r!==null&&o.push({path:F([...n,i]),expected:"scalar",got:z(r)})}):o.push({path:F(n),expected:"array",got:z(t)});return}t!==null&&typeof t=="object"&&o.push({path:F(n),expected:"scalar",got:z(t)});return}if(Array.isArray(e)){if(!Array.isArray(t)){o.push({path:F(n),expected:"array",got:z(t)});return}let r=e[1];t.forEach((i,s)=>xe(r,i,[...n,s],o));return}if(typeof e=="object"&&e!==null){if(t===null||Array.isArray(t)||typeof t!="object"){o.push({path:F(n),expected:"object",got:z(t)});return}for(let[r,i]of Object.entries(e))xe(i,t[r],[...n,r],o)}}}function z(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function F(e){return e.join(".")}function Oe(e){try{return JSON.parse(e)}catch(t){throw new v(`Invalid strict JSON: ${t.message}`,t)}}function $(e){try{return JSON.parse(e)}catch{}let t={BRACE_OPEN:"{",BRACE_CLOSE:"}",BRACKET_OPEN:"[",BRACKET_CLOSE:"]",COLON:":",COMMA:",",STRING:"STRING",SELECTOR:"SELECTOR",IDENTIFIER:"IDENTIFIER",NUMBER:"NUMBER",BOOLEAN:"BOOLEAN"};function n(r){let i=[],s=0;for(;s<r.length;){let c=r[s];if(/\s/.test(c)){s++;continue}if("{}".includes(c)){i.push({type:c,value:c}),s++;continue}if(c==="["){let p=!1,h=s+1;for(;h<r.length&&/\s/.test(r[h]);)h++;if(h<r.length&&/[a-zA-Z_]/.test(r[h])&&(p=!0),!p){i.push({type:c,value:c}),s++;continue}}if(c==="]"){i.push({type:c,value:c}),s++;continue}if(c===":"){i.push({type:t.COLON,value:c}),s++;continue}if(c===","){i.push({type:t.COMMA,value:c}),s++;continue}if(c==='"'||c==="'"){let p=c,h=s+1;for(;h<r.length&&r[h]!==p;)r[h]==="\\"&&h++,h++;i.push({type:t.STRING,value:r.substring(s+1,h),quoted:!0,sourceQuote:p}),s=h+1;continue}let l=s,a;for(;l<r.length&&!/[{},]/.test(r[l]);)if(r[l]===":"){let p=[":first",":last",":nth-child",":nth-of-type",":first-child",":last-child",":first-of-type",":last-of-type",":only-child",":only-of-type",":hover",":focus",":active",":visited",":disabled",":enabled",":checked",":empty",":root",":target",":not",":before",":after",":nth-last-child",":nth-last-of-type"],h=!1;for(let T of p){let f=T.substring(1);if(r.substring(l+1,l+1+f.length)===f){h=!0,l+=f.length;break}}if(!h)break}else if(r[l]==="["){for(l++;l<r.length&&r[l]!=="]";){if(r[l]==='"'||r[l]==="'"){let p=r[l];for(l++;l<r.length&&r[l]!==p;)r[l]==="\\"&&l++,l++}l++}l<r.length&&r[l]==="]"&&l++}else l++;a=r.substring(s,l);let u=t.IDENTIFIER;/^-?\d+(\.\d+)?$/.test(a)?u=t.NUMBER:a==="true"||a==="false"||a==="null"?u=t.BOOLEAN:/^[.#@\[]|[.#@\[]| /.test(a)&&(u=t.SELECTOR),i.push({type:u,value:a,quoted:!1}),s=l}return i}function o(r){let i="";for(let s=0;s<r.length;s++){let c=r[s];if("{}".includes(c.type)||"[]".includes(c.type)){i+=c.value;continue}if(c.type===t.COLON){i+=c.value;continue}if(c.type===t.COMMA){let l=r[s+1];if(l&&(l.type==="}"||l.type==="]"))continue;i+=c.value;continue}if(c.type===t.STRING&&c.quoted){let l=c.value;c.sourceQuote==="'"&&(l=l.replace(/\\'/g,"'"),l=l.replace(/(\\*)"/g,(a,u)=>u.length%2===0?u+'\\"':a)),i+=`"${l}"`;continue}if(c.type===t.NUMBER||c.type===t.BOOLEAN){i+=c.value;continue}if(c.type===t.SELECTOR||c.type===t.IDENTIFIER){i+=`"${c.value}"`;continue}i+=`"${c.value}"`}return i}try{let r=n(e),i=o(r);return JSON.parse(i)}catch(r){throw new v("Invalid extraction rules syntax: "+r.message,r)}}var Ee="1",Je=/^[a-zA-Z0-9_-]+$/;function K(e,t,n){let o;if(n===void 0)o="script[data-rules-name]";else{if(typeof n!="string"||!Je.test(n))throw new Error(`hyper-html-api: invalid rules token ${JSON.stringify(n)} (must match ${Je})`);o=`script[data-rules-name~="${n}"]`}let r=e.find(t,o,{includeRulesTag:!0});if(r.length===0)return null;n!==void 0&&r.length>1&&console.warn(`hyper-html-api: ${r.length} rules tags match data-rules-name~="${n}"; using the first.`);let i=r[0],s=e.attr(i,"data-rules-version");if(s!==Ee)throw new k(s);return{rules:$(e.text(i)),tagNode:i}}var ie=Object.freeze({data:Object.freeze({tokens:["no-data"],bundles:["editor-ui"]}),save:Object.freeze({tokens:["no-save"],bundles:["editor-ui"]}),snapshot:Object.freeze({tokens:["no-snapshot"],bundles:["editor-ui"]}),watch:Object.freeze({tokens:["no-watch"],bundles:["editor-ui"]}),undo:Object.freeze({tokens:["no-undo"],bundles:["editor-ui"]}),history:Object.freeze({tokens:[],bundles:["editor-ui"]})}),Wt=Object.freeze({"editor-ui":Object.freeze(["no-data","no-save","no-snapshot","no-watch","no-undo"])}),Ye=Object.freeze(["no-save","no-snapshot","no-trigger-autosave","no-dirty","no-watch","no-undo","no-data","freeze","editor-ui","live"]);function J(e,t){if(!e||e.nodeType!==1)return!1;let n=e.getAttribute?.("clay");return!!(n&&n.split(/\s+/).includes(t)||e.hasAttribute?.(t))}function be(e,t){if(J(e,t))return!0;for(let[n,o]of Object.entries(Wt))if(o.includes(t)&&J(e,n))return!0;return!1}function Y(e){let t=ie[e];if(!t)throw new Error(`Unknown region capability: ${e}`);return[...t.tokens,...t.bundles].flatMap(n=>[`[clay~="${n}"]`,`[${n}]`]).join(", ")}function Ut(e,t){let n=e&&e.nodeType===1?e:e?.parentElement;for(;n&&n.nodeType===1;){let o=ie[t];if(!o)throw new Error(`Unknown region capability: ${t}`);if(o.tokens.some(r=>be(n,r))||o.bundles.some(r=>J(n,r)))return n;n=n.parentElement}return null}function Xe(e,t){return!!Ut(e,t)}var Ht=Object.freeze({refusedRuleForms:["innerHTML","outerHTML"],refusedTargets:["script","style","template","noscript","iframe","object","embed","xmp","plaintext","noembed","noframes","meta","link","base","animate","set","animatemotion","animatetransform"],refusedAttributes:["style","srcdoc","is","http-equiv","sandbox","allow","nonce","integrity","charset","htmlclaytoken","htmlclayid","data-rules-name","data-rules-version","clay","contenteditable",...Ye],refusedAttributePrefixes:["on"],urlAttributes:["href","src","srcset","action","formaction","poster","cite","data","ping","background","longdesc","usemap","xlink:href","manifest","codebase","icon"],refusedSchemes:["javascript","vbscript","data"],customPropertyValues:Object.freeze({maxLength:200,refusedCharacters:[";","{","}","<",">","\\"],refusedFunctions:["url","src","image","image-set","-webkit-image-set","cross-fade","element","expression","paint"]})});function Se(e,t,n){if(n&&typeof n=="object")return{rules:n,tagNode:null};if(typeof n=="string"){let o=t&&t.ownerDocument?t.ownerDocument:t;return K(e,o,n)}return null}var zt=/:(?:focus(?:-within|-visible)?|hover|active|visited|defined)\b/i;function Ft(e,t){if(!/^(INPUT|TEXTAREA|SELECT|OPTION)$/.test(e.tagName||""))return;let n=(e.getAttribute?.("type")||"").toLowerCase();"value"in e&&"value"in t&&e.tagName!=="OPTION"&&n!=="checkbox"&&n!=="radio"&&n!=="file"&&(t.value=e.value),e.tagName==="INPUT"&&(n==="checkbox"||n==="radio")&&(t.checked=e.checked),e.tagName==="OPTION"&&(t.selected=e.selected),"indeterminate"in e&&"indeterminate"in t&&(t.indeterminate=e.indeterminate)}function Ge(e,t,n,o){if(o)return!!e.closest?.(t);let r=e;for(;r?.nodeType===1;){if(r.matches(t))return!0;if(r===n)break;r=r.parentElement}return!1}function Ze(e,t,n,o,r,i){return(i?Xe(e,t):Ge(e,n,r,!1))||!!(o&&(i&&e!==r?e.matches(o):Ge(e,o,r,i)))}function Kt(e,t){let n=ie[t];return n.tokens.some(o=>be(e,o))||n.bundles.some(o=>J(e,o))}var Jt=new Set(["INPUT","TEXTAREA","SELECT","OPTION"]);function Qe(e,t,n,o){if(e.nodeType===1&&o(e)){n.dropped.push(t);return}n.cloneToLive.set(t,e),n.liveToClone.set(e,t);let r=e,i=t;if(e.nodeType===1){if(Jt.has(e.tagName)&&n.controls.push(e,t),e.tagName==="TEMPLATE"){for(;t.firstChild;)t.removeChild(t.firstChild);r=e.content,i=t.content,n.cloneToLive.set(i,r),n.liveToClone.set(r,i)}}else if(e.nodeType!==11)return;let s=i.firstChild;for(let c=r.firstChild;c&&s;c=c.nextSibling)Qe(c,s,n,o),s=s.nextSibling}function X(e,{capability:t="data",exclude:n=null,inherit:o=!0,provenance:r=null}={}){if(!e)throw new TypeError("createContentView requires a DOM context");let i=e.nodeType===9?e:e.ownerDocument;if(!i?.implementation?.createHTMLDocument)throw new TypeError("createContentView requires an HTML DOM implementation");let s=i.implementation.createHTMLDocument(""),c=r||new WeakMap,l=new WeakMap,a=e.nodeType===9?e.documentElement:e;n&&s.documentElement.matches(n);let u=Y(t),p=o?f=>Kt(f,t)||!!(n&&f.matches(n)):f=>Ze(f,t,u,n,a,!1),h=null;if(a.nodeType!==1||!Ze(a,t,u,n,a,o)){h=s.importNode(a,!0);let f={cloneToLive:c,liveToClone:l,dropped:[],controls:[]};Qe(a,h,f,p);for(let m of f.dropped)m.remove();for(let m=0;m<f.controls.length;m+=2)Ft(f.controls[m],f.controls[m+1])}e.nodeType===9&&h&&(s.replaceChild(h,s.documentElement),l.set(e,s),c.set(s,e));let T=f=>{if(zt.test(f))throw new Error(`Filtered content queries do not support stateful selector: ${f}`)};return{root:h,document:s,capability:t,selector:Y(t),cloneToLive:c,liveToClone:l,original(f){return c.get(f)||null},cloneOf(f){return l.get(f)||null},query(f,m=h){return T(f),Array.from(m.querySelectorAll(f),g=>c.get(g)||g)},text(f=h){return(f===h?h:l.get(f))?.textContent||""},html(f=h){return(f===h?h:l.get(f))?.innerHTML??""},clone(f=h){let m=f===h?h:l.get(f);return m?s.importNode(m,!0):null}}}function tt(e){return e&&e.nodeType===1&&e.tagName==="SCRIPT"&&e.hasAttribute&&e.hasAttribute("data-rules-name")}function Yt(e){return e?(e.nodeType===9||e.nodeType===11,e):null}function et(e,t,n){!e||e.nodeType!==1||(t==="value"&&e.tagName==="INPUT"?e.value=n===null?"":n:t==="checked"&&e.tagName==="INPUT"?e.checked=n!==null:t==="selected"&&e.tagName==="OPTION"&&(e.selected=n!==null))}function nt(e,t){e&&e.tagName==="TEXTAREA"&&(e.value=t)}function rt(e){if(!e||e.nodeType!==1)return;let t=[e,...e.querySelectorAll?e.querySelectorAll("textarea, input, option"):[]];for(let n of t)if(n.tagName==="TEXTAREA")n.value=n.defaultValue;else if(n.tagName==="INPUT"){let o=n.type;o!=="file"&&o!=="checkbox"&&o!=="radio"&&(n.value=n.defaultValue),n.checked=n.defaultChecked}else n.tagName==="OPTION"&&(n.selected=n.defaultSelected)}var E={semanticExclude:!0,find(e,t,n={}){let o=Yt(e);if(!o||!o.querySelectorAll)return[];let r=Array.from(o.querySelectorAll(t));n.includeRulesTag||(r=r.filter(c=>!tt(c)));let i=[];n.skip&&i.push(n.skip);let s=n.templateAttr===null?null:n.templateAttr||"cms-template";if(s&&i.push("["+s+"]"),i.length){let c=i.join(", ");r=r.filter(l=>!l.closest||!l.closest(c))}return r},parent(e){return e?e.parentElement:null},children(e){return e?Array.from(e.children):[]},matches(e,t){return!!(e&&e.matches)&&e.matches(t)},text(e,t){if(t===void 0)return(e.textContent||"").trim();e.textContent=t,nt(e,t)},attr(e,t,n){if(n===void 0)return e.hasAttribute&&e.hasAttribute(t)?e.getAttribute(t):null;e.setAttribute(t,n),et(e,t,n)},removeAttr(e,t){e&&e.removeAttribute&&e.removeAttribute(t),et(e,t,null)},prop(e,t,n){if(n===void 0){let o=e?e[t]:void 0;return o!==void 0?o:null}e[t]=n},clone(e){let t=e.cloneNode(!0);return rt(t),t},insertAt(e,t,n){let o=e.children[n]||null;e.insertBefore(t,o)},insertBefore(e,t){e.parentNode.insertBefore(t,e)},insertAfter(e,t){e.parentNode.insertBefore(t,e.nextSibling)},identity(e){return e||null},remove(e){e&&e.parentNode&&e.parentNode.removeChild(e)},replaceWith(e,t){if(!e||!e.parentNode)throw new Error("dom.replaceWith: node has no parent");let o=e.ownerDocument.createElement("template");o.innerHTML=t;let r=o.content.firstElementChild;if(!r)throw new Error("dom.replaceWith: html did not parse to an element");return e.parentNode.replaceChild(r,e),r},stripIds(e){let t=0;return e.id&&(e.removeAttribute("id"),t++),(e.querySelectorAll?e.querySelectorAll("[id]"):[]).forEach(o=>{o.removeAttribute("id"),t++}),t},sameNode(e,t){return e===t}};function G(e,t={}){if(t.exclude===null)return E;let n=[Y("data"),t.exclude].filter(Boolean).join(", "),o=e.nodeType===9?e:e.ownerDocument||e,r=e.nodeType===9?e.documentElement:e;if(!t._write&&!r?.matches?.(n)&&!r?.querySelector?.(n)&&!o?.querySelector?.(n))return E;let i=e.nodeType===9||!e.isConnected?e:e.ownerDocument,s=e.nodeType===9?e:e.ownerDocument,c=null,l=()=>c||(c=X(i,{capability:"data",exclude:t.exclude||null})),a=f=>{let m=l();return f===e?m.cloneOf(e):m.cloneOf(f)||f},u=f=>c?.original(f)||f,p=(f,m)=>{l().liveToClone.set(f,m),l().cloneToLive.set(m,f);let g=f.childNodes||[],d=m.childNodes||[];for(let y=0;y<Math.min(g.length,d.length);y++)p(g[y],d[y])},h=(f,m,g,d)=>{let y=Array.from(f.childNodes).filter(x=>c.cloneOf(x)),w=y[0];for(;w&&y.includes(w);)w=w.nextSibling;for(let x of y)x.remove();if(g==="innerHTML"){let x=s.createElement("template");x.innerHTML=d;for(let H of Array.from(x.content.childNodes))f.insertBefore(H,w||null)}else f.insertBefore(s.createTextNode(d),w||null),nt(f,d);let b=X(f,{capability:"data",exclude:t.exclude||null});m.replaceChildren(...Array.from(b.root?.childNodes||[]));let O=x=>{let H=b.original(x);H&&(c.liveToClone.set(H,x),c.cloneToLive.set(x,H));for(let dt of Array.from(x.childNodes||[]))O(dt)};for(let x of Array.from(m.childNodes))O(x)},T={...E,find(f,m,g={}){let d=a(f);if(!d?.querySelectorAll)return[];let y=l().query(m,d);g.includeRulesTag||(y=y.filter(b=>!tt(b)));let A=[];g.skip&&A.push(g.skip);let w=g.templateAttr===null?null:g.templateAttr||"cms-template";if(w&&A.push(`[${w}]`),A.length){let b=A.join(", ");y=y.filter(O=>!O.closest?.(b))}return y},parent(f){let m=a(f)?.parentElement;return m?u(m):null},children(f){return Array.from(a(f)?.children||[],u)},text(f,m){if(m===void 0){let y=u(f);return!y?.matches?.(n)&&!y?.querySelector?.(n)?E.text(y):(a(f)?.textContent||"").trim()}let g=u(f);if(!g?.matches?.(n)&&!g?.querySelector?.(n)&&!c){E.text(g,m);return}let d=l().cloneOf(g);d?h(g,d,"textContent",m):E.text(g,m)},attr(f,m,g){let d=u(f);if(g===void 0)return E.attr(d,m);E.attr(d,m,g);let y=c?.cloneOf(d);y&&(E.attr(y,m,g),X(d,{capability:"data",exclude:t.exclude||null}).root===null&&(y.remove(),c.liveToClone.delete(d),c.cloneToLive.delete(y)))},removeAttr(f,m){let g=u(f);E.removeAttr(g,m);let d=c?.cloneOf(g);d&&E.removeAttr(d,m)},prop(f,m,g){let d=u(f);if(g===void 0)return m==="innerHTML"||m==="outerHTML"||m==="textContent"||m==="innerText"?E.prop(a(d),m):E.prop(d,m);let y=m==="innerHTML"||m==="textContent"||m==="innerText",A=y?l().cloneOf(d):c?.cloneOf(d);A&&y?h(d,A,m,g):(E.prop(d,m,g),A&&E.prop(A,m,g))},clone(f){let m=a(f);if(m===f)return E.clone(f);let g=s.importNode(m,!0);return rt(g),g},insertAt(f,m,g){let d=u(f),A=T.children(d)[g]||(()=>{for(let O=d.children.length-1;O>=0;O--){let x=d.children[O];if(l().cloneOf(x))return x.nextElementSibling}return d.firstElementChild})(),w=u(m);d.insertBefore(w,A||null);let b=l().cloneOf(d);if(b){let O=l().cloneOf(w);O||(O=s.importNode(w,!0),p(w,O));let x=Array.from(b.children);b.insertBefore(O,x[g]||null)}},insertBefore(f,m){let g=u(f),d=u(m);g.parentNode.insertBefore(d,g);let y=l().cloneOf(g.parentNode);if(y){let A=l().cloneOf(d);A||(A=s.importNode(d,!0),p(d,A));let w=l().cloneOf(g);w?w.before(A):y.appendChild(A)}},insertAfter(f,m){let g=u(f),d=u(m);g.parentNode.insertBefore(d,g.nextSibling);let y=l().cloneOf(g.parentNode);if(y){let A=l().cloneOf(d);A||(A=s.importNode(d,!0),p(d,A));let w=l().cloneOf(g);w?w.after(A):y.appendChild(A)}},identity(f){return u(f)||null},remove(f){let m=u(f),g=l().cloneOf(m);E.remove(m),g&&E.remove(g)},replaceWith(f,m){let g=u(f),d=l().cloneOf(g),y=E.replaceWith(g,m);if(d){let A=X(y,{capability:"data",exclude:t.exclude||null});if(!A.root)d.remove();else{d.replaceWith(A.root);let w=b=>{let O=A.original(b);O&&(c.liveToClone.set(O,b),c.cloneToLive.set(b,O));for(let x of Array.from(b.childNodes||[]))w(x)};w(A.root)}}return y}};return T}var N=E;var Re={extract:(e,t,n={})=>C(G(e,n),e,t,n),apply:(e,t,n,o={})=>j(G(e,{...o,_write:!0}),e,t,n,o),findRulesIn:(e,t)=>K(N,e,t),findRules:(e,t)=>Se(N,e,t),bind:(e,t,n={})=>{let o=Se(N,e,t);if(!o){let r=typeof t=="string"?`data-rules-name~="${t}"`:"the provided rules object";throw new Error(`hyper-html-api: could not resolve rules for ${r}`)}return{...o,get:()=>C(G(e,n),e,o.rules,n),set:r=>j(G(e,{...n,_write:!0}),e,o.rules,r,n)}},parseStrict:Oe,parseRelaxed:$,ruleAttrIndex:S,splitRule:R,errors:re,DOM_PROPERTIES:Q};var Xt="hha:upgrade-check:";function M(e,t){let n=e.querySelector(`meta[name="${t}"]`),o=n?n.getAttribute("content"):null;return o&&o.trim()?o.trim():null}function ot(e){if(typeof e!="string")return null;let t=e.trim().replace(/^v/,"");return/^\d+(\.\d+)*$/.test(t)?t.split(".").map(Number):null}function Gt(e,t){let n=ot(e),o=ot(t);if(!n||!o)return!1;let r=Math.max(n.length,o.length);for(let i=0;i<r;i++){let s=n[i]||0,c=o[i]||0;if(s!==c)return s>c}return!1}function Zt(e){try{let t=globalThis.localStorage.getItem(e);return t?JSON.parse(t):null}catch{return null}}function Qt(e,t){try{globalThis.localStorage.setItem(e,JSON.stringify(t))}catch{}}async function it({force:e=!1,doc:t,loc:n,fetchFn:o,now:r,ttlMs:i=864e5}={}){if(t=t||(typeof document<"u"?document:null),n=n||(typeof location<"u"?location:null),o=o||(h=>fetch(h)),r=r??Date.now(),!t)return null;let s=M(t,"hyper-source");if(!s)return null;let c=M(t,"hyper-version"),l;try{l=new URL(s,n?n.href:void 0)}catch{return null}if(n&&l.origin===n.origin&&l.pathname===n.pathname)return null;let a=`${Xt}${l.href}:${c||"none"}`,u,p=e?null:Zt(a);if(p&&typeof p.checkedAt=="number"&&r-p.checkedAt<i)u=p.sourceVersion;else{try{let h=await o(l.href);if(!h.ok)throw new Error(`HTTP ${h.status}`);let T=await h.text(),f=new DOMParser().parseFromString(T,"text/html");u=M(f,"hyper-version")}catch{u=null}Qt(a,{checkedAt:r,sourceVersion:u})}return u?{available:Gt(u,c||"0.0.0"),currentVersion:c,sourceVersion:u,sourceUrl:l.href}:null}var en="script[data-rules-name]";function tn(e){return typeof e=="string"?e.trim().replace(/\s+/g," "):""}function se(e,t){let n=e.find(t,en,{includeRulesTag:!0}),o=new Set,r=[];for(let i of n){let s=tn(e.attr(i,"data-rules-name"));if(!s)continue;if(o.has(s)){console.warn(`hyper-html-api: duplicate rules tag name "${s}"; using the first.`);continue}let c=e.attr(i,"data-rules-version");if(c!==Ee)throw new k(c);o.add(s),r.push({name:s,rules:$(e.text(i))})}return r}function Ne(e,t){let n={};for(let{name:o,rules:r}of se(e,t))n[o]=C(e,t,r);return n}function st(e){let t=e||document,n=t.nodeType===9?t:t.ownerDocument||t;return{dataByName:Ne(N,t),version:M(n,"hyper-version")}}var Z=class extends Error{constructor(t,n){super(`could not fetch upgrade source: ${t}`),this.name="UpgradeSourceUnreachable",this.sourceUrl=t,this.cause=n}},ce=class extends Error{constructor(t){super(`upgrade source has no rules tags; refusing to drop all existing data: ${t}`),this.name="UpgradeSourceHasNoRules",this.sourceUrl=t}},_=class extends Error{constructor(t,n){super(t),this.name="UpgradeTransformInvalid",this.cause=n}},le=class extends Error{constructor(t){super(`found ${t} script[type="text/hyper-upgrade"] tags; only one is allowed per document.`),this.name="UpgradeMultipleTransforms",this.count=t}};var nn="text/hyper-upgrade";function ct(e,t){let n=e.find(t,`script[type="${nn}"]`);if(n.length===0)return null;if(n.length>1)throw new le(n.length);return e.text(n[0])||null}var rn=new Function("url","return import(url)");async function lt(e){let t=new Blob([e],{type:"text/javascript"}),n=URL.createObjectURL(t),o;try{o=await rn(n)}catch(r){throw new _(`transform failed to load: ${r&&r.message?r.message:r}`,r)}finally{URL.revokeObjectURL(n)}if(typeof o.default!="function")throw new _("transform must `export default` a function");return o.default}function fe(e,t){let n={carriedOver:0,discarded:0,listItems:0},o=Ce(t,e,n);return Me(t,e,n),{data:o,summary:n}}function Ce(e,t,n,o=!1){if(typeof e=="string")return e.endsWith("[]")?Array.isArray(t)?(n.listItems+=t.length,n.carriedOver+=t.length,t):o?[]:void 0:t==null||typeof t=="object"?o&&!on(e)?null:void 0:(n.carriedOver++,t);if(Array.isArray(e)){let[,r]=e;return Array.isArray(t)?(n.listItems+=t.length,t.map(i=>Ce(r,i,n,!0))):o?[]:void 0}if(typeof e=="object"&&e!==null){let r={};for(let[i,s]of Object.entries(e)){let c=Ce(s,t?.[i],n,o);c!==void 0&&(r[i]=c)}return r}}function on(e){let t=S(e);return t!==-1&&D.has(e.slice(t+1))}function Me(e,t,n){if(t!=null){if(typeof e=="object"&&e!==null&&!Array.isArray(e)){if(typeof t!="object"||Array.isArray(t))return;let o=new Set(Object.keys(e));for(let r of Object.keys(t))o.has(r)?Me(e[r],t[r],n):n.discarded+=U(t[r]);return}if(Array.isArray(e)&&Array.isArray(t)){let o=e[1];t.forEach(r=>Me(o,r,n));return}typeof e=="string"&&!e.endsWith("[]")&&typeof t=="object"&&t!==null&&(n.discarded+=U(t))}}function U(e){return e==null?0:Array.isArray(e)?e.reduce((t,n)=>t+U(n),0):typeof e=="object"?Object.values(e).reduce((t,n)=>t+U(n),0):1}function ft(e,t,n){let o=se(e,t),r={carriedOver:0,discarded:0,listItems:0},i={},s=new Set;for(let{name:c,rules:l}of o){if(s.add(c),!Object.prototype.hasOwnProperty.call(n,c)){i[c]={carriedOver:0,discarded:0,listItems:0};continue}let{data:a,summary:u}=fe(n[c],l);j(e,t,l,a,{templateAttr:"cms-template"}),i[c]=u,r.carriedOver+=u.carriedOver,r.discarded+=u.discarded,r.listItems+=u.listItems}for(let c of Object.keys(n))s.has(c)||(r.discarded+=U(n[c]));return{totals:r,byName:i,rulesTagCount:o.length}}async function ut({sourceUrl:e,dataByName:t,fromVersion:n,doc:o,loc:r,fetchFn:i}={}){if(o=o||(typeof document<"u"?document:null),r=r||(typeof location<"u"?location:null),i=i||(d=>fetch(d)),!o)throw new Error("upgrade.run requires a document context");if(e=e||M(o,"hyper-source"),!e)throw new Error("upgrade.run: no sourceUrl given and no hyper-source meta tag found");let s=new URL(e,r?r.href:void 0);n=n!==void 0?n:M(o,"hyper-version"),t=t||Ne(N,o);let c;try{c=await i(s.href)}catch(d){throw new Z(s.href,d)}if(!c.ok)throw new Z(s.href,new Error(`HTTP ${c.status}`));let l=await c.text(),a=new DOMParser().parseFromString(l,"text/html"),u=M(a,"hyper-version"),p=t,h=!1,T=ct(N,a);if(T){let y=await(await lt(T))(p,{fromVersion:n,toVersion:u});if(!y||typeof y!="object"||Array.isArray(y))throw new _("transform must return a plain object map of { rulesName: data }");p=y,h=!0}let{totals:f,byName:m,rulesTagCount:g}=ft(N,a,p);if(g===0&&Object.keys(p).length>0)throw new ce(s.href);return{html:cn(a),fromVersion:n,toVersion:u,summary:{transformApplied:h,totals:f,byName:m}}}function sn(e){for(let t of e.querySelectorAll("input")){let n=(t.getAttribute("type")||"").toLowerCase();n!=="file"&&(n==="checkbox"||n==="radio"?t.checked!==t.hasAttribute("checked")&&t.toggleAttribute("checked",t.checked):t.value!==(t.getAttribute("value")??"")&&t.setAttribute("value",t.value))}for(let t of e.querySelectorAll("textarea"))t.value!==t.textContent&&(t.textContent=t.value);for(let t of e.querySelectorAll("select")){let n=[...t.options];if(!t.multiple){let o=n.findIndex(r=>r.hasAttribute("selected"));if(t.selectedIndex===o||o===-1&&t.selectedIndex<=0)continue}for(let o of n)o.selected!==o.hasAttribute("selected")&&o.toggleAttribute("selected",o.selected)}}function cn(e){return sn(e),`<!DOCTYPE ${e.doctype&&e.doctype.name?e.doctype.name:"html"}>
|
|
2
|
+
`+e.documentElement.outerHTML}var at={checkForUpdate:it,run:ut,extractAll:st,shapeMatch:fe};var ln={engine:Re,upgrade:at},fn=ln;return gt(un);})();
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"apply",
|
|
10
10
|
"CMS"
|
|
11
11
|
],
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.14.0",
|
|
13
13
|
"homepage": "https://github.com/panphora/hyper-html-api",
|
|
14
14
|
"bugs": {
|
|
15
15
|
"url": "https://github.com/panphora/hyper-html-api/issues"
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"./data": "./src/data.js",
|
|
36
36
|
"./upgrade": "./src/upgrade.js",
|
|
37
37
|
"./page": "./src/page.js",
|
|
38
|
-
"./write": "./src/write.js"
|
|
38
|
+
"./write": "./src/write.js",
|
|
39
|
+
"./site": "./src/site.js"
|
|
39
40
|
},
|
|
40
41
|
"scripts": {
|
|
41
42
|
"build": "npx esbuild src/hyper-html-api.js --bundle --minify --format=iife --global-name=HyperHtmlApi --outfile=dist/hyper-html-api.min.js && npm run build:engine && npm run build:engine:esm",
|
package/src/engine/apply.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
ShapeMismatch,
|
|
11
11
|
} from './errors.js'
|
|
12
12
|
import { listDiff } from './diff.js'
|
|
13
|
-
import { ruleAttrIndex } from './rule-syntax.js'
|
|
13
|
+
import { ruleAttrIndex, splitRule } from './rule-syntax.js'
|
|
14
14
|
import { isCustomPropertyName, setStyleVar } from './style-vars.js'
|
|
15
15
|
|
|
16
16
|
export function apply(adapter, root, rules, data, opts = {}) {
|
|
@@ -70,11 +70,10 @@ function applyScalar(adapter, ctx, rule, value, trace, opts) {
|
|
|
70
70
|
|
|
71
71
|
const at = ruleAttrIndex(rule)
|
|
72
72
|
if (at !== -1) {
|
|
73
|
-
const selector = rule
|
|
73
|
+
const { selector, all } = splitRule(rule)
|
|
74
74
|
const name = rule.slice(at + 1)
|
|
75
75
|
const matches = selector ? adapter.find(ctx, selector, opts) : [ctx]
|
|
76
|
-
|
|
77
|
-
writePropOrAttr(adapter, matches[0], name, value)
|
|
76
|
+
for (const node of all ? matches : matches.slice(0, 1)) writePropOrAttr(adapter, node, name, value)
|
|
78
77
|
return ctx
|
|
79
78
|
}
|
|
80
79
|
|
|
@@ -83,9 +82,9 @@ function applyScalar(adapter, ctx, rule, value, trace, opts) {
|
|
|
83
82
|
return ctx
|
|
84
83
|
}
|
|
85
84
|
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
writeText(adapter,
|
|
85
|
+
const { selector, all } = splitRule(rule)
|
|
86
|
+
const matches = adapter.find(ctx, selector, opts)
|
|
87
|
+
for (const node of all ? matches : matches.slice(0, 1)) writeText(adapter, node, value)
|
|
89
88
|
return ctx
|
|
90
89
|
}
|
|
91
90
|
|
package/src/engine/extract.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DOM_PROPERTIES_SET } from './dom-properties.js'
|
|
2
2
|
import { MaxRuleDepthExceeded, MAX_RULE_DEPTH } from './errors.js'
|
|
3
|
-
import { ruleAttrIndex } from './rule-syntax.js'
|
|
3
|
+
import { ruleAttrIndex, splitRule } from './rule-syntax.js'
|
|
4
4
|
import { isCustomPropertyName, readStyleVar } from './style-vars.js'
|
|
5
5
|
|
|
6
6
|
export function extract(adapter, root, rules, opts = {}) {
|
|
@@ -63,16 +63,19 @@ function extractScalar(adapter, ctx, rule, trace, opts) {
|
|
|
63
63
|
|
|
64
64
|
const at = ruleAttrIndex(rule)
|
|
65
65
|
if (at !== -1) {
|
|
66
|
-
const selector = rule
|
|
66
|
+
const { selector, all } = splitRule(rule)
|
|
67
67
|
const name = rule.slice(at + 1)
|
|
68
68
|
const matches = selector ? adapter.find(ctx, selector, opts) : [ctx]
|
|
69
|
+
if (all && opts.allMatches) return matches.map((n) => readPropOrAttr(adapter, n, name))
|
|
69
70
|
if (matches.length === 0) return null
|
|
70
71
|
return readPropOrAttr(adapter, matches[0], name)
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
if (rule === '.') return adapter.text(ctx)
|
|
74
75
|
|
|
75
|
-
const
|
|
76
|
+
const { selector, all } = splitRule(rule)
|
|
77
|
+
const matches = adapter.find(ctx, selector, opts)
|
|
78
|
+
if (all && opts.allMatches) return matches.map((n) => adapter.text(n))
|
|
76
79
|
return matches.length === 0 ? null : adapter.text(matches[0])
|
|
77
80
|
}
|
|
78
81
|
|
package/src/engine/round-trip.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
coercePropValue,
|
|
5
5
|
} from './dom-properties.js'
|
|
6
6
|
import { WriteNotRoundTripped } from './errors.js'
|
|
7
|
-
import { ruleAttrIndex } from './rule-syntax.js'
|
|
7
|
+
import { ruleAttrIndex, splitRule } from './rule-syntax.js'
|
|
8
8
|
import { isCustomPropertyName } from './style-vars.js'
|
|
9
9
|
|
|
10
10
|
// Props whose read-side value keeps its whitespace. Every other text rule reads
|
|
@@ -47,6 +47,14 @@ function checkScalarRule(rule, want, got, path) {
|
|
|
47
47
|
return
|
|
48
48
|
}
|
|
49
49
|
const at = ruleAttrIndex(rule)
|
|
50
|
+
if (splitRule(rule).all) {
|
|
51
|
+
if (!Array.isArray(got) || got.length === 0) fail(path)
|
|
52
|
+
for (const one of got) {
|
|
53
|
+
if (at !== -1) checkPropOrAttr(rule.slice(at + 1), want, one, path)
|
|
54
|
+
else checkText(want, one, path)
|
|
55
|
+
}
|
|
56
|
+
return
|
|
57
|
+
}
|
|
50
58
|
if (at !== -1) {
|
|
51
59
|
checkPropOrAttr(rule.slice(at + 1), want, got, path)
|
|
52
60
|
return
|
|
@@ -34,12 +34,22 @@ export function ruleAttrIndex(rule) {
|
|
|
34
34
|
return found
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
const ALL = '[*]'
|
|
38
|
+
|
|
37
39
|
// "<selector>@<prop>" split at that separator. selector is "" for a leading "@"
|
|
38
|
-
// (the context node itself); prop is null when the rule names no prop.
|
|
40
|
+
// (the context node itself); prop is null when the rule names no prop. A selector
|
|
41
|
+
// that ends in "[*]" names every match instead of the first: `all` is true and
|
|
42
|
+
// the marker is removed, because "[*]" is not CSS and no adapter can run it.
|
|
39
43
|
export function splitRule(rule) {
|
|
40
44
|
const at = ruleAttrIndex(rule)
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
const head = at === -1 ? rule : rule.slice(0, at)
|
|
46
|
+
const all = head.endsWith(ALL)
|
|
47
|
+
const split = {
|
|
48
|
+
selector: all ? head.slice(0, -ALL.length) : head,
|
|
49
|
+
prop: at === -1 ? null : rule.slice(at + 1) || null,
|
|
50
|
+
}
|
|
51
|
+
if (all) split.all = true
|
|
52
|
+
return split
|
|
43
53
|
}
|
|
44
54
|
|
|
45
55
|
// The list grammar needs a second split: "container > row" says where a row
|
package/src/engine/write-plan.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { splitRule } from './rule-syntax.js'
|
|
2
2
|
|
|
3
3
|
function isPlainObject(v) {
|
|
4
4
|
return v !== null && typeof v === 'object' && !Array.isArray(v)
|
|
@@ -34,8 +34,7 @@ export function planWrite(adapter, root, rules, data, opts = {}) {
|
|
|
34
34
|
if (value === undefined) return
|
|
35
35
|
if (typeof rule === 'string') {
|
|
36
36
|
if (rule.endsWith('[]') || rule === '.' || rule.startsWith('@')) return
|
|
37
|
-
const
|
|
38
|
-
const selector = at === -1 ? rule : rule.slice(0, at)
|
|
37
|
+
const { selector } = splitRule(rule)
|
|
39
38
|
if (!selector) return
|
|
40
39
|
if (adapter.find(ctx, selector, opts).length === 0) unmatched.push({ path: label(path), selector })
|
|
41
40
|
return
|
package/src/page.js
CHANGED
|
@@ -5,7 +5,7 @@ import { NoRulesTag, RulesParseError } from './engine/errors.js'
|
|
|
5
5
|
import { parseRelaxed } from './engine/rules.js'
|
|
6
6
|
import { writeDocument } from './write.js'
|
|
7
7
|
|
|
8
|
-
const PAGE = /^
|
|
8
|
+
const PAGE = /^blockeditor(?:\.[0-9]+)?$/
|
|
9
9
|
const TEXT = new Set(['paragraph', 'heading', 'list_item', 'callout', 'code_block', 'toggle'])
|
|
10
10
|
const MARKS = ['b', 'i', 's', 'c', 'a']
|
|
11
11
|
|
|
@@ -21,10 +21,19 @@ function refuse(message) {
|
|
|
21
21
|
throw new PageWriteRefused('invalid-content', message)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
// Inert content (a starter article kept in a <template>) is not part of the page, as in a browser.
|
|
25
|
+
// Cheerio parents a template's content under a root node, which closest() does not climb past.
|
|
26
|
+
function live(_, node) {
|
|
27
|
+
for (let up = node.parent; up; up = up.parent) {
|
|
28
|
+
if (up.type === 'tag' && (up.name === 'template' || up.name === 'noscript')) return false
|
|
29
|
+
}
|
|
30
|
+
return true
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
function pageNodes($) {
|
|
25
|
-
const tags = $('script[merge][clay~="live"]').filter((_, node) => PAGE.test($(node).attr('merge')))
|
|
34
|
+
const tags = $('script[merge][clay~="live"]').filter((_, node) => PAGE.test($(node).attr('merge'))).filter(live)
|
|
26
35
|
if (!tags.length) return null
|
|
27
|
-
const articles = $('article[data-
|
|
36
|
+
const articles = $('article[data-blockeditor]').filter(live)
|
|
28
37
|
if (tags.length !== 1 || articles.length !== 1) refuse('Expected one page store and one page article')
|
|
29
38
|
return { tag: tags[0], article: articles[0] }
|
|
30
39
|
}
|
|
@@ -316,8 +325,9 @@ export async function writePageDocument(load, html, data, options = {}) {
|
|
|
316
325
|
const next$ = load(candidate.html, { sourceCodeLocationInfo: true })
|
|
317
326
|
const nextNodes = pageNodes(next$)
|
|
318
327
|
const aligned$ = load(aligned)
|
|
319
|
-
const
|
|
320
|
-
const
|
|
328
|
+
const alignedArticle = pageNodes(aligned$).article
|
|
329
|
+
const changes = pageChanges(next$, nextNodes.article, aligned$, alignedArticle, page.blocks, before.model, projection)
|
|
330
|
+
const unchangedAttrs = canon(next$(nextNodes.article).attr()) === canon(aligned$(alignedArticle).attr())
|
|
321
331
|
const proposed = projectionOf(load, proposedBlocks(page.blocks, changes), projection)
|
|
322
332
|
if (!unchangedAttrs || !sameArticle(next$, nextNodes.article, proposed)) {
|
|
323
333
|
refuse('The article edit cannot be represented in the page store')
|
package/src/site.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import cheerioAdapter from './adapters/cheerio.js'
|
|
2
|
+
import { extract } from './engine/extract.js'
|
|
3
|
+
import { findRulesIn } from './engine/rules-tag.js'
|
|
4
|
+
import { splitRule } from './engine/rule-syntax.js'
|
|
5
|
+
import { writeDocument } from './write.js'
|
|
6
|
+
|
|
7
|
+
export const SITE_KEY = 'site'
|
|
8
|
+
|
|
9
|
+
function isPlainObject(value) {
|
|
10
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// The part of `value` that `rule` declares. Keys the rule does not name are
|
|
14
|
+
// dropped at every level, because the writer refuses unknown keys and a store
|
|
15
|
+
// holds keys other pages use. A key the store does not hold stays absent, and
|
|
16
|
+
// the writer skips an absent key, so the page keeps what it has.
|
|
17
|
+
export function projectSite(rule, value) {
|
|
18
|
+
if (isPlainObject(rule)) {
|
|
19
|
+
if (!isPlainObject(value)) return value
|
|
20
|
+
const out = {}
|
|
21
|
+
for (const key of Object.keys(rule)) {
|
|
22
|
+
if (value[key] !== undefined) out[key] = projectSite(rule[key], value[key])
|
|
23
|
+
}
|
|
24
|
+
return out
|
|
25
|
+
}
|
|
26
|
+
if (Array.isArray(rule) && Array.isArray(value)) {
|
|
27
|
+
return value.map((item) => projectSite(rule[1], item))
|
|
28
|
+
}
|
|
29
|
+
return value
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Writes the store's values into a page through the page's own `site` rule.
|
|
33
|
+
// Never throws for a page problem: a key that cannot be written is listed in
|
|
34
|
+
// `failed` and the other keys still land. `declared` is false when the page has
|
|
35
|
+
// no rules tag or no `site` object in it, and then `html` is `src`.
|
|
36
|
+
export function writeSite(load, src, store, options = {}) {
|
|
37
|
+
const { token = 'api' } = options
|
|
38
|
+
const none = { html: src, changed: false, declared: false, applied: [], failed: [] }
|
|
39
|
+
if (!isPlainObject(store)) return none
|
|
40
|
+
let found
|
|
41
|
+
try {
|
|
42
|
+
found = findRulesIn(cheerioAdapter, load(src).root(), token)
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return { ...none, declared: true, failed: [{ key: null, code: error.name, message: error.message }] }
|
|
45
|
+
}
|
|
46
|
+
if (!found || !isPlainObject(found.rules) || !isPlainObject(found.rules[SITE_KEY])) return none
|
|
47
|
+
const data = projectSite(found.rules[SITE_KEY], store)
|
|
48
|
+
const keys = Object.keys(data)
|
|
49
|
+
if (keys.length === 0) return { ...none, declared: true }
|
|
50
|
+
const write = (html, part) => writeDocument(load, html, { [SITE_KEY]: part }, { token, rules: found.rules }).html
|
|
51
|
+
try {
|
|
52
|
+
const html = write(src, data)
|
|
53
|
+
return { html, changed: html !== src, declared: true, applied: keys, failed: [] }
|
|
54
|
+
} catch {
|
|
55
|
+
// One key failed. Write them one at a time so the rest still land.
|
|
56
|
+
}
|
|
57
|
+
let html = src
|
|
58
|
+
const applied = []
|
|
59
|
+
const failed = []
|
|
60
|
+
for (const key of keys) {
|
|
61
|
+
try {
|
|
62
|
+
html = write(html, { [key]: data[key] })
|
|
63
|
+
applied.push(key)
|
|
64
|
+
} catch (error) {
|
|
65
|
+
failed.push({ key, code: error.name, message: error.message })
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return { html, changed: html !== src, declared: true, applied, failed }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// The same rule with each attribute read turned into a read of its element's text, which is
|
|
72
|
+
// null exactly where the element is missing: a missing element can then be told apart from
|
|
73
|
+
// an element without the attribute, which both read as a null attribute.
|
|
74
|
+
function presenceRule(rule) {
|
|
75
|
+
if (typeof rule === 'string') {
|
|
76
|
+
const { selector, prop } = splitRule(rule)
|
|
77
|
+
return prop && !prop.endsWith('[]') ? (selector || '.') : rule
|
|
78
|
+
}
|
|
79
|
+
if (Array.isArray(rule)) return rule.length < 2 ? rule : [rule[0], presenceRule(rule[1])]
|
|
80
|
+
if (isPlainObject(rule)) return Object.fromEntries(Object.entries(rule).map(([key, value]) => [key, presenceRule(value)]))
|
|
81
|
+
return rule
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// The page's own `site` rule and the values the page holds for it right now, read key by
|
|
85
|
+
// key: a key whose rule cannot be read (a broken selector) is listed in `broken` and left
|
|
86
|
+
// out of `data`, and the other keys still read. `present` mirrors `data` for
|
|
87
|
+
// siteValueProblem. Never throws: a page with no rules tag, or no `site` key, declares nothing.
|
|
88
|
+
export function readSite(load, src, options = {}) {
|
|
89
|
+
const { token = 'api' } = options
|
|
90
|
+
const none = { declared: false, rule: null, data: {}, present: {}, broken: [] }
|
|
91
|
+
let root
|
|
92
|
+
let found
|
|
93
|
+
try {
|
|
94
|
+
root = load(src).root()
|
|
95
|
+
found = findRulesIn(cheerioAdapter, root, token)
|
|
96
|
+
} catch {
|
|
97
|
+
return none
|
|
98
|
+
}
|
|
99
|
+
if (!found || !isPlainObject(found.rules) || !isPlainObject(found.rules[SITE_KEY])) return none
|
|
100
|
+
const rule = found.rules[SITE_KEY]
|
|
101
|
+
const read = (keyRule, key) => extract(cheerioAdapter, root, { [key]: keyRule }, { templateAttr: 'cms-template' })[key]
|
|
102
|
+
const data = {}
|
|
103
|
+
const present = {}
|
|
104
|
+
const broken = []
|
|
105
|
+
for (const key of Object.keys(rule)) {
|
|
106
|
+
try {
|
|
107
|
+
data[key] = read(rule[key], key)
|
|
108
|
+
present[key] = read(presenceRule(rule[key]), key)
|
|
109
|
+
} catch {
|
|
110
|
+
delete data[key]
|
|
111
|
+
broken.push(key)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return { declared: true, rule, data, present, broken }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Why a value read from a page must not be written to the store, or null when it may.
|
|
118
|
+
// A text rule that matched no element reads null, and an emptied list cannot be regrown
|
|
119
|
+
// by writeSite, so both would damage every other page. A null attribute is a real value:
|
|
120
|
+
// it means the attribute is absent, unless `present` (readSite's mirror of the value) shows
|
|
121
|
+
// that the attribute's element is missing too.
|
|
122
|
+
export function siteValueProblem(rule, value, present) {
|
|
123
|
+
if (typeof rule === 'string') {
|
|
124
|
+
if (rule.endsWith('[]')) {
|
|
125
|
+
if (!Array.isArray(value)) return 'unreadable'
|
|
126
|
+
return value.length === 0 ? 'empty-list' : null
|
|
127
|
+
}
|
|
128
|
+
if (value !== null) return null
|
|
129
|
+
return splitRule(rule).prop === null || present === null ? 'unreadable' : null
|
|
130
|
+
}
|
|
131
|
+
if (Array.isArray(rule)) {
|
|
132
|
+
if (!Array.isArray(value)) return 'unreadable'
|
|
133
|
+
if (value.length === 0) return 'empty-list'
|
|
134
|
+
if (rule.length < 2) return null
|
|
135
|
+
for (const [index, row] of value.entries()) {
|
|
136
|
+
const problem = siteValueProblem(rule[1], row, Array.isArray(present) ? present[index] : undefined)
|
|
137
|
+
if (problem) return problem
|
|
138
|
+
}
|
|
139
|
+
return null
|
|
140
|
+
}
|
|
141
|
+
if (isPlainObject(rule)) {
|
|
142
|
+
if (!isPlainObject(value)) return 'unreadable'
|
|
143
|
+
for (const key of Object.keys(rule)) {
|
|
144
|
+
const problem = siteValueProblem(rule[key], value[key], isPlainObject(present) ? present[key] : undefined)
|
|
145
|
+
if (problem) return problem
|
|
146
|
+
}
|
|
147
|
+
return null
|
|
148
|
+
}
|
|
149
|
+
return 'unreadable'
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// The store's next value for one key after a page edit. An object keeps the fields the
|
|
153
|
+
// page's rule does not name, because other pages use them. A list is taken whole from
|
|
154
|
+
// the page: rows have no identity to merge by.
|
|
155
|
+
export function mergeSiteEdit(rule, stored, edited) {
|
|
156
|
+
if (isPlainObject(rule) && isPlainObject(edited)) {
|
|
157
|
+
const out = isPlainObject(stored) ? { ...stored } : {}
|
|
158
|
+
for (const key of Object.keys(rule)) {
|
|
159
|
+
if (edited[key] !== undefined) out[key] = mergeSiteEdit(rule[key], out[key], edited[key])
|
|
160
|
+
}
|
|
161
|
+
return out
|
|
162
|
+
}
|
|
163
|
+
return edited
|
|
164
|
+
}
|
package/src/upgrade/migrate.js
CHANGED
|
@@ -21,7 +21,8 @@ export function migrateInto(adapter, root, dataByName) {
|
|
|
21
21
|
continue
|
|
22
22
|
}
|
|
23
23
|
const { data, summary } = shapeMatch(dataByName[name], rules)
|
|
24
|
-
|
|
24
|
+
// A row whose nested list is empty at that spot in v2 grows from the page's seeds, as a write does.
|
|
25
|
+
apply(adapter, root, rules, data, { templateAttr: 'cms-template' })
|
|
25
26
|
byName[name] = summary
|
|
26
27
|
totals.carriedOver += summary.carriedOver
|
|
27
28
|
totals.discarded += summary.discarded
|