@certrev/cert-block 2.0.1 → 2.1.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/CHANGELOG.md +66 -0
- package/README.md +9 -4
- package/dist/builder/cert-review-card.d.ts +2 -0
- package/dist/builder/cert-review-card.d.ts.map +1 -1
- package/dist/builder/cert-review-card.js +95 -10
- package/dist/builder/cert-review-card.js.map +1 -1
- package/dist/builder/delivery-runtime.d.ts +25 -1
- package/dist/builder/delivery-runtime.d.ts.map +1 -1
- package/dist/builder/delivery-runtime.js +26 -1
- package/dist/builder/delivery-runtime.js.map +1 -1
- package/dist/builder/envelope-face.d.ts +2 -0
- package/dist/builder/envelope-face.d.ts.map +1 -1
- package/dist/builder/envelope-face.js +9 -1
- package/dist/builder/envelope-face.js.map +1 -1
- package/dist/builder/version.d.ts +1 -1
- package/dist/builder/version.js +1 -1
- package/dist/components/CertBadge.d.ts.map +1 -1
- package/dist/components/CertBadge.js +4 -2
- package/dist/components/CertBadge.js.map +1 -1
- package/dist/components/render-cert-block.d.ts +9 -1
- package/dist/components/render-cert-block.d.ts.map +1 -1
- package/dist/components/render-cert-block.js +4 -4
- package/dist/components/render-cert-block.js.map +1 -1
- package/dist/components/render-def.d.ts +18 -0
- package/dist/components/render-def.d.ts.map +1 -1
- package/dist/components/render-def.js +15 -0
- package/dist/components/render-def.js.map +1 -1
- package/dist/modal/cert-modal-view.d.ts +3 -0
- package/dist/modal/cert-modal-view.d.ts.map +1 -1
- package/dist/modal/cert-modal-view.js +4 -3
- package/dist/modal/cert-modal-view.js.map +1 -1
- package/dist/modal/certrev-cert.js +4 -4
- package/dist/modal/display-strings.d.ts +9 -0
- package/dist/modal/display-strings.d.ts.map +1 -1
- package/dist/modal/display-strings.js +12 -1
- package/dist/modal/display-strings.js.map +1 -1
- package/dist/modal/ftc-disclosure.d.ts +6 -0
- package/dist/modal/ftc-disclosure.d.ts.map +1 -1
- package/dist/modal/ftc-disclosure.js +6 -0
- package/dist/modal/ftc-disclosure.js.map +1 -1
- package/dist/reader/render.d.ts.map +1 -1
- package/dist/reader/render.js +5 -10
- package/dist/reader/render.js.map +1 -1
- package/dist/verify/cache.d.ts +24 -0
- package/dist/verify/cache.d.ts.map +1 -1
- package/dist/verify/cache.js +78 -6
- package/dist/verify/cache.js.map +1 -1
- package/dist/verify/get-verified-delivery.d.ts +14 -0
- package/dist/verify/get-verified-delivery.d.ts.map +1 -1
- package/dist/verify/get-verified-delivery.js +21 -0
- package/dist/verify/get-verified-delivery.js.map +1 -1
- package/dist/webcomponent/render-badge-html.d.ts.map +1 -1
- package/dist/webcomponent/render-badge-html.js +6 -3
- package/dist/webcomponent/render-badge-html.js.map +1 -1
- package/package.json +1 -1
- package/src/builder/cert-review-card.tsx +108 -8
- package/src/builder/delivery-runtime.ts +28 -1
- package/src/builder/envelope-face.ts +16 -1
- package/src/builder/version.ts +1 -1
- package/src/components/CertBadge.tsx +6 -3
- package/src/components/render-cert-block.ts +13 -4
- package/src/components/render-def.ts +24 -0
- package/src/modal/cert-modal-view.ts +7 -3
- package/src/modal/display-strings.ts +14 -1
- package/src/modal/ftc-disclosure.ts +8 -0
- package/src/reader/render.ts +12 -11
- package/src/verify/cache.ts +78 -6
- package/src/verify/get-verified-delivery.ts +27 -0
- package/src/webcomponent/render-badge-html.ts +6 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* biome-ignore-all format: generated cert-badge bundle, see @certrev/cert-block src/modal/ */ /* biome-ignore-all lint: generated cert-badge bundle, see @certrev/cert-block src/modal/ */
|
|
2
|
-
"use strict";(()=>{var H="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Be=(()=>{let e=new Int8Array(128).fill(-1);for(let t=0;t<H.length;t++)e[H.charCodeAt(t)]=t;return e[45]=62,e[95]=63,e})();function g(e){let t=[];for(let i=0;i<e.length;i++){let c=e.charCodeAt(i),d=c<128?Be[c]:-1;d>=0&&t.push(d)}let r=Math.floor(t.length*6/8),n=new Uint8Array(r),o=0,a=0,s=0;for(let i=0;i<t.length;i++)o=o<<6|t[i],a+=6,a>=8&&(a-=8,n[s++]=o>>a&255);return n}function C(e){return g(e)}function p(e,t=new Set){if(typeof e=="number"&&isNaN(e))throw new Error("NaN is not allowed");if(typeof e=="number"&&!isFinite(e))throw new Error("Infinity is not allowed");if(e===null||typeof e!="object")return JSON.stringify(e);if(typeof e.toJSON=="function"){if(t.has(e))throw new Error("Circular reference detected");t.add(e);let n=p(e.toJSON(),t);return t.delete(e),n}if(t.has(e))throw new Error("Circular reference detected");t.add(e);let r;if(Array.isArray(e))r=`[${e.map(o=>p(o===void 0||typeof o=="symbol"?null:o,t)).join(",")}]`;else{let n=[];for(let o of Object.keys(e).sort())e[o]===void 0||typeof e[o]=="symbol"||n.push(`${p(o)}:${p(e[o],t)}`);r=`{${n.join(",")}}`}return t.delete(e),r}var
|
|
2
|
+
"use strict";(()=>{var H="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Be=(()=>{let e=new Int8Array(128).fill(-1);for(let t=0;t<H.length;t++)e[H.charCodeAt(t)]=t;return e[45]=62,e[95]=63,e})();function g(e){let t=[];for(let i=0;i<e.length;i++){let c=e.charCodeAt(i),d=c<128?Be[c]:-1;d>=0&&t.push(d)}let r=Math.floor(t.length*6/8),n=new Uint8Array(r),o=0,a=0,s=0;for(let i=0;i<t.length;i++)o=o<<6|t[i],a+=6,a>=8&&(a-=8,n[s++]=o>>a&255);return n}function C(e){return g(e)}function p(e,t=new Set){if(typeof e=="number"&&isNaN(e))throw new Error("NaN is not allowed");if(typeof e=="number"&&!isFinite(e))throw new Error("Infinity is not allowed");if(e===null||typeof e!="object")return JSON.stringify(e);if(typeof e.toJSON=="function"){if(t.has(e))throw new Error("Circular reference detected");t.add(e);let n=p(e.toJSON(),t);return t.delete(e),n}if(t.has(e))throw new Error("Circular reference detected");t.add(e);let r;if(Array.isArray(e))r=`[${e.map(o=>p(o===void 0||typeof o=="symbol"?null:o,t)).join(",")}]`;else{let n=[];for(let o of Object.keys(e).sort())e[o]===void 0||typeof e[o]=="symbol"||n.push(`${p(o)}:${p(e[o],t)}`);r=`{${n.join(",")}}`}return t.delete(e),r}var $e=typeof p=="function"?p:p.default;function K(e){let t=$e(e);if(typeof t!="string")throw new Error("canonicalize: value is not JSON-serializable");return t}function T(e){return new TextEncoder().encode(K(e))}function b(e,t="$"){if(typeof e=="number"){if(!Number.isInteger(e)||!Number.isSafeInteger(e))throw new Error(`canonicalPayloadBytes: number at ${t} (${e}) is not a safe integer. Signed-payload numbers must be safe integers so PHP/Go/Java verifiers reproduce identical canonical bytes`);return}if(Array.isArray(e)){e.forEach((r,n)=>b(r,`${t}[${n}]`));return}if(e&&typeof e=="object")for(let[r,n]of Object.entries(e))b(n,`${t}.${r}`)}function F(e){return b(e),T(e)}function R(e){return b(e),T(e)}var E="ed25519";var m={name:"Ed25519"};function Ne(e){return e.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,"")}async function q(e){switch(e.format){case"pem":return crypto.subtle.importKey("spki",g(Ne(e.pem)),m,!1,["verify"]);case"spki-base64":return crypto.subtle.importKey("spki",g(e.base64),m,!1,["verify"]);case"spki-der":return crypto.subtle.importKey("spki",e.bytes,m,!1,["verify"]);case"raw":{if(e.bytes.length!==32)throw new Error(`ed25519 raw public key must be 32 bytes, got ${e.bytes.length}`);return crypto.subtle.importKey("raw",e.bytes,m,!1,["verify"])}}}function Pe(e){if("format"in e)return!1;let t=e;return typeof t.type=="string"&&typeof t.algorithm=="object"&&Array.isArray(t.usages)}async function j(e){return Pe(e)?e:q(e)}async function G(e,t,r){let n=F(e),o=C(t);try{return await crypto.subtle.verify(m,r,o,n)}catch{return!1}}async function ze(e,t){let{payload:r,signature:n}=e??{};if(!r||!n||r.contractVersion!==1)return{ok:!1,reason:"unsupported_contract_version"};if(n.alg!==E)return{ok:!1,reason:"unsupported_alg"};let o=await t(n.kid);if(!o)return{ok:!1,reason:"unknown_key"};let a;try{a=await j(o)}catch{return{ok:!1,reason:"unknown_key"}}return await G(r,n.sig,a)?{ok:!0,key:a}:{ok:!1,reason:"invalid_signature"}}function J(e,t){let r=t.now??new Date;if(e.subject.platform!==t.platform)return{decision:"suppress",reason:"platform_mismatch"};if(e.subject.externalId!==t.externalId)return{decision:"suppress",reason:"subject_mismatch"};if(e.lifecycle.revokedAt!==null)return{decision:"suppress",reason:"revoked"};if(r.getTime()>=Date.parse(e.lifecycle.expiresAt))return{decision:"suppress",reason:"expired"};let n=e.subject.contentDigest,o=t.liveContentHash;return n!==null&&o!=null&&n!==o?{decision:"suppress",reason:"content_drift"}:{decision:"render",payload:e}}async function Z(e,t,r){let n;try{n=await ze(e,t)}catch{return{decision:"suppress",reason:"unknown_key"}}return n.ok?J(e.payload,r):{decision:"suppress",reason:n.reason}}function v(e){return e?.kind==="tombstone"}async function Ve(e,t){let{signature:r}=e??{};if(!e?.subject||!r||e.contractVersion!==1)return{ok:!1,reason:"unsupported_contract_version"};if(r.alg!==E)return{ok:!1,reason:"unsupported_alg"};let n=await t(r.kid);if(!n)return{ok:!1,reason:"unknown_key"};let o;try{o=await j(n)}catch{return{ok:!1,reason:"unknown_key"}}let{signature:a,...s}=e,i=C(r.sig),c=!1;try{c=await crypto.subtle.verify(m,o,i,R(s))}catch{c=!1}return c?{ok:!0,key:o}:{ok:!1,reason:"invalid_signature"}}async function W(e,t,r){let n;try{n=await Ve(e,t)}catch{return{decision:"suppress",reason:"unknown_key"}}return n.ok?e.subject.platform!==r.platform?{decision:"suppress",reason:"platform_mismatch"}:e.subject.externalId!==r.externalId?{decision:"suppress",reason:"subject_mismatch"}:{decision:"suppress",reason:"revoked"}:{decision:"suppress",reason:n.reason}}async function L(e,t,r){return v(e)?W(e,t,r):Z(e,t,r)}var Y=`
|
|
3
3
|
@font-face {
|
|
4
4
|
font-family: "DM Sans";
|
|
5
5
|
font-style: normal;
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
unicode-range:
|
|
120
120
|
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
121
121
|
}
|
|
122
|
-
`,X="https://assets.certrev.com";function f(e){return typeof e=="string"?e:typeof e=="number"&&Number.isFinite(e)?String(e):""}function l(e){return f(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var
|
|
122
|
+
`,X="https://assets.certrev.com";function f(e){return typeof e=="string"?e:typeof e=="number"&&Number.isFinite(e)?String(e):""}function l(e){return f(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var He=["assets.certrev.com","staging-assets.certrev.com"];function Ke(e){return`width=${e},height=${e},fit=cover,format=auto,onerror=redirect`}function qe(e,t){let r=(e??"").trim();if(!/^https:\/\//i.test(r))return r;let n;try{n=new URL(r)}catch{return r}if(!He.includes(n.hostname)||n.pathname.startsWith("/cdn-cgi/image/"))return r;let o=n.pathname.replace(/^\//,"");return`${n.origin}/cdn-cgi/image/${Ke(t)}/${o}`}function Q(e,t){return qe(e,t)}var ee="Independent editorial review of this article\u2019s text and sources. Not a product endorsement, nor medical advice.",te="Independent editorial review of this article\u2019s text. Not a product endorsement, nor medical advice.";var je=ee,Ge=te;function re(e){return e==="text"?Ge:je}function I(e){if(!e||typeof e!="string"&&!(e instanceof Date))return null;let t=e instanceof Date?e:new Date(e);return Number.isNaN(t.getTime())?null:t.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric",timeZone:"UTC"})}var M=["M67.59 221.77L138.77 292.95C145.8 299.98 145.8 311.44 138.77 318.47L123.02 334.22C116 341.25 104.54 341.25 97.5 334.22L26.32 263.04C19.29 256.01 19.29 244.55 26.32 237.52L42.07 221.77C49.1 214.74 60.56 214.74 67.59 221.77Z","M96.79 335.08L81.12 319.42C73.8 312.1 73.8 300.23 81.12 292.92L315.88 58.16C323.2 50.85 335.06 50.85 342.38 58.16L358.04 73.83C365.36 81.14 365.36 93.01 358.04 100.33L123.29 335.08C115.97 342.4 104.1 342.4 96.79 335.08Z","M203.5 335.14L187.83 319.48C180.52 312.16 180.52 300.29 187.83 292.98L315.88 164.93C323.2 157.62 335.06 157.62 342.38 164.93L358.04 180.6C365.36 187.92 365.36 199.78 358.04 207.1L230 335.14C222.68 342.46 210.82 342.46 203.5 335.14Z","M310.21 335.2L294.54 319.54C287.23 312.22 287.23 300.36 294.54 293.04L315.88 271.71C323.2 264.39 335.06 264.39 342.38 271.71L358.04 287.37C365.36 294.69 365.36 306.55 358.04 313.87L336.71 335.2C329.39 342.52 317.53 342.52 310.21 335.2Z"];function ne(e,t){let r=M.map(n=>`<path fill="${t}" d="${n}"/>`).join("");return`<svg width="${e}" height="${e}" viewBox="0 0 375 375" aria-hidden="true" style="display:block;flex-shrink:0">${r}</svg>`}function oe(e=8){return`<svg width="${e}" height="${e}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>`}function ae(e="crm"){let t=`crm-stamp-arc-${e}`,r=M.map(n=>`<path fill="#0a1b3f" d="${n}"/>`).join("");return`<span class="crm-stamp"><svg viewBox="0 0 128 128" width="74" height="74" role="img" aria-label="CertREV verified stamp" style="display:block"><defs><path id="${t}" d="M64 18 A46 46 0 1 1 64 110 A46 46 0 1 1 64 18"/></defs><circle cx="64" cy="64" r="58" fill="none" stroke="#0a1b3f" stroke-width="1.3"/><circle cx="64" cy="64" r="51.5" fill="none" stroke="#0a1b3f" stroke-width="0.7" stroke-opacity="0.4"/><text font-family="'JetBrains Mono',ui-monospace,monospace" font-size="7.8" font-weight="600" letter-spacing="1.3" fill="#0a1b3f"><textPath href="#${t}" startOffset="1%">CERTREV VERIFIED \xB7 CERTIFIED \xB7 </textPath></text><svg x="49" y="50" width="30" height="28" viewBox="0 0 375 375" preserveAspectRatio="xMidYMid meet">${r}</svg></svg></span>`}var B=`
|
|
123
123
|
:host {
|
|
124
124
|
--cr-navy: #0a1b3f;
|
|
125
125
|
--cr-lime: #d4e157;
|
|
@@ -552,6 +552,6 @@
|
|
|
552
552
|
padding: 18px 18px 20px;
|
|
553
553
|
}
|
|
554
554
|
}
|
|
555
|
-
`;var ae="nofollow sponsored noopener noreferrer",qe=/^(dr|prof|professor|mr|mrs|ms|mx|rev|sir|dame)\.?\s+/i;function ie(e){let t=f(e).replace(qe,"").trim(),r=t.indexOf(",");return(r===-1?t:t.slice(0,r)).trim()}function je(e){let t=ie(e).split(/\s+/).filter(Boolean);return t.length===0?"":t.length===1?t[0].slice(0,2).toUpperCase():(t[0][0]+t[t.length-1][0]).toUpperCase()}function Ge(e){return ie(e)}function Je(e){return f(e).replace(/^https?:\/\//i,"").replace(/\/$/,"")}function se(e){let t=f(e).trim();return t&&/^https?:\/\//i.test(t)?t:"#"}function Ze(e){return(f(e?.cardLabel)||f(e?.fullName)||f(e?.abbreviation)).trim()}function ce(e){let t=[],r=Array.isArray(e?.credentials)?e.credentials:[];for(let n of r){let o=Ze(n);o&&!t.includes(o)&&t.push(o)}return t}function We(e,t){return t?.showBio===!1?"":(f(e?.background)||f(e?.bio)).trim()}function le(e,t,r,n){let o=f(e?.photoUrl).trim();if(n&&/^https?:\/\//i.test(o)){let a=r.includes("--64")?64:56,s=Q(o,a===64?128:112);return`<img class="crm-avatar ${r}" src="${l(s)}" alt="" width="${a}" height="${a}" decoding="async">`}return`<span class="crm-avatar ${r}">${l(je(t))}</span>`}var fe='<button type="button" class="crm-close" data-certrev-modal-close aria-label="Close">×</button>';function de(e){return`<div class="crm-head">${re(16,"#ffffff")}<span class="crm-head__eyebrow">${l(e)}</span><span class="crm-head__wordmark">CertREV</span></div>`}function pe(e){return`<span class="${e}">${ne(8)}Certified</span>`}function ue(e){let t=f(e?.compensationCue).trim();return`<div class="crm-disclosure">${t?`<span class="crm-disclosure__cue">${l(t)}</span> `:""}${l(te)}</div>`}function me(e){let t=e.expert??null,r=f(t?.displayName).trim();if(!r)return null;let n=e.display?.showExpertPhoto!==!1,o=ce(t).join(" \xB7 "),a=M(e.certifiedAt)??"",s=f(e.displayCertId).trim(),i=f(e.articleTitle).trim(),c=f(e.verifyUrl).trim(),d=Ge(r),h=i?`<div class="crm-certifies"><div class="crm-certifies__eyebrow">Certifies the article</div><div class="crm-certifies__title">${l(i)}</div></div>`:"",x=s?`<div class="crm-meta__col"><div class="crm-meta__label">Certificate ID</div><div class="crm-meta__value crm-meta__value--mono">${l(s)}</div></div>`:"",Me=c?`<div class="crm-sig__url">${l(Je(c))}</div>`:"";return`${fe}${de("Certificate of Expert Review")}<div class="crm-body--cert"><div class="crm-expert-row">${le(t,r,"crm-avatar--56",n)}<div class="crm-expert-row__info"><div class="crm-expert-row__eyebrow">Reviewing Expert</div><div class="crm-expert-row__name">${l(r)}</div>${o?`<div class="crm-expert-row__creds">${l(o)}</div>`:""}</div></div>${h}<div class="crm-meta"><div class="crm-meta__col"><div class="crm-meta__label">Issued</div><div class="crm-meta__value">${l(a)}</div></div>${x}<div class="crm-meta__col"><div class="crm-meta__label">Status</div><div class="crm-meta__status">${pe("crm-chip")}</div></div></div><div class="crm-sig"><div><div class="crm-sig__name">${l(d)}</div><div class="crm-sig__rule"></div>${Me}</div>${oe("cert")}</div>${ue(t)}<div class="crm-actions"><a class="crm-cta" href="${l(se(c))}" target="_blank" rel="${ae}">View full certificate</a><button type="button" class="crm-ghost" data-certrev-modal-close>Close</button></div></div>`}function ye(e){let t=e.expert??null,r=f(t?.displayName).trim();if(!r)return null;let n=e.display?.showExpertPhoto!==!1,o=ce(t),a=We(t,e.display),s=M(e.certifiedAt),i=o.length?`<div class="crm-chips">${o.map(h=>`<span class="crm-chips__chip">${l(h)}</span>`).join("")}</div>`:"",c=a?`<p class="crm-bio">${l(a)}</p>`:"",d=s?`Independently reviewed \xB7 Certified ${l(s)}`:"Independently reviewed";return`${fe}${de("Verified reviewer")}<div class="crm-body--expert"><div class="crm-id">${le(t,r,"crm-avatar--64",n)}<div class="crm-id__info"><div class="crm-id__name">${l(r)}</div></div></div>${i}${c}<div class="crm-trust">${pe("crm-trust__chip")}<span class="crm-trust__text">${d}</span></div>${ue(t)}<div class="crm-actions"><a class="crm-cta" href="${l(se(t?.profileUrl))}" target="_blank" rel="${ae}">View full profile on CertREV</a><button type="button" class="crm-ghost" data-certrev-modal-close>Close</button></div></div>`}var w="certrev-cert-modal",ge="[data-certrev-cert]";function O(e){let t=e.closest(ge);for(let r=e;r;r=r.parentElement){let n=Array.from(r.querySelectorAll(w)).filter(o=>o.closest(ge)===t);if(n.length===1)return{modal:n[0],reason:null};if(n.length>1)return{modal:null,reason:"ambiguous",count:n.length};if(r===t)break}return{modal:null,reason:"none",count:0}}var E=null;function Ye(){return typeof CSSStyleSheet<"u"&&"replaceSync"in CSSStyleSheet.prototype&&"adoptedStyleSheets"in Document.prototype}function Xe(){return Ye()?(E||(E=new CSSStyleSheet,E.replaceSync(I)),E):null}var ve=!1;function Qe(e){if(ve||(ve=!0,e.querySelector("style[data-certrev-modal-fonts]")))return;if(!e.querySelector("link[data-certrev-modal-preconnect]")){let r=e.createElement("link");r.rel="preconnect",r.href=X,r.crossOrigin="",r.setAttribute("data-certrev-modal-preconnect",""),e.head.appendChild(r)}let t=e.createElement("style");t.textContent=Y,t.setAttribute("data-certrev-modal-fonts",""),e.head.appendChild(t)}var $=class extends HTMLElement{constructor(){super();this.rendered=!1;this.content=null;this.fetchInFlight=null;this.root=this.attachShadow({mode:"open"});let r=Xe();if(r)this.root.adoptedStyleSheets=[r];else{let n=document.createElement("style");n.textContent=I,this.root.appendChild(n)}this.root.addEventListener("click",n=>this.onShadowClick(n))}open(r){return this.getAttribute("data-fonts")!=="host"&&Qe(document),this.ensureRendered()?(this.show(r),!0):this.hasFetchSource()?(this.fetchThenShow(r),!0):!1}ensureRendered(){if(this.rendered)return this.content!=null;let r=this.readSyncContent();return r?(this.content=r,this.renderDialogs(r),this.rendered=!0,!0):!1}readSyncContent(){let r=this.getAttribute("data-envelope");if(r)return he(r);let n=this.querySelector("script[data-certrev-envelope]");return n?.textContent?he(n.textContent):null}hasFetchSource(){return!!(this.getAttribute("data-delivery-api")&&this.getAttribute("data-platform")&&this.getAttribute("data-external-id"))}async fetchThenShow(r){if(!this.fetchInFlight){let n=(this.getAttribute("data-delivery-api")||"").replace(/\/$/,""),o=this.getAttribute("data-platform")||"",a=this.getAttribute("data-external-id")||"";this.fetchInFlight=(async()=>{try{let s=await fetch(`${n}/api/cert/v1/delivery/${encodeURIComponent(o)}/${encodeURIComponent(a)}`,{cache:"no-store",credentials:"omit"});if(!s.ok)return;let i=await s.json();if(et(i)){this.markSuppressed();return}let c=v(i)?void 0:i.payload?.content;c&&(this.content=c,this.renderDialogs(c),this.rendered=!0)}catch{}})()}await this.fetchInFlight,this.rendered&&this.show(r)}renderDialogs(r){let n=me(r),o=ye(r),a=document.createElement("div");a.innerHTML=`${n?`<dialog id="cert" class="crm-dialog crm-dialog--cert" aria-label="CertREV certificate">${n}</dialog>`:""}${o?`<dialog id="expert" class="crm-dialog crm-dialog--expert" aria-label="Verified reviewer profile">${o}</dialog>`:""}`;for(let s of Array.from(a.childNodes))this.root.appendChild(s)}show(r){let n=this.root.getElementById(r);n&&typeof n.showModal=="function"&&!n.open&&n.showModal()}markSuppressed(){this.setAttribute("data-certrev-suppressed","");for(let r of Array.from(this.ownerDocument.querySelectorAll("[data-certrev-modal-open]")))O(r).modal===this&&(r.setAttribute("hidden",""),r.setAttribute("aria-hidden","true"))}onShadowClick(r){let n=r.target;if(!n)return;if(n instanceof HTMLDialogElement&&n.classList.contains("crm-dialog")){n.close();return}let o=n.closest("[data-certrev-modal-close]");o&&(r.preventDefault(),o.closest("dialog")?.close())}};function he(e){try{let t=JSON.parse(e);return t&&typeof t=="object"?t:null}catch{return null}}function et(e){if(!e)return!1;if(v(e))return!0;let t=e.payload?.lifecycle;return t?!!(t.revokedAt!=null||t.expiresAt&&Date.now()>=new Date(t.expiresAt).getTime()):!1}function tt(){typeof customElements>"u"||customElements.get(w)||customElements.define(w,$)}tt();var xe="data-certrev-acc",A="data-certrev-modal-open",N="data-certrev-initials";var rt="data-certrev-modal-unresolved",nt="certrev:modal-unresolved",ot=["avatar","certrev-memo__avatar"],Ce=new WeakSet;function be(e){let t=e.classList.toggle("open");e.setAttribute("aria-expanded",t?"true":"false")}function Ue(e){return e==="expert"?"expert":"cert"}function Ee(e,t){let r=O(e);if(r.modal){let n=r.modal;return typeof n.open=="function"?n.open(t):!1}return r.reason==="ambiguous"&&(e.setAttribute(rt,r.reason),e.dispatchEvent(new CustomEvent(nt,{bubbles:!0,detail:{reason:r.reason,modals:r.count}}))),!1}function we(e){return e&&e.closest?e:null}function Ae(e){let t=e.getAttribute(N);if(t==null)return;let r=ot.find(o=>e.classList.contains(o));if(!r)return;let n=e.ownerDocument.createElement("span");n.className=`${r} ${r}--initials`,n.setAttribute("aria-hidden","true"),n.textContent=t,e.replaceWith(n)}function at(e){for(let t of Array.from(e.querySelectorAll(`img[${N}]`)))t.complete&&t.naturalWidth===0&&Ae(t)}function it(e){Ce.has(e)||(Ce.add(e),e.addEventListener("click",t=>{let r=we(t.target);if(!r)return;let n=r.closest(`[${A}]`);if(n){Ee(n,Ue(n.getAttribute(A)))&&t.preventDefault();return}let o=r.closest(`[${xe}]`);o&&!r.closest("a, button")&&be(o)}),e.addEventListener("error",t=>{let r=t.target;r&&r.tagName==="IMG"&&r.hasAttribute(N)&&Ae(r)},!0),at(e),e.addEventListener("keydown",t=>{if(t.key!=="Enter"&&t.key!==" "&&t.key!=="Spacebar")return;let r=we(t.target);if(!r||r.closest("a, button"))return;let n=r.closest(`[${A}]`);if(n&&Ee(n,Ue(n.getAttribute(A)))){t.preventDefault();return}let o=r.closest(`[${xe}]`);o&&(t.preventDefault(),be(o))}))}function _e(e){let t=()=>it(e);e.readyState==="loading"?e.addEventListener("DOMContentLoaded",t,{once:!0}):t()}var st=[{selector:"main article",tier:"article"},{selector:"article",tier:"article"},{selector:"main",tier:"main"},{selector:".article-template__content",tier:"theme-class"},{selector:'[id^="ArticleContent"]',tier:"theme-class"},{selector:".rte",tier:"theme-class"}],y=[{selector:".article-template__content",tier:"theme-class"},{selector:'[id^="ArticleContent"]',tier:"theme-class"},{selector:".rte",tier:"theme-class"},{selector:"main article",tier:"article"},{selector:"article",tier:"article"},{selector:"main",tier:"main"}],P=y.map(e=>e.selector).join(", "),ct='header, [role="banner"], [class*="announcement"], footer, [role="contentinfo"], nav, [role="navigation"], cart-drawer, .cart-drawer, .drawer, .mini-cart, .modal, [role="dialog"]',u="data-certrev-placement",De="data-certrev-anchor",lt='script[type="application/ld+json"][data-certrev-graph]',ft=".certrev-card-wrap",Fe=".certrev-memo-wrap",dt=".certrev-pill-wrap",Te=384,pt=24,_="#references";function S(e){for(let t=e;t;t=t.parentElement){if(t.hasAttribute("hidden")||t.getAttribute("aria-hidden")==="true")return!1;let r=getComputedStyle(t);if(r.display==="none"||r.visibility==="hidden")return!1}return!0}function z(e){return e.closest(ct)!==null}function Se(e,t){for(let{selector:r,tier:n}of t)if(e.matches(r))return n;return"article"}function D(e,t,r){for(let{selector:n,tier:o}of r)for(let a of Array.from(e.querySelectorAll(n)))if(a!==t&&!a.contains(t)&&!t.contains(a)&&S(a)&&!z(a))return{el:a,tier:o};return null}function V(e,t){let r=t.getAttribute(u);if(r)return{anchored:r!=="body-fallback",tier:r};let n=t.getAttribute(De);if(n==="rail"){let i=e.querySelector(_)?.closest(P)??D(e,t,y)?.el??null,c=e.defaultView;if(i&&c&&S(i)&&!z(i)){let d=i.getBoundingClientRect();if(c.innerWidth-d.right>=Te)return t.style.setProperty("--certrev-rail-left",`${Math.round(d.right+pt)}px`),t.setAttribute(u,"rail"),{anchored:!0,tier:"rail"};i.insertAdjacentElement("afterbegin",t);let x=Se(i,y);return t.setAttribute(u,x),{anchored:!0,tier:x}}return t.setAttribute(u,"body-fallback"),{anchored:!1,tier:"body-fallback"}}let o=n==="bottom"?"bottom":"top",a="body-fallback";if(o==="top"){let i=e.querySelector(_)?.closest(P)??null;if(i&&i!==t&&!i.contains(t)&&!t.contains(i)&&S(i)&&!z(i))i.insertAdjacentElement("afterbegin",t),a=Se(i,y);else{let c=D(e,t,y);c&&(c.el.insertAdjacentElement("afterbegin",t),a=c.tier)}}else{let s=e.querySelector(_);if(s&&s!==t&&!t.contains(s)&&!s.contains(t)&&S(s))s.insertAdjacentElement("beforebegin",t),a="references";else{let i=D(e,t,st);i&&(i.el.insertAdjacentElement("afterend",t),a=i.tier)}}return t.setAttribute(u,a),{anchored:a!=="body-fallback",tier:a}}function ut(e){let t=e.querySelector(lt),r=!1;t&&t.parentNode!==e.head&&(e.head.appendChild(t),r=!0);let n=e.querySelector(ft),o=e.querySelector(Fe);return e.querySelector(dt)?.setAttribute(u,"pill-fixed"),{graph:r,card:n?V(e,n):null,memo:o?V(e,o):null}}function mt(e){let t=e.defaultView;if(!t)return;let r=e.querySelector(`${Fe}[${De}="rail"]`);if(!r||r.getAttribute(u)!=="rail")return;let n,o=()=>{n&&clearTimeout(n),n=setTimeout(()=>{if(r.getAttribute(u)!=="rail"){t.removeEventListener("resize",o);return}let s=e.querySelector(_)?.closest(P)??D(e,r,y)?.el??null;(s?t.innerWidth-s.getBoundingClientRect().right:0)<Te&&(r.style.removeProperty("--certrev-rail-left"),r.removeAttribute(u),V(e,r),t.removeEventListener("resize",o))},150)};t.addEventListener("resize",o)}function Re(e){let t=()=>{ut(e),mt(e)};e.readyState==="loading"?e.addEventListener("DOMContentLoaded",t,{once:!0}):t()}async function yt(e,t){let r=e.querySelector(".certrev-badge");if(!r)return;let n=e.getAttribute("data-delivery-api"),o=e.getAttribute("data-external-id"),a=e.getAttribute("data-platform")??"shopify";if(!n||!o)return;let s;try{s=await t.verify({baseUrl:n,platform:a,externalId:o})}catch{return}s.decision!=="render"&&(r.setAttribute("hidden",""),r.setAttribute("data-certrev-suppressed",s.reason))}function ke(e,t){let r=()=>{for(let n of Array.from(e.querySelectorAll("certrev-badge[revalidate]")))yt(n,t)};e.readyState==="loading"?e.addEventListener("DOMContentLoaded",r,{once:!0}):r()}function Le(e,t=fetch){return async r=>{let o=`${r.baseUrl.replace(/\/+$/,"")}/api/cert/v1/delivery/${encodeURIComponent(r.platform)}/${encodeURIComponent(r.externalId)}`,a=await t(o,{headers:{accept:"application/json"}});if(!a.ok)throw new Error(`cert delivery ${a.status}`);let s=await a.json();return L(s,e,{platform:r.platform,externalId:r.externalId,liveContentHash:null,now:new Date})}}var gt="cert-issuer-1",vt=`-----BEGIN PUBLIC KEY-----
|
|
555
|
+
`;var ie="nofollow sponsored noopener noreferrer",Je=/^(dr|prof|professor|mr|mrs|ms|mx|rev|sir|dame)\.?\s+/i;function se(e){let t=f(e).replace(Je,"").trim(),r=t.indexOf(",");return(r===-1?t:t.slice(0,r)).trim()}function Ze(e){let t=se(e).split(/\s+/).filter(Boolean);return t.length===0?"":t.length===1?t[0].slice(0,2).toUpperCase():(t[0][0]+t[t.length-1][0]).toUpperCase()}function We(e){return se(e)}function Ye(e){return f(e).replace(/^https?:\/\//i,"").replace(/\/$/,"")}function ce(e){let t=f(e).trim();return t&&/^https?:\/\//i.test(t)?t:"#"}function Xe(e){return(f(e?.cardLabel)||f(e?.fullName)||f(e?.abbreviation)).trim()}function le(e){let t=[],r=Array.isArray(e?.credentials)?e.credentials:[];for(let n of r){let o=Xe(n);o&&!t.includes(o)&&t.push(o)}return t}function Qe(e,t){return t?.showBio===!1?"":(f(e?.background)||f(e?.bio)).trim()}function fe(e,t,r,n){let o=f(e?.photoUrl).trim();if(n&&/^https?:\/\//i.test(o)){let a=r.includes("--64")?64:56,s=Q(o,a===64?128:112);return`<img class="crm-avatar ${r}" src="${l(s)}" alt="" width="${a}" height="${a}" decoding="async">`}return`<span class="crm-avatar ${r}">${l(Ze(t))}</span>`}var de='<button type="button" class="crm-close" data-certrev-modal-close aria-label="Close">×</button>';function pe(e){return`<div class="crm-head">${ne(16,"#ffffff")}<span class="crm-head__eyebrow">${l(e)}</span><span class="crm-head__wordmark">CertREV</span></div>`}function ue(e){return`<span class="${e}">${oe(8)}Certified</span>`}function me(e){let t=f(e?.compensationCue).trim();return`<div class="crm-disclosure">${t?`<span class="crm-disclosure__cue">${l(t)}</span> `:""}${l(re(e?.reviewScope))}</div>`}function ye(e){let t=e.expert??null,r=f(t?.displayName).trim();if(!r)return null;let n=e.display?.showExpertPhoto!==!1,o=le(t).join(" \xB7 "),a=I(e.certifiedAt)??"",s=f(e.displayCertId).trim(),i=f(e.articleTitle).trim(),c=f(e.verifyUrl).trim(),d=We(r),h=i?`<div class="crm-certifies"><div class="crm-certifies__eyebrow">Certifies the article</div><div class="crm-certifies__title">${l(i)}</div></div>`:"",x=s?`<div class="crm-meta__col"><div class="crm-meta__label">Certificate ID</div><div class="crm-meta__value crm-meta__value--mono">${l(s)}</div></div>`:"",Me=c?`<div class="crm-sig__url">${l(Ye(c))}</div>`:"";return`${de}${pe("Certificate of Expert Review")}<div class="crm-body--cert"><div class="crm-expert-row">${fe(t,r,"crm-avatar--56",n)}<div class="crm-expert-row__info"><div class="crm-expert-row__eyebrow">Reviewing Expert</div><div class="crm-expert-row__name">${l(r)}</div>${o?`<div class="crm-expert-row__creds">${l(o)}</div>`:""}</div></div>${h}<div class="crm-meta"><div class="crm-meta__col"><div class="crm-meta__label">Issued</div><div class="crm-meta__value">${l(a)}</div></div>${x}<div class="crm-meta__col"><div class="crm-meta__label">Status</div><div class="crm-meta__status">${ue("crm-chip")}</div></div></div><div class="crm-sig"><div><div class="crm-sig__name">${l(d)}</div><div class="crm-sig__rule"></div>${Me}</div>${ae("cert")}</div>${me(t)}<div class="crm-actions"><a class="crm-cta" href="${l(ce(c))}" target="_blank" rel="${ie}">View full certificate</a><button type="button" class="crm-ghost" data-certrev-modal-close>Close</button></div></div>`}function ge(e){let t=e.expert??null,r=f(t?.displayName).trim();if(!r)return null;let n=e.display?.showExpertPhoto!==!1,o=le(t),a=Qe(t,e.display),s=I(e.certifiedAt),i=o.length?`<div class="crm-chips">${o.map(h=>`<span class="crm-chips__chip">${l(h)}</span>`).join("")}</div>`:"",c=a?`<p class="crm-bio">${l(a)}</p>`:"",d=s?`Independently reviewed \xB7 Certified ${l(s)}`:"Independently reviewed";return`${de}${pe("Verified reviewer")}<div class="crm-body--expert"><div class="crm-id">${fe(t,r,"crm-avatar--64",n)}<div class="crm-id__info"><div class="crm-id__name">${l(r)}</div></div></div>${i}${c}<div class="crm-trust">${ue("crm-trust__chip")}<span class="crm-trust__text">${d}</span></div>${me(t)}<div class="crm-actions"><a class="crm-cta" href="${l(ce(t?.profileUrl))}" target="_blank" rel="${ie}">View full profile on CertREV</a><button type="button" class="crm-ghost" data-certrev-modal-close>Close</button></div></div>`}var w="certrev-cert-modal",ve="[data-certrev-cert]";function O(e){let t=e.closest(ve);for(let r=e;r;r=r.parentElement){let n=Array.from(r.querySelectorAll(w)).filter(o=>o.closest(ve)===t);if(n.length===1)return{modal:n[0],reason:null};if(n.length>1)return{modal:null,reason:"ambiguous",count:n.length};if(r===t)break}return{modal:null,reason:"none",count:0}}var U=null;function et(){return typeof CSSStyleSheet<"u"&&"replaceSync"in CSSStyleSheet.prototype&&"adoptedStyleSheets"in Document.prototype}function tt(){return et()?(U||(U=new CSSStyleSheet,U.replaceSync(B)),U):null}var he=!1;function rt(e){if(he||(he=!0,e.querySelector("style[data-certrev-modal-fonts]")))return;if(!e.querySelector("link[data-certrev-modal-preconnect]")){let r=e.createElement("link");r.rel="preconnect",r.href=X,r.crossOrigin="",r.setAttribute("data-certrev-modal-preconnect",""),e.head.appendChild(r)}let t=e.createElement("style");t.textContent=Y,t.setAttribute("data-certrev-modal-fonts",""),e.head.appendChild(t)}var $=class extends HTMLElement{constructor(){super();this.rendered=!1;this.content=null;this.fetchInFlight=null;this.root=this.attachShadow({mode:"open"});let r=tt();if(r)this.root.adoptedStyleSheets=[r];else{let n=document.createElement("style");n.textContent=B,this.root.appendChild(n)}this.root.addEventListener("click",n=>this.onShadowClick(n))}open(r){return this.getAttribute("data-fonts")!=="host"&&rt(document),this.ensureRendered()?(this.show(r),!0):this.hasFetchSource()?(this.fetchThenShow(r),!0):!1}ensureRendered(){if(this.rendered)return this.content!=null;let r=this.readSyncContent();return r?(this.content=r,this.renderDialogs(r),this.rendered=!0,!0):!1}readSyncContent(){let r=this.getAttribute("data-envelope");if(r)return xe(r);let n=this.querySelector("script[data-certrev-envelope]");return n?.textContent?xe(n.textContent):null}hasFetchSource(){return!!(this.getAttribute("data-delivery-api")&&this.getAttribute("data-platform")&&this.getAttribute("data-external-id"))}async fetchThenShow(r){if(!this.fetchInFlight){let n=(this.getAttribute("data-delivery-api")||"").replace(/\/$/,""),o=this.getAttribute("data-platform")||"",a=this.getAttribute("data-external-id")||"";this.fetchInFlight=(async()=>{try{let s=await fetch(`${n}/api/cert/v1/delivery/${encodeURIComponent(o)}/${encodeURIComponent(a)}`,{cache:"no-store",credentials:"omit"});if(!s.ok)return;let i=await s.json();if(nt(i)){this.markSuppressed();return}let c=v(i)?void 0:i.payload?.content;c&&(this.content=c,this.renderDialogs(c),this.rendered=!0)}catch{}})()}await this.fetchInFlight,this.rendered&&this.show(r)}renderDialogs(r){let n=ye(r),o=ge(r),a=document.createElement("div");a.innerHTML=`${n?`<dialog id="cert" class="crm-dialog crm-dialog--cert" aria-label="CertREV certificate">${n}</dialog>`:""}${o?`<dialog id="expert" class="crm-dialog crm-dialog--expert" aria-label="Verified reviewer profile">${o}</dialog>`:""}`;for(let s of Array.from(a.childNodes))this.root.appendChild(s)}show(r){let n=this.root.getElementById(r);n&&typeof n.showModal=="function"&&!n.open&&n.showModal()}markSuppressed(){this.setAttribute("data-certrev-suppressed","");for(let r of Array.from(this.ownerDocument.querySelectorAll("[data-certrev-modal-open]")))O(r).modal===this&&(r.setAttribute("hidden",""),r.setAttribute("aria-hidden","true"))}onShadowClick(r){let n=r.target;if(!n)return;if(n instanceof HTMLDialogElement&&n.classList.contains("crm-dialog")){n.close();return}let o=n.closest("[data-certrev-modal-close]");o&&(r.preventDefault(),o.closest("dialog")?.close())}};function xe(e){try{let t=JSON.parse(e);return t&&typeof t=="object"?t:null}catch{return null}}function nt(e){if(!e)return!1;if(v(e))return!0;let t=e.payload?.lifecycle;return t?!!(t.revokedAt!=null||t.expiresAt&&Date.now()>=new Date(t.expiresAt).getTime()):!1}function ot(){typeof customElements>"u"||customElements.get(w)||customElements.define(w,$)}ot();var Ce="data-certrev-acc",A="data-certrev-modal-open",N="data-certrev-initials";var at="data-certrev-modal-unresolved",it="certrev:modal-unresolved",st=["avatar","certrev-memo__avatar"],be=new WeakSet;function Ee(e){let t=e.classList.toggle("open");e.setAttribute("aria-expanded",t?"true":"false")}function Ue(e){return e==="expert"?"expert":"cert"}function we(e,t){let r=O(e);if(r.modal){let n=r.modal;return typeof n.open=="function"?n.open(t):!1}return r.reason==="ambiguous"&&(e.setAttribute(at,r.reason),e.dispatchEvent(new CustomEvent(it,{bubbles:!0,detail:{reason:r.reason,modals:r.count}}))),!1}function Ae(e){return e&&e.closest?e:null}function _e(e){let t=e.getAttribute(N);if(t==null)return;let r=st.find(o=>e.classList.contains(o));if(!r)return;let n=e.ownerDocument.createElement("span");n.className=`${r} ${r}--initials`,n.setAttribute("aria-hidden","true"),n.textContent=t,e.replaceWith(n)}function ct(e){for(let t of Array.from(e.querySelectorAll(`img[${N}]`)))t.complete&&t.naturalWidth===0&&_e(t)}function lt(e){be.has(e)||(be.add(e),e.addEventListener("click",t=>{let r=Ae(t.target);if(!r)return;let n=r.closest(`[${A}]`);if(n){we(n,Ue(n.getAttribute(A)))&&t.preventDefault();return}let o=r.closest(`[${Ce}]`);o&&!r.closest("a, button")&&Ee(o)}),e.addEventListener("error",t=>{let r=t.target;r&&r.tagName==="IMG"&&r.hasAttribute(N)&&_e(r)},!0),ct(e),e.addEventListener("keydown",t=>{if(t.key!=="Enter"&&t.key!==" "&&t.key!=="Spacebar")return;let r=Ae(t.target);if(!r||r.closest("a, button"))return;let n=r.closest(`[${A}]`);if(n&&we(n,Ue(n.getAttribute(A)))){t.preventDefault();return}let o=r.closest(`[${Ce}]`);o&&(t.preventDefault(),Ee(o))}))}function Se(e){let t=()=>lt(e);e.readyState==="loading"?e.addEventListener("DOMContentLoaded",t,{once:!0}):t()}var ft=[{selector:"main article",tier:"article"},{selector:"article",tier:"article"},{selector:"main",tier:"main"},{selector:".article-template__content",tier:"theme-class"},{selector:'[id^="ArticleContent"]',tier:"theme-class"},{selector:".rte",tier:"theme-class"}],y=[{selector:".article-template__content",tier:"theme-class"},{selector:'[id^="ArticleContent"]',tier:"theme-class"},{selector:".rte",tier:"theme-class"},{selector:"main article",tier:"article"},{selector:"article",tier:"article"},{selector:"main",tier:"main"}],P=y.map(e=>e.selector).join(", "),dt='header, [role="banner"], [class*="announcement"], footer, [role="contentinfo"], nav, [role="navigation"], cart-drawer, .cart-drawer, .drawer, .mini-cart, .modal, [role="dialog"]',u="data-certrev-placement",Te="data-certrev-anchor",pt='script[type="application/ld+json"][data-certrev-graph]',ut=".certrev-card-wrap",Fe=".certrev-memo-wrap",mt=".certrev-pill-wrap",Re=384,yt=24,_="#references";function S(e){for(let t=e;t;t=t.parentElement){if(t.hasAttribute("hidden")||t.getAttribute("aria-hidden")==="true")return!1;let r=getComputedStyle(t);if(r.display==="none"||r.visibility==="hidden")return!1}return!0}function z(e){return e.closest(dt)!==null}function De(e,t){for(let{selector:r,tier:n}of t)if(e.matches(r))return n;return"article"}function D(e,t,r){for(let{selector:n,tier:o}of r)for(let a of Array.from(e.querySelectorAll(n)))if(a!==t&&!a.contains(t)&&!t.contains(a)&&S(a)&&!z(a))return{el:a,tier:o};return null}function V(e,t){let r=t.getAttribute(u);if(r)return{anchored:r!=="body-fallback",tier:r};let n=t.getAttribute(Te);if(n==="rail"){let i=e.querySelector(_)?.closest(P)??D(e,t,y)?.el??null,c=e.defaultView;if(i&&c&&S(i)&&!z(i)){let d=i.getBoundingClientRect();if(c.innerWidth-d.right>=Re)return t.style.setProperty("--certrev-rail-left",`${Math.round(d.right+yt)}px`),t.setAttribute(u,"rail"),{anchored:!0,tier:"rail"};i.insertAdjacentElement("afterbegin",t);let x=De(i,y);return t.setAttribute(u,x),{anchored:!0,tier:x}}return t.setAttribute(u,"body-fallback"),{anchored:!1,tier:"body-fallback"}}let o=n==="bottom"?"bottom":"top",a="body-fallback";if(o==="top"){let i=e.querySelector(_)?.closest(P)??null;if(i&&i!==t&&!i.contains(t)&&!t.contains(i)&&S(i)&&!z(i))i.insertAdjacentElement("afterbegin",t),a=De(i,y);else{let c=D(e,t,y);c&&(c.el.insertAdjacentElement("afterbegin",t),a=c.tier)}}else{let s=e.querySelector(_);if(s&&s!==t&&!t.contains(s)&&!s.contains(t)&&S(s))s.insertAdjacentElement("beforebegin",t),a="references";else{let i=D(e,t,ft);i&&(i.el.insertAdjacentElement("afterend",t),a=i.tier)}}return t.setAttribute(u,a),{anchored:a!=="body-fallback",tier:a}}function gt(e){let t=e.querySelector(pt),r=!1;t&&t.parentNode!==e.head&&(e.head.appendChild(t),r=!0);let n=e.querySelector(ut),o=e.querySelector(Fe);return e.querySelector(mt)?.setAttribute(u,"pill-fixed"),{graph:r,card:n?V(e,n):null,memo:o?V(e,o):null}}function vt(e){let t=e.defaultView;if(!t)return;let r=e.querySelector(`${Fe}[${Te}="rail"]`);if(!r||r.getAttribute(u)!=="rail")return;let n,o=()=>{n&&clearTimeout(n),n=setTimeout(()=>{if(r.getAttribute(u)!=="rail"){t.removeEventListener("resize",o);return}let s=e.querySelector(_)?.closest(P)??D(e,r,y)?.el??null;(s?t.innerWidth-s.getBoundingClientRect().right:0)<Re&&(r.style.removeProperty("--certrev-rail-left"),r.removeAttribute(u),V(e,r),t.removeEventListener("resize",o))},150)};t.addEventListener("resize",o)}function ke(e){let t=()=>{gt(e),vt(e)};e.readyState==="loading"?e.addEventListener("DOMContentLoaded",t,{once:!0}):t()}async function ht(e,t){let r=e.querySelector(".certrev-badge");if(!r)return;let n=e.getAttribute("data-delivery-api"),o=e.getAttribute("data-external-id"),a=e.getAttribute("data-platform")??"shopify";if(!n||!o)return;let s;try{s=await t.verify({baseUrl:n,platform:a,externalId:o})}catch{return}s.decision!=="render"&&(r.setAttribute("hidden",""),r.setAttribute("data-certrev-suppressed",s.reason))}function Le(e,t){let r=()=>{for(let n of Array.from(e.querySelectorAll("certrev-badge[revalidate]")))ht(n,t)};e.readyState==="loading"?e.addEventListener("DOMContentLoaded",r,{once:!0}):r()}function Ie(e,t=fetch){return async r=>{let o=`${r.baseUrl.replace(/\/+$/,"")}/api/cert/v1/delivery/${encodeURIComponent(r.platform)}/${encodeURIComponent(r.externalId)}`,a=await t(o,{headers:{accept:"application/json"}});if(!a.ok)throw new Error(`cert delivery ${a.status}`);let s=await a.json();return L(s,e,{platform:r.platform,externalId:r.externalId,liveContentHash:null,now:new Date})}}var xt="cert-issuer-1",Ct=`-----BEGIN PUBLIC KEY-----
|
|
556
556
|
MCowBQYDK2VwAyEAMWN956IOPjpAq900dL428VzA28TO/pVXnq3brwqUmwM=
|
|
557
|
-
-----END PUBLIC KEY-----`,
|
|
557
|
+
-----END PUBLIC KEY-----`,bt=e=>e===xt?{format:"pem",pem:Ct}:null;typeof document<"u"&&(ke(document),Se(document),Le(document,{verify:Ie(bt)}));})();
|
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
export declare const COMPENSATED_EXPERT_CUE = "Compensated expert";
|
|
18
18
|
/** The FTC scope disclaimer, re-exported from the FTC SoT (portal `CERT_SCOPE_LINE = FTC_DISCLOSURE_LINE`). */
|
|
19
19
|
export declare const CERT_SCOPE_LINE: "Independent editorial review of this article’s text and sources. Not a product endorsement, nor medical advice.";
|
|
20
|
+
/** 2.1.0: the text-only scope line (portal `FTC_DISCLOSURE_LINE_TEXT_ONLY`), for a review that covered the text only. */
|
|
21
|
+
export declare const CERT_SCOPE_LINE_TEXT_ONLY: "Independent editorial review of this article’s text. Not a product endorsement, nor medical advice.";
|
|
22
|
+
/**
|
|
23
|
+
* 2.1.0: the scope line for the signed `content.expert.reviewScope`. Only an exact `"text"` is the text-only line; absent,
|
|
24
|
+
* null, `"text_and_sources"` or any other value is `CERT_SCOPE_LINE`, as 2.0.2 printed it. The same rule as
|
|
25
|
+
* `certScopeLineFor` in `../components/render-def.ts`, repeated because `src/modal/` imports nothing from `src/components/`
|
|
26
|
+
* (it is bundled standalone into `certrev-cert.js`).
|
|
27
|
+
*/
|
|
28
|
+
export declare function scopeLineForReview(reviewScope: unknown): typeof CERT_SCOPE_LINE | typeof CERT_SCOPE_LINE_TEXT_ONLY;
|
|
20
29
|
/**
|
|
21
30
|
* Format a timestamp the way every cert byline renders dates ("Jun 14, 2026", en-US short month,
|
|
22
31
|
* UTC-pinned). Null for an unparseable input — callers treat that as "no date, no byline".
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-strings.d.ts","sourceRoot":"","sources":["../../src/modal/display-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,iGAAiG;AACjG,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAE3D,+GAA+G;AAC/G,eAAO,MAAM,eAAe,mHAAsB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GACnC,MAAM,GAAG,IAAI,CAWf"}
|
|
1
|
+
{"version":3,"file":"display-strings.d.ts","sourceRoot":"","sources":["../../src/modal/display-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,iGAAiG;AACjG,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAE3D,+GAA+G;AAC/G,eAAO,MAAM,eAAe,mHAAsB,CAAC;AAEnD,yHAAyH;AACzH,eAAO,MAAM,yBAAyB,uGAAgC,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,eAAe,GAAG,OAAO,yBAAyB,CAElH;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GACnC,MAAM,GAAG,IAAI,CAWf"}
|
|
@@ -13,11 +13,22 @@
|
|
|
13
13
|
* every well-formed value renders the exact string portal renders, and a value the wire could
|
|
14
14
|
* never legitimately carry renders nothing (see `formatCertDisplayDate`).
|
|
15
15
|
*/
|
|
16
|
-
import { FTC_DISCLOSURE_LINE } from "./ftc-disclosure.js";
|
|
16
|
+
import { FTC_DISCLOSURE_LINE, FTC_DISCLOSURE_LINE_TEXT_ONLY } from "./ftc-disclosure.js";
|
|
17
17
|
/** The compensation cue (guide "line A"), byte-verbatim from portal `COMPENSATED_EXPERT_CUE`. */
|
|
18
18
|
export const COMPENSATED_EXPERT_CUE = "Compensated expert";
|
|
19
19
|
/** The FTC scope disclaimer, re-exported from the FTC SoT (portal `CERT_SCOPE_LINE = FTC_DISCLOSURE_LINE`). */
|
|
20
20
|
export const CERT_SCOPE_LINE = FTC_DISCLOSURE_LINE;
|
|
21
|
+
/** 2.1.0: the text-only scope line (portal `FTC_DISCLOSURE_LINE_TEXT_ONLY`), for a review that covered the text only. */
|
|
22
|
+
export const CERT_SCOPE_LINE_TEXT_ONLY = FTC_DISCLOSURE_LINE_TEXT_ONLY;
|
|
23
|
+
/**
|
|
24
|
+
* 2.1.0: the scope line for the signed `content.expert.reviewScope`. Only an exact `"text"` is the text-only line; absent,
|
|
25
|
+
* null, `"text_and_sources"` or any other value is `CERT_SCOPE_LINE`, as 2.0.2 printed it. The same rule as
|
|
26
|
+
* `certScopeLineFor` in `../components/render-def.ts`, repeated because `src/modal/` imports nothing from `src/components/`
|
|
27
|
+
* (it is bundled standalone into `certrev-cert.js`).
|
|
28
|
+
*/
|
|
29
|
+
export function scopeLineForReview(reviewScope) {
|
|
30
|
+
return reviewScope === "text" ? CERT_SCOPE_LINE_TEXT_ONLY : CERT_SCOPE_LINE;
|
|
31
|
+
}
|
|
21
32
|
/**
|
|
22
33
|
* Format a timestamp the way every cert byline renders dates ("Jun 14, 2026", en-US short month,
|
|
23
34
|
* UTC-pinned). Null for an unparseable input — callers treat that as "no date, no byline".
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-strings.js","sourceRoot":"","sources":["../../src/modal/display-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"display-strings.js","sourceRoot":"","sources":["../../src/modal/display-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AAEzF,iGAAiG;AACjG,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D,+GAA+G;AAC/G,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAEnD,yHAAyH;AACzH,MAAM,CAAC,MAAM,yBAAyB,GAAG,6BAA6B,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAoB;IACtD,OAAO,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,eAAe,CAAC;AAC7E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,qBAAqB,CACpC,GAAqC;IAErC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnE,MAAM,IAAI,GAAG,GAAG,YAAY,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE;QACvC,KAAK,EAAE,OAAO;QACd,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,KAAK;KACf,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -13,4 +13,10 @@
|
|
|
13
13
|
* its disclosure is settled where the face is configured, not by hiding or replacing it in the page.
|
|
14
14
|
*/
|
|
15
15
|
export declare const FTC_DISCLOSURE_LINE: "Independent editorial review of this article\u2019s text and sources. Not a product endorsement, nor medical advice.";
|
|
16
|
+
/**
|
|
17
|
+
* 2.1.0: the line for an article whose review covered its TEXT only (no references or sources section): a byte-faithful
|
|
18
|
+
* copy of the portal's `FTC_DISCLOSURE_LINE_TEXT_ONLY` (Owen, Console decision af5b0db5). Same contract status and curly
|
|
19
|
+
* apostrophe as `FTC_DISCLOSURE_LINE`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const FTC_DISCLOSURE_LINE_TEXT_ONLY: "Independent editorial review of this article\u2019s text. Not a product endorsement, nor medical advice.";
|
|
16
22
|
//# sourceMappingURL=ftc-disclosure.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ftc-disclosure.d.ts","sourceRoot":"","sources":["../../src/modal/ftc-disclosure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,mBAAmB,EAC/B,sHAA0H,CAAC"}
|
|
1
|
+
{"version":3,"file":"ftc-disclosure.d.ts","sourceRoot":"","sources":["../../src/modal/ftc-disclosure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,mBAAmB,EAC/B,sHAA0H,CAAC;AAE5H;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EACzC,0GAA8G,CAAC"}
|
|
@@ -13,4 +13,10 @@
|
|
|
13
13
|
* its disclosure is settled where the face is configured, not by hiding or replacing it in the page.
|
|
14
14
|
*/
|
|
15
15
|
export const FTC_DISCLOSURE_LINE = "Independent editorial review of this article’s text and sources. Not a product endorsement, nor medical advice.";
|
|
16
|
+
/**
|
|
17
|
+
* 2.1.0: the line for an article whose review covered its TEXT only (no references or sources section): a byte-faithful
|
|
18
|
+
* copy of the portal's `FTC_DISCLOSURE_LINE_TEXT_ONLY` (Owen, Console decision af5b0db5). Same contract status and curly
|
|
19
|
+
* apostrophe as `FTC_DISCLOSURE_LINE`.
|
|
20
|
+
*/
|
|
21
|
+
export const FTC_DISCLOSURE_LINE_TEXT_ONLY = "Independent editorial review of this article’s text. Not a product endorsement, nor medical advice.";
|
|
16
22
|
//# sourceMappingURL=ftc-disclosure.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ftc-disclosure.js","sourceRoot":"","sources":["../../src/modal/ftc-disclosure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAC/B,iHAA0H,CAAC"}
|
|
1
|
+
{"version":3,"file":"ftc-disclosure.js","sourceRoot":"","sources":["../../src/modal/ftc-disclosure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAC/B,iHAA0H,CAAC;AAE5H;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GACzC,qGAA8G,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"AAoDA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAmBxD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE5D,wHAAwH;AACxH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEnD,MAAM,WAAW,eAAe;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,sGAAsG;IACtG,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,+FAA+F;IAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,2GAA2G;IAC3G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,8FAA8F;IAC9F,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAC/B;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"AAoDA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAmBxD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE5D,wHAAwH;AACxH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEnD,MAAM,WAAW,eAAe;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,sGAAsG;IACtG,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,+FAA+F;IAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,2GAA2G;IAC3G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,8FAA8F;IAC9F,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAC/B;AAqSD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAQ/D"}
|
package/dist/reader/render.js
CHANGED
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
*/
|
|
50
50
|
import { asText } from '../components/escape.js';
|
|
51
51
|
import { CERTREV_LINK_REL } from '../components/rel.js';
|
|
52
|
-
import {
|
|
52
|
+
import { CERT_STRINGS_VERSION, COMPENSATED_EXPERT_CUE, certScopeLineFor } from '../components/render-def.js';
|
|
53
53
|
import { readerFace } from './face.js';
|
|
54
54
|
import { cleaned, contains, esc, firstName, isBlank, isPresent, isTruthy, longDate, rec, safeUrl, textOr, } from './helpers.js';
|
|
55
55
|
import { readerLogo } from './logo.js';
|
|
@@ -87,6 +87,7 @@ function readFacts(input) {
|
|
|
87
87
|
showPhoto,
|
|
88
88
|
creds: rung === 'named' || minimal ? '' : labels.join(', '),
|
|
89
89
|
hasCue,
|
|
90
|
+
scope: certScopeLineFor(expert.reviewScope),
|
|
90
91
|
illus: input.illustrative === true && !hasCue,
|
|
91
92
|
hasMemo: !isBlank(content.memo) && rung === 'memo',
|
|
92
93
|
toned: isTonedStyle(style),
|
|
@@ -128,12 +129,6 @@ function scopeLead(f) {
|
|
|
128
129
|
return '<em>Illustrative example</em> · <!-- -->';
|
|
129
130
|
return '';
|
|
130
131
|
}
|
|
131
|
-
/**
|
|
132
|
-
* The scope sentence is DIRECT text of the scope element (the demo's `<span class="dg-scope">`), which carries the
|
|
133
|
-
* `data-ftc-line` marker itself: no inner span, so the element's `.certrev-r-scope em` cue and the sentence are leaves of
|
|
134
|
-
* one element, as the demo paints them. The marker is on exactly one element per render, as before.
|
|
135
|
-
*/
|
|
136
|
-
const SCOPE = CERT_SCOPE_LINE;
|
|
137
132
|
/**
|
|
138
133
|
* The muted credential line, empty when the reviewer has no displayed credential (so no "verified" claim prints).
|
|
139
134
|
*
|
|
@@ -208,7 +203,7 @@ function bannerCard(f) {
|
|
|
208
203
|
foot = `<div class="certrev-r-foot">${when}${cue}</div>`;
|
|
209
204
|
}
|
|
210
205
|
// POR-9317: the memo card carries the scope line when there is a memo; with none this card is the sole claim face.
|
|
211
|
-
const scope = scopeOn ? `<div class="certrev-r-scope" data-ftc-disclosure data-ftc-line>${
|
|
206
|
+
const scope = scopeOn ? `<div class="certrev-r-scope" data-ftc-disclosure data-ftc-line>${f.scope}</div>` : '';
|
|
212
207
|
return (`${sectionOpen(f, true, f.minimal ? 'Expert reviewed' : credentialAria(f))}\n <div class="certrev-r-card">\n` +
|
|
213
208
|
` <div class="certrev-r-cap">${readerLogo(f.fg === '#ffffff' ? 'white' : 'mono', 18, 'CertREV')}Expert reviewed${f.minimal ? '' : ' & certified'}</div>\n` +
|
|
214
209
|
` <div class="certrev-r-cap-body">\n ${bys}` +
|
|
@@ -231,7 +226,7 @@ function bannerMemo(f) {
|
|
|
231
226
|
` <blockquote>${esc(f.content.memo)}</blockquote>${links}</div>\n </div>\n` +
|
|
232
227
|
' <div class="certrev-r-rule"></div>\n <div class="certrev-r-vfoot">\n' +
|
|
233
228
|
` <span class="certrev-r-verified">${readerLogo('mono', 17, '')}Verified by <b>CertREV</b></span>\n` +
|
|
234
|
-
` <span class="certrev-r-scope" data-ftc-disclosure data-ftc-line>${scopeLead(f)}${
|
|
229
|
+
` <span class="certrev-r-scope" data-ftc-disclosure data-ftc-line>${scopeLead(f)}${f.scope}</span>\n </div>\n </div>\n</section>`);
|
|
235
230
|
}
|
|
236
231
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
237
232
|
// Sidebar and floating pill
|
|
@@ -264,7 +259,7 @@ function sidebar(f) {
|
|
|
264
259
|
return (`${open}<div class="certrev-r-side-body">\n <div class="certrev-r-by">${avatar}<div>\n` +
|
|
265
260
|
` <b>${esc(f.ename)}${f.creds !== '' ? `<!-- -->, <!-- -->${esc(f.creds)}` : ''}</b>${verifiedLine(f, false)}</div>\n </div>` +
|
|
266
261
|
`${fold}${more}` +
|
|
267
|
-
`<div class="certrev-r-scope" data-ftc-disclosure data-ftc-line>${scopeLead(f)}${
|
|
262
|
+
`<div class="certrev-r-scope" data-ftc-disclosure data-ftc-line>${scopeLead(f)}${f.scope}</div>\n </div>` +
|
|
268
263
|
`${links}</div>\n</section>`);
|
|
269
264
|
}
|
|
270
265
|
function pill(f) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"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"}
|
package/dist/verify/cache.d.ts
CHANGED
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
* down costs the page nothing it already had. A definitive answer (a revocation, say)
|
|
19
19
|
* replaces the entry the moment the refresh lands. With the default `staleMs` of 0 an
|
|
20
20
|
* expired entry is gone, exactly as before 1.2.0.
|
|
21
|
+
* 5. (2.0.2, opt-in through `failureTtlMs`) FAILURE MEMORY: a transient result (`isTransient`: the origin was not
|
|
22
|
+
* reached) is remembered in a slot of its own for `failureTtlMs`, beside a positive entry and never over it. While
|
|
23
|
+
* it is remembered nothing loads for the key: a read with no servable entry gets the failure at once, and a stale
|
|
24
|
+
* entry is served without starting a refresh. A definitive answer clears it. So an ongoing outage costs a caller at
|
|
25
|
+
* most one load per key per failure window. `markFailed` lets a caller that stopped waiting (a render deadline)
|
|
26
|
+
* remember one before the load itself settles. Without `failureTtlMs` the cache behaves exactly as 2.0.1's.
|
|
21
27
|
*
|
|
22
28
|
* It is deliberately tiny + dependency-free (a Map + timestamps) so it runs in any server
|
|
23
29
|
* runtime (Node, edge, workerd). For multi-instance deployments this is per-instance L1 and
|
|
@@ -43,21 +49,30 @@ export interface TtlCacheOptions {
|
|
|
43
49
|
* it and none would ever refresh again.
|
|
44
50
|
*/
|
|
45
51
|
readonly inflightMaxMs?: number;
|
|
52
|
+
/**
|
|
53
|
+
* 2.0.2: how long a transient result (`isTransient`) is remembered, in a slot of its own (default: none, and a transient
|
|
54
|
+
* result is cached as a negative entry as before). See the module header, point 5.
|
|
55
|
+
*/
|
|
56
|
+
readonly failureTtlMs?: number;
|
|
46
57
|
/** Injectable clock for deterministic tests. */
|
|
47
58
|
readonly now?: () => number;
|
|
48
59
|
}
|
|
49
60
|
export declare class TtlCache<V> {
|
|
50
61
|
private readonly store;
|
|
51
62
|
private readonly inflight;
|
|
63
|
+
private readonly failures;
|
|
52
64
|
private readonly ttlMs;
|
|
53
65
|
private readonly negativeTtlMs;
|
|
54
66
|
private readonly maxEntries;
|
|
55
67
|
private readonly staleMs;
|
|
56
68
|
private readonly inflightMaxMs;
|
|
69
|
+
private readonly failureTtlMs;
|
|
57
70
|
private readonly now;
|
|
58
71
|
constructor(opts?: TtlCacheOptions);
|
|
59
72
|
/** The entry while it may still be served (fresh, or positive and inside the stale window); prunes it past that. */
|
|
60
73
|
private servable;
|
|
74
|
+
/** 2.0.2: the remembered failure while it lasts (only with `failureTtlMs`); prunes it past that. */
|
|
75
|
+
private failure;
|
|
61
76
|
/** Read a live (non-expired) entry, or undefined. Never serves a stale one; prunes an entry past its stale window. */
|
|
62
77
|
peek(key: string): V | undefined;
|
|
63
78
|
/**
|
|
@@ -92,6 +107,15 @@ export declare class TtlCache<V> {
|
|
|
92
107
|
/** Insert/overwrite an entry. `ttlMsOverride` replaces the TTL this write would otherwise
|
|
93
108
|
* get (positive or negative); omit it for the cache's configured TTLs. */
|
|
94
109
|
set(key: string, value: V, negative?: boolean, ttlMsOverride?: number): void;
|
|
110
|
+
/** 2.0.2: whether a load for `key` is running (and still joinable, younger than `inflightMaxMs`). */
|
|
111
|
+
loading(key: string): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* 2.0.2: remember a transient failure for `key` for `failureTtlMs` from now (a caller that stopped waiting for a load, or
|
|
114
|
+
* a load that settled on one), beside the key's entry: it never touches a positive entry. Without `failureTtlMs` it is
|
|
115
|
+
* a negative entry for the negative TTL, as a transient result was before 2.0.2, and like any `set` it replaces the
|
|
116
|
+
* key's entry.
|
|
117
|
+
*/
|
|
118
|
+
markFailed(key: string, value: V): void;
|
|
95
119
|
/** Drop a key (e.g. on a known revocation push). */
|
|
96
120
|
delete(key: string): void;
|
|
97
121
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/verify/cache.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/verify/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,eAAe;IAC/B,kDAAkD;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC3B;AAcD,qBAAa,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmE;IAC5F,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;gBAEtB,IAAI,GAAE,eAAoB;IAUtC,oHAAoH;IACpH,OAAO,CAAC,QAAQ;IAUhB,oGAAoG;IACpG,OAAO,CAAC,OAAO;IAQf,sHAAsH;IACtH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAMhC;;;;;OAKG;IACH,aAAa,CACZ,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACxB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,EAC9B,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,GAC7B,CAAC,GAAG,SAAS;IAWhB;;;;;;;;;;;;;;;;;;OAkBG;IACG,SAAS,CACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACxB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,EAC9B,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,GAC7B,OAAO,CAAC,CAAC,CAAC;IAMb,2FAA2F;IAC3F,OAAO,CAAC,IAAI;IAuCZ;+EAC2E;IAC3E,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,UAAQ,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAW1E,qGAAqG;IACrG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAK7B;;;;;OAKG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAiBvC,oDAAoD;IACpD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKzB;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IASlC,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI,MAAM,CAEjB;CACD"}
|
package/dist/verify/cache.js
CHANGED
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
* down costs the page nothing it already had. A definitive answer (a revocation, say)
|
|
19
19
|
* replaces the entry the moment the refresh lands. With the default `staleMs` of 0 an
|
|
20
20
|
* expired entry is gone, exactly as before 1.2.0.
|
|
21
|
+
* 5. (2.0.2, opt-in through `failureTtlMs`) FAILURE MEMORY: a transient result (`isTransient`: the origin was not
|
|
22
|
+
* reached) is remembered in a slot of its own for `failureTtlMs`, beside a positive entry and never over it. While
|
|
23
|
+
* it is remembered nothing loads for the key: a read with no servable entry gets the failure at once, and a stale
|
|
24
|
+
* entry is served without starting a refresh. A definitive answer clears it. So an ongoing outage costs a caller at
|
|
25
|
+
* most one load per key per failure window. `markFailed` lets a caller that stopped waiting (a render deadline)
|
|
26
|
+
* remember one before the load itself settles. Without `failureTtlMs` the cache behaves exactly as 2.0.1's.
|
|
21
27
|
*
|
|
22
28
|
* It is deliberately tiny + dependency-free (a Map + timestamps) so it runs in any server
|
|
23
29
|
* runtime (Node, edge, workerd). For multi-instance deployments this is per-instance L1 and
|
|
@@ -27,11 +33,13 @@
|
|
|
27
33
|
export class TtlCache {
|
|
28
34
|
store = new Map();
|
|
29
35
|
inflight = new Map();
|
|
36
|
+
failures = new Map();
|
|
30
37
|
ttlMs;
|
|
31
38
|
negativeTtlMs;
|
|
32
39
|
maxEntries;
|
|
33
40
|
staleMs;
|
|
34
41
|
inflightMaxMs;
|
|
42
|
+
failureTtlMs;
|
|
35
43
|
now;
|
|
36
44
|
constructor(opts = {}) {
|
|
37
45
|
this.ttlMs = opts.ttlMs ?? 60_000;
|
|
@@ -39,6 +47,7 @@ export class TtlCache {
|
|
|
39
47
|
this.maxEntries = opts.maxEntries ?? 1000;
|
|
40
48
|
this.staleMs = opts.staleMs !== undefined && opts.staleMs > 0 ? opts.staleMs : 0;
|
|
41
49
|
this.inflightMaxMs = opts.inflightMaxMs ?? Number.POSITIVE_INFINITY;
|
|
50
|
+
this.failureTtlMs = opts.failureTtlMs !== undefined && opts.failureTtlMs > 0 ? opts.failureTtlMs : 0;
|
|
42
51
|
this.now = opts.now ?? Date.now;
|
|
43
52
|
}
|
|
44
53
|
/** The entry while it may still be served (fresh, or positive and inside the stale window); prunes it past that. */
|
|
@@ -54,10 +63,22 @@ export class TtlCache {
|
|
|
54
63
|
this.store.delete(key);
|
|
55
64
|
return undefined;
|
|
56
65
|
}
|
|
66
|
+
/** 2.0.2: the remembered failure while it lasts (only with `failureTtlMs`); prunes it past that. */
|
|
67
|
+
failure(key) {
|
|
68
|
+
const f = this.failures.get(key);
|
|
69
|
+
if (!f)
|
|
70
|
+
return undefined;
|
|
71
|
+
if (f.until > this.now())
|
|
72
|
+
return f;
|
|
73
|
+
this.failures.delete(key);
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
57
76
|
/** Read a live (non-expired) entry, or undefined. Never serves a stale one; prunes an entry past its stale window. */
|
|
58
77
|
peek(key) {
|
|
59
78
|
const e = this.servable(key);
|
|
60
|
-
|
|
79
|
+
if (e && e.expiresAt > this.now())
|
|
80
|
+
return e.value;
|
|
81
|
+
return this.failure(key)?.value;
|
|
61
82
|
}
|
|
62
83
|
/**
|
|
63
84
|
* The synchronous stale-while-revalidate read: a fresh value; or a positive entry past its TTL but inside the stale
|
|
@@ -67,9 +88,11 @@ export class TtlCache {
|
|
|
67
88
|
*/
|
|
68
89
|
peekOrRefresh(key, loader, isNegative, positiveTtlMs, isTransient) {
|
|
69
90
|
const e = this.servable(key);
|
|
91
|
+
const failed = this.failure(key);
|
|
70
92
|
if (!e)
|
|
71
|
-
return
|
|
72
|
-
|
|
93
|
+
return failed?.value;
|
|
94
|
+
// 2.0.2: no refresh while a failure is remembered; the stale value is still served.
|
|
95
|
+
if (e.expiresAt <= this.now() && !failed) {
|
|
73
96
|
this.load(key, loader, isNegative, positiveTtlMs, isTransient).catch(() => undefined);
|
|
74
97
|
}
|
|
75
98
|
return e.value;
|
|
@@ -104,9 +127,22 @@ export class TtlCache {
|
|
|
104
127
|
const existing = this.inflight.get(key);
|
|
105
128
|
if (existing && this.now() - existing.startedAt < this.inflightMaxMs)
|
|
106
129
|
return existing.promise;
|
|
130
|
+
const token = {};
|
|
107
131
|
const promise = (async () => {
|
|
108
132
|
const value = await loader();
|
|
109
|
-
|
|
133
|
+
// 2.0.2: a load that was replaced (abandoned past `inflightMaxMs`) never writes: its answer may be older than
|
|
134
|
+
// the replacement's, and a late verified read must never overwrite a newer revocation.
|
|
135
|
+
if (this.inflight.get(key)?.token !== token)
|
|
136
|
+
return value;
|
|
137
|
+
if (this.failureTtlMs > 0) {
|
|
138
|
+
if (isTransient?.(value)) {
|
|
139
|
+
this.markFailed(key, value);
|
|
140
|
+
const kept = this.servable(key);
|
|
141
|
+
return kept && !kept.negative ? kept.value : value;
|
|
142
|
+
}
|
|
143
|
+
this.failures.delete(key);
|
|
144
|
+
}
|
|
145
|
+
else if (isTransient?.(value)) {
|
|
110
146
|
const kept = this.servable(key);
|
|
111
147
|
if (kept && !kept.negative)
|
|
112
148
|
return kept.value;
|
|
@@ -116,10 +152,10 @@ export class TtlCache {
|
|
|
116
152
|
return value;
|
|
117
153
|
})().finally(() => {
|
|
118
154
|
// Only this load's own slot: a newer load that replaced an abandoned one keeps its place.
|
|
119
|
-
if (this.inflight.get(key)?.
|
|
155
|
+
if (this.inflight.get(key)?.token === token)
|
|
120
156
|
this.inflight.delete(key);
|
|
121
157
|
});
|
|
122
|
-
this.inflight.set(key, { promise, startedAt: this.now() });
|
|
158
|
+
this.inflight.set(key, { promise, startedAt: this.now(), token });
|
|
123
159
|
return promise;
|
|
124
160
|
}
|
|
125
161
|
/** Insert/overwrite an entry. `ttlMsOverride` replaces the TTL this write would otherwise
|
|
@@ -135,9 +171,40 @@ export class TtlCache {
|
|
|
135
171
|
const ttl = ttlMsOverride !== undefined && Number.isFinite(ttlMsOverride) ? ttlMsOverride : configured;
|
|
136
172
|
this.store.set(key, { value, expiresAt: this.now() + ttl, negative });
|
|
137
173
|
}
|
|
174
|
+
/** 2.0.2: whether a load for `key` is running (and still joinable, younger than `inflightMaxMs`). */
|
|
175
|
+
loading(key) {
|
|
176
|
+
const existing = this.inflight.get(key);
|
|
177
|
+
return existing !== undefined && this.now() - existing.startedAt < this.inflightMaxMs;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* 2.0.2: remember a transient failure for `key` for `failureTtlMs` from now (a caller that stopped waiting for a load, or
|
|
181
|
+
* a load that settled on one), beside the key's entry: it never touches a positive entry. Without `failureTtlMs` it is
|
|
182
|
+
* a negative entry for the negative TTL, as a transient result was before 2.0.2, and like any `set` it replaces the
|
|
183
|
+
* key's entry.
|
|
184
|
+
*/
|
|
185
|
+
markFailed(key, value) {
|
|
186
|
+
if (this.failureTtlMs <= 0) {
|
|
187
|
+
this.set(key, value, true);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Bounded like the store (break-it B3): past `maxEntries`, drop the expired failures, then the oldest.
|
|
191
|
+
if (this.failures.size >= this.maxEntries && !this.failures.has(key)) {
|
|
192
|
+
const now = this.now();
|
|
193
|
+
for (const [k, f] of this.failures)
|
|
194
|
+
if (f.until <= now)
|
|
195
|
+
this.failures.delete(k);
|
|
196
|
+
if (this.failures.size >= this.maxEntries) {
|
|
197
|
+
const oldest = this.failures.keys().next().value;
|
|
198
|
+
if (oldest !== undefined)
|
|
199
|
+
this.failures.delete(oldest);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
this.failures.set(key, { value, until: this.now() + this.failureTtlMs });
|
|
203
|
+
}
|
|
138
204
|
/** Drop a key (e.g. on a known revocation push). */
|
|
139
205
|
delete(key) {
|
|
140
206
|
this.store.delete(key);
|
|
207
|
+
this.failures.delete(key);
|
|
141
208
|
}
|
|
142
209
|
/**
|
|
143
210
|
* Drop every key under a prefix. WHY it exists: a cache key identifies everything the
|
|
@@ -151,10 +218,15 @@ export class TtlCache {
|
|
|
151
218
|
if (key.startsWith(prefix))
|
|
152
219
|
this.store.delete(key);
|
|
153
220
|
}
|
|
221
|
+
for (const key of this.failures.keys()) {
|
|
222
|
+
if (key.startsWith(prefix))
|
|
223
|
+
this.failures.delete(key);
|
|
224
|
+
}
|
|
154
225
|
}
|
|
155
226
|
clear() {
|
|
156
227
|
this.store.clear();
|
|
157
228
|
this.inflight.clear();
|
|
229
|
+
this.failures.clear();
|
|
158
230
|
}
|
|
159
231
|
get size() {
|
|
160
232
|
return this.store.size;
|