+
+
+ You signed in with another tab or window. Reload to refresh your session.
+ You signed out in another tab or window. Reload to refresh your session.
+ You switched accounts on another tab or window. Reload to refresh your session.
+
+ Dismiss alert
+
+
+
+
`}const ps="core/templates/show-logo";function fs(e,t){const n=kn`
+ `;if(!e.alt){const r=gr`Add the missing "\`alt\`" property describing the logo. See ${"[logos]"} for more information.`;lr(`Logo at index ${t}${e.src?`, with \`src\` ${e.src}, `:""} is missing required "\`alt\`" property.`,ps,{hint:r,elements:[n]})}if(!e.src){const e=gr`The \`src\` property is required on every logo. See ${"[logos]"} for more information.`;lr(`Logo at index ${t} is missing "\`src\`" property.`,ps,{hint:e,elements:[n]})}return n}const hs="core/templates/show-people",ms=Wn({en:{until:e=>kn` Until ${e} `},es:{until:e=>kn` Hasta ${e} `},ko:{until:e=>kn` ${e} 이전 `},ja:{until:e=>kn` ${e} 以前 `},de:{until:e=>kn` bis ${e} `},zh:{until:e=>kn` 直到 ${e} `}}),gs=()=>kn``;function bs(e,t){const n=e[t];if(!Array.isArray(n)||!n.length)return;const r=(s=t,function(e,t){const n="https://respec.org/docs/",r=`See [person](${n}#person) configuration for available options.`,o=`Error processing the [person object](${n}#person) at index ${t} of the "[\`${s}\`](${n}#${s})" configuration option.`;if(!e.name)return lr(`${o} Missing required property \`"name"\`.`,hs,{hint:r}),!1;if(e.orcid){const{orcid:n}=e,r=new URL(n,"https://orcid.org/");if("https://orcid.org"!==r.origin){const n=`${o} ORCID "${e.orcid}" at index ${t} is invalid.`,s=`The origin should be "https://orcid.org", not "${r.origin}".`;return lr(n,hs,{hint:s}),!1}const s=r.pathname.slice(1).replace(/\/$/,"");if(!/^\d{4}-\d{4}-\d{4}-\d{3}(\d|X)$/.test(s))return lr(`${o} ORCID "${s}" has wrong format.`,hs,{hint:'ORCIDs have the format "1234-1234-1234-1234."'}),!1;if(!function(e){const t=e[e.length-1],n=e.split("").slice(0,-1).filter((e=>/\d/.test(e))).map(Number).reduce(((e,t)=>2*(e+t)),0),r=(12-n%11)%11,s=10===r?"X":String(r);return t===s}(n))return lr(`${o} ORCID "${n}" failed checksum check.`,hs,{hint:"Please check that the ORCID is valid."}),!1;e.orcid=r.href}return e.retiredDate&&(i=e.retiredDate,"Invalid Date"===(/\d{4}-\d{2}-\d{2}/.test(i)?new Date(i):"Invalid Date").toString())?(lr(`${o} The property "\`retiredDate\`" is not a valid date.`,hs,{hint:`The expected format is YYYY-MM-DD. ${r}`}),!1):!(e.hasOwnProperty("extras")&&!function(e,t,n){return Array.isArray(e)?e.every(((e,r)=>{switch(!0){case"object"!=typeof e:return lr(`${n}. Member "extra" at index ${r} is not an object.`,hs,{hint:t}),!1;case!e.hasOwnProperty("name"):return lr(`${n} \`PersonExtra\` object at index ${r} is missing required "name" member.`,hs,{hint:t}),!1;case"string"==typeof e.name&&""===e.name.trim():return lr(`${n} \`PersonExtra\` object at index ${r} "name" can't be empty.`,hs,{hint:t}),!1}return!0})):(lr(`${n}. A person's "extras" member must be an array.`,hs,{hint:t}),!1)}(e.extras,r,o))&&(e.url&&e.mailto&&ur(`${o} Has both "url" and "mailto" property.`,hs,{hint:`Please choose either "url" or "mailto" ("url" is preferred). ${r}`}),e.companyURL&&!e.company&&ur(`${o} Has a "\`companyURL\`" property but no "\`company\`" property.`,hs,{hint:`Please add a "\`company\`" property. ${r}.`}),!0);var i});var s;return n.filter(r).map(ys)}function ys(e){const t=[e.name],n=[e.company],r=e.w3cid||null,s=[];if(e.mailto&&(e.url=`mailto:${e.mailto}`),e.url){const n="mailto:"===new URL(e.url,document.location.href).protocol?"ed_mailto u-email email p-name":"u-url url p-name fn";s.push(kn`${t}`)}else s.push(kn`${t}`);if(e.orcid&&s.push(kn`${gs()}`),e.company){const t="p-org org h-org",r=e.companyURL?kn`${n}`:kn`${n}`;s.push(kn` (${r})`)}e.note&&s.push(document.createTextNode(` (${e.note})`)),e.extras&&s.push(...e.extras.map((e=>kn`, ${function(e){const t=e.class||null,{name:n,href:r}=e;return r?kn`${n}`:kn`${n}`}(e)}`)));const{retiredDate:o}=e;if(e.retiredDate){const e=kn``;s.push(kn` - ${ms.until(e)} `)}return kn`
+ ${s}
+
`}const ws=Wn({en:{archives:"archives",author:"Author:",authors:"Authors:",commit_history:"Commit history",edited_in_place:"edited in place",editor:"Editor:",editors:"Editors:",feedback:"Feedback:",former_editor:"Former editor:",former_editors:"Former editors:",history:"History:",implementation_report:"Implementation report:",latest_editors_draft:"Latest editor's draft:",latest_published_version:"Latest published version:",latest_recommendation:"Latest Recommendation:",message_topic:"… message topic …",more_details_about_this_doc:"More details about this document",multiple_alternates:e=>`This document is also available in ${e?"these non-normative formats":"this non-normative format"}:`,prev_editor_draft:"Previous editor's draft:",prev_recommendation:"Previous Recommendation:",prev_version:"Previous version:",publication_history:"Publication history",test_suite:"Test suite:",this_version:"This version:",with_subject_line:"with subject line",your_topic_here:"YOUR TOPIC HERE"},ko:{author:"저자:",authors:"저자:",editor:"편집자:",editors:"편집자:",former_editor:"이전 편집자:",former_editors:"이전 편집자:",latest_editors_draft:"최신 편집 초안:",latest_published_version:"최신 버전:",this_version:"현재 버전:"},zh:{author:"作者:",authors:"作者:",commit_history:"Git提交历史",editor:"编辑:",editors:"编辑:",feedback:"反馈:",former_editor:"原编辑:",former_editors:"原编辑:",history:"历史:",implementation_report:"实现报告:",latest_editors_draft:"最新编辑草稿:",latest_published_version:"最新发布版本:",latest_recommendation:"最新发布的正式推荐标准:",message_topic:"… 邮件主题 …",prev_editor_draft:"上一版编辑草稿:",prev_recommendation:"上一版正式推荐标准:",prev_version:"上一版:",test_suite:"测试套件:",this_version:"本版本:"},ja:{archives:"アーカイブ",author:"著者:",authors:"著者:",commit_history:"更新履歴",edited_in_place:"改版なく更新",editor:"編者:",editors:"編者:",feedback:"フィードバック:",former_editor:"以前の版の編者:",former_editors:"以前の版の編者:",history:"履歴:",implementation_report:"実装レポート:",latest_editors_draft:"最新の編集用草案:",latest_published_version:"最新バージョン:",latest_recommendation:"最新の勧告版:",message_topic:"… メール件名 …",more_details_about_this_doc:"この文書についてのより詳細",prev_editor_draft:"前回の編集用草案:",prev_recommendation:"前回の勧告版:",prev_version:"前回のバージョン:",publication_history:"公表履歴",test_suite:"テストスイート:",this_version:"このバージョン:",with_subject_line:"次の件名で"},nl:{author:"Auteur:",authors:"Auteurs:",editor:"Redacteur:",editors:"Redacteurs:",latest_editors_draft:"Laatste werkversie:",latest_published_version:"Laatst gepubliceerde versie:",this_version:"Deze versie:"},es:{archives:"archivos",author:"Autor:",authors:"Autores:",commit_history:"Historial de cambios",edited_in_place:"editado en lugar",editor:"Editor:",editors:"Editores:",feedback:"Comentarios:",former_editor:"Antiguo editor:",former_editors:"Antiguos editores:",history:"Historia:",implementation_report:"Informe de implementación:",latest_editors_draft:"Última versión del editor:",latest_published_version:"Última versión publicada:",latest_recommendation:"Recomendación más reciente:",message_topic:"… detalles de mensaje …",more_details_about_this_doc:"Más detalles sobre este documento:",publication_history:"Historial de publicación",prev_editor_draft:"Última versión del editor:",prev_recommendation:"Última Recomendación:",prev_version:"Última versión:",test_suite:"Suite de pruebas:",this_version:"Esta versión:",with_subject_line:"con línea de asunto",your_topic_here:"TU SUJETO AQUÍ"},de:{archives:"Archiv",author:"Autor/in:",authors:"Autor/innen:",commit_history:"Commit-Historie",edited_in_place:"zuletzt geändert am",editor:"Redaktion:",editors:"Redaktion:",feedback:"Feedback:",former_editor:"Frühere Mitwirkende:",former_editors:"Frühere Mitwirkende:",history:"Verlauf:",implementation_report:"Umsetzungsbericht:",latest_editors_draft:"Letzter Entwurf:",latest_published_version:"Letzte publizierte Fassung:",latest_recommendation:"Aktuellste Empfehlung:",more_details_about_this_doc:"Mehr Informationen über dieses Dokument",multiple_alternates:e=>`Dieses Dokument ist ebenfalls in ${e?"diesen nicht-normativen Formaten verfügbar":"diesem nicht-normativen Format verfügbar"}:`,prev_editor_draft:"Vorheriger Entwurf:",prev_recommendation:"Vorherige Empfehlung:",prev_version:"Vorherige Version:",publication_history:"Veröffentlichungsverlauf",test_suite:"Testumgebung:",this_version:"Diese Fassung:"},cs:{archives:"archivy",author:"Autor:",authors:"Autoři:",commit_history:"Historie změn",edited_in_place:"upraveno přímo",editor:"Editor:",editors:"Editoři:",feedback:"Zpětná vazba:",former_editor:"Bývalý editor:",former_editors:"Bývalí editoři:",history:"Historie:",implementation_report:"Implementační zpráva:",latest_editors_draft:"Nejnovější pracovní verze:",latest_published_version:"Nejnovější publikovaná verze:",latest_recommendation:"Nejnovější doporučení:",message_topic:"… předmět zprávy …",more_details_about_this_doc:"Více informací o tomto dokumentu",multiple_alternates:e=>`Tento dokument je také dostupný v ${e?"těchto ne-normativních formátech":"tomto ne-normativním formátu"}:`,prev_editor_draft:"Předchozí pracovní verze:",prev_recommendation:"Předchozí doporučení:",prev_version:"Předchozí verze:",publication_history:"Historie publikací",test_suite:"Testovací sada:",this_version:"Tato verze:",with_subject_line:"s předmětem",your_topic_here:"VÁŠ PŘEDMĚT ZDE"}});function vs(e){let t=document.querySelector("h2#subtitle");return t&&t.parentElement?(t.remove(),e.subtitle=t.textContent.trim()):e.subtitle&&(t=document.createElement("h2"),t.textContent=e.subtitle,t.id="subtitle"),t&&t.classList.add("subtitle"),t}var ks=(e,t)=>(vr("beforesave",(e=>{const t=e.querySelector(".head details");t&&(t.open=!0)})),kn`
+ ${t.multipleAlternates?"This document is also available in these non-normative formats:":"This document is also available in this non-normative format:"}
+ ${t.alternatesHTML}
+
`};const _s=Wn({en:{sotd:"Status of This Document",status_at_publication:kn`This section describes the status of this
+ document at the time of its publication. A list of current W3C
+ publications and the latest revision of this technical report can be found
+ in the
+ W3C standards and drafts index.`},ko:{sotd:"현재 문서의 상태",status_at_publication:kn`이 부분은 현재 문서의 발행 당시 상태에 대해
+ 기술합니다. W3C 발행 문서의 최신 목록 및 테크니컬 리포트 최신판의
+ W3C standards and drafts index 에서
+ 열람할 수 있습니다.`},zh:{sotd:"关于本文档",status_at_publication:kn`本章节描述了本文档的发布状态。W3C的文档列表和最新版本可通过W3C技术报告索引访问。`},ja:{sotd:"この文書の位置付け",status_at_publication:kn`この節には、公開時点でのこの文書の位置づけが記されている。現時点でのW3Cの発行文書とこのテクニカルレポートの最新版は、下記から参照できる。
+ W3C standards and drafts index`},nl:{sotd:"Status van dit document"},es:{sotd:"Estado de este Document",status_at_publication:kn`Esta sección describe el estado del presente
+ documento al momento de su publicación. Una lista de las publicaciones
+ actuales del W3C y la última revisión del presente informe técnico puede
+ hallarse en
+ el índice de normas y borradores del
+ W3C.`},de:{sotd:"Status dieses Dokuments",status_at_publication:kn`Dieser Abschnitt beschreibt den Status des
+ Dokuments zum Zeitpunkt der Publikation. Eine Liste der aktuellen
+ Publikatinen des W3C und die aktuellste Fassung dieser Spezifikation kann
+ im W3C standards and drafts index.`},cs:{sotd:"Stav tohoto dokumentu",status_at_publication:kn`Tato sekce popisuje stav tohoto dokumentu v době
+ jeho zveřejnění. Seznam aktuálních publikací W3C a nejnovější verzi této
+ technické zprávy najdete v
+ indexu standardů a návrhů W3C
+ na https://www.w3.org/TR/.`}}),Cs="https://www.w3.org/policies/process/20250818/";function Ss(e){return/^[aeiou]/i.test(e)?`an ${e}`:`a ${e}`}var Rs=(e,t)=>kn`
+
+ This document is a draft of a potential specification. It has no official
+ standing of any kind and does not represent the support or consensus of
+ any standards organization.
+
+ This document is merely a W3C-internal
+ ${n?"member-confidential":""} document. It has no official standing
+ of any kind and does not represent consensus of the W3C Membership.
+
+ By publishing this document, W3C acknowledges that the
+ Submitting Members have made a formal
+ Submission request to W3C for discussion. Publication of this document by
+ W3C indicates no endorsement of its content by W3C, nor that W3C has, is, or
+ will be allocating any resources to the issues addressed by it. This
+ document is not the product of a chartered W3C group, but is published as
+ potential input to the
+ W3C Process. A
+ W3C Team Comment has been published in
+ conjunction with this Member Submission. Publication of acknowledged Member
+ Submissions at the W3C site is one of the benefits of
+
+ W3C Membership. Please consult the requirements associated with Member Submissions of
+ section 3.3 of the W3C Patent Policy. Please consult the complete
+ list of acknowledged W3C Member Submissions.
+
`}(e):""}
+ `}(e,t):kn`
+ ${e.sotdAfterWGinfo?"":t.additionalContent}
+ ${e.overrideStatus?"":kn` ${function(e){if(!e.wg)return;let t=null;const n=document.querySelector(".proposed-addition"),r=document.querySelector(".proposed-correction"),s=document.querySelector(".addition"),o=document.querySelector(".correction"),i=n||r||s||o;e.isRec&&i&&(n&&r||s&&o?t=kn`It includes
+ ${n?kn`
+ proposed amendments`:kn`
+ candidate amendments`},
+ introducing substantive changes and new features since the previous
+ Recommendation.`:n||s?t=kn`It includes
+ ${n?kn`
+ proposed additions`:kn`
+ candidate additions`},
+ introducing new features since the previous Recommendation.`:(r||o)&&(t=kn`It includes
+ ${r?kn`
+ proposed corrections`:kn`
+ candidate corrections`}.`));const a=js[e.specStatus]?kn` using the
+ ${js[e.specStatus]} track`:"";return kn`
+ This document was published by ${As(e)} as
+ ${Ss(e.longStatus)}${a}. ${t}
+
+ W3C recommends the wide deployment of this specification as a standard for
+ the Web.
+
+
+
+ A W3C Recommendation is a specification that, after extensive
+ consensus-building, is endorsed by
+ W3C and its Members, and
+ has commitments from Working Group members to
+ royalty-free licensing
+ for implementations.
+ ${n?kn`Future updates to this Recommendation may incorporate
+ new features.`:""}
+
+ ${document.querySelector(".addition")?kn`
+ Candidate additions are marked in the document.
+
+ Proposed corrections are marked in the document.
+
`:""}
+ ${r?kn`
+ The W3C Membership and other interested parties are invited to review
+ the proposed ${r} and send comments through
+ ${Ln.format(t)}. Advisory Committee Representatives
+ should consult their
+ WBS questionnaires.
+
`:""}
+ `}(e):function(e){const t=document.querySelector("#sotd.updateable-rec");let n=null,r=null,s=kn`Publication as ${Ss(e.textStatus)} does not
+ imply endorsement by W3C and its Members.`,o=kn`
+ This is a draft document and may be updated, replaced, or obsoleted by other
+ documents at any time. It is inappropriate to cite this document as other
+ than a work in progress.
+ ${t?kn`Future updates to this upcoming Recommendation may incorporate
+ new features.`:""}
+
`;"DISC"===e.specStatus&&(o=kn`
+ Publication as a Discontinued Draft implies that this document is no
+ longer intended to advance or to be maintained. It is inappropriate to
+ cite this document as other than abandoned work.
+
`);const i=kn`
+ This document is maintained and updated at any time. Some parts of this
+ document are work in progress.
+
`;switch(e.specStatus){case"STMT":s=kn`
+ A W3C Statement is a specification that, after extensive
+ consensus-building, is endorsed by
+ W3C and its Members.
+
`;break;case"RY":s=kn`
W3C recommends the wide usage of this registry.
+
+ A W3C Registry is a specification that, after extensive
+ consensus-building, is endorsed by
+ W3C and its Members.
+
`;break;case"CRD":n=kn`A Candidate Recommendation Draft integrates
+ changes from the previous Candidate Recommendation that the Working Group
+ intends to include in a subsequent Candidate Recommendation Snapshot.`,"LS"===e.pubMode&&(o=i);break;case"CRYD":n=kn`A Candidate Registry Draft integrates changes
+ from the previous Candidate Registry Snapshot that the Working Group
+ intends to include in a subsequent Candidate Registry Snapshot.`,"LS"===e.pubMode&&(o=i);break;case"CRY":n=kn`A Candidate Registry Snapshot has received
+ wide review.`,r=kn`
+ The W3C Membership and other interested parties are invited to review
+ the document and send comments through ${e.humanPREnd}. Advisory
+ Committee Representatives should consult their
+ WBS questionnaires. Note that substantive technical comments were expected during the
+ Candidate Recommendation review period that ended ${e.humanCREnd}.
+
`;break;case"CR":n=kn`A Candidate Recommendation Snapshot has received
+ wide review, is intended to
+ gather
+ implementation experience,
+ and has commitments from Working Group members to
+ royalty-free licensing
+ for implementations.`,o=kn`${t?kn`Future updates to this upcoming Recommendation may incorporate
+ new features.`:""}`,r="LS"===e.pubMode?kn`
+ Comments are welcome at any time but most especially before
+ ${Ln.format(e.crEnd)}.
+
`:kn`
+ This Candidate Recommendation is not expected to advance to Proposed
+ Recommendation any earlier than ${Ln.format(e.crEnd)}.
+
`;break;case"PR":r=kn`
+ The W3C Membership and other interested parties are invited to review
+ the document and send comments through ${Ln.format(e.prEnd)}.
+ Advisory Committee Representatives should consult their
+ WBS questionnaires. Note that substantive technical comments were expected during the
+ Candidate Recommendation review period that ended
+ ${Ln.format(e.crEnd)}.
+
`;break;case"DNOTE":s=kn`${e.textStatus}s are not endorsed by
+ W3C nor its Members.`;break;case"NOTE":s=kn`This ${e.textStatus} is endorsed by
+ ${As(e)}, but is not endorsed by
+ W3C itself nor its
+ Members.`,o=""}return kn`
${s} ${n}
+ ${o} ${r}`}(e)}
+ ${function(e){const{isNote:t,isRegistry:n,wgId:r,multipleWGs:s,wgPatentHTML:o,wgPatentURI:i,wgPatentPolicy:a}=e,c="PP2017"===a?"https://www.w3.org/Consortium/Patent-Policy-20170801/":"https://www.w3.org/policies/patent-policy/",l=t||n?kn`
+ The
+ ${"PP2017"===a?"1 August 2017 ":""}W3C Patent
+ Policy
+ does not carry any licensing requirements or commitments on this
+ document.
+ `:kn`
+ This document was produced by ${s?"groups":"a group"}
+ operating under the
+ ${"PP2017"===a?"1 August 2017 ":""}W3C Patent
+ Policy.
+ `;return kn`
+ ${l}
+ ${t||n?"":kn`
+ ${s?kn` W3C maintains ${o} `:kn`
+ W3C maintains a
+ public list of any patent disclosures
+ `}
+ made in connection with the deliverables of
+ ${s?"each group; these pages also include":"the group; that page also includes"}
+ instructions for disclosing a patent. An individual who has actual
+ knowledge of a patent that the individual believes contains
+ Essential Claim(s)
+ must disclose the information in accordance with
+ section 6 of the W3C Patent Policy.
+ `}
+
+ `}
+ `}
+ ${t.additionalSections}
+ `;function Es(e){const{prUrl:t,prNumber:n,edDraftURI:r}=e;return kn`
+
+ This is a
+ preview${t&&n?kn`
+ of pull request
+ #${n}
+ `:""}
+
+
+ Do not attempt to implement this version of the specification. Do not
+ reference this version as authoritative in any way.
+ ${r?kn`
+ Instead, see
+ ${r} for the Editor's draft.
+ `:""}
+
+ If you wish to make comments regarding this document, please send them to
+ ${s}@w3.org
+ (subscribe,
+ archives)${o?kn` with ${o} at the start of your email's
+ subject`:""}.
+
+ ${e.github?kn`
+ GitHub Issues are preferred for
+ discussion of this specification.
+ `:""}
+ ${e.wgPublicList?kn`
+ ${e.github&&e.wgPublicList?"Alternatively, you can send comments to our mailing list.":"Comments regarding this document are welcome."}
+ Please send them to
+ ${e.wgPublicList}@w3.org
+ (subscribe,
+ archives)${e.subjectPrefix?kn` with ${e.subjectPrefix} at the start of your
+ email's subject`:""}.
+ `:""}
+
`}(e,t):""}
+ ${e.sotdAfterWGinfo?t.additionalContent:""}
+ ${t.additionalSections}
+ `;const Ts="w3c/headers";function Ps(e){return new URL(e,"https://www.w3.org/").href}const Is={LS:"WD",LD:"WD",FPWD:"WD","Member-SUBM":"SUBM"},Ds={DNOTE:"Group Note Draft",NOTE:"Group Note",STMT:"Statement","Member-SUBM":"Member Submission",MO:"Member-Only Document",ED:"Editor's Draft",LS:"Living Standard",LD:"Living Document",FPWD:"First Public Working Draft",WD:"Working Draft",CR:"Candidate Recommendation",CRD:"Candidate Recommendation",PR:"Proposed Recommendation",REC:"Recommendation",DISC:"Discontinued Draft",RSCND:"Rescinded Recommendation",DRY:"Registry Draft",CRYD:"Candidate Registry",CRY:"Candidate Registry",RY:"Registry",unofficial:"Unofficial Draft",UD:"Unofficial Draft",base:"",finding:"TAG Finding","draft-finding":"Draft TAG Finding","editor-draft-finding":"Draft TAG Finding","CG-DRAFT":"Draft Community Group Report","CG-FINAL":"Final Community Group Report","BG-DRAFT":"Draft Business Group Report","BG-FINAL":"Final Business Group Report"},Ns={...Ds,CR:"Candidate Recommendation Snapshot",CRD:"Candidate Recommendation Draft",CRY:"Candidate Registry Snapshot",CRYD:"Candidate Registry Draft"},js={DNOTE:"Note",NOTE:"Note",STMT:"Note","WG-NOTE":"Note","IG-NOTE":"Note",FPWD:"Recommendation",WD:"Recommendation",CR:"Recommendation",CRD:"Recommendation",PR:"Recommendation",REC:"Recommendation",DISC:"Recommendation",RSCND:"Recommendation",DRY:"Registry",CRYD:"Registry",CRY:"Registry",RY:"Registry"},Os=["DNOTE","NOTE","STMT"],zs=["CR","CRD","DISC","FPWD","PR","REC","RSCND","WD"],Ms=["DRY","CRY","CRYD","RY"],qs=["draft-finding","finding","editor-draft-finding"],Ws=["CG-DRAFT","CG-FINAL"],Us=["BG-DRAFT","BG-FINAL"],Fs=[...Ws,...Us],Bs=[...Os,...zs,...Ms],Hs=["base",...Ws,...Us,"editor-draft-finding","draft-finding","finding","MO","unofficial"],Vs=new Map([["cc0",{name:"Creative Commons 0 Public Domain Dedication",short:"CC0",url:"https://creativecommons.org/publicdomain/zero/1.0/"}],["w3c-software",{name:"W3C Software Notice and License",short:"W3C Software",url:"https://www.w3.org/copyright/software-license-2002/"}],["w3c-software-doc",{name:"W3C Software and Document Notice and License",short:"permissive document license",url:"https://www.w3.org/copyright/software-license-2023/"}],["cc-by",{name:"Creative Commons Attribution 4.0 International Public License",short:"CC-BY",url:"https://creativecommons.org/licenses/by/4.0/legalcode"}],["document",{name:"W3C Document License",short:"document use",url:"https://www.w3.org/copyright/document-license/"}],["dual",{name:"W3C Dual License",short:"dual license",url:"https://www.w3.org/Consortium/Legal/2013/copyright-documents-dual.html"}],[void 0,{name:"unlicensed",url:null,short:"UNLICENSED"}]]),Gs=["PP2017","PP2020"];function Ys(e,t,n=new Date){const r=e[t]?new Date(e[t]):new Date(n);if(Number.isFinite(r.valueOf())){const e=En.format(r);return new Date(e)}return lr(gr`${t} is not a valid date: "${e[t]}". Expected format 'YYYY-MM-DD'.`,Ts),new Date(En.format(new Date))}function Ks(e,{isTagFinding:t=!1}){const n=e.cloneNode(!0),r=document.createDocumentFragment();for(;n.hasChildNodes()&&(n.nodeType!==Node.ELEMENT_NODE||"section"!==n.firstChild.localName);)r.appendChild(n.firstChild);if(t&&!r.hasChildNodes()){ur(gr`ReSpec does not support automated SotD generation for TAG findings.`,Ts,{hint:"Please add the prerequisite content in the 'sotd' section."})}return{additionalContent:r,additionalSections:n.childNodes}}var Zs=Object.freeze({__proto__:null,W3CNotes:Os,bgStatus:Us,cgStatus:Ws,cgbgStatus:Fs,licenses:Vs,name:Ts,noTrackStatus:Hs,recTrackStatus:zs,registryTrackStatus:Ms,run:async function(e){if(e.isBasic="base"===e.specStatus,e.isCGBG=Fs.includes(e.specStatus),e.isCGFinal=e.isCGBG&&e.specStatus.endsWith("G-FINAL"),e.isCR="CR"===e.specStatus||"CRD"===e.specStatus,e.isCRDraft="CRD"===e.specStatus,e.isCRY="CRY"===e.specStatus||"CRYD"===e.specStatus,e.isEd="ED"===e.specStatus,e.isMemberSubmission="Member-SUBM"===e.specStatus,e.isMO="MO"===e.specStatus,e.isNote=Os.includes(e.specStatus),e.isNoTrack=Hs.includes(e.specStatus),e.isPR="PR"===e.specStatus,e.isRecTrack=zs.includes(e.specStatus),e.isRec=e.isRecTrack&&"REC"===e.specStatus,e.isRegistry=Ms.includes(e.specStatus),e.isRegular=!e.isCGBG&&!e.isBasic,e.isTagEditorFinding="editor-draft-finding"===e.specStatus,e.isTagFinding=qs.includes(e.specStatus),e.isUnofficial="unofficial"===e.specStatus,e.licenseInfo=function(e){let t;if("string"==typeof e.license){const n=e.license.toLowerCase();if(Vs.has(n))t=n;else{const t=`The license "\`${e.license}\`" is not supported.`,n=gr`Please set
+ ${"[license]"} to one of: ${fr([...Vs.keys()].filter((e=>e)),{quotes:!0})}. If in doubt, remove \`license\` and let ReSpec pick one for you.`;lr(t,Ts,{hint:n})}}if(e.isUnofficial&&!t&&(t="cc-by"),!e.isUnofficial&&["cc-by","cc0"].includes(t)){const t=gr`Please set ${"[license]"} to \`"w3c-software-doc"\` instead.`;lr(gr`License "\`${e.license}\`" is not allowed for W3C Specifications.`,Ts,{hint:t})}return Vs.get(t)}(e),e.prependW3C=!e.isBasic&&!e.isUnofficial,e.longStatus=Ns[e.specStatus],e.textStatus=Ds[e.specStatus],e.showPreviousVersion=!1,e.isRegular&&!e.shortName){const e=gr`Please set ${"[shortName]"} to a short name for the specification.`;lr(gr`The ${"[shortName]"} configuration option is required for this kind of document.`,Ts,{hint:e})}if(e.publishDate=Ys(e,"publishDate",document.lastModified),e.publishYear=e.publishDate.getUTCFullYear(),e.modificationDate&&(e.modificationDate=Ys(e,"modificationDate",document.lastModified)),e.isRecTrack&&!e.github&&!e.wgPublicList){const e=gr`Use the ${"[github]"} configuration option to add a link to a repository. Alternatively use ${"[wgPublicList]"} to link to a mailing list.`;lr("W3C Process requires a either a link to a public repository or mailing list.",Ts,{hint:e})}if(e.isEd&&!e.edDraftURI){const e=gr`Please set ${"[edDraftURI]"} to the URL of the Editor's Draft. Alternatively, use the set ${"[github]"} option, which automatically sets it for you.`;ur(gr`Editor's Drafts should set ${"[edDraftURI]"} configuration option.`,Ts,{hint:e})}const t=function(e){const{specStatus:t,group:n}=e;if(Bs.includes(t)||"wg"===e.groupType)return"/TR";switch(t){case"CG-FINAL":case"BG-FINAL":return`/community/reports/${n}`;case"finding":case"draft-finding":return"/2001/tag/doc";case"Member-SUBM":return"/Submission"}if(("tag"===e.group||"ab"===e.group)&&"TR"===e.canonicalURI)return"/TR";return""}(e);if(t&&!e.thisVersion){const n=Is[e.specStatus]||e.specStatus,{shortName:r,publishDate:s}=e,o=`${n}-${r}-${Fn(s)}`,i=[...Bs,"Member-SUBM"].includes(e.specStatus)?`${s.getUTCFullYear()}/`:"";e.thisVersion=Ps(`${t}/${i}${o}/`)}e.isEd&&(e.thisVersion=e.edDraftURI),e.isCGBG&&function(e){const t=Ds[e.specStatus],n=e.latestVersion?new URL(Ps(e.latestVersion)):null;if(!e.wg){return void lr(gr`The ${"[group]"} configuration option is required for this kind of document (${t}).`,Ts)}if(e.isCGFinal){if(!1===("https://www.w3.org"===n?.origin||"https://w3.org/"===n?.origin)){lr(gr`For ${t}, the ${"[latestVersion]"} URL must point to somewhere at https://www.w3.org/.`,Ts,{hint:"Ask a W3C Team Member for a W3C URL where the report can be published."})}}}(e),null!==e.latestVersion&&(e.latestVersion=e.latestVersion?Ps(e.latestVersion):Ps(`${t}/${e.shortName}/`)),e.latestVersion&&function(e){const t=new URL(e.latestVersion);if(("https://www.w3.org"===t.origin||"https://w3.org/"===t.origin)&&t.pathname.startsWith("/TR/")&&!1===["ED",...Bs].includes(e.specStatus)){const t=gr`Ask a W3C Team Member for a W3C URL where the report can be published and change ${"[latestVersion]"} to something else.`;lr(gr`Documents with a status of \`"${e.specStatus}"\` can't be published on the W3C's /TR/ (Technical Report) space.`,Ts,{hint:t})}}(e);const n=`${t}/${e.shortName}`;if(e.previousPublishDate){if(!e.previousMaturity&&!e.isTagFinding){lr(gr`${"[`previousPublishDate`]"} is set, but missing ${"[`previousMaturity`]"}.`,Ts)}e.previousPublishDate=Ys(e,"previousPublishDate");const r=Is[e.previousMaturity]??e.previousMaturity;if(e.isTagFinding&&e.latestVersion){const t=En.format(e.publishDate);e.thisVersion=Ps(`${n}-${t}`);const r=En.format(e.previousPublishDate);e.prevVersion=Ps(`${n}-${r}}`)}else if(e.isCGBG||e.isBasic)e.prevVersion=e.prevVersion||"";else{const n=e.previousPublishDate.getUTCFullYear(),{shortName:s}=e,o=Fn(e.previousPublishDate);e.prevVersion=Ps(`${t}/${n}/${r}-${s}-${o}/`)}}e.prevRecShortname&&!e.prevRecURI&&(e.prevRecURI=Ps(`${t}/${e.prevRecShortname}`));for(let t=0;t{if(e.w3cid)return;const n=gr`See ${"[w3cid]"} for instructions for how to retrieve it and add it.`;lr(gr`Editor ${e.name?`"${e.name}"`:`number ${t+1}`} is missing their ${"[w3cid]"}.`,Ts,{hint:n})}));if(e.alternateFormats?.some((({uri:e,label:t})=>!e||!t))){lr(gr`Every ${"[`alternateFormats`]"} entry must have a \`uri\` and a \`label\`.`,Ts)}e.copyrightStart==e.publishYear&&(e.copyrightStart=""),e.dashDate=En.format(e.publishDate),e.publishISODate=e.publishDate.toISOString(),e.shortISODate=En.format(e.publishDate),function(e){if(!e.wgPatentPolicy)return;const t=new Set([].concat(e.wgPatentPolicy));if(t.size&&![...t].every((e=>Gs.includes(e)))){const e=gr`Invalid ${"[wgPatentPolicy]"} value(s): ${hr([...t].filter((e=>!Gs.includes(e))))}.`,n=`Please use one of: ${fr(Gs)}.`;lr(e,Ts,{hint:n})}if(1!==t.size){const e="When collaborating across multiple groups, they must use the same patent policy.",n=gr`For ${"[wgPatentPolicy]"}, please check the patent policies of each group. The patent policies were: ${[...t].join(", ")}.`;lr(e,Ts,{hint:n})}e.wgPatentPolicy=[...t][0]}(e),await async function(e){if(!e.shortName||null===e.historyURI||!e.latestVersion)return;const t=e.isEd||Bs.includes(e.specStatus);if(e.historyURI&&!t){const t=gr`Please remove ${"[historyURI]"}.`;return lr(gr`The ${"[historyURI]"} can't be used with non /TR/ documents.`,Ts,{hint:t}),void(e.historyURI=null)}const n=new URL(e.historyURI??`${e.shortName}/`,"https://www.w3.org/standards/history/");if(e.historyURI&&t||["FPWD","DNOTE","NOTE","DRY"].includes(e.specStatus))return void(e.historyURI=n.href);try{const t=await fetch(n,{method:"HEAD"});t.ok&&(e.historyURI=t.url)}catch{}}(e),e.isTagEditorFinding&&(delete e.thisVersion,delete e.latestVersion),e.isTagFinding&&(e.showPreviousVersion=!!e.previousPublishDate);const r={get multipleAlternates(){return e.alternateFormats&&e.alternateFormats.length>1},get alternatesHTML(){return e.alternateFormats&&Gn(e.alternateFormats.map((({label:e})=>e)),((t,n)=>{const r=e.alternateFormats[n];return kn`${r.label}`}))}},s=(e.isCGBG?xs:ks)(e,r);document.body.prepend(s),document.body.classList.add("h-entry");const o=document.getElementById("sotd")||document.createElement("section");if((e.isCGBG||!e.isNoTrack||e.isTagFinding)&&!o.id){lr("A Status of This Document must include at least on custom paragraph.",Ts,{elements:[o],hint:"Add a `
` in the 'sotd' section that reflects the status of this specification."})}o.id=o.id||"sotd",o.classList.add("introductory");const i=[e.wg,e.wgURI,e.wgPatentURI];if(i.some((e=>Array.isArray(e)))&&!i.every((e=>Array.isArray(e)))){const e=gr`Use the ${"[group]"} option with an array instead.`;lr(gr`If one of ${"[wg]"}, ${"[wgURI]"}, or ${"[wgPatentURI]"} is an array, they all have to be.`,Ts,{hint:e})}if(Array.isArray(e.wg)?(e.multipleWGs=e.wg.length>1,e.wgPatentHTML=Gn(e.wg,((t,n)=>kn`a
+ public list of any patent disclosures (${t})`))):e.multipleWGs=!1,e.isPR&&!e.crEnd){lr(gr`${"[specStatus]"} is "PR" but no ${"[crEnd]"} is specified in the ${"[respecConfig]"} (needed to indicate end of previous CR).`,Ts)}if(e.isCR&&!e.crEnd){lr(gr`${"[specStatus]"} is "CR", but no ${"[crEnd]"} is specified in the ${"[respecConfig]"}.`,Ts)}if(e.crEnd=Ys(e,"crEnd"),e.isPr&&!e.prEnd){lr(gr`${"[specStatus]"} is "PR" but no ${"[prEnd]"} is specified in the ${"[respecConfig]"}.`,Ts)}e.prEnd=Ys(e,"prEnd");const a=o.classList.contains("updateable-rec"),c=null!==document.querySelector(".correction"),l=null!==document.querySelector(".proposed-correction"),u=null!==document.querySelector(".addition"),d=null!==document.querySelector(".proposed-addition"),p=c||u||d||l;if(e.isRec&&!e.errata&&!p){const e=gr`Add an ${"[errata]"} URL to your ${"[respecConfig]"}.`;lr("Recommendations must have an errata link.",Ts,{hint:e})}if(!a&&(u||c)){lr(gr`${"[specStatus]"} is "REC" with proposed additions but the Recommendation is not marked as allowing new features.`,Ts)}if(e.isRec&&a&&(d||l)&&!e.revisedRecEnd){lr(gr`${"[specStatus]"} is "REC" with proposed corrections or additions but no ${"[revisedRecEnd]"} is specified in the ${"[respecConfig]"}.`,Ts)}if(e.revisedRecEnd=Ys(e,"revisedRecEnd"),e.noRecTrack&&zs.includes(e.specStatus)){const t=gr`Document configured as ${"[noRecTrack]"}, but its status ("${e.specStatus}") puts it on the W3C Rec Track.`,n=fr(zs,{quotes:!0});lr(t,Ts,{hint:`Status **can't** be any of: ${n}.`})}if(o.classList.contains("override")||kn.bind(o)`${function(e,t){const n={...Ks(t,e),get mailToWGPublicList(){return`mailto:${e.wgPublicList}@w3.org`},get mailToWGPublicListWithSubject(){const t=e.subjectPrefix?`?subject=${encodeURIComponent(e.subjectPrefix)}`:"";return this.mailToWGPublicList+t},get mailToWGPublicListSubscription(){return`mailto:${e.wgPublicList}-request@w3.org?subject=subscribe`}},r=e.isCGBG?Ls:Rs;return r(e,n)}(e,o)}`,!e.implementationReportURI&&e.isCR){const e=gr`CR documents must have an ${"[implementationReportURI]"} that describes the [implementation experience](https://www.w3.org/policies/process/#implementation-experience).`;lr(gr`Missing ${"[implementationReportURI]"} configuration option in ${"[respecConfig]"}.`,Ts,{hint:e})}if(!e.implementationReportURI&&e.isPR){ur(gr`PR documents should include an ${"[implementationReportURI]"}, which needs to link to a document that describes the [implementation experience](https://www.w3.org/policies/process-20190301/#implementation-experience).`,Ts)}wr("amend-user-config",{publishISODate:e.publishISODate,generatedSubtitle:qn(document.getElementById("w3c-state")?.textContent??"")})},status2text:Ds,status2track:js,tagStatus:qs,trStatus:Bs});const Js={lint:{"no-headingless-sections":!0,"no-http-props":!0,"no-unused-vars":!1,"check-punctuation":!1,"local-refs-exist":!0,"check-internal-slots":!1,"check-charset":!1,"privsec-section":!1},pluralize:!0,specStatus:"base",highlightVars:!0,addSectionLinks:!0},Qs="w3c/defaults",Xs={src:"https://www.w3.org/StyleSheets/TR/2021/logos/W3C",alt:"W3C",height:48,width:72,url:"https://www.w3.org/"},eo={alt:"W3C Member Submission",href:"https://www.w3.org/Submission/",src:"https://www.w3.org/Icons/member_subm-v.svg",width:"211",height:"48"},to={lint:{"privsec-section":!1,"required-sections":!0,"wpt-tests-exist":!1,"informative-dfn":"warn","no-unused-dfns":"warn",a11y:!1},doJsonLd:!1,logos:[],xref:!0,wgId:"",otherLinks:[],excludeGithubLinks:!0,subtitle:"",prevVersion:"",formerEditors:[],editors:[],authors:[]};var no=Object.freeze({__proto__:null,name:Qs,run:function(e){const t=!1!==e.lint&&{...Js.lint,...to.lint,...e.lint};Object.assign(e,{...Js,...to,...e,lint:t}),"unofficial"===e.specStatus||e.hasOwnProperty("license")||(e.license="w3c-software-doc"),function(e){const{specStatus:t,groupType:n,group:r}=e;if(!t){const t=gr`Select an appropriate status from ${"[specStatus]"} based on your W3C group. If in doubt, use \`"unofficial"\`.`;return lr(gr`The ${"[specStatus]"} configuration option is required.`,Qs,{hint:t}),void(e.specStatus="base")}if(void 0===Ds[t]){const n=gr`The ${"[specStatus]"} "\`${t}\`" is not supported at for this type of document.`,r=gr`set ${"[specStatus]"} to one of: ${fr(Object.keys(Ds),{quotes:!0})}.`;return lr(n,Qs,{hint:r}),void(e.specStatus="base")}switch(n){case"cg":if(![...Ws,"unofficial","UD"].includes(t)){const n=gr`W3C Community Group documents can't use \`"${t}"\` for the ${"[specStatus]"} configuration option.`,r=fr(Ws,{quotes:!0});lr(n,Qs,{hint:`Please use one of: ${r}. Automatically falling back to \`"CG-DRAFT"\`.`}),e.specStatus="CG-DRAFT"}break;case"bg":if(![...Us,"unofficial","UD"].includes(t)){const n=gr`W3C Business Group documents can't use \`"${t}"\` for the ${"[specStatus]"} configuration option.`,r=fr(Us,{quotes:!0});lr(n,Qs,{hint:`Please use one of: ${r}. Automatically falling back to \`"BG-DRAFT"\`.`}),e.specStatus="BG-DRAFT"}break;case"wg":if(![...Bs,"unofficial","UD","ED"].includes(t)){const e=gr`Pleas see ${"[specStatus]"} for appropriate status for W3C Working Group documents.`;lr(gr`W3C Working Group documents can't use \`"${t}"\` for the ${"[specStatus]"} configuration option.`,Qs,{hint:e})}break;case"other":if("tag"===r&&!["ED",...Bs,...qs].includes(t)){const n=gr`The W3C Technical Architecture Group's documents can't use \`"${t}"\` for the ${"[specStatus]"} configuration option.`,r=fr(["ED",...Bs,...qs],{quotes:!0});lr(n,Qs,{hint:`Please use one of: ${r}. Automatically falling back to \`"unofficial"\`.`}),e.specStatus="unofficial"}break;default:if(!e.wgId&&!["unofficial","base","UD","Member-SUBM"].includes(e.specStatus)){const t="Document is not associated with a [W3C group](https://respec.org/w3c/groups/). Defaulting to 'base' status.",n=gr`Use the ${"[group]"} configuration option to associated this document with a W3C group.`;e.specStatus="base",lr(t,Qs,{hint:n})}}}(e),function(e){const{specStatus:t,wg:n}=e,r=[...zs,...Ms,...Os,...qs,"ED"].includes(t),s=n&&n.length&&r,o=["Member-SUBM"].includes(t);(s||o)&&(e.logos.unshift(Xs),"Member-SUBM"===t&&e.logos.push(eo))}(e)}});var ro=String.raw`@keyframes pop{
+0%{transform:scale(1,1)}
+25%{transform:scale(1.25,1.25);opacity:.75}
+100%{transform:scale(1,1)}
+}
+a.internalDFN{color:inherit;border-bottom:1px solid #99c;text-decoration:none}
+a.externalDFN{color:inherit;border-bottom:1px dotted #ccc;text-decoration:none}
+a.bibref{text-decoration:none}
+.respec-offending-element:target{animation:pop .25s ease-in-out 0s 1}
+.respec-offending-element,a[href].respec-offending-element{text-decoration:red wavy underline}
+@supports not (text-decoration:red wavy underline){
+.respec-offending-element:not(pre){display:inline-block}
+.respec-offending-element{background:url(data:image/gif;base64,R0lGODdhBAADAPEAANv///8AAP///wAAACwAAAAABAADAEACBZQjmIAFADs=) bottom repeat-x}
+}
+#references :target{background:#eaf3ff;animation:pop .4s ease-in-out 0s 1}
+cite .bibref{font-style:italic}
+a[href].orcid{padding-left:4px;padding-right:4px}
+a[href].orcid>svg{margin-bottom:-2px}
+ol.tof,ul.tof{list-style:none outside none}
+.caption{margin-top:.5em;font-style:italic}
+#issue-summary>ul{column-count:2}
+#issue-summary li{list-style:none;display:inline-block}
+details.respec-tests-details{margin-left:1em;display:inline-block;vertical-align:top}
+details.respec-tests-details>*{padding-right:2em}
+details.respec-tests-details[open]{z-index:999999;position:absolute;border:thin solid #cad3e2;border-radius:.3em;background-color:#fff;padding-bottom:.5em}
+details.respec-tests-details[open]>summary{border-bottom:thin solid #cad3e2;padding-left:1em;margin-bottom:1em;line-height:2em}
+details.respec-tests-details>ul{width:100%;margin-top:-.3em}
+details.respec-tests-details>li{padding-left:1em}
+.self-link:hover{opacity:1;text-decoration:none;background-color:transparent}
+aside.example .marker>a.self-link{color:inherit}
+.header-wrapper{display:flex;align-items:baseline}
+:is(h2,h3,h4,h5,h6):not(#toc>h2,#abstract>h2,#sotd>h2,.head>h2){position:relative;left:-.5em}
+:is(h2,h3,h4,h5,h6):not(#toch2)+a.self-link{color:inherit;order:-1;position:relative;left:-1.1em;font-size:1rem;opacity:.5}
+:is(h2,h3,h4,h5,h6)+a.self-link::before{content:"§";text-decoration:none;color:var(--heading-text)}
+:is(h2,h3)+a.self-link{top:-.2em}
+:is(h4,h5,h6)+a.self-link::before{color:#000}
+@media (max-width:767px){
+dd{margin-left:0}
+}
+@media print{
+.removeOnSave{display:none}
+}`;const so=function(){const e=document.createElement("style");return e.id="respec-mainstyle",e.textContent=ro,document.head.appendChild(e),e}();var oo=Object.freeze({__proto__:null,name:"core/style",run:function(e){e.noReSpecCSS&&so.remove()}});function io(){const e=document.createElement("script");e.src="https://www.w3.org/scripts/TR/2021/fixup.js",location.hash&&e.addEventListener("load",(()=>{window.location.href=location.hash}),{once:!0}),document.body.appendChild(e)}const ao=function(){const e=[{hint:"preconnect",href:"https://www.w3.org"},{hint:"preload",href:"https://www.w3.org/scripts/TR/2021/fixup.js",as:"script"},{hint:"preload",href:lo("base.css").href,as:"style"},{hint:"preload",href:lo("dark.css").href,as:"style"},{hint:"preload",href:"https://www.w3.org/StyleSheets/TR/2021/logos/W3C",as:"image",corsMode:"anonymous"}],t=document.createDocumentFragment();for(const n of e.map(Pn))t.appendChild(n);return t}();function co(e){return t=>{const n=t.querySelector(`head link[href="${e}"]`);t.querySelector("head").append(n)}}function lo(e="base.css"){return new URL(`/StyleSheets/TR/2021/${e}`,"https://www.w3.org/")}ao.appendChild(kn``),document.head.querySelector("meta[name=viewport]")||ao.prepend(kn``),document.head.prepend(ao);var uo=Object.freeze({__proto__:null,name:"w3c/style",run:function(e){e.noToc||vr("end-all",io,{once:!0});const t=lo(function(e){const t=e.specStatus?.toUpperCase()??"";let n="";const r=[...zs,...Ms,...Os,"ED","MEMBER-SUBM"].includes(t)&&e.wgId;switch(t){case"WD":case"FPWD":n=r?"W3C-WD":"base.css";break;case"CG-DRAFT":case"CG-FINAL":case"BG-DRAFT":case"BG-FINAL":n=t.toLowerCase();break;case"UD":case"UNOFFICIAL":n="W3C-UD";break;case"FINDING":case"DRAFT-FINDING":case"EDITOR-DRAFT-FINDING":case"BASE":n="base.css";break;case"MEMBER-SUBM":n="W3C-Member-SUBM";break;default:n=r?`W3C-${e.specStatus}`:"base.css"}return n}(e));document.head.appendChild(kn``),vr("beforesave",co(t));let n=document.querySelector("head meta[name=color-scheme]");if(n||(n=kn``,document.head.appendChild(n)),n.content.includes("dark")){const e=lo("dark.css");document.head.appendChild(kn``),vr("beforesave",co(e))}}});const po="core/github";let fo,ho;const mo=new Promise(((e,t)=>{fo=e,ho=e=>{lr(e,po),t(new Error(e))}})),go=Wn({en:{file_a_bug:"File an issue",participate:"Participate:",commit_history:"Commit history"},ko:{participate:"참여"},zh:{file_a_bug:"反馈错误",participate:"参与:"},ja:{commit_history:"変更履歴",file_a_bug:"問題報告",participate:"参加方法:"},nl:{commit_history:"Revisiehistorie",file_a_bug:"Dien een melding in",participate:"Doe mee:"},es:{commit_history:"Historia de cambios",file_a_bug:"Nota un bug",participate:"Participe:"},de:{commit_history:"Revisionen",file_a_bug:"Fehler melden",participate:"Mitmachen:"}});var bo=Object.freeze({__proto__:null,github:mo,name:po,run:async function(e){if(!e.hasOwnProperty("github")||!e.github)return void fo(null);if("object"==typeof e.github&&!e.github.hasOwnProperty("repoURL")){const e=gr`Config option ${"[github]"} is missing property \`repoURL\`.`;return void ho(e)}let t,n=e.github.repoURL||e.github;n.endsWith("/")||(n+="/");try{t=new URL(n,"https://github.com")}catch{const e=gr`${"[github]"} configuration option is not a valid URL? (${n}).`;return void ho(e)}if("https://github.com"!==t.origin){const e=gr`${"[github]"} configuration option must be HTTPS and pointing to GitHub. (${t.href}).`;return void ho(e)}const[r,s]=t.pathname.split("/").filter((e=>e));if(!r||!s){const e=gr`${"[github]"} URL needs a path. For example, "w3c/my-spec".`;return void ho(e)}const o=e.github.branch||"gh-pages",i=new URL("./issues/",t).href,a=new URL(`./commits/${e.github.branch??""}`,t.href),c={edDraftURI:`https://${r.toLowerCase()}.github.io/${s}/`,githubToken:void 0,githubUser:void 0,issueBase:i,atRiskBase:i,otherLinks:[],pullBase:new URL("./pulls/",t).href,shortName:s};let l="https://respec.org/github";if(e.githubAPI)if(new URL(e.githubAPI).hostname===window.parent.location.hostname)l=e.githubAPI;else{ur("The `githubAPI` configuration option is private and should not be added manually.",po)}if(!e.excludeGithubLinks){const n={key:go.participate,data:[{value:`GitHub ${r}/${s}`,href:t},{value:go.file_a_bug,href:c.issueBase},{value:go.commit_history,href:a.href},{value:"Pull requests",href:c.pullBase}]};e.otherLinks||(e.otherLinks=[]),e.otherLinks.unshift(n)}const u={branch:o,repoURL:t.href,apiBase:l,fullName:`${r}/${s}`,issuesURL:i,pullsURL:c.pullBase,newIssuesURL:new URL("./new/choose",i).href,commitHistoryURL:a.href};fo(u);const d={...c,...e,github:u,githubAPI:l};Object.assign(e,d)}});class yo{constructor(e){this.doc=e,this.root=e.createDocumentFragment(),this.stack=[this.root],this.current=this.root}static sectionClasses=new Set(["appendix","informative","notoc"]);findPosition(e){return parseInt(e.tagName.charAt(1),10)}findParent(e){let t;for(;e>0;)if(e--,t=this.stack[e],t)return t}findHeader({firstChild:e}){for(;e;){if(/H[1-6]/.test(e.tagName))return e;e=e.nextSibling}return null}addHeader(e){const t=this.doc.createElement("section"),n=this.findPosition(e);t.appendChild(e),this.findParent(n).appendChild(t),this.stack[n]=t,this.stack.length=n+1,this.current=t,this.processHeader(e,t)}processHeader(e,t){yo.sectionClasses.intersection(new Set(e.classList)).forEach((e=>{t.classList.add(e)}))}addSection(e){const t=this.findHeader(e),n=t?this.findPosition(t):1,r=this.findParent(n);t&&e.removeChild(t),e.appendChild(wo(e)),t&&e.prepend(t),r.appendChild(e),this.current=r}addElement(e){this.current.appendChild(e)}}function wo(e){const t=new yo(e.ownerDocument);for(;e.firstChild;){const n=e.firstChild;switch(n.localName){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":t.addHeader(n);break;case"section":t.addSection(n);break;default:t.addElement(n)}}return t.root}function vo(e){const t=wo(e);if("section"===t.firstElementChild.localName&&"section"===e.localName){const n=t.firstElementChild;n.remove(),e.append(...n.childNodes)}else e.textContent="";e.appendChild(t)}var ko=Object.freeze({__proto__:null,name:"core/sections",restructure:vo,run:function(){vo(document.body)}});const $o="core/data-include";function xo(e,t,n){const r=document.querySelector(`[data-include-id=${t}]`),s=Bn(e,r.dataset.oninclude,n),o="string"==typeof r.dataset.includeReplace;!function(e,t,{replace:n}){const{includeFormat:r}=e.dataset;let s=t;"markdown"===r&&(s=Nr(s)),"text"===r?e.textContent=s:e.innerHTML=s,"markdown"===r&&vo(e),n&&e.replaceWith(...e.childNodes)}(r,s,{replace:o}),o||function(e){["data-include","data-include-format","data-include-replace","data-include-id","oninclude"].forEach((t=>e.removeAttribute(t)))}(r)}async function _o(e,t){const n=e.querySelectorAll("[data-include]"),r=Array.from(n).map((async e=>{const n=e.dataset.include;if(!n)return;const r=`include-${String(Math.random()).slice(2)}`;e.dataset.includeId=r;try{const s=await fetch(n);xo(await s.text(),r,n),t<3&&await _o(e,t+1)}catch(t){lr(`\`data-include\` failed: \`${n}\` (${t.message}).`,$o,{elements:[e],cause:t})}}));await Promise.all(r)}var Co=Object.freeze({__proto__:null,name:$o,run:async function(){await _o(document,1)}});var So=Object.freeze({__proto__:null,name:"core/reindent",run:function(){for(const e of document.getElementsByTagName("pre"))e.innerHTML=br(e.innerHTML)}});const Ro="core/title",Eo=Wn({en:{default_title:"No Title"},de:{default_title:"Kein Titel"},zh:{default_title:"无标题"},cs:{default_title:"Bez názvu"}});var Ao=Object.freeze({__proto__:null,name:Ro,run:function(e){const t=document.querySelector("h1#title")||kn`
`;if(t.isConnected&&""===t.textContent.trim()){lr('The document is missing a title, so using a default title. To fix this, please give your document a ``. If you need special markup in the document\'s title, please use a `
`.',Ro,{title:"Document is missing a title",elements:[t]})}t.id||(t.id="title"),t.classList.add("title"),function(e,t){t.isConnected||(t.textContent=document.title||`${Eo.default_title}`);const n=document.createElement("h1");n.innerHTML=t.innerHTML.replace(/: /g,": ").replace(/ /g," - ");let r=qn(n.textContent);if(e.isPreview&&e.prNumber){const n=e.prUrl||`${e.github.repoURL}pull/${e.prNumber}`,{childNodes:s}=kn`
+ Preview of PR #${e.prNumber}:
+ `;t.prepend(...s),r=`Preview of PR #${e.prNumber}: ${r}`}document.title=r,e.title=r}(e,t),document.body.prepend(t)}});const Lo="w3c/level",To=Wn({en:{level:"Level"},ja:{level:"レベル"},nl:{level:"Niveau"},de:{level:"Stufe"},zh:{level:"级别"}});var Po=Object.freeze({__proto__:null,name:Lo,run:function(e){if(!e.hasOwnProperty("level"))return;const t=document.querySelector("h1#title"),n=parseInt(e.level);if(!Number.isInteger(n)||n<0){lr(`The \`level\` configuration option must be a number greater or equal to 0. It is currently set to \`${n}\``,Lo,{title:"Invalid level config.",elements:[t]})}else t.append(` ${To.level} ${n}`),document.title=`${document.title} ${To.level} ${n}`,e.shortName=`${e.shortName}-${n}`,e.level=n}});const Io="w3c/abstract",Do=Wn({en:{abstract:"Abstract"},ko:{abstract:"요약"},zh:{abstract:"摘要"},ja:{abstract:"要約"},nl:{abstract:"Samenvatting"},es:{abstract:"Resumen"},de:{abstract:"Zusammenfassung"},cs:{abstract:"Abstrakt"}});var No=Object.freeze({__proto__:null,name:Io,run:async function(){const e=function(){const e=document.getElementById("abstract");if(e)switch(e.localName){case"section":return e;case"div":return Jn(e,"section");default:return lr("The abstract should be a `` element.",Io,{elements:[e]}),e}const t=Do.abstract.toLocaleLowerCase(o);for(const e of document.querySelectorAll("h2, h3, h4, h5, h6"))if(qn(e.textContent).toLocaleLowerCase(o)===t)return e.closest("section");return e}();e?(e.classList.add("introductory"),e.id="abstract",e.querySelector("h2")||e.prepend(kn`
${Do.abstract}
`)):lr('Document must have one ``.',Io)}});var jo=Object.freeze({__proto__:null,name:"core/data-transform",run:function(){document.querySelectorAll("[data-transform]").forEach((e=>{e.innerHTML=Bn(e.innerHTML,e.dataset.transform),e.removeAttribute("data-transform")}))}});const Oo="core/dfn-abbr";function zo(e){const t=(n=e).dataset.abbr?n.dataset.abbr:n.textContent.match(/\b([a-z])/gi).join("").toUpperCase();var n;const r=e.textContent.replace(/\s\s+/g," ").trim();e.insertAdjacentHTML("afterend",` (${t})`);const s=e.dataset.lt||"";e.dataset.lt=s.split("|").filter((e=>e.trim())).concat(t).join("|")}var Mo=Object.freeze({__proto__:null,name:Oo,run:function(){const e=document.querySelectorAll("[data-abbr]");for(const t of e){const{localName:e}=t;if("dfn"===e)zo(t);else{lr(`\`data-abbr\` attribute not supported on \`${e}\` elements.`,Oo,{elements:[t],title:"Error: unsupported."})}}}});const qo=/^[a-z]+(\s+[a-z]+)+\??$/,Wo=/\B"([^"]*)"\B/,Uo=/^(\w+)\(([^\\)]*)\)(?:\|(\w+)(?:\((?:([^\\)]*))\))?)?$/,Fo=/\[\[(\w+(?: +\w+)*)\]\](\([^)]*\))?$/,Bo=/^((?:\[\[)?(?:\w+(?: +\w+)*)(?:\]\])?)$/,Ho=/^(?:\w+)\??$/,Vo=/^(\w+)\["([\w- ]*)"\]$/,Go=/\.?(\w+\(.*\)$)/,Yo=/\/(.+)/,Ko=/\[\[.+\]\]/;function Zo(e){const{identifier:t,renderParent:n,nullable:r}=e;if(n)return kn`${t+(r?"?":"")}`}function Jo(e){const{identifier:t,parent:n,slotType:r,renderParent:s,args:o}=e,{identifier:i}=n||{},a="method"===r,c=a?kn`(${Vn(o,Qo)})`:null,l=a?`(${o.join(", ")})`:"";return kn`${n&&s?".":""}[[${t}]]${c}`}function Qo(e,t,n){if(t${e}`;const r=e.split(/(^\.{3})(.+)/),s=r.length>1,o=s?r[2]:r[0];return kn`${s?"...":null}${o}`}function Xo(e){const{parent:t,identifier:n,renderParent:r}=e,{identifier:s}=t||{};return kn`${r?".":""}${n}`}function ei(e){const{args:t,identifier:n,type:r,parent:s,renderParent:o}=e,{renderText:i,renderArgs:a}=e,{identifier:c}=s||{},l=Vn(a||t,Qo),u=`${n}(${t.join(", ")})`;return kn`${s&&o?".":""}${i||n}${!i||a?kn`(${l})`:""}`}function ti(e){const{identifier:t,enumValue:n,parent:r}=e,s=r?r.identifier:t;return kn`"${n}"`}function ni(e){const{identifier:t}=e;return kn`"${t}"`}function ri(e){const{identifier:t,nullable:n}=e;return kn`${t+(n?"?":"")}`}function si(e){let t;try{t=function(e){const t=Ko.test(e),n=t?Yo:Go,[r,s]=e.split(n);if(t&&r&&!s)throw new SyntaxError(`Internal slot missing "for" part. Expected \`{{ InterfaceName/${r}}}\` }.`);const o=r.split(/[./]/).concat(s).filter((e=>e&&e.trim())).map((e=>e.trim())),i=!e.includes("/"),a=[];for(;o.length;){const t=o.pop();if(Uo.test(t)){const[,e,n,r,s]=t.match(Uo),o=n.split(/,\s*/).filter((e=>e)),c=r?.trim(),l=s?.split(/,\s*/).filter((e=>e));a.push({type:"method",identifier:e,args:o,renderParent:i,renderText:c,renderArgs:l})}else if(Vo.test(t)){const[,e,n]=t.match(Vo);a.push({type:"enum",identifier:e,enumValue:n,renderParent:i})}else if(Wo.test(t)){const[,e]=t.match(Wo);i?a.push({type:"exception",identifier:e}):a.push({type:"enum",enumValue:e,renderParent:i})}else if(Fo.test(t)){const[,e,n]=t.match(Fo),r=n?"method":"attribute",s=n?.slice(1,-1).split(/,\s*/).filter((e=>e));a.push({type:"internal-slot",slotType:r,identifier:e,args:s,renderParent:i})}else if(Bo.test(t)&&o.length){const[,e]=t.match(Bo);a.push({type:"attribute",identifier:e,renderParent:i})}else if(qo.test(t)){const e=t.endsWith("?"),n=e?t.slice(0,-1):t;a.push({type:"idl-primitive",identifier:n,renderParent:i,nullable:e})}else{if(!Ho.test(t)||0!==o.length)throw new SyntaxError(`IDL micro-syntax parsing error in \`{{ ${e} }}\``);{const e=t.endsWith("?"),n=e?t.slice(0,-1):t;a.push({type:"base",identifier:n,renderParent:i,nullable:e})}}}return a.forEach(((e,t,n)=>{e.parent=n[t+1]||null})),a.reverse()}(e)}catch(t){const n=kn`{{ ${e} }}`,r="Error: Invalid inline IDL string.";return lr(t.message,"core/inlines",{title:r,elements:[n]}),n}const n=kn(document.createDocumentFragment()),r=[];for(const e of t)switch(e.type){case"base":{const t=Zo(e);t&&r.push(t);break}case"attribute":r.push(Xo(e));break;case"internal-slot":r.push(Jo(e));break;case"method":r.push(ei(e));break;case"enum":r.push(ti(e));break;case"exception":r.push(ni(e));break;case"idl-primitive":r.push(ri(e));break;default:throw new Error("Unknown type.")}return n`${r}`}const oi=new Set(["alias","reference"]),ii=async function(){const e=await $n.openDB("respec-biblio2",12,{upgrade(e){Array.from(e.objectStoreNames).map((t=>e.deleteObjectStore(t)));e.createObjectStore("alias",{keyPath:"id"}).createIndex("aliasOf","aliasOf",{unique:!1}),e.createObjectStore("reference",{keyPath:"id"})}}),t=Date.now();for(const n of[...oi]){const r=e.transaction(n,"readwrite").store,s=IDBKeyRange.lowerBound(t);let o=await r.openCursor(s);for(;o?.value;){const e=o.value;(void 0===e.expires||e.expiresn[e].map((t=>this.add(e,t)))));await Promise.all(r)},async add(e,t){if(!oi.has(e))throw new TypeError(`Invalid type: ${e}`);if("object"!=typeof t)throw new TypeError("details should be an object");if("alias"===e&&!t.hasOwnProperty("aliasOf"))throw new TypeError("Invalid alias object.");const n=await this.ready;let r=await this.has(e,t.id);if(r){const s=await this.get(e,t.id);if(s?.expiresn.objectStore(e).clear()));await Promise.all(r)}},ci={},li=new URL("https://api.specref.org/bibrefs?refs="),ui=Pn({hint:"dns-prefetch",href:li.origin});let di;document.head.appendChild(ui);const pi=new Promise((e=>{di=e}));async function fi(e,t={forceUpdate:!1}){const n=[...new Set(e)].filter((e=>e.trim()));if(!n.length||!1===navigator.onLine)return null;let r;try{r=await fetch(li.href+n.join(","))}catch(e){return console.error(e),null}if(!t.forceUpdate&&!r.ok||200!==r.status)return null;const s=await r.json(),o=Date.now()+36e5;try{const e=r.headers.has("Expires")?Math.min(Date.parse(r.headers.get("Expires")),o):o;await ai.addAll(s,e)}catch(e){console.error(e)}return s}async function hi(e){const t=await pi;if(!t.hasOwnProperty(e))return null;const n=t[e];return n.aliasOf?await hi(n.aliasOf):n}var mi=Object.freeze({__proto__:null,Plugin:class{constructor(e){this.conf=e}normalizeReferences(){const e=new Set([...this.conf.normativeReferences].map((e=>e.toLowerCase())));Array.from(this.conf.informativeReferences).filter((t=>e.has(t.toLowerCase()))).forEach((e=>this.conf.informativeReferences.delete(e)))}getRefKeys(){return{informativeReferences:Array.from(this.conf.informativeReferences),normativeReferences:Array.from(this.conf.normativeReferences)}}async run(){this.conf.localBiblio||(this.conf.localBiblio={}),this.conf.biblio=ci;const e=Object.keys(this.conf.localBiblio).filter((e=>this.conf.localBiblio[e].hasOwnProperty("aliasOf"))).map((e=>this.conf.localBiblio[e].aliasOf)).filter((e=>!this.conf.localBiblio.hasOwnProperty(e)));this.normalizeReferences();const t=this.getRefKeys(),n=Array.from(new Set(t.normativeReferences.concat(t.informativeReferences).filter((e=>!this.conf.localBiblio.hasOwnProperty(e))).concat(e).sort())),r=n.length?await async function(e){const t=[];try{await ai.ready;const n=e.map((async e=>({id:e,data:await ai.find(e)})));t.push(...await Promise.all(n))}catch(n){t.push(...e.map((e=>({id:e,data:null})))),console.warn(n)}return t}(n):[],s={hasData:[],noData:[]};r.forEach((e=>{(e.data?s.hasData:s.noData).push(e)})),s.hasData.forEach((e=>{ci[e.id]=e.data}));const o=s.noData.map((e=>e.id));if(o.length){const e=await fi(o,{forceUpdate:!0});Object.assign(ci,e)}Object.assign(ci,this.conf.localBiblio),(()=>{di(this.conf.biblio)})()}},biblio:ci,name:"core/biblio",resolveRef:hi,updateFromNetwork:fi});const gi="core/render-biblio",bi=Wn({en:{info_references:"Informative references",norm_references:"Normative references",references:"References",reference_not_found:"Reference not found."},ko:{references:"참조"},nl:{info_references:"Informatieve referenties",norm_references:"Normatieve referenties",references:"Referenties"},es:{info_references:"Referencias informativas",norm_references:"Referencias normativas",references:"Referencias",reference_not_found:"Referencia no encontrada."},ja:{info_references:"参照用参考文献",norm_references:"規範的参考文献",references:"参考文献"},de:{info_references:"Weiterführende Informationen",norm_references:"Normen und Spezifikationen",references:"Referenzen"},zh:{info_references:"非规范性引用",norm_references:"规范性引用",references:"参考文献"},cs:{info_references:"Informativní odkazy",norm_references:"Normativní odkazy",references:"Odkazy",reference_not_found:"Odkaz nebyl nalezen."}}),yi=new Map([["CR","W3C Candidate Recommendation"],["ED","W3C Editor's Draft"],["LCWD","W3C Last Call Working Draft"],["NOTE","W3C Working Group Note"],["PR","W3C Proposed Recommendation"],["REC","W3C Recommendation"],["WD","W3C Working Draft"]]),wi=(vi=".",e=>{const t=e.trim();return!t||t.endsWith(vi)?t:t+vi});var vi;function ki(e,t){const{goodRefs:n,badRefs:r}=function(e){const t=[],n=[];for(const r of e)r.refcontent?t.push(r):n.push(r);return{goodRefs:t,badRefs:n}}(e.map($i)),s=function(e){const t=new Map;for(const n of e)t.has(n.refcontent.id)||t.set(n.refcontent.id,n);return[...t.values()]}(n),o=s.concat(r).sort(((e,t)=>e.ref.toLocaleLowerCase().localeCompare(t.ref.toLocaleLowerCase()))),i=kn`
+
${t}
+
${o.map(_i)}
+ `;Kn(i,"",t);const a=function(e){return e.reduce(((e,t)=>{const n=t.refcontent.id;return(e.has(n)?e.get(n):e.set(n,[]).get(n)).push(t.ref),e}),new Map)}(n);return function(e,t){e.map((({ref:e,refcontent:n})=>{const r=`#bib-${e.toLowerCase()}`,s=t.get(n.id).map((e=>`a.bibref[href="#bib-${e.toLowerCase()}"]`)).join(",");return{refUrl:r,elems:document.querySelectorAll(s),refcontent:n}})).forEach((({refUrl:e,elems:t,refcontent:n})=>{t.forEach((t=>{t.setAttribute("href",e),t.setAttribute("title",n.title),t.dataset.linkType="biblio"}))}))}(s,a),function(e){for(const{ref:t}of e){const e=[...document.querySelectorAll(`a.bibref[href="#bib-${t.toLowerCase()}"]`)].filter((({textContent:e})=>e.toLowerCase()===t.toLowerCase()));lr(`Reference "[${t}]" not found.`,gi,{hint:`Search for ["${t}"](https://www.specref.org?q=${t}) on Specref to see if it exists or if it's misspelled.`,elements:e})}}(r),i}function $i(e){let t=ci[e],n=e;const r=new Set([n]);for(;t&&t.aliasOf;)if(r.has(t.aliasOf)){t=null;lr(`Circular reference in biblio DB between [\`${e}\`] and [\`${n}\`].`,gi)}else n=t.aliasOf,t=ci[n],r.add(n);return t&&!t.id&&(t.id=e.toLowerCase()),{ref:e,refcontent:t}}function xi(e,t){const n=e.replace(/^(!|\?)/,""),r=`#bib-${n.toLowerCase()}`,s=kn`${t||n}`;return t?s:kn`[${s}]`}function _i(e){const{ref:t,refcontent:n}=e,r=`bib-${t.toLowerCase()}`;return kn`
+
`),r.classList.add("appendix"),n.length){const e=ki(n,bi.norm_references);r.appendChild(e)}if(t.length){const e=ki(t,bi.info_references);r.appendChild(e)}document.body.appendChild(r)}});const Ri="core/inlines",Ei={},Ai=e=>new RegExp(e.map((e=>e.source)).join("|")),Li=Wn({en:{rfc2119Keywords:()=>Ai([/\bMUST(?:\s+NOT)?\b/,/\bSHOULD(?:\s+NOT)?\b/,/\bSHALL(?:\s+NOT)?\b/,/\bMAY\b/,/\b(?:NOT\s+)?REQUIRED\b/,/\b(?:NOT\s+)?RECOMMENDED\b/,/\bOPTIONAL\b/])},de:{rfc2119Keywords:()=>Ai([/\bMUSS\b/,/\bMÜSSEN\b/,/\bERFORDERLICH\b/,/\b(?:NICHT\s+)?NÖTIG\b/,/\bDARF(?:\s+NICHT)?\b/,/\bDÜRFEN(?:\s+NICHT)?\b/,/\bVERBOTEN\b/,/\bSOLL(?:\s+NICHT)?\b/,/\bSOLLEN(?:\s+NICHT)?\b/,/\b(?:NICHT\s+)?EMPFOHLEN\b/,/\bKANN\b/,/\bKÖNNEN\b/,/\bOPTIONAL\b/])}}),Ti=/(?:`[^`]+`)(?!`)/,Pi=/(?:{{[^}]+\?*}})/,Ii=/\B\|\w[\w\s]*(?:\s*:[\w\s&;"?<>]+\??)?\|\B/,Di=/(?:\[\[(?:!|\\|\?)?[\w.-]+(?:|[^\]]+)?\]\])/,Ni=/(?:\[\[\[(?:!|\\|\?)?#?[\w-.]+\]\]\])/,ji=/(?:\[=[^=]+=\])/,Oi=/(?:\[\^[^^]+\^\])/;function zi(e){const t=e.slice(2,-2).trim(),[n,r,s]=t.split("/",3).map((e=>e&&e.trim())).filter((e=>!!e)),[o,i,a]=t.startsWith("/")?["element-attr",null,n]:s?["attr-value",`${n}/${r}`,s]:r?["element-attr",n,r]:["element",null,n];return kn`${a}`}function Mi(e){const t=qn(e),n=kn`${t}`;return Ei[t]=!0,n}function qi(e){const t=e.slice(3,-3).trim();return t.startsWith("#")?kn``:kn``}function Wi(e,t){const n=qn(e.slice(2,-2));if(n.startsWith("\\"))return e.replace("\\","");const r=si(n);return!!t.parentElement.closest("dfn,a")?Vi(`\`${r.textContent}\``):r}function Ui(e,t,n){const r=e.slice(2,-2);if(r.startsWith("\\"))return[`[[${r.slice(1)}]]`];const[s,o]=r.split("|").map(qn),{type:i,illegal:a}=Qn(s,t.parentElement),c=xi(s,o),l=s.replace(/^(!|\?)/,"");if(a&&!n.normativeReferences.has(l)){const e=c.childNodes[1]||c;ur("Normative references in informative sections are not allowed. ",Ri,{elements:[e],hint:`Remove '!' from the start of the reference \`[[${r}]]\``})}return"informative"!==i||a?n.normativeReferences.add(l):n.informativeReferences.add(l),c.childNodes[1]?c.childNodes:[c]}function Fi(e,t,n){return"ABBR"===t.parentElement.tagName?e:kn`${e}`}function Bi(e){const t=e.slice(1,-1).split(":",2),[n,r]=t.map((e=>e.trim()));return kn`${n}`}function Hi(e){const t=function(e){const t=e=>e.replace("%%","/").split("/").map(qn).join("/"),n=e.replace("\\/","%%"),r=n.lastIndexOf("/");if(-1===r)return[t(n)];const s=n.substring(0,r),o=n.substring(r+1,n.length);return[t(s),t(o)]}(e=e.slice(2,-2)),[n,r]=2===t.length?t:[null,t[0]],[s,o]=r.includes("|")?r.split("|",2).map((e=>e.trim())):[null,r],i=Gi(o),a=n?qn(n):null;return kn`${i}`}function Vi(e){const t=e.slice(1,-1);return kn`${t}`}function Gi(e){return Ti.test(e)?e.split(/(`[^`]+`)(?!`)/).map((e=>e.startsWith("`")?Vi(e):Gi(e))):document.createTextNode(e)}var Yi=Object.freeze({__proto__:null,name:Ri,rfc2119Usage:Ei,run:function(e){const t=new Map;document.normalize(),document.querySelector("section#conformance")||document.body.classList.add("informative"),e.normativeReferences=new rr,e.informativeReferences=new rr,e.respecRFC2119||(e.respecRFC2119=Ei);const n=document.querySelectorAll("abbr[title]:not(.exclude)");for(const{textContent:e,title:r}of n){const n=qn(e),s=qn(r);t.set(n,s)}const r=t.size?new RegExp(`(?:\\b${[...t.keys()].join("\\b)|(?:\\b")}\\b)`):null,s=function(e,t=[],n={wsNodes:!0}){const r=t.join(", "),s=document.createNodeIterator(e,NodeFilter.SHOW_TEXT,(e=>n.wsNodes||e.data.trim()?r&&e.parentElement.closest(r)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT)),o=[];let i;for(;i=s.nextNode();)o.push(i);return o}(document.body,["#respec-ui",".head","pre","svg","script","style"],{wsNodes:!1}),o=Li.rfc2119Keywords(),i=new RegExp(`(${Ai([o,Pi,Ii,Di,Ni,ji,Ti,Oi,...r?[r]:[]]).source})`);for(const n of s){const r=n.data.split(i);if(1===r.length)continue;const s=document.createDocumentFragment();let a=!0;for(const i of r)if(a=!a,a)switch(!0){case i.startsWith("{{"):s.append(Wi(i,n));break;case i.startsWith("[[["):s.append(qi(i));break;case i.startsWith("[["):s.append(...Ui(i,n,e));break;case i.startsWith("|"):s.append(Bi(i));break;case i.startsWith("[="):s.append(Hi(i));break;case i.startsWith("`"):s.append(Vi(i));break;case i.startsWith("[^"):s.append(zi(i));break;case t.has(i):s.append(Fi(i,n,t));break;case o.test(i):s.append(Mi(i))}else s.append(i);n.replaceWith(s)}}});const Ki="w3c/conformance",Zi=Wn({en:{conformance:"Conformance",normativity:"As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.",keywordInterpretation:(e,t)=>kn`
+ The key word${t?"s":""} ${e} in this document
+ ${t?"are":"is"} to be interpreted as described in
+ BCP 14
+ ${xi("RFC2119")} ${xi("RFC8174")}
+ when, and only when, ${t?"they appear":"it appears"} in all
+ capitals, as shown here.
+
`},de:{conformance:"Anforderungen",normativity:"Neben den explizit als nicht-normativ gekennzeichneten Abschnitten sind auch alle Diagramme, Beispiele und Hinweise in diesem Dokument nicht normativ. Alle anderen Angaben sind normativ.",keywordInterpretation:(e,t)=>kn`
+ ${t?"Die Schlüsselwörter":"Das Schlüsselwort"} ${e} in
+ diesem Dokument ${t?"sind":"ist"} gemäß
+ BCP 14
+ ${xi("RFC2119")} ${xi("RFC8174")}
+ und unter Berücksichtigung von
+ 2119de
+ zu interpretieren, wenn und nur wenn ${t?"sie":"es"} wie hier
+ gezeigt durchgehend groß geschrieben wurde${t?"n":""}.
+
+ ${n.length?Zi.keywordInterpretation(r,s):null}
+ `;e.prepend(...o.childNodes)}(t,e),!t&&Object.keys(Ei).length){ur("Document uses RFC2119 keywords but lacks a conformance section.",Ki,{hint:'Please add a ``.'})}}});function Qi(e,t,n,r){try{switch(t){case"element-attr":return document.createAttribute(e),!0;case"element":return document.createElement(e),!0}}catch(s){lr(`Invalid ${t} name "${e}": ${s.message}`,r,{hint:`Check that the ${t} name is allowed per the XML's Name production for ${t}.`,elements:[n]})}return!1}function Xi(e,t,n,r){if(/^[a-z]+(-[a-z]+)*$/i.test(e))return!0;return lr(`Invalid ${t} name "${e}".`,r,{hint:`Check that the ${t} name is allowed per the naming rules for this type.`,elements:[n]}),!1}const ea=new ar;function ta(e,t){for(const n of t)ea.has(n)||ea.set(n,new Set),ea.get(n).add(e)}const na="core/dfn",ra=new Map([["abstract-op",{requiresFor:!1}],["attr-value",{requiresFor:!0,associateWith:"a markup attribute",validator:Xi}],["element",{requiresFor:!1,validator:Qi}],["element-attr",{requiresFor:!1,validator:Qi}],["element-state",{requiresFor:!0,associateWith:"a markup attribute",validator:Xi}],["event",{requiresFor:!1,validator:Xi}],["http-header",{requiresFor:!1}],["media-type",{requiresFor:!1,validator:function(e,t,n,r){try{const t=new _n(e);if(t.toString()!==e)throw new Error(`Input doesn't match its canonical form: "${t}".`)}catch(s){return lr(`Invalid ${t} "${e}": ${s.message}.`,r,{hint:"Check that the MIME type has both a type and a sub-type, and that it's in a canonical form (e.g., `text/plain`).",elements:[n]}),!1}return!0}}],["scheme",{requiresFor:!1,validator:Xi}],["permission",{requiresFor:!1,validator:function(e,t,n,r){return e.startsWith('"')&&e.endsWith('"')?Xi(e.slice(1,-1),t,n,r):(lr(`Invalid ${t} "${e}".`,r,{hint:`Check that the ${t} is quoted with double quotes.`,elements:[n]}),!1)}}]]),sa=[...ra.keys()];function oa(e,t){let n="";switch(!0){case sa.some((t=>e.classList.contains(t))):n=[...e.classList].find((e=>ra.has(e))),function(e,t,n){const r=ra.get(t);if(r.requiresFor&&!n.dataset.dfnFor){const e=gr`Definition of type "\`${t}\`" requires a ${"[data-dfn-for]"} attribute.`,{associateWith:s}=r,o=gr`Use a ${"[data-dfn-for]"} attribute to associate this with ${s}.`;lr(e,na,{hint:o,elements:[n]})}r.validator&&r.validator(e,t,n,na)}(t,n,e);break;case Fo.test(t):n=function(e,t){t.dataset.hasOwnProperty("idl")||(t.dataset.idl="");const n=t.closest("[data-dfn-for]");t!==n&&n?.dataset.dfnFor&&(t.dataset.dfnFor=n.dataset.dfnFor);if(!t.dataset.dfnFor){const n=gr`Use a ${"[data-dfn-for]"} attribute to associate this dfn with a WebIDL interface.`;lr(`Internal slot "${e}" must be associated with a WebIDL interface.`,na,{hint:n,elements:[t]})}t.matches(".export, [data-export]")||(t.dataset.noexport="");const r=e.endsWith(")")?"method":"attribute";if(!t.dataset.dfnType)return r;const s=["attribute","method"],{dfnType:o}=t.dataset;if(!s.includes(o)||r!==o){const n=gr`Invalid ${"[data-dfn-type]"} attribute on internal slot.`,o=`The only allowed types are: ${fr(s,{quotes:!0})}. The slot "${e}" seems to be a "${pr(r)}"?`;return lr(n,na,{hint:o,elements:[t]}),"dfn"}return o}(t,e)}if(!n&&!e.matches("[data-dfn-type]")){const t=e.closest("[data-dfn-type]");n=t?.dataset.dfnType}n&&!e.dataset.dfnType&&(e.dataset.dfnType=n)}function ia(e){switch(!0){case e.matches(".export.no-export"):lr(gr`Declares both "${"[no-export]"}" and "${"[export]"}" CSS class.`,na,{elements:[e],hint:"Please use only one."});break;case e.matches(".no-export, [data-noexport]"):if(e.matches("[data-export]")){lr(gr`Declares ${"[no-export]"} CSS class, but also has a "${"[data-export]"}" attribute.`,na,{elements:[e],hint:"Please chose only one."}),delete e.dataset.export}e.dataset.noexport="";break;case e.matches(":is(.export):not([data-noexport], .no-export)"):e.dataset.export=""}}var aa=Object.freeze({__proto__:null,name:na,run:function(){for(const e of document.querySelectorAll("dfn")){const t=Zn(e);if(ta(e,t),e.dataset.cite&&/\b#\b/.test(e.dataset.cite))continue;const[n]=t;oa(e,n),ia(e);const r=(e.dataset.localLt||"").split("|").map(qn),s=t.filter((e=>!r.includes(e)));(s.length>1||n!==qn(e.textContent))&&(e.dataset.lt=s.join("|"))}}});var ca=Object.freeze({__proto__:null,name:"core/pluralize",run:function(e){if(!e.pluralize)return;const t=function(){const e=new Set;document.querySelectorAll("a:not([href])").forEach((t=>{const n=qn(t.textContent).toLowerCase();e.add(n),t.dataset.lt&&e.add(t.dataset.lt)}));const t=new Set,n=document.querySelectorAll("dfn:not([data-lt-noDefault])");return n.forEach((e=>{const n=qn(e.textContent).toLowerCase();t.add(n),e.dataset.lt&&e.dataset.lt.split("|").forEach((e=>t.add(e))),e.dataset.localLt&&e.dataset.localLt.split("|").forEach((e=>t.add(e)))})),function(n){const r=qn(n).toLowerCase(),s=Cn.isSingular(r)?Cn.plural(r):Cn.singular(r);return e.has(s)&&!t.has(s)?s:""}}();document.querySelectorAll("dfn:not([data-lt-no-plural]):not([data-lt-noDefault])").forEach((e=>{const n=[e.textContent];e.dataset.lt&&n.push(...e.dataset.lt.split("|")),e.dataset.localLt&&n.push(...e.dataset.localLt.split("|"));const r=new Set(n.map(t).filter((e=>e)));if(r.size){const t=e.dataset.plurals?e.dataset.plurals.split("|"):[],n=[...new Set([...t,...r])];e.dataset.plurals=n.join("|"),ta(e,n)}}))}});var la=String.raw`span.example-title{text-transform:none}
+:is(aside,div).example,div.illegal-example{padding:.5em;margin:1em 0;position:relative;clear:both}
+div.illegal-example{color:red}
+div.illegal-example p{color:#000}
+aside.example div.example{border-left-width:.1em;border-color:#999;background:#fff}`;const ua=Wn({en:{example:"Example"},nl:{example:"Voorbeeld"},es:{example:"Ejemplo"},ko:{example:"예시"},ja:{example:"例"},de:{example:"Beispiel"},zh:{example:"例"},cs:{example:"Příklad"}});function da(e,t,n){n.title=e.title,n.title&&e.removeAttribute("title");const r=t>0?` ${t}`:"",s=n.title?kn`: ${n.title}`:"";return kn`
`;Kn(a,"example",r||String(t));a.querySelector("a.self-link").href=`#${a.id}`,e.replaceWith(a)}}))}});var fa=String.raw`.issue-label{text-transform:initial}
+.warning>p:first-child{margin-top:0}
+.warning{padding:.5em;border-left-width:.5em;border-left-style:solid}
+span.warning{padding:.1em .5em .15em}
+.issue.closed span.issue-number{text-decoration:line-through}
+.issue.closed span.issue-number::after{content:" (Closed)";font-size:smaller}
+.warning{border-color:#f11;border-color:var(--warning-border,#f11);border-width:.2em;border-style:solid;background:#fbe9e9;background:var(--warning-bg,#fbe9e9);color:#000;color:var(--text,#000)}
+.warning-title:before{content:"⚠";font-size:1.3em;float:left;padding-right:.3em;margin-top:-.3em}
+li.task-list-item{list-style:none}
+input.task-list-item-checkbox{margin:0 .35em .25em -1.6em;vertical-align:middle}
+.issue a.respec-gh-label{padding:5px;margin:0 2px 0 2px;font-size:10px;text-transform:none;text-decoration:none;font-weight:700;border-radius:4px;position:relative;bottom:2px;border:none;display:inline-block}`;const ha="core/issues-notes",ma=Wn({en:{editors_note:"Editor's note",feature_at_risk:"(Feature at Risk) Issue",issue:"Issue",issue_summary:"Issue summary",no_issues_in_spec:"There are no issues listed in this specification.",note:"Note",warning:"Warning"},ja:{note:"注",editors_note:"編者注",feature_at_risk:"(変更の可能性のある機能) Issue",issue:"Issue",issue_summary:"Issue の要約",no_issues_in_spec:"この仕様には未解決の issues は含まれていません.",warning:"警告"},nl:{editors_note:"Redactionele noot",issue_summary:"Lijst met issues",no_issues_in_spec:"Er zijn geen problemen vermeld in deze specificatie.",note:"Noot",warning:"Waarschuwing"},es:{editors_note:"Nota de editor",issue:"Cuestión",issue_summary:"Resumen de la cuestión",note:"Nota",no_issues_in_spec:"No hay problemas enumerados en esta especificación.",warning:"Aviso"},de:{editors_note:"Redaktioneller Hinweis",issue:"Frage",issue_summary:"Offene Fragen",no_issues_in_spec:"Diese Spezifikation enthält keine offenen Fragen.",note:"Hinweis",warning:"Warnung"},zh:{editors_note:"编者注",feature_at_risk:"(有可能变动的特性)Issue",issue:"Issue",issue_summary:"Issue 总结",no_issues_in_spec:"本规范中未列出任何 issue。",note:"注",warning:"警告"},cs:{editors_note:"Poznámka editora",feature_at_risk:"(Funkce v ohrožení) Problém",issue:"Problém",issue_summary:"Souhrn problémů",no_issues_in_spec:"V této specifikaci nejsou uvedeny žádné problémy.",note:"Poznámka",warning:"Varování"}});function ga(e,t,n){const r=function(){if(document.querySelector(".issue[data-number]"))return e=>{if(e.dataset.number)return Number(e.dataset.number)};let e=0;return t=>{if(t.classList.contains("issue")&&"span"!==t.localName)return++e}}(),s=document.createElement("ul");e.forEach((e=>{const{type:o,displayType:i,isFeatureAtRisk:a}=function(e){const t=e.classList.contains("issue"),n=e.classList.contains("warning"),r=e.classList.contains("ednote"),s=e.classList.contains("atrisk"),o=t?"issue":n?"warning":r?"ednote":"note",i=t?s?ma.feature_at_risk:ma.issue:n?ma.warning:r?ma.editors_note:ma.note;return{type:o,displayType:i,isFeatureAtRisk:s}}(e),c="issue"===o,l="span"===e.localName,{number:u}=e.dataset,d={title:e.title,number:r(e)};if(!l){const r=kn``,l=document.createElement("span"),p=kn`
${l}
`;Kn(p,"h",o);let f,h=i;if(e.id?(r.id=e.id,e.removeAttribute("id")):Kn(r,"issue-container",d.number?`number-${d.number}`:""),c){if(void 0!==d.number&&(h+=` ${d.number}`),e.dataset.hasOwnProperty("number")){const e=function(e,t,{isFeatureAtRisk:n=!1}={}){if(!n&&t.issueBase)return kn``;if(n&&t.atRiskBase)return kn``}(u,n,{isFeatureAtRisk:a});if(e&&(l.before(e),e.append(l)),l.classList.add("issue-number"),f=t.get(u),!f){ur(`Failed to fetch issue number ${u}.`,ha)}f&&!d.title&&(d.title=f.title)}s.append(function(e,t,n){const r=`${e}${t.number?` ${t.number}`:""}`,s=t.title?kn`: ${t.title}`:"";return kn`
`),t.appendChild(n));else if(t){ur("Using best practices summary (#bp-summary) but no best practices found.",ya),t.remove()}}});const xa="core/figures",_a=Wn({en:{list_of_figures:"List of Figures",fig:"Figure "},ja:{fig:"図 ",list_of_figures:"図のリスト"},ko:{fig:"그림 ",list_of_figures:"그림 목록"},nl:{fig:"Figuur ",list_of_figures:"Lijst met figuren"},es:{fig:"Figura ",list_of_figures:"Lista de Figuras"},zh:{fig:"图 ",list_of_figures:"规范中包含的图"},de:{fig:"Abbildung",list_of_figures:"Abbildungsverzeichnis"}});var Ca=Object.freeze({__proto__:null,name:xa,run:function(){const e=function(){const e=[];return document.querySelectorAll("figure").forEach(((t,n)=>{const r=t.querySelector("figcaption");if(r)!function(e,t,n){const r=t.textContent;Kn(e,"fig",r),Xn(t,kn``),t.prepend(kn`${_a.fig}${n+1}`," ")}(t,r,n),e.push(function(e,t){const n=t.cloneNode(!0);return n.querySelectorAll("a").forEach((e=>{Jn(e,"span").removeAttribute("href")})),kn`
` without a ``.",xa,{elements:[t]})}})),e}(),t=document.getElementById("tof");e.length&&t&&(!function(e){if(e.classList.contains("appendix")||e.classList.contains("introductory")||e.closest("section"))return;const t=er(e);t.every((e=>e.classList.contains("introductory")))?e.classList.add("introductory"):t.some((e=>e.classList.contains("appendix")))&&e.classList.add("appendix")}(t),t.append(kn`
${_a.list_of_figures}
`,kn`
+ ${e}
+
`))}});const Sa=Wn({en:{list_of_tables:"List of Tables",table:"Table "}});var Ra=Object.freeze({__proto__:null,name:"core/tables",run:function(){const e=function(){const e=[],t=document.querySelectorAll("table.numbered");return[...t].filter((e=>!!e.querySelector("caption"))).forEach(((t,n)=>{const r=t.querySelector("caption");!function(e,t,n){const r=t.textContent;Kn(e,"table",r),Xn(t,kn``),t.prepend(kn`${Sa.table}${n+1}`," ")}(t,r,n),e.push(function(e,t){const n=t.cloneNode(!0);for(const e of n.querySelectorAll("a"))Jn(e,"span",{copyAttributes:!1});return kn`
`}()}
+ `;e.append(r);for(const e of r.querySelectorAll(".index-term"))Kn(e,"index-term");vr("toc",Oc,{once:!0}),vr("beforesave",Uc)}});const Bc="core/contrib";var Hc=Object.freeze({__proto__:null,name:Bc,run:async function(e){if(!document.getElementById("gh-contributors"))return;if(!e.github){return void lr(gr`Requested list of contributors from GitHub, but ${"[github]"} configuration option is not set.`,Bc)}const t=e.editors.map((e=>e.name)),n=`${e.github.apiBase}/${e.github.fullName}/`;await async function(e,t){const n=document.getElementById("gh-contributors");if(!n)return;n.textContent="Fetching list of contributors...";const r=await s();null!==r?function(e,t){const n=e.sort(((e,t)=>{const n=e.name||e.login,r=t.name||t.login;return n.toLowerCase().localeCompare(r.toLowerCase())}));if("UL"===t.tagName)return void kn(t)`${n.map((({name:e,login:t})=>`
`))}`;const r=n.map((e=>e.name||e.login));t.textContent=On(r)}(r,n):n.textContent="Failed to fetch contributors.";async function s(){const{href:n}=new URL("contributors",t);try{const t=await Hn(n);if(!t.ok)throw new Error(`Request to ${n} failed with status code ${t.status}`);return(await t.json()).filter((t=>!e.includes(t.name||t.login)&&!t.login.includes("[bot]")))}catch(e){return lr("Error loading contributors from GitHub.",Bc,{cause:e}),null}}}(t,n)}});var Vc=Object.freeze({__proto__:null,name:"core/fix-headers",run:function(){[...document.querySelectorAll("section:not(.introductory)")].map((e=>e.querySelector("h1, h2, h3, h4, h5, h6"))).filter((e=>e)).forEach((e=>{const t=Math.min(function(e,t){const n=[];for(;e!=e.ownerDocument.body;)e.matches(t)&&n.push(e),e=e.parentElement;return n}(e,"section").length+1,6);Jn(e,`h${t}`)}))}});var Gc=Object.freeze({__proto__:null,name:"core/webidl-index",run:function(){const e=document.querySelector("section#idl-index");if(!e)return;const t=[2,3,4,5,6].map((e=>`h${e}:first-child`)).join(",");if(!e.querySelector(t)){const t=document.createElement("h2");e.title?(t.textContent=e.title,e.removeAttribute("title")):t.textContent="IDL Index",e.prepend(t)}const n=Array.from(document.querySelectorAll("pre.idl:not(.exclude) > code")).filter((e=>!e.closest(Tn)));if(0===n.length){const t="This specification doesn't normatively declare any Web IDL.";return void e.append(t)}const r=document.createElement("pre");r.classList.add("idl","def"),r.id="actual-idl-index",n.map((e=>{const t=document.createDocumentFragment();for(const n of e.children)t.appendChild(n.cloneNode(!0));return t})).forEach((e=>{r.lastChild&&r.append("\n\n"),r.appendChild(e)})),r.querySelectorAll("*[id]").forEach((e=>e.removeAttribute("id"))),e.appendChild(r),Xn(r,document.createElement("code")),Ya(r)}});const Yc=["h2","h3","h4","h5","h6"],Kc="core/structure",Zc=Wn({en:{toc:"Table of Contents",back_to_top:"Back to Top"},zh:{toc:"内容大纲",back_to_top:"返回顶部"},ko:{toc:"목차",back_to_top:"맨 위로"},ja:{toc:"目次",back_to_top:"先頭に戻る"},nl:{toc:"Inhoudsopgave",back_to_top:"Terug naar boven"},es:{toc:"Tabla de Contenidos",back_to_top:"Volver arriba"},de:{toc:"Inhaltsverzeichnis",back_to_top:"Zurück nach oben"},cs:{toc:"Obsah",back_to_top:"Zpět na začátek"}});function Jc(e,t,{prefix:n=""}={}){let r=!1,s=0,o=1;if(n.length&&!n.endsWith(".")&&(n+="."),0===e.length)return null;const i=kn``;for(const a of e){!a.isAppendix||n||r||(s=o,r=!0);let e=a.isIntro?"":r?Qc(o-s+1):n+o;const c=e.split(".").length;if(1===c&&(e+=".",a.header.before(document.createComment("OddPage"))),a.isIntro||(o+=1,a.header.prepend(kn`${e} `)),c<=t){const n=a.header.id||a.element.id,r=el(a.header,n),s=Jc(a.subsections,t,{prefix:e});s&&r.append(s),i.append(r)}}return i}function Qc(e){let t="";for(;e>0;)e-=1,t=String.fromCharCode(65+e%26)+t,e=Math.floor(e/26);return t}function Xc(e){const t=e.querySelectorAll(":scope > section"),n=[];for(const e of t){const t=e.classList.contains("notoc");if(!e.children.length||t)continue;const r=e.children[0];if(!Yc.includes(r.localName))continue;const s=r.textContent;Kn(e,null,s),n.push({element:e,header:r,title:s,isIntro:Boolean(e.closest(".introductory")),isAppendix:e.classList.contains("appendix"),subsections:Xc(e)})}return n}function el(e,t){const n=kn``;var r;return n.append(...e.cloneNode(!0).childNodes),(r=n).querySelectorAll("a").forEach((e=>{const t=Jn(e,"span");t.className="formerLink",t.removeAttribute("href")})),r.querySelectorAll("dfn").forEach((e=>{Jn(e,"span").removeAttribute("id")})),kn`
${n}
`}var tl=Object.freeze({__proto__:null,name:Kc,run:function(e){if("maxTocLevel"in e==!1&&(e.maxTocLevel=1/0),function(){const e=[...document.querySelectorAll("section:not(.introductory) :is(h1,h2,h3,h4,h5,h6):first-child")].filter((e=>!e.closest("section.introductory")));if(!e.length)return;e.forEach((e=>{const t=`h${Math.min(tr(e,"section").length+1,6)}`;e.localName!==t&&Jn(e,t)}))}(),!e.noTOC){!function(){const e=document.querySelectorAll("section[data-max-toc]");for(const t of e){const e=parseInt(t.dataset.maxToc,10);if(e<0||e>6||Number.isNaN(e)){lr("`data-max-toc` must have a value between 0-6 (inclusive).",Kc,{elements:[t]});continue}if(0===e){t.classList.add("notoc");continue}const n=t.querySelectorAll(`:scope > ${Array.from({length:e},(()=>"section")).join(" > ")}`);for(const e of n)e.classList.add("notoc")}}();const t=Jc(Xc(document.body),e.maxTocLevel);t&&function(e){if(!e)return;const t=kn``,n=kn`
`;document.body.append(s)}(t)}wr("toc")}});const nl=Wn({en:{informative:"This section is non-normative."},nl:{informative:"Dit onderdeel is niet normatief."},ko:{informative:"이 부분은 비규범적입니다."},ja:{informative:"この節は仕様には含まれません."},de:{informative:"Dieser Abschnitt ist nicht normativ."},zh:{informative:"本章节不包含规范性内容。"},cs:{informative:"Tato sekce není normativní."}});var rl=Object.freeze({__proto__:null,name:"core/informative",run:function(){Array.from(document.querySelectorAll("section.informative")).map((e=>e.querySelector("h2, h3, h4, h5, h6"))).filter((e=>e)).forEach((e=>{e.after(kn`
${nl.informative}
`)}))}});const sl=Wn({en:{permalinkLabel(e,t){let n=`Permalink for${t?"":" this"} ${e}`;return t&&(n+=` ${qn(t.textContent)}`),n}}});var ol=Object.freeze({__proto__:null,name:"core/id-headers",run:function(e){const t=document.querySelectorAll("section:not(.head,#abstract,#sotd) h2, h3, h4, h5, h6");for(const n of t){let t=n.id;if(t||(Kn(n),t=n.parentElement.id||n.id),!e.addSectionLinks)continue;const r=sl.permalinkLabel(n.closest(".appendix")?"Appendix":"Section",n.querySelector(":scope > bdi.secno")),s=kn``;n.replaceWith(s);const o=kn``;s.append(n,o)}}});var il=String.raw`.caniuse-stats{display:flex;column-gap:2em}
+.caniuse-group{display:flex;flex:1;flex-direction:column;justify-content:flex-end;flex-basis:auto}
+.caniuse-browsers{display:flex;align-items:baseline;justify-content:space-between;flex-wrap:wrap;margin-top:.2em;column-gap:.4em;border-bottom:1px solid #ccc;row-gap:.4em;padding-bottom:.4cm}
+.caniuse-type{align-self:center;border-top:none;text-transform:capitalize;font-size:.8em;margin-top:-.8em;font-weight:700}
+.caniuse-type span{background-color:var(--bg,#fff);padding:0 .4em}
+.caniuse-cell{align-items:center;border-radius:1cm;color:#fff;display:flex;font-size:90%;min-width:1.5cm;padding:.3rem;justify-content:space-evenly;--supported:#2a8436dd;--no-support:#c44230dd;--no-support-alt:#b43b2bdd;--partial:#807301dd;--partial-alt:#746c00dd;--unknown:#757575;background:repeating-linear-gradient(var(--caniuse-angle,45deg),var(--caniuse-bg) 0,var(--caniuse-bg-alt) 1px,var(--caniuse-bg-alt) .4em,var(--caniuse-bg) calc(.25em + 1px),var(--caniuse-bg) .75em)}
+img.caniuse-browser{filter:drop-shadow(0 0 .1cm #666);background:0 0}
+.caniuse-cell span.browser-version{margin-left:.4em;text-shadow:0 0 .1em #fff;font-weight:100;font-size:.9em}
+.caniuse-stats a[href]{white-space:nowrap;align-self:flex-end}
+.caniuse-cell.y{background:var(--supported)}
+.caniuse-cell:is(.n,.d){--caniuse-angle:45deg;--caniuse-bg:var(--no-support);--caniuse-bg-alt:var(--no-support-alt)}
+.caniuse-cell.u{background:var(--unknown)}
+.caniuse-cell.d{--caniuse-angle:180deg}
+.caniuse-cell:is(.a,.x,.p){--caniuse-angle:90deg;--caniuse-bg:var(--partial);--caniuse-bg-alt:var(--partial-alt)}
+@media print{
+.caniuse-cell.y::before{content:"✔️";padding:.5em}
+.caniuse-cell.n::before{content:"❌";padding:.5em}
+.caniuse-cell:is(.a,.d,.p,.x,.u)::before{content:"⚠️";padding:.5em}
+}`;const al="core/caniuse",cl="https://respec.org/caniuse/",ll=new Map([["and_chr",{name:"Android Chrome",path:"chrome",type:"mobile"}],["and_ff",{name:"Android Firefox",path:"firefox",type:"mobile"}],["and_uc",{name:"Android UC",path:"uc",type:"mobile"}],["chrome",{name:"Chrome",type:"desktop"}],["edge",{name:"Edge",type:"desktop"}],["firefox",{name:"Firefox",type:"desktop"}],["ios_saf",{name:"iOS Safari",path:"safari-ios",type:"mobile"}],["op_mob",{name:"Opera Mobile",path:"opera",type:"mobile"}],["opera",{name:"Opera",type:"desktop"}],["safari",{name:"Safari",type:"desktop"}],["samsung",{name:"Samsung Internet",path:"samsung-internet",type:"mobile"}]]),ul=new Map([["a","almost supported (aka Partial support)"],["d","disabled by default"],["n","no support, or disabled by default"],["p","no support, but has Polyfill"],["u","unknown support"],["x","requires prefix to work"],["y","supported by default"]]);var dl=Object.freeze({__proto__:null,BROWSERS:ll,name:al,prepare:function(e){if(!e.caniuse)return;!function(e){const t=new Set(ll.keys());t.delete("op_mob"),t.delete("opera");const n={removeOnSave:!0,browsers:[...t]};if("string"==typeof e.caniuse)return void(e.caniuse={feature:e.caniuse,...n});e.caniuse={...n,...e.caniuse}}(e),function({caniuse:e}){const{browsers:t}=e,n=t.filter((e=>!ll.has(e)));if(n.length){ur(gr`Invalid browser(s): (${hr(n,{quotes:!0})}) in the \`browser\` property of ${"[caniuse]"}.`,al)}}(e);const t=e.caniuse;t.feature&&document.head.appendChild(kn``)},run:async function(e){const t=e.caniuse;if(!t?.feature)return;const n=new URL(t.feature,"https://caniuse.com/").href,r=document.querySelector(".head dl"),s=async function(e){const{feature:t,browsers:n,apiURL:r}=e,s=new URL(r||`./${t}`,cl);n.forEach((e=>s.searchParams.append("browsers",e)));const o=await fetch(s);if(!o.ok){const{status:e,statusText:t}=o;throw new Error(`Failed to get caniuse data: (${e}) ${t}`)}return o.json()}(e.caniuse).then((e=>async function(e,{feature:t}){const n=e.result,r=new Map([["desktop",[]],["mobile",[]]]),s=function(e){return(t,{browser:n,version:r,caniuse:s})=>{const{name:o,type:i}=ll.get(n),a=`${o}${r?` version ${r}`:""}`,c=ul.get(s),l=`${e} is ${c} since ${a} on ${i}.`,u=`caniuse-cell ${s}`,d=(p=`${c} since ${a}.`).charAt(0).toUpperCase()+p.slice(1);var p;const f=r||"—",h=function(e){const t=ll.get(e).path??e;return`https://www.w3.org/assets/logos/browser-logos/${t}/${t}.svg`}(n),m=kn`
+
`));return o.push(kn`More info`),o}(e,t))).catch((e=>function(e,t,n){const r=`Failed to retrieve feature "${t.feature}".`,s=gr`Please check the feature key on [caniuse.com](https://caniuse.com) and update ${"[caniuse]"}.`;return lr(r,al,{hint:s,cause:e}),kn`caniuse.com`}(e,t,n))),o=kn`
Browser support:
+
+ ${{any:s,placeholder:"Fetching data from caniuse.com..."}}
+
`;r.append(...o.childNodes),await s,wr("amend-user-config",{caniuse:t.feature}),t.removeOnSave&&(r.querySelectorAll(".caniuse-browser").forEach((e=>e.classList.add("removeOnSave"))),vr("beforesave",(e=>{kn.bind(e.querySelector(".caniuse-stats"))`
+ caniuse.com`})))}});var pl=String.raw`.mdn{font-size:.75em;position:absolute;right:.3em;min-width:0;margin-top:3rem}
+.mdn details{width:100%;margin:1px 0;position:relative;z-index:10;box-sizing:border-box;padding:.4em;padding-top:0}
+.mdn details[open]{min-width:25ch;max-width:32ch;background:#fff;background:var(--indextable-hover-bg,#fff);color:#000;color:var(--indextable-hover-text,#000);box-shadow:0 1em 3em -.4em rgba(0,0,0,.3),0 0 1px 1px rgba(0,0,0,.05);box-shadow:0 1em 3em -.4em var(--tocsidebar-shadow,rgba(0,0,0,.3)),0 0 1px 1px var(--tocsidebar-shadow,rgba(0,0,0,.05));border-radius:2px;z-index:11;margin-bottom:.4em}
+.mdn summary{text-align:right;cursor:default;margin-right:-.4em}
+.mdn summary span{font-family:zillaslab,Palatino,"Palatino Linotype",serif;color:#fff;color:var(--bg,#fff);background-color:#000;background-color:var(--text,#000);display:inline-block;padding:3px}
+.mdn a{display:inline-block;word-break:break-all}
+.mdn p{margin:0}
+.mdn .engines-all{color:#058b00}
+.mdn .engines-some{color:#b00}
+.mdn table{width:100%;font-size:.9em}
+.mdn td{border:none}
+.mdn td:nth-child(2){text-align:right}
+.mdn .nosupportdata{font-style:italic;margin:0}
+.mdn tr::before{content:"";display:table-cell;width:1.5em;height:1.5em;background:no-repeat center center/contain;font-size:.75em}
+.mdn .no,.mdn .unknown{color:#ccc;filter:grayscale(100%)}
+.mdn .no::before,.mdn .unknown::before{opacity:.5}
+.mdn .chrome::before,.mdn .chrome_android::before{background-image:url(https://www.w3.org/assets/logos/browser-logos/chrome/chrome.svg)}
+.mdn .edge::before,.mdn .edge_mobile::before{background-image:url(https://www.w3.org/assets/logos/browser-logos/edge/edge.svg)}
+.mdn .firefox::before,.mdn .firefox_android::before{background-image:url(https://www.w3.org/assets/logos/browser-logos/firefox/firefox.svg)}
+.mdn .opera::before,.mdn .opera_android::before{background-image:url(https://www.w3.org/assets/logos/browser-logos/opera/opera.svg)}
+.mdn .safari::before{background-image:url(https://www.w3.org/assets/logos/browser-logos/safari/safari.svg)}
+.mdn .safari_ios::before{background-image:url(https://www.w3.org/assets/logos/browser-logos/safari-ios/safari-ios.svg)}
+.mdn .samsunginternet_android::before{background-image:url(https://www.w3.org/assets/logos/browser-logos/samsung-internet/samsung-internet.svg)}
+.mdn .webview_android::before{background-image:url(https://www.w3.org/assets/logos/browser-logos/android-webview/android-webview.png)}`;const fl="core/mdn-annotation",hl="https://w3c.github.io/mdn-spec-links/",ml="https://developer.mozilla.org/en-US/docs/Web/",gl={chrome:"Chrome",chrome_android:"Chrome Android",edge:"Edge",edge_mobile:"Edge Mobile",firefox:"Firefox",firefox_android:"Firefox Android",opera:"Opera",opera_android:"Opera Android",safari:"Safari",safari_ios:"Safari iOS",samsunginternet_android:"Samsung Internet",webview_android:"WebView Android"},bl=Wn({en:{inAllEngines:"This feature is in all major engines.",inSomeEngines:"This feature has limited support."},zh:{inAllEngines:"所有主要引擎均支持此特性。",inSomeEngines:"此功能支持有限。"},cs:{inAllEngines:"Tato funkce je podporována ve všech hlavních prohlížečích.",inSomeEngines:"Tato funkce má omezenou podporu."}});function yl(e){const t=e.closest("section");if(!t)return;const{previousElementSibling:n}=t;if(n&&n.classList.contains("mdn"))return n;const r=kn``;return t.before(r),r}function wl(e){const{name:t,slug:n,summary:r,support:s,engines:o}=e,i=n.slice(n.indexOf("/")+1),a=`${ml}${n}`,c=`Expand MDN details for ${t}`,l=function(e){if(3===e.length)return kn`✅`;if(e.length<2)return kn`🚫`;return kn``}(o);return kn`
+ MDN${l}
+ ${i}
+ ${function(e){if(3===e.length)return kn`
`}
+ `}var vl=Object.freeze({__proto__:null,name:fl,run:async function(e){const t=function(e){const{shortName:t,mdn:n}=e;if(!n)return;return"string"==typeof n?n:n.key||t}(e);if(!t)return;const n=await async function(e,t){const{baseJsonPath:n=hl,maxAge:r=864e5}=t,s=new URL(`${e}.json`,n).href,o=await Hn(s,r);if(404===o.status){return void lr(`Could not find MDN data associated with key "${e}".`,fl,{hint:"Please add a valid key to `respecConfig.mdn`"})}return await o.json()}(t,e.mdn);if(!n)return;const r=document.createElement("style");r.textContent=pl,document.head.append(r);for(const e of function(e){return[...document.body.querySelectorAll("[id]:not(script)")].filter((({id:t})=>Array.isArray(e[t])))}(n)){const t=n[e.id],r=yl(e);if(r)for(const e of t)r.append(wl(e))}}});const kl="ui/save-html",$l=Wn({en:{save_snapshot:"Export"},nl:{save_snapshot:"Bewaar Snapshot"},ja:{save_snapshot:"保存する"},de:{save_snapshot:"Exportieren"},zh:{save_snapshot:"导出"}}),xl=[{id:"respec-save-as-html",ext:"html",title:"HTML",type:"text/html",get href(){return xr(this.type)}},{id:"respec-save-as-xml",ext:"xhtml",title:"XML",type:"application/xml",get href(){return xr(this.type)}},{id:"respec-save-as-epub",ext:"epub",title:"EPUB 3",type:"application/epub+zip",get href(){const e=new URL("https://labs.w3.org/r2epub/");return e.searchParams.append("respec","true"),e.searchParams.append("url",document.location.href),e.href}}];var _l=Object.freeze({__proto__:null,exportDocument:function(e,t){return ur("Exporting via ui/save-html module's `exportDocument()` is deprecated and will be removed.",kl,{hint:"Use core/exporter `rsDocToDataURL()` instead."}),xr(t)},name:kl,run:function(e){const t={async show(t){await document.respec.ready;const n=kn`
+ `}var zl=Object.freeze({__proto__:null});var Ml=Object.freeze({__proto__:null,name:"core/seo",run:function(e){if(e.gitRevision){const t=kn``;document.head.appendChild(t)}const t=document.querySelector("#abstract p:first-of-type");if(!t)return;const n=t.textContent.replace(/\s+/," ").trim(),r=document.createElement("meta");r.name="description",r.content=n,document.head.appendChild(r)}});const ql="w3c/seo",Wl={NOTE:"w3p:NOTE",WD:"w3p:WD",LC:"w3p:LastCall",CR:"w3p:CR",CRD:"w3p:CRD",PR:"w3p:PR",REC:"w3p:REC",RSCND:"w3p:RSCND"},Ul=new Set([...Os,...zs,...Ms,"BG-FINAL","CG-FINAL","CRY","DRY","draft-finding","finding"]);function Fl({name:e,url:t,mailto:n,company:r,companyURL:s}){const o={type:"Person",name:e,url:t,"foaf:mbox":n};return(r||s)&&(o.worksFor={name:r,url:s}),o}function Bl(e){const{href:t,title:n,href:r}=e,s={id:t,type:"TechArticle",name:n,url:r};return e.authors&&(s.creator=e.authors.map((e=>({name:e})))),e.rawDate&&(s.publishedDate=e.rawDate),e.isbn&&(s.identifier=e.isbn),e.publisher&&(s.publisher={name:e.publisher}),s}var Hl=Object.freeze({__proto__:null,name:ql,requiresCanonicalLink:Ul,run:async function(e){if((e.canonicalURI||Ul.has(e.specStatus))&&e.shortName){switch(e.canonicalURI){case"edDraft":if(e.edDraftURI)e.canonicalURI=new URL(e.edDraftURI,document.location.href).href;else{ur("Canonical URI set to edDraft, but no edDraftURI is set in configuration",ql),e.canonicalURI=null}break;case"TR":if(e.latestVersion)e.canonicalURI=e.latestVersion;else{ur("Canonical URI set to TR, but no shortName is set in configuration",ql),e.canonicalURI=null}break;default:e.latestVersion&&!e.canonicalURI&&(e.canonicalURI=e.latestVersion)}if(e.canonicalURI){const t=kn``;document.head.appendChild(t)}e.doJsonLd&&await async function(e,t){const n=Wl[e.specStatus],r=["TechArticle"];n&&r.push(n);const s={"@context":["http://schema.org",{"@vocab":"http://schema.org/","@language":t.documentElement.lang||"en",w3p:"http://www.w3.org/2001/02pd/rec54#",foaf:"http://xmlns.com/foaf/0.1/",datePublished:{"@type":"http://www.w3.org/2001/XMLSchema#date"},inLanguage:{"@language":null},isBasedOn:{"@type":"@id"},license:{"@type":"@id"}}],id:e.canonicalURI||e.thisVersion,type:r,name:document.title,inLanguage:t.documentElement.lang||"en",license:e.licenseInfo?.url,datePublished:e.dashDate,copyrightHolder:{name:"World Wide Web Consortium",url:"https://www.w3.org/"},discussionUrl:e.issueBase,alternativeHeadline:e.subtitle,isBasedOn:e.prevVersion};if(e.additionalCopyrightHolders){const t=Array.isArray(e.additionalCopyrightHolders)?e.additionalCopyrightHolders:[e.additionalCopyrightHolders];s.copyrightHolder=[s.copyrightHolder,...t.map((e=>({name:e})))]}const o=t.head.querySelector("meta[name=description]");o&&(s.description=o.content);e.editors&&(s.editor=e.editors.map(Fl));e.authors&&(s.contributor=e.authors.map(Fl));const i=[...e.normativeReferences,...e.informativeReferences],a=await Promise.all(i.map((e=>hi(e))));s.citation=a.filter((e=>"object"==typeof e)).map(Bl);const c=t.createElement("script");c.type="application/ld+json",c.textContent=JSON.stringify(s,null,2),t.head.appendChild(c)}(e,document)}}});var Vl=String.raw`.hljs{--base:#fafafa;--mono-1:#383a42;--mono-2:#686b77;--mono-3:#717277;--hue-1:#0b76c5;--hue-2:#336ae3;--hue-3:#a626a4;--hue-4:#42803c;--hue-5:#ca4706;--hue-5-2:#c91243;--hue-6:#986801;--hue-6-2:#9a6a01}
+@media (prefers-color-scheme:dark){
+.hljs{--base:#282c34;--mono-1:#abb2bf;--mono-2:#818896;--mono-3:#5c6370;--hue-1:#56b6c2;--hue-2:#61aeee;--hue-3:#c678dd;--hue-4:#98c379;--hue-5:#e06c75;--hue-5-2:#be5046;--hue-6:#d19a66;--hue-6-2:#e6c07b}
+}
+.hljs{display:block;overflow-x:auto;padding:.5em;color:#383a42;color:var(--mono-1,#383a42);background:#fafafa;background:var(--base,#fafafa)}
+.hljs-comment,.hljs-quote{color:#717277;color:var(--mono-3,#717277);font-style:italic}
+.hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4;color:var(--hue-3,#a626a4)}
+.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#ca4706;color:var(--hue-5,#ca4706);font-weight:700}
+.hljs-literal{color:#0b76c5;color:var(--hue-1,#0b76c5)}
+.hljs-addition,.hljs-attribute,.hljs-meta-string,.hljs-regexp,.hljs-string{color:#42803c;color:var(--hue-4,#42803c)}
+.hljs-built_in,.hljs-class .hljs-title{color:#9a6a01;color:var(--hue-6-2,#9a6a01)}
+.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801;color:var(--hue-6,#986801)}
+.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#336ae3;color:var(--hue-2,#336ae3)}
+.hljs-emphasis{font-style:italic}
+.hljs-strong{font-weight:700}
+.hljs-link{text-decoration:underline}`;async function Gl(t){const n=await fetch(new URL(`../../${t}`,e&&"SCRIPT"===e.tagName.toUpperCase()&&e.src||new URL("respec-w3c.js",document.baseURI).href));return await n.text()}const Yl=Pn({hint:"preload",href:"https://www.w3.org/Tools/respec/respec-highlight",as:"script"});document.head.appendChild(Yl);const Kl=async function(){const e=await async function(){try{return(await Promise.resolve().then((function(){return Pd}))).default}catch{return Gl("worker/respec-worker.js")}}(),t=URL.createObjectURL(new Blob([e],{type:"application/javascript"}));return new Worker(t)}();n("core/worker",Kl.then((e=>({worker:e}))));const Zl=function(e,t=0){const n=function*(e,t){for(;;)yield`${e}:${t}`,t++}(e,t);return()=>n.next().value}("highlight");async function Jl(e){e.setAttribute("aria-busy","true");const t=(n=e.classList,Array.from(n).filter((e=>"highlight"!==e&&"nolinks"!==e)).map((e=>e.toLowerCase())));var n;let r;try{r=await async function(e,t){const n={action:"highlight",code:e,id:Zl(),languages:t},r=await Kl;return r.postMessage(n),new Promise(((e,t)=>{const s=setTimeout((()=>{t(new Error("Timed out waiting for highlight."))}),4e3);r.addEventListener("message",(function t(o){const{data:{id:i,language:a,value:c}}=o;i===n.id&&(r.removeEventListener("message",t),clearTimeout(s),e({language:a,value:c}))}))}))}(e.innerText,t)}catch(e){return void console.error(e)}const{language:s,value:o}=r;switch(e.localName){case"pre":e.classList.remove(s),e.innerHTML=`${o}`,e.classList.length||e.removeAttribute("class");break;case"code":e.innerHTML=o,e.classList.add("hljs"),s&&e.classList.add(s)}e.setAttribute("aria-busy","false")}var Ql=Object.freeze({__proto__:null,name:"core/highlight",run:async function(e){if(e.noHighlightCSS)return;const t=[...document.querySelectorAll("\n pre:not(.idl):not(.nohighlight) > code:not(.nohighlight),\n pre:not(.idl):not(.nohighlight),\n code.highlight\n ")].filter((e=>"pre"!==e.localName||!e.querySelector("code")));if(!t.length)return;const n=t.filter((e=>e.textContent.trim())).map(Jl);document.head.appendChild(kn``),await Promise.all(n)}});const Xl=Wn({en:{missing_test_suite_uri:gr`Found tests in your spec, but missing ${"[testSuiteURI]"} in your ReSpec config.`,tests:"tests",test:"test"},ja:{missing_test_suite_uri:gr`この仕様内にテストの項目を検出しましたが,ReSpec の設定に ${"[testSuiteURI]"} が見つかりません.`,tests:"テスト",test:"テスト"},de:{missing_test_suite_uri:gr`Die Spezifikation enthält Tests, aber in der ReSpec-Konfiguration ist keine ${"[testSuiteURI]"} angegeben.`,tests:"Tests",test:"Test"},zh:{missing_test_suite_uri:gr`本规范中包含测试,但在 ReSpec 配置中缺少 ${"[testSuiteURI]"}。`,tests:"测试",test:"测试"}}),eu="core/data-tests";function tu(e){const t=[],[n]=new URL(e).pathname.split("/").reverse(),r=n.split(".");let[s]=r;if(r.find((e=>"https"===e))){const e=document.createElement("span");e.textContent="🔒",e.setAttribute("aria-label","requires a secure connection"),e.setAttribute("title","Test requires HTTPS"),s=s.replace(".https",""),t.push(e)}if(s.split(".").join("-").split("-").find((e=>"manual"===e))){const e=document.createElement("span");e.textContent="💪",e.setAttribute("aria-label","the test must be run manually"),e.setAttribute("title","Manual test"),s=s.replace("-manual",""),t.push(e)}return kn`
+
`}))}(e))).catch((e=>lr(e.message,Eu,{elements:[this],cause:e}))).finally((()=>{this.dispatchEvent(new CustomEvent("done"))})),placeholder:"Loading list of commits..."}}
+
+ `}};async function Lu(e,t,n){let r;try{const s=await mo;if(!s)throw new Error("`respecConfig.github` is not set");const o=new URL("commits",`${s.apiBase}/${s.fullName}/`);o.searchParams.set("from",e),o.searchParams.set("to",t);const i=await fetch(o.href);if(!i.ok)throw new Error(`Request to ${o} failed with status code ${i.status}`);if(r=await i.json(),!r.length)throw new Error(`No commits between ${e}..${t}.`);r=r.filter(n)}catch(e){const t=`Error loading commits from GitHub. ${e.message}`;throw new Error(t,{cause:e})}return r}const Tu=[Object.freeze({__proto__:null,element:Au,name:Eu})];var Pu=Object.freeze({__proto__:null,name:"core/custom-elements/index",run:async function(){Tu.forEach((e=>{customElements.define(e.name,e.element)}));const e=Tu.map((e=>e.name)).join(", "),t=[...document.querySelectorAll(e)].map((e=>new Promise((t=>e.addEventListener("done",t,{once:!0})))));await Promise.all(t)}});var Iu=Object.freeze({__proto__:null,name:"core/web-monetization",run:function(e){if(!1===e.monetization)return;const{monetization:t}=e,{removeOnSave:n,paymentPointer:r}=function(e){const t={paymentPointer:"$respec.org",removeOnSave:!0};switch(typeof e){case"string":t.paymentPointer=e;break;case"object":e.paymentPointer&&(t.paymentPointer=String(e.paymentPointer)),!1===e.removeOnSave&&(t.removeOnSave=!1)}return t}(t),s=n?"removeOnSave":null;document.head.append(kn``)}});var Du=Object.freeze({__proto__:null,name:"core/dfn-contract",run:function(){!function(){const e=document.querySelectorAll("dfn:is([data-dfn-type=''],:not([data-dfn-type]))");for(const t of e)t.dataset.dfnType="dfn";const t=document.querySelectorAll("dfn:not([data-noexport], [data-export], [data-dfn-type='dfn'], [data-cite])");for(const e of t)e.dataset.export=""}(),function(){const e=document.querySelectorAll("dl.definitions dt:has(dfn[data-dfn-type])");for(const t of e){const e=t.querySelector("dfn[data-dfn-type]").id,n=t.nextElementSibling;n&&!n.dataset.defines&&e&&(n.dataset.defines=`#${e}`)}const t=document.querySelectorAll(".definition:has(dfn[data-dfn-type])");for(const e of t){const t=e.querySelector("dfn[data-dfn-type]");t.id&&!e.dataset.defines&&(e.dataset.defines=`#${t.id}`)}}()}});const Nu="core/before-save";var ju=Object.freeze({__proto__:null,name:Nu,run:function(e){if(e.beforeSave)if(Array.isArray(e.beforeSave)&&!e.beforeSave.some((e=>"function"!=typeof e||"AsyncFunction"===e.constructor.name)))vr("beforesave",(t=>{!function(e,t){let n=0;for(const r of e)try{r(t)}catch(e){lr(gr`Function ${`\`${r.name}\``||`at position ${n}`}\` threw an error during processing of ${"[beforeSave]"}.`,Nu,{hint:"See developer console.",cause:e})}finally{n++}}(e.beforeSave,t.ownerDocument)}),{once:!0});else{lr(gr`${"[beforeSave]"} configuration option must be an array of synchronous JS functions.`,Nu)}}});const Ou="core/linter-rules/check-charset",zu=Wn({en:{msg:"Document must only contain one `` tag with charset set to 'utf-8'",hint:'Add this line in your document `` section - `` or set charset to "utf-8" if not set already.'},zh:{msg:"文档只能包含一个 charset 属性为 utf-8 的 `` 标签",hint:'将此行添加到文档的 `` 部分—— `` 或将 charset 设置为 utf-8(如果尚未设置)。'},cs:{msg:"Dokument smí obsahovat pouze jeden tag `` s charset nastaveným na 'utf-8'",hint:'Přidejte tento řádek do sekce `` vašeho dokumentu - `` nebo nastavte charset na "utf-8", pokud ještě není nastaven.'}});var Mu=Object.freeze({__proto__:null,name:Ou,run:function(e){if(!e.lint?.["check-charset"])return;const t=document.querySelectorAll("meta[charset]"),n=[];for(const e of t)n.push(e.getAttribute("charset").trim().toLowerCase());n.includes("utf-8")&&1===t.length||ur(zu.msg,Ou,{hint:zu.hint,elements:[...t]})}});const qu="core/linter-rules/check-punctuation",Wu=[".",":","!","?"],Uu=Wu.map((e=>`"${e}"`)).join(", "),Fu=Wn({en:{msg:"`p` elements should end with a punctuation mark.",hint:`Please make sure \`p\` elements end with one of: ${Uu}.`},cs:{msg:"Elementy `p` by měly končit interpunkčním znaménkem.",hint:`Ujistěte se, že elementy \`p\` končí jedním z těchto znaků: ${Uu}.`}});var Bu=Object.freeze({__proto__:null,name:qu,run:function(e){if(!e.lint?.["check-punctuation"])return;const t=new RegExp(`[${Wu.join("")}\\]]$|^ *$`,"m"),n=[...document.querySelectorAll("p:not(#back-to-top,#w3c-state)")].filter((e=>!t.test(e.textContent.trim())));n.length&&ur(Fu.msg,qu,{hint:Fu.hint,elements:n})}});const Hu="core/linter-rules/check-internal-slots",Vu=Wn({en:{msg:"Internal slots should be preceded by a '.'",hint:"Add a '.' between the elements mentioned."},cs:{msg:"Interní sloty by měly být uvedeny s tečkou '.' před názvem",hint:"Přidejte tečku '.' mezi uvedené prvky."}});var Gu=Object.freeze({__proto__:null,name:Hu,run:function(e){if(!e.lint?.["check-internal-slots"])return;const t=[...document.querySelectorAll("var+a")].filter((({previousSibling:{nodeName:e}})=>e&&"VAR"===e));t.length&&ur(Vu.msg,Hu,{hint:Vu.hint,elements:t})}});const Yu="core/linter-rules/local-refs-exist",Ku=Wn({en:{msg:"Broken local reference found in document.",hint:"Please fix the links mentioned."},cs:{msg:"V dokumentu byla nalezena nefunkční lokální reference.",hint:"Opravte prosím uvedené odkazy."}});function Zu(e){const t=e.getAttribute("href").substring(1),n=e.ownerDocument;return!n.getElementById(t)&&!n.getElementsByName(t).length}var Ju=Object.freeze({__proto__:null,name:Yu,run:function(e){if(!e.lint?.["local-refs-exist"])return;const t=[...document.querySelectorAll("a[href^='#']")].filter(Zu);t.length&&ur(Ku.msg,Yu,{hint:Ku.hint,elements:t})}});const Qu="core/linter-rules/no-captionless-tables",Xu=Wn({en:{msg:"All tables marked with class='numbered' must start with a caption element.",hint:"Add a `caption` to the offending table."},cs:{msg:"Všechny tabulky označené class='numbered' musí začínat elementem caption.",hint:"Přidejte k dané tabulce element `caption`."}});var ed=Object.freeze({__proto__:null,name:Qu,run:function(e){if(!e.lint?.["no-captionless-tables"])return;const t=[...document.querySelectorAll("table.numbered")].filter((e=>!(e.firstElementChild instanceof HTMLTableCaptionElement)));t.length&&ur(Xu.msg,Qu,{hint:Xu.hint,elements:t})}});const td="no-unused-dfns",nd="core/linter-rules/no-unused-dfns",rd=Wn({en:{msg:e=>`Found definition for "${e}", but nothing links to it. This is usually a spec bug!`,get hint(){return gr`
+ You can do one of the following...
+
+ * Add a \`class="lint-ignore"\` attribute the definition.
+ * Either remove the definition or change \`\` to another type of HTML element.
+ * If you meant to ${"[export|#data-export]"} the definition, add \`class="export"\` to the definition.
+
+ To silence this warning entirely, set \`lint: { "no-unused-dfns": false }\` in your \`respecConfig\`.`}},cs:{msg:e=>`Nalezena definice pro "${e}", ale nic na ni neodkazuje. Toto je obvykle chyba ve specifikaci!`,get hint(){return gr`
+ Můžete udělat jedno z následujícího...
+
+ * Přidejte k definici atribut \`class="lint-ignore"\`.
+ * Definici buď odstraňte, nebo změňte \`\` na jiný typ HTML elementu.
+ * Pokud jste chtěli ${"[export|#data-export]"} tuto definici, přidejte k ní \`class="export"\`.
+
+ Pro úplné potlačení tohoto varování nastavte \`lint: { "no-unused-dfns": false }\` ve vaší \`respecConfig\`.`}}});function sd(e){return!document.querySelector(`a[href="#${e.id}"]:not(.index-term, .self-link)`)}var od=Object.freeze({__proto__:null,name:nd,run:function(e){if(!e.lint?.[td])return;const t="error"===e.lint[td]?lr:ur;[...document.querySelectorAll("dfn:not(.lint-ignore, [data-export], [data-cite])")].filter(sd).forEach((e=>{const n=[e],r=qn(e.textContent);t(rd.msg(r),nd,{elements:n,hint:rd.hint})}))}});const id="core/linter-rules/no-headingless-sections",ad=Wn({en:{msg:"All sections must start with a `h2-6` element.",hint:"Add a `h2-6` to the offending section or use a `
`."},nl:{msg:"Alle secties moeten beginnen met een `h2-6` element.",hint:"Voeg een `h2-6` toe aan de conflicterende sectie of gebruik een `
`。"},cs:{msg:"Všechny sekce musí začínat elementem `h2-6`.",hint:"Přidejte do problematické sekce `h2-6` nebo použijte `
`."}});var cd=Object.freeze({__proto__:null,name:id,run:function(e){if(!e.lint?.["no-headingless-sections"])return;const t=[...document.querySelectorAll("section:not(.head,#abstract,#sotd)")].filter((({firstElementChild:e})=>!e||!(e.matches(".header-wrapper")||e instanceof HTMLHeadingElement)));t.length&&ur(ad.msg,id,{hint:ad.hint,elements:t})}});const ld="core/linter-rules/no-unused-vars",ud=Wn({en:{msg:"Variable was defined, but never used.",hint:"Add a `data-ignore-unused` attribute to the ``."},cs:{msg:"Proměnná byla definována, ale nikdy nebyla použita.",hint:"Přidejte atribut `data-ignore-unused` k elementu ``."}});var dd=Object.freeze({__proto__:null,name:ld,run:function(e){if(!e.lint?.["no-unused-vars"])return;const t=[],n=e=>!!e.querySelector(":scope > :not(section) ~ .algorithm, :scope > :not(section) .algorithm");for(const e of document.querySelectorAll("section")){if(!n(e))continue;const r=e.querySelectorAll(":scope > :not(section) var");if(!r.length)continue;const s=new Map;for(const e of r){const t=qn(e.textContent);(s.get(t)||s.set(t,[]).get(t)).push(e)}for(const e of s.values())1!==e.length||e[0].hasAttribute("data-ignore-unused")||t.push(e[0])}t.length&&ur(ud.msg,ld,{hint:ud.hint,elements:t})}});const pd="required-sections",fd="w3c/linter-rules/required-sections",hd={en:{msg:e=>`W3C Recommendation track documents require a separate "${e}" section.`,hint:e=>gr`Add a \`\` with a "${e}" header. See the [Horizontal review guidelines](https://www.w3.org/Guide/documentreview/#how_to_get_horizontal_review).
+ If the document is not intended for the W3C Recommendation track, set ${"[noRecTrack]"} to \`true\`
+ or turn off the ${`[${pd}]`} linter rule.`,privacy_considerations:"Privacy Considerations",security_considerations:"Security Considerations"},es:{msg:e=>`Documentos que van a ser "W3C Recommendation" requieren una sección "${e}" separada.`,hint:e=>gr`Agrega una \`\` con título "${e}". Ver los [Horizontal review guidelines](https://www.w3.org/Guide/documentreview/#how_to_get_horizontal_review).
+ Si el documento no está destinado a ser un W3C Recommendation, puedes poner ${"[noRecTrack]"} a \`true\`
+ o apaga la regla de linter ${`[${pd}]`}.`,privacy_considerations:"Consideraciones de privacidad",security_considerations:"Consideraciones de Seguridad"},cs:{msg:e=>`Dokumenty na "W3C Recommendation track" vyžadují samostatnou sekci "${e}".`,hint:e=>gr`Přidejte \`\` s nadpisem "${e}". Viz [Horizontal review guidelines](https://www.w3.org/Guide/documentreview/#how_to_get_horizontal_review).
+ Pokud dokument není určen pro "W3C Recommendation track", nastavte ${"[noRecTrack]"} na \`true\`
+ nebo vypněte linter pravidlo ${`[${pd}]`}.
+ `,privacy_considerations:"Zásady ochrany soukromí",security_considerations:"Zásady bezpečnosti"}},md=Wn(hd),gd=new Set([...zs]);gd.delete("DISC"),Os.forEach((e=>gd.delete(e)));var bd=Object.freeze({__proto__:null,name:fd,requiresSomeSectionStatus:gd,run:function(e){if(!e.lint?.[pd])return;if(!Un(hd,"privacy_considerations")){return void ur("Cannot check for required sections as translations are not available.",fd,{hint:"File an issue to add translations or use a supported language."})}if(e.noRecTrack||!gd.has(e.specStatus))return;const t="error"===e.lint[pd]?lr:ur,n=new rr([md.privacy_considerations,md.security_considerations]),r=document.querySelectorAll("h2, h3, h4, h5, h6");for(const e of r){const t=e.cloneNode(!0);t.querySelectorAll("bdi")?.forEach((e=>e.remove()));const r=qn(t.textContent);if(n.has(r)&&(n.delete(r),0===n.size))return}for(const e of n)t(md.msg(e),fd,{hint:md.hint(e)})}});const yd="core/linter-rules/wpt-tests-exist",wd=Wn({en:{msg:"The following test could not be found in Web Platform Tests:",hint:"Check [wpt.live](https://wpt.live) to see if it was deleted or renamed."},cs:{msg:"Následující test nebyl nalezen ve Web Platform Tests:",hint:"Zkontrolujte [wpt.live](https://wpt.live), zda nebyl smazán nebo přejmenován."}});var vd=Object.freeze({__proto__:null,name:yd,run:async function(e){if(!e.lint?.["wpt-tests-exist"])return;const t=await async function(e,t){let n;try{const t=new URL(e);if(t.pathname.startsWith("/web-platform-tests/wpt/tree/master/")){const e=/web-platform-tests\/wpt\/tree\/master\/(.+)/;n=t.pathname.match(e)[1].replace(/\//g,"")}else n=t.pathname.replace(/\//g,"")}catch(e){return ur("Failed to parse WPT directory from testSuiteURI",`linter/${yd}`),console.error(e),null}const r=new URL("web-platform-tests/wpt/files",`${t}/`);r.searchParams.set("path",n);const s=await fetch(r);if(!s.ok){return ur(`Failed to fetch files from WPT repository. Request failed with error: ${await s.text()} (${s.status})`,`linter/${yd}`),null}const{entries:o}=await s.json(),i=o.filter((e=>!e.endsWith("/")));return new Set(i)}(e.testSuiteURI,e.githubAPI);if(!t)return;const n=[...document.querySelectorAll("[data-tests]")].filter((e=>e.dataset.tests));for(const e of n)e.dataset.tests.split(/,/gm).map((e=>e.trim().split(/\?|#/)[0])).filter((e=>e&&!t.has(e))).map((t=>{ur(`${wd.msg} \`${t}\`.`,yd,{hint:wd.hint,elements:[e]})}))}});const kd="core/linter-rules/no-http-props",$d=Wn({en:{msg:gr`Insecure URLs are not allowed in ${"[respecConfig]"}.`,hint:"Please change the following properties to 'https://': "},zh:{msg:gr`${"[respecConfig]"} 中不允许使用不安全的URL.`,hint:"请将以下属性更改为 https://:"},cs:{msg:gr`V ${"[respecConfig]"} nejsou povoleny nezabezpečené URL adresy.`,hint:"Změňte prosím následující vlastnosti na 'https://': "}});var xd=Object.freeze({__proto__:null,name:kd,run:function(e){if(!e.lint?.["no-http-props"])return;if(!parent.location.href.startsWith("http"))return;const t=Object.getOwnPropertyNames(e).filter((t=>t.endsWith("URI")&&e[t]||"prevED"===t)).filter((t=>new URL(e[t],parent.location.href).href.startsWith("http://")));if(t.length){const e=On(t,(e=>gr`${`[${e}]`}`));ur($d.msg,kd,{hint:$d.hint+e})}}});const _d="core/linter-rules/a11y",Cd=["color-contrast","landmark-one-main","landmark-unique","region"];function Sd(e){const t=[];for(const n of e.split("\n\n")){const[e,...r]=n.split(/^\s{2}/m),s=r.map((e=>`- ${e.trimEnd()}`)).join("\n");t.push(`${e}${s}`)}return t.join("\n\n")}var Rd=Object.freeze({__proto__:null,name:_d,run:async function(e){if(!e.lint?.a11y&&!e.a11y)return;const t=e.lint?.a11y||e.a11y,n=!0===t?{}:t,r=await async function(e){const{rules:t,...n}=e,r={rules:{...Object.fromEntries(Cd.map((e=>[e,{enabled:!1}]))),...t},...n,elementRef:!0,resultTypes:["violations"],reporter:"v1"};let s;try{s=await function(){const e=document.createElement("script");return e.classList.add("remove"),e.src="https://cdn.jsdelivr.net/npm/axe-core@4/axe.min.js",document.head.appendChild(e),new Promise(((t,n)=>{e.onload=()=>t(window.axe),e.onerror=n}))}()}catch(e){return lr("Failed to load a11y linter.",_d),console.error(e),[]}try{return(await s.run(document,r)).violations}catch(e){return lr("Error while looking for a11y issues.",_d),console.error(e),[]}}(n);for(const e of r){const t=new Map;for(const n of e.nodes){const{failureSummary:e,element:r}=n;(t.get(e)||t.set(e,[]).get(e)).push(r)}const{id:n,help:r,description:s,helpUrl:o}=e,i=`a11y/${n}: ${r}.`;for(const[e,n]of t){const t=Sd(e);ur(i,_d,{details:`\n\n${s}.\n\n${t}. ([Learn more](${o}))`,elements:n})}}}});const Ed="informative-dfn",Ad="core/linter-rules/informative-dfn",Ld=Wn({en:{msg:(e,t)=>`Normative reference to "${e}" found but term is defined "informatively" in "${t}".`,get hint(){return gr`
+ You can do one of the following...
+
+ * Get the source definition to be made normative
+ * Add a \`class="lint-ignore"\` attribute to the link.
+ * Use a local normative proxy for the definition à la \`term\`
+
+ To silence this warning entirely, set \`lint: { "${Ed}": false }\` in your \`respecConfig\`.`}},cs:{msg:(e,t)=>`Nalezen normativní odkaz na "${e}", ale pojem je definován pouze informativně v "${t}".`,get hint(){return gr`
+ Můžete udělat jedno z následujícího...
+
+ * Požádejte o to, aby zdrojová definice byla normativní
+ * Přidejte atribut \`class=\"lint-ignore\"\` k odkazu.
+ * Použijte lokální normativní proxy pro definici, např. \`term\`
+
+ Pro úplné potlačení tohoto varování nastavte \`lint: { \"${Ed}\": false }\` ve vaší \`respecConfig\`.`}}});var Td=Object.freeze({__proto__:null,name:Ad,run:function(e){if(!e.lint?.[Ed])return;const t="error"===e.lint[Ed]?lr:ur;xc.forEach((({term:e,spec:n,element:r})=>{r.classList.contains("lint-ignore")||t(Ld.msg(e,n),Ad,{title:"Normative reference to non-normative term.",elements:[r],hint:Ld.hint})}))}}),Pd=Object.freeze({__proto__:null,default:'// ReSpec Worker v1.0.0\n"use strict";\ntry {\n importScripts("https://www.w3.org/Tools/respec/respec-highlight");\n} catch (err) {\n console.error("Network error loading highlighter", err);\n}\n\nself.addEventListener("message", ({ data: originalData }) => {\n const data = Object.assign({}, originalData);\n switch (data.action) {\n case "highlight-load-lang": {\n const { langURL, propName, lang } = data;\n importScripts(langURL);\n self.hljs.registerLanguage(lang, self[propName]);\n break;\n }\n case "highlight": {\n const { code } = data;\n const langs = data.languages.length ? data.languages : undefined;\n try {\n const { value, language } = self.hljs.highlightAuto(code, langs);\n Object.assign(data, { value, language });\n } catch (err) {\n console.error("Could not transform some code?", err);\n // Post back the original code\n Object.assign(data, { value: code, language: "" });\n }\n break;\n }\n }\n self.postMessage(data);\n});\n'}),Id=Object.freeze({__proto__:null,default:'(() => {\n// @ts-check\n\nif (document.respec) {\n document.respec.ready.then(setupVarHighlighter);\n} else {\n setupVarHighlighter();\n}\n\nfunction setupVarHighlighter() {\n document\n .querySelectorAll("var")\n .forEach(varElem => varElem.addEventListener("click", highlightListener));\n}\n\nfunction highlightListener(ev) {\n ev.stopPropagation();\n const { target: varElem } = ev;\n const hightligtedElems = highlightVars(varElem);\n const resetListener = () => {\n const hlColor = getHighlightColor(varElem);\n hightligtedElems.forEach(el => removeHighlight(el, hlColor));\n [...HL_COLORS.keys()].forEach(key => HL_COLORS.set(key, true));\n };\n if (hightligtedElems.length) {\n document.body.addEventListener("click", resetListener, { once: true });\n }\n}\n\n// availability of highlight colors. colors from var.css\nconst HL_COLORS = new Map([\n ["respec-hl-c1", true],\n ["respec-hl-c2", true],\n ["respec-hl-c3", true],\n ["respec-hl-c4", true],\n ["respec-hl-c5", true],\n ["respec-hl-c6", true],\n ["respec-hl-c7", true],\n]);\n\nfunction getHighlightColor(target) {\n // return current colors if applicable\n const { value } = target.classList;\n const re = /respec-hl-\\w+/;\n const activeClass = re.test(value) && value.match(re);\n if (activeClass) return activeClass[0];\n\n // first color preference\n if (HL_COLORS.get("respec-hl-c1") === true) return "respec-hl-c1";\n\n // otherwise get some other available color\n return [...HL_COLORS.keys()].find(c => HL_COLORS.get(c)) || "respec-hl-c1";\n}\n\nfunction highlightVars(varElem) {\n const textContent = norm(varElem.textContent);\n const parent = varElem.closest(".algorithm, section");\n const highlightColor = getHighlightColor(varElem);\n\n const varsToHighlight = [...parent.querySelectorAll("var")].filter(\n el =>\n norm(el.textContent) === textContent &&\n el.closest(".algorithm, section") === parent\n );\n\n // update availability of highlight color\n const colorStatus = varsToHighlight[0].classList.contains("respec-hl");\n HL_COLORS.set(highlightColor, colorStatus);\n\n // highlight vars\n if (colorStatus) {\n varsToHighlight.forEach(el => removeHighlight(el, highlightColor));\n return [];\n } else {\n varsToHighlight.forEach(el => addHighlight(el, highlightColor));\n }\n return varsToHighlight;\n}\n\nfunction removeHighlight(el, highlightColor) {\n el.classList.remove("respec-hl", highlightColor);\n // clean up empty class attributes so they don\'t come in export\n if (!el.classList.length) el.removeAttribute("class");\n}\n\nfunction addHighlight(elem, highlightColor) {\n elem.classList.add("respec-hl", highlightColor);\n}\n\n/**\n * Same as `norm` from src/core/utils, but our build process doesn\'t allow\n * imports in runtime scripts, so duplicated here.\n * @param {string} str\n */\nfunction norm(str) {\n return str.trim().replace(/\\s+/g, " ");\n}\n})()'}),Dd=Object.freeze({__proto__:null,default:'(() => {\n// @ts-check\nif (document.respec) {\n document.respec.ready.then(setupPanel);\n} else {\n setupPanel();\n}\n\nfunction setupPanel() {\n const listener = panelListener();\n document.body.addEventListener("keydown", listener);\n document.body.addEventListener("click", listener);\n}\n\nfunction panelListener() {\n /** @type {HTMLElement} */\n let panel = null;\n return event => {\n const { target, type } = event;\n\n if (!(target instanceof HTMLElement)) return;\n\n // For keys, we only care about Enter key to activate the panel\n // otherwise it\'s activated via a click.\n if (type === "keydown" && event.key !== "Enter") return;\n\n const action = deriveAction(event);\n\n switch (action) {\n case "show": {\n hidePanel(panel);\n /** @type {HTMLElement} */\n const dfn = target.closest("dfn, .index-term");\n panel = document.getElementById(`dfn-panel-for-${dfn.id}`);\n const coords = deriveCoordinates(event);\n displayPanel(dfn, panel, coords);\n break;\n }\n case "dock": {\n panel.style.left = null;\n panel.style.top = null;\n panel.classList.add("docked");\n break;\n }\n case "hide": {\n hidePanel(panel);\n panel = null;\n break;\n }\n }\n };\n}\n\n/**\n * @param {MouseEvent|KeyboardEvent} event\n */\nfunction deriveCoordinates(event) {\n const target = /** @type HTMLElement */ (event.target);\n\n // We prevent synthetic AT clicks from putting\n // the dialog in a weird place. The AT events sometimes\n // lack coordinates, so they have clientX/Y = 0\n const rect = target.getBoundingClientRect();\n if (\n event instanceof MouseEvent &&\n event.clientX >= rect.left &&\n event.clientY >= rect.top\n ) {\n // The event probably happened inside the bounding rect...\n return { x: event.clientX, y: event.clientY };\n }\n\n // Offset to the middle of the element\n const x = rect.x + rect.width / 2;\n // Placed at the bottom of the element\n const y = rect.y + rect.height;\n return { x, y };\n}\n\n/**\n * @param {Event} event\n */\nfunction deriveAction(event) {\n const target = /** @type {HTMLElement} */ (event.target);\n const hitALink = !!target.closest("a");\n if (target.closest("dfn:not([data-cite]), .index-term")) {\n return hitALink ? "none" : "show";\n }\n if (target.closest(".dfn-panel")) {\n if (hitALink) {\n return target.classList.contains("self-link") ? "hide" : "dock";\n }\n const panel = target.closest(".dfn-panel");\n return panel.classList.contains("docked") ? "hide" : "none";\n }\n if (document.querySelector(".dfn-panel:not([hidden])")) {\n return "hide";\n }\n return "none";\n}\n\n/**\n * @param {HTMLElement} dfn\n * @param {HTMLElement} panel\n * @param {{ x: number, y: number }} clickPosition\n */\nfunction displayPanel(dfn, panel, { x, y }) {\n panel.hidden = false;\n // distance (px) between edge of panel and the pointing triangle (caret)\n const MARGIN = 20;\n\n const dfnRects = dfn.getClientRects();\n // Find the `top` offset when the `dfn` can be spread across multiple lines\n let closestTop = 0;\n let minDiff = Infinity;\n for (const rect of dfnRects) {\n const { top, bottom } = rect;\n const diffFromClickY = Math.abs((top + bottom) / 2 - y);\n if (diffFromClickY < minDiff) {\n minDiff = diffFromClickY;\n closestTop = top;\n }\n }\n\n const top = window.scrollY + closestTop + dfnRects[0].height;\n const left = x - MARGIN;\n panel.style.left = `${left}px`;\n panel.style.top = `${top}px`;\n\n // Find if the panel is flowing out of the window\n const panelRect = panel.getBoundingClientRect();\n const SCREEN_WIDTH = Math.min(window.innerWidth, window.screen.width);\n if (panelRect.right > SCREEN_WIDTH) {\n const newLeft = Math.max(MARGIN, x + MARGIN - panelRect.width);\n const newCaretOffset = left - newLeft;\n panel.style.left = `${newLeft}px`;\n /** @type {HTMLElement} */\n const caret = panel.querySelector(".caret");\n caret.style.left = `${newCaretOffset}px`;\n }\n\n // As it\'s a dialog, we trap focus.\n // TODO: when
+`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`${n}>
+`}strong({tokens:e}){return`${this.parser.parseInline(e)}`}em({tokens:e}){return`${this.parser.parseInline(e)}`}codespan({text:e}){return`${w(e,!0)}`}br(e){return" "}del({tokens:e}){return`${this.parser.parseInline(e)}`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=X(e);if(null===i)return r;e=i;let s=""+r+"",s}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=X(e);if(null===i)return w(n);e=i;let s=`",s}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:w(e.text)}},$=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}checkbox({raw:e}){return e}},b=class u{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new P,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new $}static parse(e,t){return new u(t).parse(e)}static parseInline(e,t){return new u(t).parseInline(e)}parse(e){let t="";for(let n=0,r;n{let a=i[s].flat(1/0);n=n.concat(this.walkTokens(a,t))}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||!1,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error("extension name required");if("renderer"in i){let s=t.renderers[i.name];t.renderers[i.name]=s?function(...a){let o=i.renderer.apply(this,a);return!1===o&&(o=s.apply(this,a)),o}:i.renderer}if("tokenizer"in i){if(!i.level||"block"!==i.level&&"inline"!==i.level)throw new Error("extension level must be 'block' or 'inline'");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&("block"===i.level?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:"inline"===i.level&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]))}"childTokens"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens)}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new P(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if(["options","parser"].includes(s))continue;let a=s,o=n.renderer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return!1===c&&(c=l.apply(i,p)),c||""}}r.renderer=i}if(n.tokenizer){let i=this.defaults.tokenizer||new y(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if(["options","rules","lexer"].includes(s))continue;let a=s,o=n.tokenizer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return!1===c&&(c=l.apply(i,p)),c}}r.tokenizer=i}if(n.hooks){let i=this.defaults.hooks||new S;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if(["options","block"].includes(s))continue;let a=s,o=n.hooks[a],l=i[a];i[a]=S.passThroughHooks.has(s)?p=>{if(this.defaults.async&&S.passThroughHooksRespectAsync.has(s))return(async()=>{let g=await o.call(i,p);return l.call(i,g)})();let c=o.call(i,p);return l.call(i,c)}:(...p)=>{if(this.defaults.async)return(async()=>{let g=await o.apply(i,p);return!1===g&&(g=await l.apply(i,p)),g})();let c=o.apply(i,p);return!1===c&&(c=l.apply(i,p)),c}}r.hooks=i}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(a){let o=[];return o.push(s.call(this,a)),i&&(o=o.concat(i.call(this,a))),o}}this.defaults={...this.defaults,...r}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return(n,r)=>{let i={...r},s={...this.defaults,...i},a=this.onError(!!s.silent,!!s.async);if(!0===this.defaults.async&&!1===i.async)return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if("u"{let o=s.hooks?await s.hooks.preprocess(n):n,p=await(s.hooks?await s.hooks.provideLexer():e?x.lex:x.lexInline)(o,s),c=s.hooks?await s.hooks.processAllTokens(p):p;s.walkTokens&&(await Promise.all(this.walkTokens(c,s.walkTokens)));let h=await(s.hooks?await s.hooks.provideParser():e?b.parse:b.parseInline)(c,s);return s.hooks?await s.hooks.postprocess(h):h})().catch(a);try{s.hooks&&(n=s.hooks.preprocess(n));let l=(s.hooks?s.hooks.provideLexer():e?x.lex:x.lexInline)(n,s);s.hooks&&(l=s.hooks.processAllTokens(l)),s.walkTokens&&this.walkTokens(l,s.walkTokens);let c=(s.hooks?s.hooks.provideParser():e?b.parse:b.parseInline)(l,s);return s.hooks&&(c=s.hooks.postprocess(c)),c}catch(o){return a(o)}}}onError(e,t){return n=>{if(n.message+=`
+Please report this to https://github.com/markedjs/marked.`,e){let r="
An error occurred:
"+w(n.message+"",!0)+"
";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}},_=new B;function d(u,e){return _.parse(u,e)}d.options=d.setOptions=function(u){return _.setOptions(u),d.defaults=_.defaults,Z(d.defaults),d},d.getDefaults=L,d.defaults=T,d.use=function(...u){return _.use(...u),d.defaults=_.defaults,Z(d.defaults),d},d.walkTokens=function(u,e){return _.walkTokens(u,e)},d.parseInline=_.parseInline,d.Parser=b,d.parser=b.parse,d.Renderer=P,d.TextRenderer=$,d.Lexer=x,d.lexer=x.lex,d.Tokenizer=y,d.Hooks=S,d.parse=d,d.options,d.setOptions,d.use,d.walkTokens,d.parseInline,b.parse,x.lex;class ExternalReviewer{static get(repo){return"mozilla/standards-positions"===repo?new ExternalReviewer("https://avatars.githubusercontent.com/u/131524?s=48&v=4",{"position: defer":{description:"Defer",variant:"neutral"},"position: negative":{description:"Negative",variant:"danger"},"position: neutral":{description:"Neutral",variant:"neutral"},"position: positive":{description:"Positive",variant:"success"},"position: under consideration":{description:"Under Consideration",variant:"neutral"}}):"WebKit/standards-positions"===repo?new ExternalReviewer("https://avatars.githubusercontent.com/u/6458?s=48&v=4",{"position: oppose":{description:"Oppose",variant:"danger"},"position: neutral":{description:"Neutral",variant:"neutral"},"position: support":{description:"Support",variant:"success"}}):"w3ctag/design-reviews"===repo?new ExternalReviewer("https://avatars.githubusercontent.com/u/3874462?s=48&v=4",{"Resolution: ambivalent":{description:"Ambivalent",variant:"neutral"},"Resolution: decline":{description:"Decline",variant:"neutral"},"Resolution: lack of consensus":{description:"Lack of Consensus",variant:"neutral"},"Resolution: object":{description:"Object",variant:"danger"},"Resolution: out of scope":{description:"Out of Scope",variant:"neutral"},"Resolution: overtaken":{description:"Overtaken",variant:"warning"},"Resolution: satisfied with concerns":{description:"Satisfied with Concerns",variant:"warning"},"Resolution: satisfied":{description:"Satisfied",variant:"success"},"Resolution: timed out":{description:"Timed Out",variant:"warning"},"Resolution: too early":{description:"Too Early",variant:"warning"},"Resolution: unsatisfied":{description:"Unsatisfied",variant:"danger"},"Resolution: validated":{description:"Early Review Validated",variant:"warning"},"Resolution: withdrawn":{description:"Withdrawn",variant:"warning"}}):void 0}label(name){return this._labels[name]}constructor(icon,labels){this.icon=icon,this._labels=labels}}var __decorate$19=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3maxLength?text.substring(0,35)+"..."+text.substring(text.length-15,text.length):text}const _dateTimeFormat=new Intl.DateTimeFormat("en-US",{weekday:"long",year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"numeric"});function enhanceChromeStatusLink(featureLink,text){function _formatTimestamp(timestamp){return _dateTimeFormat.format(new Date(1e3*timestamp))}function renderTooltipContent(){return x$1`
+
+
+ Spec: ${_formatLongText(title)}
+
+
+ `}function enhanceMDNDocsLink(featureLink){return _enhanceLinkWithTitleAndDescription(featureLink,"https://developer.mozilla.org/favicon-48x48.png")}function enhanceMozillaBugLink(featureLink){return _enhanceLinkWithTitleAndDescription(featureLink,"https://bugzilla.mozilla.org/favicon.ico")}function enhanceWebKitBugLink(featureLink){return _enhanceLinkWithTitleAndDescription(featureLink,"https://bugs.webkit.org/images/favicon.ico")}function enhanceGoogleDocsLink(featureLink){const url=featureLink.url,type=url.split("/")[3];let iconUrl="https://ssl.gstatic.com/docs/documents/images/kix-favicon7.ico";return"spreadsheets"===type?iconUrl="https://ssl.gstatic.com/docs/spreadsheets/favicon3.ico":"presentation"===type?iconUrl="https://ssl.gstatic.com/docs/presentations/images/favicon5.ico":"forms"===type&&(iconUrl="https://ssl.gstatic.com/docs/spreadsheets/forms/favicon_qp2.png"),_enhanceLinkWithTitleAndDescription(featureLink,iconUrl)}let ChromedashLink=class ChromedashLink extends i$4{constructor(){super(...arguments),this.showContentAsLabel=!1,this.class="",this.featureLinks=[],this.ignoreHttpErrorCodes=[],this.alwaysInTag=!1}static{this.styles=[...SHARED_STYLES,i$7`
+ :host {
+ display: inline;
+ white-space: normal;
+ line-break: anywhere;
+ color: var(--default-font-color);
+ }
+
+ a:hover {
+ text-decoration: none;
+ }
+
+ sl-badge::part(base) {
+ display: inline;
+ padding: 0 4px;
+ border-width: 0;
+ text-transform: capitalize;
+ font-weight: 400;
+ }
+
+ sl-tag::part(base) {
+ vertical-align: middle;
+ height: 18px;
+ background-color: rgb(232, 234, 237);
+ color: var(--default-font-color);
+ border: none;
+ border-radius: 500px;
+ display: inline-flex;
+ align-items: center;
+ column-gap: 0.3em;
+ padding: 1px 5px;
+ margin: 1px 0;
+ }
+
+ sl-tag::part(base):hover {
+ background-color: rgb(209, 211, 213);
+ }
+
+ sl-relative-time {
+ margin: 0;
+ }
+
+ .icon {
+ display: block;
+ width: 12px;
+ height: 12px;
+ }
+
+ .tooltip {
+ display: flex;
+ flex-direction: column;
+ row-gap: 0.5em;
+ }
+ `]}willUpdate(changedProperties){(changedProperties.has("href")||changedProperties.has("featureLinks"))&&(this._featureLink=this.featureLinks.find(fe=>fe.url===this.href))}fallback(){const slot=x$1`${this.href}`;return x$1`${this.alwaysInTag?x$1`${slot}`:slot}`}withLabel(link){return this.showContentAsLabel?x$1`: ${link}`:link}render(){if(!this.href)return console.error("Missing [href] attribute in",this),x$1``;const featureLink=this._featureLink;if(!featureLink)return this.fallback();if(!featureLink.information)return featureLink.http_error_code&&!this.ignoreHttpErrorCodes.includes(featureLink.http_error_code)?x$1`
+
+
+ ${featureLink.http_error_code}
+
+ ${this.fallback()}
+ `:this.fallback();try{switch(featureLink.type){case LINK_TYPE_CHROMIUM_BUG:return this.withLabel(enhanceChromeStatusLink(featureLink));case LINK_TYPE_GITHUB_ISSUE:return this.withLabel(enhanceGithubIssueLink(featureLink));case LINK_TYPE_GITHUB_PULL_REQUEST:return this.withLabel(enhanceGithubIssueLink(featureLink));case LINK_TYPE_GITHUB_MARKDOWN:return this.withLabel(enhanceGithubMarkdownLink(featureLink));case LINK_TYPE_MDN_DOCS:return this.withLabel(enhanceMDNDocsLink(featureLink));case LINK_TYPE_GOOGLE_DOCS:return this.withLabel(enhanceGoogleDocsLink(featureLink));case LINK_TYPE_MOZILLA_BUG:return this.withLabel(enhanceMozillaBugLink(featureLink));case LINK_TYPE_WEBKIT_BUG:return this.withLabel(enhanceWebKitBugLink(featureLink));case LINK_TYPE_SPECS:return this.withLabel(enhanceSpecsLink(featureLink));default:return this.fallback()}}catch(e){return console.log("feature link render error:",this,e),this.fallback()}}};__decorate$19([n$5({type:String})],ChromedashLink.prototype,"href",void 0),__decorate$19([n$5({type:Boolean})],ChromedashLink.prototype,"showContentAsLabel",void 0),__decorate$19([n$5({type:String})],ChromedashLink.prototype,"class",void 0),__decorate$19([n$5({type:Array})],ChromedashLink.prototype,"featureLinks",void 0),__decorate$19([n$5({type:Array})],ChromedashLink.prototype,"ignoreHttpErrorCodes",void 0),__decorate$19([n$5({type:Boolean})],ChromedashLink.prototype,"alwaysInTag",void 0),__decorate$19([r$6()],ChromedashLink.prototype,"_featureLink",void 0),ChromedashLink=__decorate$19([t$3("chromedash-link")],ChromedashLink);function enhanceUrl(url,featureLinks=[],text){return x$1`${url}`}function enhanceAutolink(part,featureLinks){return x$1`${part.content}`}const CRBUG_DEFAULT_PROJECT="chromium",CRBUG_URL="https://bugs.chromium.org",ISSUE_TRACKER_RE=/(\b(issues?|bugs?)[ \t]*(:|=|\b)|\bfixed[ \t]*:)([ \t]*((\b[-a-z0-9]+)[:\#])?(\#?)(\d+)\b(,?[ \t]*(and|or)?)?)+/gi,PROJECT_LOCALID_RE=/((\b(issue|bug)[ \t]*(:|=)?[ \t]*|\bfixed[ \t]*:[ \t]*)?((\b[-a-z0-9]+)[:\#])?(\#?)(\d+))/gi,PROJECT_COMMENT_BUG_RE=/(((\b(issue|bug)[ \t]*(:|=)?[ \t]*)(\#?)(\d+)[ \t*])?((\b((comment)[ \t]*(:|=)?[ \t]*(\#?))|(\B((\#))(c)))(\d+)))/gi,PROJECT_LOCALID_RE_PROJECT_GROUP=6,PROJECT_LOCALID_RE_ID_GROUP=8,SHORT_LINK_RE=/(^|[^-\/._])\b(https?:\/\/|ftp:\/\/|mailto:)?(go|g|shortn|who|teams)\/([^\s<]+)/gi,NUMERIC_SHORT_LINK_RE=/(^|[^-\/._])\b(https?:\/\/|ftp:\/\/)?(b|t|o|omg|cl|cr|fxr|fxrev|fxb|tqr)\/([0-9]+)/gi,IMPLIED_LINK_RE=/(?!@)(^|[^-\/._])\b[a-z]((-|\.)?[a-z0-9])+\.(com|net|org|edu|dev)\b(\/[^\s<]*)?/gi,IS_LINK_RE=/()\b(https?:\/\/|ftp:\/\/|mailto:)([^\s<]+)/gi,LINK_TRAILING_CHARS=[[null,":"],[null,"."],[null,","],[null,">"],["(",")"],["[","]"],["{","}"],["'","'"],["\"","\""]],GOOG_SHORT_LINK_RE=/^(b|t|o|omg|cl|cr|go|g|shortn|who|teams|fxr|fxrev|fxb|tqr)\/.*/gi,Components=new Map;Components.set("00-commentbug",{refRegs:[PROJECT_COMMENT_BUG_RE],replacer:replaceCommentBugRef}),Components.set("02-full-urls",{refRegs:[IS_LINK_RE],replacer:replaceLinkRef}),Components.set("04-tracker-regular",{refRegs:[ISSUE_TRACKER_RE],replacer:replaceTrackerIssueRef}),Components.set("05-linkify-shorthand",{refRegs:[SHORT_LINK_RE,NUMERIC_SHORT_LINK_RE,IMPLIED_LINK_RE],replacer:replaceLinkRef});function replaceIssueRef(stringMatch,projectName,localId,commentId){return createIssueRefRun(projectName,localId,stringMatch,commentId)}function replaceTrackerIssueRef(match,currentProjectName=CRBUG_DEFAULT_PROJECT){const issueRefRE=PROJECT_LOCALID_RE,commentId="",textRuns=[];let pos=0,refMatch;for(;null!==(refMatch=issueRefRE.exec(match[0]));)refMatch.index>pos&&textRuns.push({content:match[0].slice(pos,refMatch.index)}),refMatch[PROJECT_LOCALID_RE_PROJECT_GROUP]&&(currentProjectName=refMatch[PROJECT_LOCALID_RE_PROJECT_GROUP]),textRuns.push(replaceIssueRef(refMatch[0],currentProjectName,refMatch[PROJECT_LOCALID_RE_ID_GROUP],commentId)),pos=refMatch.index+refMatch[0].length;return""!==match[0].slice(pos)&&textRuns.push({content:match[0].slice(pos)}),textRuns}function replaceCommentBugRef(match){let textRun;const issueNum=match[7],commentNum=match[18];if(issueNum&&commentNum){const href=`${CRBUG_URL}/p/${CRBUG_DEFAULT_PROJECT}/issues/detail?id=${issueNum}#c${commentNum}`;textRun={content:match[0],tag:"a",href}}else if(commentNum){const href=`${CRBUG_URL}/p/${CRBUG_DEFAULT_PROJECT}/issues/detail#c${commentNum}`;textRun={content:match[0],tag:"a",href}}else textRun={content:match[0]};return[textRun]}function replaceLinkRef(match){const textRuns=[];let content=match[0],trailing="";match[1]&&(textRuns.push({content:match[1]}),content=content.slice(match[1].length)),LINK_TRAILING_CHARS.forEach(([begin,end])=>{!content.endsWith(end)||begin&&content.slice(0,-end.length).includes(begin)||(trailing=end+trailing,content=content.slice(0,-end.length))});let href=content;const lowerHref=href.toLowerCase();return lowerHref.startsWith("http")||lowerHref.startsWith("ftp")||lowerHref.startsWith("mailto")||(href=GOOG_SHORT_LINK_RE.test(lowerHref)?"http://"+href:"https://"+href,GOOG_SHORT_LINK_RE.lastIndex=0),textRuns.push({content:content,tag:"a",href:href}),trailing.length&&textRuns.push({content:trailing}),textRuns}function createIssueRefRun(projectName,localId,content,commentId){return{tag:"a",content:content,href:`${CRBUG_URL}/p/${projectName}/issues/detail?id=${localId}${commentId}`}}function markupAutolinks(plainString,featureLinks=[]){plainString=plainString||"";const chunks=[plainString.trim()],textRuns=[];chunks.filter(Boolean).forEach(chunk=>{textRuns.push(...autolinkChunk(chunk))});const result=textRuns.map(part=>"a"===part.tag?enhanceAutolink(part,featureLinks):x$1`${part.content}`);return result}function autolinkChunk(chunk){let textRuns=[{content:chunk}];return Components.forEach(({refRegs,replacer})=>{refRegs.forEach(re=>{textRuns=applyLinks(textRuns,replacer,re)})}),textRuns}function applyLinks(textRuns,replacer,re){const resultRuns=[];return textRuns.forEach(textRun=>{if(textRun.tag)resultRuns.push(textRun);else{const content=textRun.content;let pos=0,match;for(;null!==(match=re.exec(content));)match.index>pos&&resultRuns.push({content:content.slice(pos,match.index)}),resultRuns.push(...replacer(match)),pos=match.index+match[0].length;""!==content.slice(pos)&&resultRuns.push({content:content.slice(pos)})}}),resultRuns}const FEATURE_CATEGORIES={WEBCOMPONENTS:[1,"Web Components"],MISC:[2,"Miscellaneous"],SECURITY:[3,"Security"],MULTIMEDIA:[4,"Multimedia"],DOM:[5,"DOM"],FILE:[6,"File APIs"],OFFLINE:[7,"Offline / Storage"],DEVICE:[8,"Device"],COMMUNICATION:[9,"Realtime / Communication"],JAVASCRIPT:[10,"JavaScript"],NETWORKING:[11,"Network / Connectivity"],INPUT:[12,"User input"],PERFORMANCE:[13,"Performance"],GRAPHICS:[14,"Graphics"],CSS:[15,"CSS"],HOUDINI:[16,"Houdini"],SERVICEWORKER:[17,"Service Worker"],WEBRTC:[18,"WebRTC"],LAYERED:[19,"Layered APIs"],WEBASSEMBLY:[20,"WebAssembly"],CAPABILITIES:[21,"Capabilities (Fugu)"],IWA:[22,"Isolated Web Apps-specific API"]},ENTERPRISE_FEATURE_CATEGORIES={SECURITYANDPRIVACY:[1,"Security / Privacy"],USERPRODUCTIVITYANDAPPS:[2,"User Productivity / Apps"],MANAGEMENT:[3,"Management"]},ENTERPRISE_FEATURE_CATEGORIES_DISPLAYNAME={1:"Security/Privacy",2:"User Productivity/Apps",3:"Management"},PLATFORM_CATEGORIES={PLATFORM_ANDROID:[1,"Android"],PLATFORM_IOS:[2,"iOS"],PLATFORM_CHROMEOS:[3,"ChromeOS"],PLATFORM_LACROS:[4,"LaCrOS",!0],PLATFORM_LINUX:[5,"Linux"],PLATFORM_MAC:[6,"MacOS"],PLATFORM_WINDOWS:[7,"Windows"],PLATFORM_FUCHSIA:[8,"Fuchsia"]},PLATFORMS_DISPLAYNAME={1:"Android",2:"iOS",3:"ChromeOS",4:"LaCrOS",5:"Linux",6:"MacOS",7:"Windows",8:"Fuchsia"},ROLLOUT_STAGE_PLAN_CATEGORIES={ROLLOUT_STAGE_PLAN_SLOW:[0,"Feature rolls out gradually"],ROLLOUT_STAGE_PLAN_TRUSTED_TESTERS:[1,"Early preview available to Chrome Enterprise Truster Testers"],ROLLOUT_STAGE_PLAN_CUSTOM:[2,"Custom rollout (explain in Rollout details field)"]},ROLLOUT_STAGE_PLAN_DISPLAYNAME={0:"Feature rolls out gradually",1:"Early preview available to Chrome Enterprise Truster Testers",2:"Custom rollout (explain in Rollout details field)"},ENTERPRISE_IMPACT_DISPLAYNAME={1:"None",2:"Low",3:"Medium",4:"High"},ENTERPRISE_IMPACT={IMPACT_NONE:[1,"None"],IMPACT_LOW:[2,"Low"],IMPACT_MEDIUM:[3,"Medium"],IMPACT_HIGH:[4,"High"]},ROLLOUT_PLAN={ROLLOUT_100:[0,"Will ship enabled for all users"],ROLLOUT_0_THEN_100:[1,"(RARE) Ships disabled, then flips on for all users"],ROLLOUT_GRADUAL:[2,"(RARE) Experiment users ramp up over time"],ROLLOUT_OTHER:[3,"(RARE) It's complicated or unusual"]},ROLLOUT_PLAN_DISPLAYNAME={0:ROLLOUT_PLAN.ROLLOUT_100[1],1:ROLLOUT_PLAN.ROLLOUT_0_THEN_100[1],2:ROLLOUT_PLAN.ROLLOUT_GRADUAL[1],3:ROLLOUT_PLAN.ROLLOUT_OTHER[1]},USE_COUNTER_TYPE_WEBFEATURE=0,USE_COUNTER_TYPE_WEBDXFEATURE=1,USE_COUNTER_TYPE_CSS_PROPERTY_ID=2,WEBFEATURE_USE_COUNTER_TYPES={WEBFEATURE:[USE_COUNTER_TYPE_WEBFEATURE,"WebFeature",x$1`The feature's use counter has been added to
+ web_feature.mojom.`],WEBDXFEATURE:[USE_COUNTER_TYPE_WEBDXFEATURE,"WebDXFeature",x$1`The feature's use counter has been added to
+ webdx_feature.mojom.`],CSS:[USE_COUNTER_TYPE_CSS_PROPERTY_ID,"CSSSampleID",x$1`The feature's use counter has been added to
+ css_property_id.mojom.`]};var FeatureType;(function(FeatureType){FeatureType[FeatureType.Incubate=0]="Incubate",FeatureType[FeatureType.Existing=1]="Existing",FeatureType[FeatureType.CodeChange=2]="CodeChange",FeatureType[FeatureType.Deprecation=3]="Deprecation",FeatureType[FeatureType.Enterprise=4]="Enterprise"})(FeatureType||(FeatureType={}));var AITestEvaluationStatus;(function(AITestEvaluationStatus){AITestEvaluationStatus[AITestEvaluationStatus.COMPLETE=1]="COMPLETE",AITestEvaluationStatus[AITestEvaluationStatus.IN_PROGRESS=2]="IN_PROGRESS",AITestEvaluationStatus[AITestEvaluationStatus.FAILED=3]="FAILED"})(AITestEvaluationStatus||(AITestEvaluationStatus={}));const FEATURE_TYPES_WITHOUT_ENTERPRISE={FEATURE_TYPE_INCUBATE_ID:[0,"New or changed feature",x$1`Choose this if you're still working on the design of a feature and
+ might need to send an Intent to Prototype or request a TAG review. Note
+ that backward-incompatible changes sometimes need to be implemented as a
+ pair of adding the new behavior and a separate entry to remove the old
+ behavior. This feature type follows the
+ New Feature Incubation
+ process.`],FEATURE_TYPE_EXISTING_ID:[1,"Chromium catches up",x$1`Choose this if a standards body already has consensus for a feature, or
+ it's already shipped in another implementation. This feature type omits
+ some options that the "New feature" type includes. It follows the
+ Implementations of already-defined consensus-based standards
+ process.`],FEATURE_TYPE_CODE_CHANGE_ID:[2,"No developer-visible change",x$1`Choose this if you're hoping that nobody notices the change you're
+ going to make, but there's a chance that a bug will make it visible. This
+ feature type follows the
+ Web-developer-facing change to existing behavior
+ process.`],FEATURE_TYPE_DEPRECATION_ID:[3,"Feature removal",x$1`Choose this if you are deprecating and then removing an existing
+ feature. This feature type follows the
+ Feature deprecations
+ process.`]},FEATURE_TYPES={...FEATURE_TYPES_WITHOUT_ENTERPRISE,FEATURE_TYPE_ENTERPRISE_ID:[4,"New Feature or removal affecting enterprises","For features or changes that need to be communicated to enterprises or schools."]},ENTERPRISE_PRODUCT_CATEGORY={CHROME_BROWSER_UPDATE:[0,"Chrome Browser update","New features, performance improvements, security fixes and minor updates addressing security vulnerabilities and bugs. These features apply to both consumers and enterprises."],CHROME_ENTERPRISE_CORE:[1,"Chrome Enterprise Core (CEC)","These features allow IT administrators to manage Chrome browser settings, policies, apps and extensions across an organization from a central location (Admin Console)."],CHROME_ENTERPRISE_PREMIUM:[2,"Chrome Enterprise Premium (CEP, paid SKU)","These features add advanced security and enhanced controls for organizations with more custom needs e.g. data masking functionality."]},ENTERPRISE_PRODUCT_CATEGORY_DISPLAYNAME={0:"Chrome Browser update",1:"Chrome Enterprise Core (CEC)",2:"Chrome Enterprise Premium (CEP, paid SKU)"},STAGE_BLINK_INCUBATE=110,STAGE_BLINK_PROTOTYPE=120,STAGE_BLINK_DEV_TRIAL=130,STAGE_BLINK_EVAL_READINESS=140,STAGE_BLINK_ORIGIN_TRIAL=150,STAGE_BLINK_EXTEND_ORIGIN_TRIAL=151,STAGE_BLINK_SHIPPING=160,STAGE_FAST_PROTOTYPE=220,STAGE_FAST_DEV_TRIAL=230,STAGE_FAST_ORIGIN_TRIAL=250,STAGE_FAST_EXTEND_ORIGIN_TRIAL=251,STAGE_FAST_SHIPPING=260,STAGE_PSA_IMPLEMENT_FIELDS=320,STAGE_PSA_DEV_TRIAL=330,STAGE_PSA_SHIPPING=360,STAGE_DEP_PLAN=410,STAGE_DEP_DEV_TRIAL=430,STAGE_DEP_DEPRECATION_TRIAL=450,STAGE_DEP_EXTEND_DEPRECATION_TRIAL=451,STAGE_DEP_SHIPPING=460,STAGE_ENT_ROLLOUT=1061,STAGE_ENT_SHIPPED=1070,STAGE_TYPES_DEV_TRIAL=new Set([STAGE_BLINK_DEV_TRIAL,STAGE_FAST_DEV_TRIAL,STAGE_PSA_DEV_TRIAL,STAGE_DEP_DEV_TRIAL]),STAGE_TYPES_ORIGIN_TRIAL=new Set([STAGE_BLINK_ORIGIN_TRIAL,STAGE_FAST_ORIGIN_TRIAL,STAGE_DEP_DEPRECATION_TRIAL]),STAGE_TYPES_SHIPPING=new Set([STAGE_BLINK_SHIPPING,STAGE_FAST_SHIPPING,STAGE_PSA_SHIPPING,STAGE_DEP_SHIPPING]),OT_EXTENSION_STAGE_MAPPING={[STAGE_BLINK_ORIGIN_TRIAL]:STAGE_BLINK_EXTEND_ORIGIN_TRIAL,[STAGE_FAST_ORIGIN_TRIAL]:STAGE_FAST_EXTEND_ORIGIN_TRIAL,[STAGE_DEP_DEPRECATION_TRIAL]:STAGE_DEP_EXTEND_DEPRECATION_TRIAL},STAGE_SHORT_NAMES={[STAGE_BLINK_INCUBATE]:"Incubate",[STAGE_BLINK_PROTOTYPE]:"Prototype",[STAGE_BLINK_DEV_TRIAL]:"DevTrial",[STAGE_BLINK_EVAL_READINESS]:"Eval readiness",[STAGE_BLINK_ORIGIN_TRIAL]:"OT",[STAGE_BLINK_EXTEND_ORIGIN_TRIAL]:"Extend OT",[STAGE_BLINK_SHIPPING]:"Ship",[STAGE_FAST_PROTOTYPE]:"Prototype",[STAGE_FAST_DEV_TRIAL]:"DevTrial",[STAGE_FAST_ORIGIN_TRIAL]:"OT",[STAGE_FAST_EXTEND_ORIGIN_TRIAL]:"Extend OT",[STAGE_FAST_SHIPPING]:"Ship",[STAGE_PSA_IMPLEMENT_FIELDS]:"Implement",[STAGE_PSA_DEV_TRIAL]:"DevTrial",[STAGE_PSA_SHIPPING]:"Ship",[STAGE_DEP_PLAN]:"Plan",[STAGE_DEP_DEV_TRIAL]:"DevTrial",[STAGE_DEP_DEPRECATION_TRIAL]:"Dep Trial",[STAGE_DEP_EXTEND_DEPRECATION_TRIAL]:"Extend Dep Trial",[STAGE_DEP_SHIPPING]:"Ship",[STAGE_ENT_ROLLOUT]:"Rollout",[STAGE_ENT_SHIPPED]:"Ship"},INTENT_STAGES={INTENT_NONE:[0,"None"],INTENT_INCUBATE:[7,"Start incubating"],INTENT_IMPLEMENT:[1,"Start prototyping"],INTENT_EXPERIMENT:[2,"Dev trials"],INTENT_IMPLEMENT_SHIP:[4,"Evaluate readiness to ship"],INTENT_ORIGIN_TRIAL:[3,"Origin Trial"],INTENT_EXTEND_ORIGIN_TRIAL:[11,"Extend Trial"],INTENT_SHIP:[5,"Prepare to ship"],INTENT_REMOVED:[6,"Removed"],INTENT_SHIPPED:[8,"Shipped"],INTENT_PARKED:[9,"Parked"],INTENT_ROLLOUT:[10,"Rollout"]},DT_MILESTONE_FIELDS=new Set(["dt_milestone_desktop_start","dt_milestone_android_start","dt_milestone_ios_start","dt_milestone_webview_start"]),OT_MILESTONE_START_FIELDS=new Set(["ot_milestone_desktop_start","ot_milestone_android_start","ot_milestone_webview_start"]),SHIPPED_MILESTONE_FIELDS=new Set(["shipped_milestone","shipped_android_milestone","shipped_ios_milestone","shipped_webview_milestone"]);var UsageType;(function(UsageType){UsageType[UsageType.Prototype=0]="Prototype",UsageType[UsageType.DeveloperTesting=1]="DeveloperTesting",UsageType[UsageType.Experiment=2]="Experiment",UsageType[UsageType.Ship=3]="Ship",UsageType[UsageType.PSA=4]="PSA",UsageType[UsageType.DeprecateAndRemove=5]="DeprecateAndRemove",UsageType[UsageType.CrossFunctionReview=6]="CrossFunctionReview",UsageType[UsageType.ReleaseNotes=7]="ReleaseNotes"})(UsageType||(UsageType={}));const ALL_FEATURE_TYPE_INCUBATE_INTENTS=new Set([UsageType.Prototype,UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),ALL_FEATURE_TYPE_EXISTING_INTENTS=new Set([UsageType.Prototype,UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),ALL_FEATURE_TYPE_CODE_CHANGE_INTENTS=new Set([UsageType.DeveloperTesting,UsageType.PSA]),ALL_FEATURE_TYPE_DEPRECATION_INTENTS=new Set([UsageType.DeprecateAndRemove,UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),ALL_INTENT_USAGE_BY_FEATURE_TYPE={[FeatureType.Incubate]:ALL_FEATURE_TYPE_INCUBATE_INTENTS,[FeatureType.Existing]:ALL_FEATURE_TYPE_EXISTING_INTENTS,[FeatureType.CodeChange]:ALL_FEATURE_TYPE_CODE_CHANGE_INTENTS,[FeatureType.Deprecation]:ALL_FEATURE_TYPE_DEPRECATION_INTENTS},STAGE_SPECIFIC_FIELDS=new Set(["shipped_milestone","shipped_android_milestone","shipped_ios_milestone","shipped_webview_milestone","ot_milestone_desktop_start","ot_milestone_desktop_end","ot_milestone_android_start","ot_milestone_android_end","ot_milestone_webview_start","ot_milestone_webview_end","dt_milestone_desktop_start","dt_milestone_android_start","dt_milestone_ios_start","dt_milestone_webview_start","extension_desktop_last","extension_android_last","extension_webview_last","intent_to_implement_url","intent_to_ship_url","intent_to_experiment_url","intent_to_extend_experiment_url","intent_thread_url","ot_creation__intent_to_experiment_url","ot_extension__intent_to_extend_experiment_url","r4dt_url","display_name","ot_display_name","ot_owner_email","origin_trial_feedback_url","ot_chromium_trial_name","ot_description","ot_emails","ot_feedback_submission_url","ot_request_note","ot_webfeature_use_counter","ot_documentation_url","ot_creation__bypass_file_checks","ot_creation__ot_documentation_url","ot_is_deprecation_trial","ot_has_third_party_support","ot_is_critical_trial","ot_creation__milestone_desktop_first","ot_creation__milestone_desktop_last","ot_extension__milestone_desktop_last","ot_require_approvals","ot_approval_buganizer_component","ot_approval_buganizer_custom_field_id","ot_approval_group_email","ot_approval_criteria_url","finch_url","experiment_goals","experiment_risks","experiment_extension_reason","rollout_milestone","rollout_platforms","rollout_details","rollout_stage_plan","enterprise_policies","announcement_url"]),STAGE_FIELD_NAME_MAPPING={shipped_milestone:"desktop_first",shipped_android_milestone:"android_first",shipped_ios_milestone:"ios_first",shipped_webview_milestone:"webview_first",ot_milestone_desktop_start:"desktop_first",ot_milestone_desktop_end:"desktop_last",ot_milestone_android_start:"android_first",ot_milestone_android_end:"android_last",ot_milestone_webview_start:"webview_first",ot_milestone_webview_end:"webview_last",ot_creation__milestone_desktop_first:"desktop_first",ot_creation__milestone_desktop_last:"desktop_last",ot_creation__ot_documentation_url:"ot_documentation_url",ot_extension__milestone_desktop_last:"desktop_last",dt_milestone_desktop_start:"desktop_first",dt_milestone_android_start:"android_first",dt_milestone_ios_start:"ios_first",dt_milestone_webview_start:"webview_first",extension_desktop_last:"desktop_last",extension_android_last:"android_last",extension_webview_last:"webview_last",rollout_milestone:"desktop_first",intent_to_implement_url:"intent_thread_url",intent_to_ship_url:"intent_thread_url",intent_to_experiment_url:"intent_thread_url",intent_to_extend_experiment_url:"intent_thread_url",ot_creation__intent_to_experiment_url:"intent_thread_url",ot_extension__intent_to_extend_experiment_url:"intent_thread_url",r4dt_url:"intent_thread_url"},GATE_TYPES={API_PROTOTYPE:1,API_ORIGIN_TRIAL:2,API_EXTEND_ORIGIN_TRIAL:3,API_SHIP:4,API_PLAN:5,PRIVACY_ORIGIN_TRIAL:32,PRIVACY_SHIP:34,SECURITY_ORIGIN_TRIAL:42,SECURITY_SHIP:44,ENTERPRISE_SHIP:54,ENTERPRISE_PLAN:55,DEBUGGABILITY_ORIGIN_TRIAL:62,DEBUGGABILITY_SHIP:64,DEBUGGABILITY_PLAN:65,TESTING_SHIP:74,TESTING_PLAN:75},GATE_PREPARING=0,GATE_REVIEW_REQUESTED=2,GATE_NA_REQUESTED=9,VOTE_OPTIONS={NO_RESPONSE:[7,"No response"],NA:[1,"N/a or Ack"],REVIEW_STARTED:[3,"Review started"],NEEDS_WORK:[4,"Needs work"],INTERNAL_REVIEW:[8,"Internal review"],APPROVED:[5,"Approved"],DENIED:[6,"Denied"]},VOTE_NA_SELF=10,VOTE_NA_VERIFIED=11,GATE_ACTIVE_REVIEW_STATES=[GATE_REVIEW_REQUESTED,VOTE_OPTIONS.REVIEW_STARTED[0],VOTE_OPTIONS.NEEDS_WORK[0],VOTE_OPTIONS.INTERNAL_REVIEW[0],GATE_NA_REQUESTED],GATE_FINISHED_REVIEW_STATES=[VOTE_OPTIONS.NA[0],VOTE_OPTIONS.APPROVED[0],VOTE_OPTIONS.DENIED[0],VOTE_NA_SELF,VOTE_NA_VERIFIED],GATE_APPROVED_REVIEW_STATES=[VOTE_OPTIONS.APPROVED[0],VOTE_OPTIONS.NA[0],VOTE_NA_SELF,VOTE_NA_VERIFIED],GATE_TEAM_ORDER=["Privacy","WP Security","Enterprise","Debuggability","Testing","API Owners"],OT_MILESTONE_END_FIELDS={ot_milestone_desktop_end:"desktop_last",ot_milestone_android_end:"android_last",ot_milestone_webview_end:"webview_last"},OT_SETUP_STATUS_OPTIONS={OT_NOT_CREATED:1,OT_READY_FOR_CREATION:2,OT_CREATION_FAILED:3,OT_ACTIVATION_FAILED:4},IMPLEMENTATION_STATUS={NO_ACTIVE_DEV:[1,"No active development"],PROPOSED:[2,"Proposed"],IN_DEVELOPMENT:[3,"In development"],BEHIND_A_FLAG:[4,"In developer trial (Behind a flag)"],ENABLED_BY_DEFAULT:[5,"Enabled by default"],DEPRECATED:[6,"Deprecated"],REMOVED:[7,"Removed"],ORIGIN_TRIAL:[8,"Origin trial"],ON_HOLD:[10,"On hold"],NO_LONGER_PURSUING:[1e3,"No longer pursuing"]},STANDARD_MATURITY_CHOICES={UNKNOWN_STD:[1,"Unknown standards status - check spec link for status"],PROPOSAL_STD:[2,"Proposal in a personal repository, no adoption from community"],INCUBATION_STD:[3,"Specification being incubated in a Community Group"],WORKINGDRAFT_STD:[4,"Specification currently under development in a Working Group"],STANDARD_STD:[5,"Final published standard: Recommendation, Living Standard, Candidate Recommendation, or similar final form"]},REVIEW_STATUS_CHOICES={REVIEW_PENDING:[1,"Pending"],REVIEW_ISSUES_OPEN:[2,"Issues open"],REVIEW_ISSUES_ADDRESSED:[3,"Issues addressed"],REVIEW_NA:[4,"Not applicable"]},VENDOR_VIEWS_COMMON={SHIPPED:[1,"Shipped/Shipping"],IN_DEV:[2,"In development"],PUBLIC_SUPPORT:[3,"Positive"],NO_PUBLIC_SIGNALS:[5,"No signal"],OPPOSED:[7,"Negative"],NEUTRAL:[8,"Neutral"],SIGNALS_NA:[9,"N/A"]},VENDOR_VIEWS_GECKO={NO_PUBLIC_SIGNALS:[5,"No signal"],SIGNALS_NA:[9,"N/A"],GECKO_UNDER_CONSIDERATION:[10,"Under consideration"],GECKO_DEFER:[14,"Defer"],PUBLIC_SUPPORT:[3,"Positive"],OPPOSED:[7,"Negative"],NEUTRAL:[8,"Neutral"],SHIPPED:[1,"Shipped/Shipping"]},WEB_DEV_VIEWS={DEV_STRONG_POSITIVE:[1,"Strongly positive"],DEV_POSITIVE:[2,"Positive"],DEV_MIXED_SIGNALS:[3,"Mixed signals"],DEV_NO_SIGNALS:[4,"No signals"],DEV_NEGATIVE:[5,"Negative"],DEV_STRONG_NEGATIVE:[6,"Strongly negative"]},COMMA_SEPARATED_FIELDS=["owner","editors","cc_recipients","spec_mentors","search_tags","devrel","i2e_lgtms","i2s_lgtms"],LINE_SEPARATED_FIELDS=["explainer_links","doc_links","sample_links","screenshot_links"];function formatFeatureForEdit(feature){const formattedFeature={...feature,category:feature.category_int,enterprise_feature_categories:Array.from(new Set(feature.enterprise_feature_categories||[])).map(x=>parseInt(x).toString()),enterprise_product_category:feature.enterprise_product_category,feature_type:feature.feature_type_int,intent_stage:feature.intent_stage_int,accurate_as_of:!0,spec_link:feature.standards.spec,standard_maturity:feature.standards.maturity.val,tag_review_status:feature.tag_review_status_int,security_review_status:feature.security_review_status_int,privacy_review_status:feature.privacy_review_status_int,sample_links:feature.resources.samples,doc_links:feature.resources.docs,search_tags:feature.tags,blink_components:feature.browsers.chrome.blink_components?.[0],bug_url:feature.browsers.chrome.bug,devrel:feature.browsers.chrome.devrel,owner:feature.browsers.chrome.owners,prefixed:feature.browsers.chrome.prefixed,impl_status_chrome:feature.browsers.chrome.status.val,shipped_milestone:feature.browsers.chrome.desktop,shipped_android_milestone:feature.browsers.chrome.android,shipped_webview_milestone:feature.browsers.chrome.webview,shipped_ios_milestone:feature.browsers.chrome.ios,ff_views:feature.browsers.ff.view?.val,ff_views_link:feature.browsers.ff.view?.url,ff_views_notes:feature.browsers.ff.view?.notes,safari_views:feature.browsers.safari.view?.val,safari_views_link:feature.browsers.safari.view?.url,safari_views_notes:feature.browsers.safari.view?.notes,web_dev_views:feature.browsers.webdev.view?.val,web_dev_views_link:feature.browsers.webdev.view?.url,web_dev_views_notes:feature.browsers.webdev.view?.notes,other_views_notes:feature.browsers.other.view?.notes};return COMMA_SEPARATED_FIELDS.map(field=>{formattedFeature[field]&&(formattedFeature[field]=formattedFeature[field].join(", "))}),LINE_SEPARATED_FIELDS.map(field=>{formattedFeature[field]&&(formattedFeature[field]=formattedFeature[field].join("\r\n"))}),formattedFeature}const NEW_FEATURE_FORM_FIELDS=["name","summary","unlisted","enterprise_impact","enterprise_feature_categories","shipping_year","owner","editors","cc_recipients","blink_components","category","web_feature"],ENTERPRISE_NEW_FEATURE_FORM_FIELDS=["name","summary","owner","editors","enterprise_feature_categories","enterprise_product_category","first_enterprise_notification_milestone","enterprise_impact","confidential"],FLAT_METADATA_FIELDS={name:"Feature metadata",sections:[{name:"Feature metadata",fields:["name","summary","unlisted","enterprise_impact","enterprise_feature_categories","shipping_year","owner","editors","cc_recipients","devrel","category","feature_type","active_stage_id","search_tags","web_feature"]},{name:"Implementation in Chromium",fields:["blink_components","bug_url","launch_bug_url","comments"]}]},FLAT_ENTERPRISE_METADATA_FIELDS={sections:[{name:"Feature metadata",fields:["name","summary","owner","editors","enterprise_feature_categories","enterprise_product_category","enterprise_impact","confidential","first_enterprise_notification_milestone","screenshot_links"]}]},FLAT_INCUBATE_FIELDS={name:"Identify the need",sections:[{name:"Identify the need",fields:["motivation","initial_public_proposal_url","explainer_links"]},{name:"Implementation in Chromium",fields:["requires_embedder_support"]}]},FLAT_PROTOTYPE_FIELDS={name:"Prototype a solution",sections:[{name:"Prototype a solution",fields:["motivation","spec_link","standard_maturity","api_spec","automation_spec","spec_mentors","intent_to_implement_url"]}]},FLAT_DEV_TRIAL_FIELDS={name:"Dev trials and iterate on design",sections:[{name:"Dev trial",fields:["devtrial_instructions","doc_links","interop_compat_risks","safari_views","safari_views_link","safari_views_notes","ff_views","ff_views_link","ff_views_notes","web_dev_views","web_dev_views_link","web_dev_views_notes","other_views_notes","security_review_status","privacy_review_status","ergonomics_risks","activation_risks","security_risks","debuggability","measurement","all_platforms","all_platforms_descr","wpt","wpt_descr","sample_links"]},{name:"Implementation in Chromium",fields:["flag_name","finch_name","non_finch_justification","dt_milestone_desktop_start","dt_milestone_android_start","dt_milestone_ios_start","announcement_url"]}]},FLAT_ORIGIN_TRIAL_FIELDS={name:"Origin trial",sections:[{name:"Origin trial",fields:["display_name","experiment_goals","experiment_risks","ongoing_constraints","i2e_lgtms","ot_documentation_url","intent_to_experiment_url","origin_trial_feedback_url"]},{name:"Implementation in Chromium",fields:["ot_milestone_desktop_start","ot_milestone_desktop_end","ot_milestone_android_start","ot_milestone_android_end","ot_milestone_webview_start","ot_milestone_webview_end","experiment_timeline"]}]},FLAT_TRIAL_EXTENSION_FIELDS={name:"Trial extension",sections:[{name:"Trial extension",fields:["experiment_extension_reason","intent_to_extend_experiment_url","extension_desktop_last"]}]},FLAT_EVAL_READINESS_TO_SHIP_FIELDS={name:"Evaluate readiness to ship",sections:[{name:"Evaluate readiness to ship",fields:["prefixed","tag_review"]}]},FLAT_PREPARE_TO_SHIP_FIELDS={name:"Prepare to ship",sections:[{name:"Prepare to ship",fields:["display_name","tag_review_status","webview_risks","anticipated_spec_changes","i2s_lgtms","availability_expectation","adoption_expectation","adoption_plan","non_oss_deps","finch_url","intent_to_ship_url"]},{name:"Implementation in Chromium",fields:["rollout_plan","shipped_milestone","shipped_android_milestone","shipped_ios_milestone","shipped_webview_milestone"]}]},FLAT_ENTERPRISE_PREPARE_TO_SHIP_FIELDS={name:"Rollout step",sections:[{name:"Rollout step",fields:["rollout_milestone","rollout_platforms","rollout_details","rollout_stage_plan","enterprise_policies"]}]},PSA_IMPLEMENT_FIELDS={name:"Start prototyping",sections:[{name:"Start prototyping",fields:["motivation","spec_link","standard_maturity"]}]},PSA_PREPARE_TO_SHIP_FIELDS={name:"Prepare to ship",sections:[{name:"Prepare to ship",fields:["intent_to_ship_url"]},{name:"Implementation in Chromium",fields:["rollout_plan","shipped_milestone","shipped_android_milestone","shipped_ios_milestone","shipped_webview_milestone"]}]},DEPRECATION_PLAN_FIELDS={name:"Write up deprecation plan",sections:[{name:"Write up deprecation plan",fields:["deprecation_motivation","spec_link"]}]},DEPRECATION_DEV_TRIAL_FIELDS={name:"Dev trial of deprecation",sections:[{name:"Dev trial of deprecation",fields:["devtrial_instructions","doc_links","interop_compat_risks","safari_views","safari_views_link","safari_views_notes","ff_views","ff_views_link","ff_views_notes","web_dev_views","web_dev_views_link","web_dev_views_notes","other_views_notes","security_review_status","privacy_review_status","ergonomics_risks","activation_risks","security_risks","webview_risks","debuggability","measurement","all_platforms","all_platforms_descr","wpt","wpt_descr","sample_links"]},{name:"Implementation in Chromium",fields:["flag_name","finch_name","non_finch_justification","dt_milestone_desktop_start","dt_milestone_android_start","dt_milestone_ios_start","announcement_url"]}]},ORIGIN_TRIAL_CREATION_FIELDS={sections:[{fields:["ot_display_name","ot_description","ot_owner_email","ot_emails","ot_creation__milestone_desktop_first","ot_creation__milestone_desktop_last","ot_creation__intent_to_experiment_url","ot_creation__ot_documentation_url","ot_feedback_submission_url","ot_chromium_trial_name","ot_is_deprecation_trial","ot_webfeature_use_counter","ot_has_third_party_support","ot_is_critical_trial","ot_require_approvals"]}]},ORIGIN_TRIAL_EXTENSION_FIELDS={sections:[{fields:["ot_extension__milestone_desktop_last","experiment_extension_reason"]}]},DEPRECATION_ORIGIN_TRIAL_FIELDS={name:"Prepare for Deprecation Trial",sections:[{name:"Prepare for Deprecation Trial",fields:["display_name","experiment_goals","experiment_risks","ongoing_constraints","r4dt_url","r4dt_lgtms","origin_trial_feedback_url"]},{name:"Implementation in Chromium",fields:["ot_milestone_desktop_start","ot_milestone_desktop_end","ot_milestone_android_start","ot_milestone_android_end","ot_milestone_webview_start","ot_milestone_webview_end","experiment_timeline"]}]},DEPRECATION_PREPARE_TO_SHIP_FIELDS={name:"Prepare to ship",sections:[{name:"Prepare to ship",fields:["display_name","intent_to_ship_url","i2s_lgtms"]},{name:"Implementation in Chromium",fields:["rollout_plan","shipped_milestone","shipped_android_milestone","shipped_ios_milestone","shipped_webview_milestone"]}]},VERIFY_ACCURACY_METADATA_FIELDS={name:"Important fields",sections:[{name:"Feature Metadata",fields:["summary","owner","finch_name","non_finch_justification","bug_url"]}]},VERIFY_ACCURACY_PREPARE_TO_SHIP_FIELDS={name:"Prepare to ship",sections:[{name:"Shipping milestones",fields:["shipped_milestone","shipped_android_milestone","shipped_ios_milestone","shipped_webview_milestone"]}]},VERIFY_ACCURACY_ENTERPRISE_PREPARE_TO_SHIP_FIELDS={name:"Rollout step",sections:[{name:"Rollout milestones",fields:["rollout_milestone","rollout_platforms","rollout_details","rollout_stage_plan","enterprise_policies"]}]},VERIFY_ACCURACY_CONFIRMATION_FIELD={name:"Verify Accuracy",sections:[{name:"Verify Accuracy",fields:["accurate_as_of"]}]},FORMS_BY_STAGE_TYPE={[STAGE_BLINK_INCUBATE]:FLAT_INCUBATE_FIELDS,[STAGE_BLINK_PROTOTYPE]:FLAT_PROTOTYPE_FIELDS,[STAGE_BLINK_DEV_TRIAL]:FLAT_DEV_TRIAL_FIELDS,[STAGE_BLINK_EVAL_READINESS]:FLAT_EVAL_READINESS_TO_SHIP_FIELDS,[STAGE_BLINK_ORIGIN_TRIAL]:FLAT_ORIGIN_TRIAL_FIELDS,[STAGE_BLINK_EXTEND_ORIGIN_TRIAL]:FLAT_TRIAL_EXTENSION_FIELDS,[STAGE_BLINK_SHIPPING]:FLAT_PREPARE_TO_SHIP_FIELDS,[STAGE_FAST_PROTOTYPE]:FLAT_PROTOTYPE_FIELDS,[STAGE_FAST_DEV_TRIAL]:FLAT_DEV_TRIAL_FIELDS,[STAGE_FAST_ORIGIN_TRIAL]:FLAT_ORIGIN_TRIAL_FIELDS,[STAGE_FAST_EXTEND_ORIGIN_TRIAL]:FLAT_TRIAL_EXTENSION_FIELDS,[STAGE_FAST_SHIPPING]:FLAT_PREPARE_TO_SHIP_FIELDS,[STAGE_PSA_IMPLEMENT_FIELDS]:PSA_IMPLEMENT_FIELDS,[STAGE_PSA_DEV_TRIAL]:FLAT_DEV_TRIAL_FIELDS,[STAGE_PSA_SHIPPING]:PSA_PREPARE_TO_SHIP_FIELDS,[STAGE_DEP_PLAN]:DEPRECATION_PLAN_FIELDS,[STAGE_DEP_DEV_TRIAL]:DEPRECATION_DEV_TRIAL_FIELDS,[STAGE_DEP_DEPRECATION_TRIAL]:DEPRECATION_ORIGIN_TRIAL_FIELDS,[STAGE_DEP_EXTEND_DEPRECATION_TRIAL]:FLAT_TRIAL_EXTENSION_FIELDS,[STAGE_DEP_SHIPPING]:DEPRECATION_PREPARE_TO_SHIP_FIELDS,[STAGE_ENT_ROLLOUT]:FLAT_ENTERPRISE_PREPARE_TO_SHIP_FIELDS,[STAGE_ENT_SHIPPED]:FLAT_PREPARE_TO_SHIP_FIELDS},CREATEABLE_STAGES={[FEATURE_TYPES.FEATURE_TYPE_INCUBATE_ID[0]]:[STAGE_BLINK_ORIGIN_TRIAL,STAGE_BLINK_SHIPPING,STAGE_ENT_ROLLOUT],[FEATURE_TYPES.FEATURE_TYPE_EXISTING_ID[0]]:[STAGE_FAST_ORIGIN_TRIAL,STAGE_FAST_SHIPPING,STAGE_ENT_ROLLOUT],[FEATURE_TYPES.FEATURE_TYPE_CODE_CHANGE_ID[0]]:[STAGE_PSA_SHIPPING,STAGE_ENT_ROLLOUT],[FEATURE_TYPES.FEATURE_TYPE_DEPRECATION_ID[0]]:[STAGE_DEP_DEPRECATION_TRIAL,STAGE_DEP_SHIPPING,STAGE_ENT_ROLLOUT],[FEATURE_TYPES.FEATURE_TYPE_ENTERPRISE_ID[0]]:[STAGE_ENT_ROLLOUT]},VERIFY_ACCURACY_FORMS_BY_STAGE_TYPE={[STAGE_BLINK_SHIPPING]:VERIFY_ACCURACY_PREPARE_TO_SHIP_FIELDS,[STAGE_FAST_SHIPPING]:VERIFY_ACCURACY_PREPARE_TO_SHIP_FIELDS,[STAGE_PSA_SHIPPING]:VERIFY_ACCURACY_PREPARE_TO_SHIP_FIELDS,[STAGE_DEP_SHIPPING]:VERIFY_ACCURACY_PREPARE_TO_SHIP_FIELDS,[STAGE_ENT_ROLLOUT]:VERIFY_ACCURACY_ENTERPRISE_PREPARE_TO_SHIP_FIELDS,[STAGE_ENT_SHIPPED]:VERIFY_ACCURACY_PREPARE_TO_SHIP_FIELDS};let toastEl;const NARROW_WINDOW_MAX_WIDTH=700,ACCURACY_GRACE_PERIOD=2419200000,SHIPPED_FEATURE_OUTDATED_GRACE_PERIOD=5443200000,IS_MOBILE=(()=>{const width=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;return width<=NARROW_WINDOW_MAX_WIDTH})();function autolink(s,featureLinks=[],isMarkdown=!1){if(s=s??"",isMarkdown){const rendered=d.parse(s),sanitized=purify.sanitize(rendered),markup=x$1`${o$2(sanitized)}`;return[markup]}else{const withLinks=markupAutolinks(s,featureLinks);return withLinks}}function showToastMessage(msg){toastEl||(toastEl=document.querySelector("chromedash-toast")),toastEl?.showMessage&&toastEl.showMessage(msg)}function findProcessStage(feStage,process){for(const processStage of process.stages)if(feStage.stage_type==processStage.stage_type)return processStage;return null}function shouldShowDisplayNameField(feStages,stageType){let matchingStageCount=0;for(let i=0;is.stage_type===stage.stage_type).findIndex(s=>s.id===stage.id);return 0milestoneValue?`${feStage[maxMilestoneFieldName]} (extended from ${milestoneValue})`:milestoneValue}}function isDefinedValue(value){return value!==void 0&&null!==value&&0!=value.length}function hasFieldValue(fieldName,feStage,feature){const value=getFieldValueFromFeature(fieldName,feStage,feature);return isDefinedValue(value)}function getFieldValueFromFeature(fieldName,feStage,feature){if(STAGE_SPECIFIC_FIELDS.has(fieldName)){const value=getStageValue(feStage,fieldName);return"rollout_platforms"===fieldName&&value?value.map(platformId=>PLATFORMS_DISPLAYNAME[platformId]):"rollout_stage_plan"===fieldName?ROLLOUT_STAGE_PLAN_DISPLAYNAME[value]:fieldName in OT_MILESTONE_END_FIELDS?_getMilestoneExtensionValue(feStage,fieldName):value}if(!feature)return null;const fieldNameMapping={owner:"browsers.chrome.owners",editors:"editors",search_tags:"tags",spec_link:"standards.spec",standard_maturity:"standards.maturity.text",sample_links:"resources.samples",docs_links:"resources.docs",bug_url:"browsers.chrome.bug",blink_components:"browsers.chrome.blink_components",devrel:"browsers.chrome.devrel",prefixed:"browsers.chrome.prefixed",impl_status_chrome:"browsers.chrome.status.text",shipped_milestone:"browsers.chrome.desktop",shipped_android_milestone:"browsers.chrome.android",shipped_webview_milestone:"browsers.chrome.webview",shipped_ios_milestone:"browsers.chrome.ios",ff_views:"browsers.ff.view.text",ff_views_link:"browsers.ff.view.url",ff_views_notes:"browsers.ff.view.notes",safari_views:"browsers.safari.view.text",safari_views_link:"browsers.safari.view.url",safari_views_notes:"browsers.safari.view.notes",web_dev_views:"browsers.webdev.view.text",web_dev_views_link:"browsers.webdev.view.url",web_dev_views_notes:"browsers.webdev.view.notes",other_views_notes:"browsers.other.view.notes"};let value;if(fieldNameMapping[fieldName]){let propertyValue=feature;for(const step of fieldNameMapping[fieldName].split("."))propertyValue&&(propertyValue=propertyValue[step]);value=propertyValue}else value=feature[fieldName];if("enterprise_product_category"===fieldName&&void 0!==value)return ENTERPRISE_PRODUCT_CATEGORY_DISPLAYNAME[value];if("enterprise_feature_categories"===fieldName&&value)return value.map(categoryId=>ENTERPRISE_FEATURE_CATEGORIES_DISPLAYNAME[categoryId]);if("enterprise_impact"===fieldName&&value)return ENTERPRISE_IMPACT_DISPLAYNAME[value];if("rollout_plan"===fieldName&&void 0!==value)return ROLLOUT_PLAN_DISPLAYNAME[value];if("active_stage_id"===fieldName&&value){for(const stage of feature.stages)if(stage.id===value)return unambiguousStageName(stage,feature);return}return value}function flattenSections(stage){return stage.sections.reduce((combined,section)=>[...combined,...section.fields],[])}function setupScrollToHash(pageElement){const scrollToElement=hash=>{if(hash){const el=pageElement.shadowRoot.querySelector(hash);if(el){el.input?el.focus():setTimeout(()=>{el.focus()},100);const fieldRowSelector=`chromedash-form-field[name="${el.name}"] tr + tr`,fieldRow=pageElement.shadowRoot.querySelector(fieldRowSelector);fieldRow?fieldRow.scrollIntoView({block:"center",behavior:"smooth"}):el.scrollIntoView({behavior:"smooth"})}}};if(window.scrollToElement=hash=>{scrollToElement(hash)},location.hash){const hash=decodeURIComponent(location.hash);scrollToElement(hash)}}function redirectToCurrentPage(){const url=window.location.href.split("?")[0];window.location.href=url}function renderHTMLIf(condition,originalHTML){return condition?originalHTML:E$1}function _parseDateStr(dateStr){dateStr=dateStr||"",dateStr=dateStr.replace(" ","T");const dateObj=new Date(`${dateStr}Z`);return isNaN(+dateObj)?null:dateObj}function renderAbsoluteDate(dateStr,includeTime=!1){return dateStr?includeTime?dateStr.split(".")[0]:dateStr.split(" ")[0]:""}function renderRelativeDate(dateStr){const dateObj=_parseDateStr(dateStr);return dateObj?x$1`
+ ()
+ `:E$1}function isoDateString(date){return date.toISOString().slice(0,10)}function parseRawQuery(rawQuery){const params=new URLSearchParams(rawQuery),result={};for(const param of params.keys()){const values=params.getAll(param);values.length&&(result[param]=values[0])}return result}function getNewLocation(params,location){const url=new URL(location);if(url.search="",params)for(const[k,v]of Object.entries(params))v&&url.searchParams.append(k,v.toString());return url}function getDisabledHelpText(field,feStage){return("ot_milestone_desktop_start"===field||"ot_milestone_desktop_end"===field)&&(feStage?.ot_setup_status===OT_SETUP_STATUS_OPTIONS.OT_READY_FOR_CREATION||feStage?.ot_setup_status===OT_SETUP_STATUS_OPTIONS.OT_CREATION_FAILED||feStage?.ot_setup_status===OT_SETUP_STATUS_OPTIONS.OT_ACTIVATION_FAILED)?"Origin trial milestone cannot be edited while a creation request is in progress":""}function updateURLParams(key,val){const newURL=formatURLParams(key,val);newURL.toString()===window.location.toString()||window.history.pushState({path:newURL.toString()},"",newURL)}function formatURLParams(key,val){const rawQuery=parseRawQuery(window.location.search);rawQuery[key]=encodeURIComponent(val);const newURL=getNewLocation(rawQuery,window.location);return newURL.hash="",newURL}function formatUrlForRelativeOffset(start,delta,pageSize,totalCount){const offset=start+delta;return void 0===totalCount||offset<=-pageSize||offset>=totalCount?void 0:formatUrlForOffset(Math.max(0,offset))}function formatUrlForOffset(offset){return formatURLParams("start",offset).toString()}function clearURLParams(key){const rawQuery=parseRawQuery(window.location.search);delete rawQuery[key];const newURL=getNewLocation(rawQuery,window.location);newURL.hash="";newURL.toString()===window.location.toString()||window.history.pushState({path:newURL.toString()},"",newURL)}function formatFeatureChanges(fieldValues,featureId,formStageId){let hasChanges=!1;const featureChanges={id:featureId},stages={};formStageId&&(stages[formStageId]={id:formStageId});for(const{name,touched,value,stageId,implicitValue,isMarkdown}of fieldValues){if(!touched)continue;let formattedValue=value;if(Array.isArray(formattedValue)&&(formattedValue=formattedValue.join(",")),void 0!==implicitValue){if(!formattedValue)continue;featureChanges[name]=implicitValue}else stageId?(stageId in stages||(stages[stageId]={id:stageId}),stages[stageId][STAGE_FIELD_NAME_MAPPING[name]||name]={form_field_name:name,value:formattedValue}):(featureChanges[name]=formattedValue,void 0!==isMarkdown&&(featureChanges[name+"_is_markdown"]=isMarkdown));hasChanges=!0}return{feature_changes:featureChanges,stages:Object.values(stages),has_changes:hasChanges}}function handleSaveChangesResponse(response){const app=document.querySelector("chromedash-app");app.setUnsavedChanges(""!==response)}function extensionMilestoneIsValid(value,currentMilestone){if(isNaN(value))return!1;for(let i=0;ivalue[i]||"9" all properties",cssanimated:"CSS usage metrics > animated properties",featurepopularity:"HTML & JavaScript usage metrics > all features",webfeaturepopularity:"Web features usage metrics > all features"};function isShippedFeatureOutdated(feature,hasShipped,closestShippingDate){return!!hasShipped&&!!(feature.accurate_as_of&&closestShippingDate)&&Date.parse(feature.accurate_as_of){channels[key].version===foundMilestone&&(closestShippingDate=channels[key].final_beta||"")});else{const shippedMilestonesTarget=shippingTypeMilestones;let latestMilestone=0;for(const ms of shippedMilestonesTarget)ms&&ms<=latestStableVersion&&(latestMilestone=_Mathmax2(latestMilestone,ms));latestMilestone===latestStableVersion?(closestShippingDate=channels.stable?.final_beta||"",hasShipped=!0):(closestShippingDate=await fetchClosestShippingDate(latestMilestone),hasShipped=!0)}return{closestShippingDate,isUpcoming,hasShipped}}function isUpcomingFeatureOutdated(feature,isUpcoming,currentDate){return isUpcoming&&!isVerifiedWithinGracePeriod(feature.accurate_as_of,currentDate)}function getFeatureOutdatedBanner(feature,shippingInfo,currentDate,userCanEdit){currentDate||(currentDate=Date.now());const{closestShippingDate,hasShipped,isUpcoming}=shippingInfo;if(isUpcomingFeatureOutdated(feature,isUpcoming,currentDate))return userCanEdit?x$1`
+
+
+
+
+
+ Your feature hasn't been verified as accurate since
+ , but it is scheduled to ship
+ .
+ Please
+ verify that your feature is accurate.
+
+
+ `:x$1`
+
+
+
+
+
+ This feature hasn't been verified as accurate since
+ , but it is scheduled to ship
+ .
+
+
+
+
+
+
+ Your feature hasn't been verified as accurate since
+ , but it claims to have shipped
+ .
+ Please
+ verify that your feature is accurate.
+
+
+
+
+
+
+ This feature hasn't been verified as accurate since
+ , but it claims to have shipped
+ .
+
+
+ `}return null}var __decorate$18=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3{this.usersMap=new Map(response.users.map(user=>[user.id,user])),this.components=response.components,this.loading=!1}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later.")})}_onEditModeToggle(){this._editMode=!this._editMode}_addComponentUserListener(e){const component=Object.assign({},this.components[e.detail.index]);return e.detail.isError?void showToastMessage(`"Unable to add ${this.usersMap.get(e.detail.userId).name} to ${component.name}".`):void(!component.subscriber_ids?.includes(e.detail.userId)&&(component.subscriber_ids=[...(component.subscriber_ids??[]),e.detail.userId]),e.detail.toggleAsOwner&&(component.owner_ids=[...(component.owner_ids??[]),e.detail.userId]),showToastMessage(`"${this.usersMap.get(e.detail.userId).name} added to ${component.name}".`),this.components[e.detail.index]=component,this.requestUpdate())}_removeComponentUserListener(e){const component=Object.assign({},this.components[e.detail.index]);return e.detail.isError?void showToastMessage(`"Unable to remove ${this.usersMap.get(e.detail.userId).name} from ${component.name}".`):void(component.subscriber_ids=component.subscriber_ids.filter(currentUserId=>e.detail.userId!==currentUserId),e.detail.toggleAsOwner&&(component.owner_ids=component.owner_ids.filter(currentUserId=>e.detail.userId!==currentUserId)),showToastMessage(`"${this.usersMap.get(e.detail.userId).name} removed from ${component.name}".`),this.components[e.detail.index]=component,this.requestUpdate())}renderSubheader(){return x$1`
+
+ `}render(){return x$1` ${this.loading?x$1``:this.renderComponents()} `}};__decorate$17([r$6()],ChromedashAdminFeatureLinksPage.prototype,"sampleId",void 0),__decorate$17([r$6()],ChromedashAdminFeatureLinksPage.prototype,"samplesLoading",void 0),__decorate$17([r$6()],ChromedashAdminFeatureLinksPage.prototype,"loading",void 0),__decorate$17([r$6()],ChromedashAdminFeatureLinksPage.prototype,"featureLinksSamples",void 0),__decorate$17([r$6()],ChromedashAdminFeatureLinksPage.prototype,"featureLinksSummary",void 0),ChromedashAdminFeatureLinksPage=__decorate$17([t$3("chromedash-admin-feature-links-page")],ChromedashAdminFeatureLinksPage);const TEXT_KIND="text",NUM_KIND="number",MILESTONE_KIND="milestone",DATE_KIND="YYYY-MM-DD",EMAIL_KIND="user@example.com",ENUM_KIND="enum",QUERIABLE_FIELDS=[{name:"created.when",kind:DATE_KIND,doc:"Date that the feature entry was created"},{name:"updated.when",kind:DATE_KIND,doc:"Date that the feature was most recently edited"},{name:"name",kind:"text",doc:"The name of the feature"},{name:"tag",kind:"text",doc:"Search tags for finding feature entries"},{name:"web_feature_id",kind:"text",doc:"String ID of a related WebDX feature"},{name:"owner",kind:EMAIL_KIND,doc:"One of the feature owners"},{name:"shipping_year",kind:NUM_KIND,doc:"Estimated shipping year"},{name:"browsers.chrome.devrel",kind:EMAIL_KIND,doc:"Developer relations contact"},{name:"browsers.chrome.desktop",kind:MILESTONE_KIND,doc:"Desktop shipping milestone"},{name:"browsers.chrome.android",kind:MILESTONE_KIND,doc:"Android shipping milestone"},{name:"browsers.chrome.ios",kind:MILESTONE_KIND,doc:"iOS shipping milestone"},{name:"browsers.chrome.webview",kind:MILESTONE_KIND,doc:"Webview shipping milestone"},{name:"browsers.chrome.flag_name",kind:"text",doc:"Flag name that allows developers to enable the feature"},{name:"browsers.chrome.finch_name",kind:"text",doc:"Finch name"},{name:"browsers.chrome.devtrial.desktop.start",kind:MILESTONE_KIND,doc:"Desktop DevTrial start"},{name:"browsers.chrome.devtrial.android.start",kind:MILESTONE_KIND,doc:"Android DevTrial start"},{name:"browsers.chrome.devtrial.ios.start",kind:MILESTONE_KIND,doc:"iOS DevTrial start"},{name:"browsers.chrome.devtrial.webview.start",kind:MILESTONE_KIND,doc:"WebView DevTrial start"},{name:"browsers.chrome.ot.desktop.start",kind:MILESTONE_KIND,doc:"Desktop Origin Trial start"},{name:"browsers.chrome.ot.desktop.end",kind:MILESTONE_KIND,doc:"Desktop Origin Trial end"},{name:"browsers.chrome.ot.android.start",kind:MILESTONE_KIND,doc:"Android Origin Trial start"},{name:"browsers.chrome.ot.android.end",kind:MILESTONE_KIND,doc:"Android Origin Trial end"},{name:"browsers.chrome.ot.webview.start",kind:MILESTONE_KIND,doc:"WebView Origin Trial start"},{name:"browsers.chrome.ot.webview.end",kind:MILESTONE_KIND,doc:"WebView Origin Trial end"},{name:"rollout_milestone",kind:MILESTONE_KIND,doc:"Stable rollout milestone"},{name:"rollout_stage_plan",kind:ENUM_KIND,doc:"Stage rollout plan"},{name:"any_start_milestone",kind:MILESTONE_KIND,doc:"A milestone in which the feature is scheduled to ship or start an origin trial or dev trial, on any platform"},{name:"category",kind:ENUM_KIND,doc:"Feature category",choices:FEATURE_CATEGORIES},{name:"enterprise_product_category",kind:ENUM_KIND,doc:"Enterprise product category",choices:ENTERPRISE_PRODUCT_CATEGORY},{name:"feature_type",kind:ENUM_KIND,doc:"Feature type",choices:FEATURE_TYPES},{name:"impl_status_chrome",kind:ENUM_KIND,doc:"Implementation status",choices:IMPLEMENTATION_STATUS},{name:"intent_stage",kind:ENUM_KIND,doc:"Spec process stage",choices:INTENT_STAGES},{name:"security_review_status",kind:ENUM_KIND,doc:"Security review status",choices:REVIEW_STATUS_CHOICES},{name:"privacy_review_status",kind:ENUM_KIND,doc:"Privacy review status",choices:REVIEW_STATUS_CHOICES},{name:"tag_review_status",kind:ENUM_KIND,doc:"TAG Specification Review Status",choices:REVIEW_STATUS_CHOICES},{name:"browsers.webkit.view",kind:ENUM_KIND,doc:"WebKit views",choices:VENDOR_VIEWS_COMMON},{name:"browsers.ff.view",kind:ENUM_KIND,doc:"Firefox views",choices:VENDOR_VIEWS_GECKO},{name:"browsers.webdev.view",kind:ENUM_KIND,doc:"Web / Framework developer views",choices:WEB_DEV_VIEWS},{name:"accurate_as_of",kind:DATE_KIND,doc:"When the feature's fields were last verified"}];var __decorate$16=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3
+
${terms.map(term=>x$1`
${term}
`)}
+
${explanation}
+
+ `}renderCommonSearchExamples(){return x$1`
+
Common search examples
+
+
+ ${this.renderExampleRow(["memory","memory pool","memory -pool"],"Features that include or exclude words in any field.")}
+ ${this.renderExampleRow(["browsers.chrome.desktop:123","browsers.chrome.desktop:current_stable+1"],"Features shipping in the specified milestone.")}
+ ${this.renderExampleRow(["browsers.chrome.desktop:120..122","browsers.chrome.desktop:current_stable-1..current_stable+1"],"Features shipping in a milestone range.")}
+ ${this.renderExampleRow(["owner:user@example.com"],"Features with the specified owner.")}
+ ${this.renderExampleRow(["created.when>2024-01-01","created.when
+
+ `}renderSearchSyntax(){return x$1`
+
Search syntax
+
+
+ A search query consists of a series of terms that are separated by
+ spaces. Terms can be single words or conditions.
+
+
+
+ When searching for words, the results will include features that
+ include those words in any field of the feature entry. We do not
+ support searching for wildcards, partial words, punctuation, or quoted
+ phrases.
+
+
+
+ When searching using conditions, each condition consists of three
+ parts: FIELD OPERATOR VALUE(S)
+
+
+
+
FIELD: One of the fields listed below.
+
+ OPERATOR: Usually a colon, but it can be an inequality for numeric,
+ date, or enum fields. The colon operator does case-insensitive
+ matching of words within a text field, while an equals-sign does
+ exact matching of an entire string value.
+
+
+ VALUE(S): A single word, number, date, or enum value listed below.
+ If the value contains spaces, it must be inside double quotes.
+
+
+ Use the equals operator with a comma-separated list to match any
+ value in that list.
+
+
+ Use the equals operator with two number or date values separated
+ by ".." to find any value between or including
+ those endpoints. The left value must be less than the right
+ value.
+
+
+ For dates, you can compute a date a certain number of days or
+ weeks before or after now. "now-3d" is 3 days ago,
+ and "now+2w" is 2 weeks from now.
+
+
+ For milestones, you can compute a milestone relative to the
+ current stable version of Chrome.
+ "current_stable+1" is 1 version after the current
+ stable version.
+
+
+
+
+
+
+ You may negate any search term by prefixing it with a minus sign.
+ Search terms are implicitly joined together by a logical-AND. However,
+ you may type the keyword OR between terms as a logical-OR
+ operator. We do not support parenthesis in queries.
+
+ Select a CSV file to see the preview. The CSV file should have one
+ column labeled "Chrome Status Entry" and one column labled "Feature
+ ID", although some variations may work. Once the file is parsed, the
+ table below will preview changes that will be made.
+
+ When a specific milestone is approved by API owners, the trial's end
+ date is set based on the stable release date of (end milestone +2). Most
+ of the time when a trial ends, the feature will be enabled by default
+ within the next Chrome release. This additional trial time window
+ ensures users don't see breakage before upgrading to the version with
+ the feature enabled by default.
+
+ `}submitTrialExtension(){window.csClient.extendOriginTrial(this.featureId,this.stage.id).then(()=>{showToastMessage("Extension processed!"),setTimeout(()=>{location.assign(`/feature/${this.featureId}`)},1e3)}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later.")})}renderThreadMissingDialog(){return x$1`
+
+ LGTMs have been detected for this trial extension, but
+ no intent thread link has been detected or provided.
+ All extension proposals must be discussed publicly on blink-dev. Please
+ add the value to the "Intent to Extend Experiment link" field by
+ selecting "Edit fields" button on your feature's "Origin Trial" section.
+
+ Before submitting a creation request, please ensure the
+ following prerequisite steps have been completed:
+
+
+
+
+ The trial's UseCounter has landed on
+
+ web_feature.mojom
+
+ and is being properly used.
+
+
+ A Chromium trial name has landed on
+
+ runtime_enabled_features.json5
+
+ that has not been used for any previous trials. No
+ trial names can be reused, even if used for the same feature!
+
+
+ For a third-party trial, the feature entry in
+
+ runtime_enabled_features.json5
+
+ contains the key "origin_trial_allows_third_party: true".
+
+ If you haven't already, please review the docs for
+
+ running an origin trial . If you have any further questions, contact us at
+ origin-trials-support@google.com.
+
+
+ location.assign(`/ot_creation_request/${this.featureId}/${this.stage.id}`)}
+ size="small"
+ >Proceed
+ `}render(){return this.dialogType===dialogTypes.END_MILESTONE_EXPLANATION?this.renderEndMilestoneExplanationDialog():this.dialogType===dialogTypes.FINALIZE_EXTENSION?this.renderFinalizeExtensionDialog():this.dialogType===dialogTypes.EXTENSION?this.renderExtensionPrereqs():this.renderCreationPrereqs()}};__decorate$U([n$5({type:Number})],ChromedashOTPrereqsDialog.prototype,"featureId",void 0),__decorate$U([n$5({attribute:!1})],ChromedashOTPrereqsDialog.prototype,"stage",void 0),__decorate$U([n$5({type:Number})],ChromedashOTPrereqsDialog.prototype,"milestone",void 0),__decorate$U([n$5({type:Number})],ChromedashOTPrereqsDialog.prototype,"dialogType",void 0),ChromedashOTPrereqsDialog=__decorate$U([t$3("chromedash-ot-prereqs-dialog")],ChromedashOTPrereqsDialog);var __decorate$T=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3!progress.hasOwnProperty(itemName))}function somePendingGates(featureGates,feStage){return 0g.stage_id==feStage.id),otherGates=gatesForStage.filter(g=>"API Owners"!=g.team_name),pendingGates=otherGates.filter(g=>!GATE_FINISHED_REVIEW_STATES.includes(g.state));return pendingGates.sort((g1,g2)=>GATE_TEAM_ORDER.indexOf(g1.team_name)-GATE_TEAM_ORDER.indexOf(g2.team_name)),pendingGates}let ChromedashPreflightDialog=class ChromedashPreflightDialog extends i$4{static get styles(){return[...SHARED_STYLES,i$7`
+ li {
+ margin-top: 0.5em;
+ }
+
+ .missing-prereqs-list {
+ padding-bottom: 1em;
+ }
+
+ .edit-progress-item {
+ visibility: hidden;
+ margin-left: var(--content-padding-half);
+ }
+
+ .active .edit-progress-item,
+ .missing-prereqs .edit-progress-item,
+ .pending:hover .edit-progress-item,
+ .done:hover .edit-progress-item {
+ visibility: visible;
+ }
+
+ sl-button {
+ float: right;
+ margin: var(--content-padding-half);
+ }
+ `]}openWithContext(feature,progress,process,action,stage,feStage,featureGates,url){this._feature=feature,this._progress=progress,this._process=process,this._action=action,this._stage=stage,this._feStage=feStage,this._featureGates=featureGates,this._url=url,this.renderRoot.querySelector("sl-dialog")?.show()}hide(){this.renderRoot.querySelector("sl-dialog")?.hide()}handleCancel(){this.hide()}handleProceed(){this.hide()}renderEditLink(stage,feStage,pi){if(!pi.field)return E$1;const pathSegment=stage?`${stage.outgoing_stage}/${feStage.id}`:"metadata";return x$1`
+
+ Edit
+
+ `}makePrereqItem(itemName){if("Web feature"===itemName)return{name:itemName,field:"web_feature",stage:null};if("Tracking bug URL"===itemName)return{name:itemName,field:"bug_url",stage:null};for(const s of this._process.stages||[])for(const pi of s.progress_items)if(itemName==pi.name)return{...pi,stage:s};throw new Error("prerequiste is not a defined progress item: "+itemName)}renderDialogContent(){if(null==this._feature)return E$1;const prereqItems=[];for(const itemName of this._action.prerequisites||[])this._progress.hasOwnProperty(itemName)||prereqItems.push(this.makePrereqItem(itemName));const pendingGates=findPendingGates(this._featureGates,this._feStage);return x$1`
+ Before you ${this._action.name}, it is strongly recommended that you do
+ the following:
+
+
+ Proceed anyway
+
+ Don't draft email yet
+ `}render(){return x$1`
+
+ ${this.renderDialogContent()}
+
+ `}};__decorate$T([r$6()],ChromedashPreflightDialog.prototype,"_feature",void 0),__decorate$T([r$6()],ChromedashPreflightDialog.prototype,"_featureGates",void 0),__decorate$T([r$6()],ChromedashPreflightDialog.prototype,"_progress",void 0),__decorate$T([r$6()],ChromedashPreflightDialog.prototype,"_process",void 0),__decorate$T([r$6()],ChromedashPreflightDialog.prototype,"_action",void 0),__decorate$T([r$6()],ChromedashPreflightDialog.prototype,"_stage",void 0),__decorate$T([r$6()],ChromedashPreflightDialog.prototype,"_feStage",void 0),__decorate$T([r$6()],ChromedashPreflightDialog.prototype,"_url",void 0),ChromedashPreflightDialog=__decorate$T([t$3("chromedash-preflight-dialog")],ChromedashPreflightDialog);function resolveFieldForFeature(field,feature){const result={...field};return field.computedChoices&&(result.choices=field.computedChoices(feature)),result}const USER_REGEX="[A-Za-z0-9_#$&*+\\/=?\\{\\}~^.\\-]+",DOMAIN_NAME_REGEX="(([A-Za-z0-9\\-]+\\.)+[A-Za-z]{2,6})",LOCALHOST_REGEX="(localhost|127\\.0\\.0\\.1)",DOMAIN_REGEX="("+DOMAIN_NAME_REGEX+"|"+LOCALHOST_REGEX+")",FINCH_NAMES_REGEX="[\\-_a-zA-Z0-9,]*",EMAIL_ADDRESS_REGEX="[A-Za-z0-9_#$&*+\\/=?\\{\\}~^.\\-]+@"+DOMAIN_NAME_REGEX,GOOGLE_EMAIL_ADDRESS_REGEX=`${"[A-Za-z0-9_#$&*+\\/=?\\{\\}~^.\\-]+"}@google.com`,EMAIL_ADDRESSES_REGEX=EMAIL_ADDRESS_REGEX+"([ ]*,[ ]*"+EMAIL_ADDRESS_REGEX+")*",PORTNUM_REGEX="(:[0-9]+)?",URL_REGEX="(https?)://"+DOMAIN_REGEX+PORTNUM_REGEX+"(/\\S*)?",URL_PADDED_REGEX="\\s*"+URL_REGEX+"\\s*",URL_FIELD_ATTRS={title:"Enter a full URL https://...",type:"url",placeholder:"https://...",pattern:URL_PADDED_REGEX},MULTI_STRING_FIELD_ATTRS={title:"Enter one or more comma-separated complete words.",type:"text",multiple:!0,placeholder:"EnableFeature1, Feature1Policy"},MULTI_EMAIL_FIELD_ATTRS={title:"Enter one or more comma-separated complete email addresses.",type:"text",multiple:!0,placeholder:"user1@domain.com, user2@chromium.org",pattern:EMAIL_ADDRESSES_REGEX},TEXT_FIELD_ATTRS={type:"text"},MILESTONE_NUMBER_FIELD_ATTRS={type:"number",placeholder:"Milestone number"},OT_MILESTONE_DESKTOP_RANGE={earlier:"ot_milestone_desktop_start",later:"ot_milestone_desktop_end"},OT_MILESTONE_ANDROID_RANGE={earlier:"ot_milestone_android_start",later:"ot_milestone_android_end"},OT_MILESTONE_WEBVIEW_RANGE={earlier:"ot_milestone_webview_start",later:"ot_milestone_webview_end"},OT_ALL_SHIPPED_MILESTONE_DESKTOP_RANGE={earlier:"ot_milestone_desktop_start",allLater:"shipped_milestone",warning:"Origin trial starting milestone should be before all feature shipping milestones."},ALL_OT_SHIPPED_MILESTONE_DESKTOP_RANGE={allEarlier:"ot_milestone_desktop_start",later:"shipped_milestone",warning:"All origin trials starting milestones should be before feature shipping milestone."},OT_ALL_SHIPPED_MILESTONE_WEBVIEW_RANGE={earlier:"ot_milestone_webview_start",allLater:"shipped_webview_milestone",warning:"Origin trial starting milestone should be before all feature shipping milestones."},ALL_OT_SHIPPED_MILESTONE_WEBVIEW_RANGE={allEarlier:"ot_milestone_webview_start",later:"shipped_webview_milestone",warning:"All origin trials starting milestones should be before feature shipping milestone."},OT_ALL_SHIPPED_MILESTONE_ANDROID_RANGE={earlier:"ot_milestone_android_start",allLater:"shipped_android_milestone",warning:"Origin trial starting milestone should be before all feature shipping milestones."},ALL_OT_SHIPPED_MILESTONE_ANDROID_RANGE={allEarlier:"ot_milestone_android_start",later:"shipped_android_milestone",warning:"All origin trials starting milestones should be before feature shipping milestone."},DT_ALL_SHIPPED_MILESTONE_DESKTOP_RANGE={earlier:"dt_milestone_desktop_start",allLater:"shipped_milestone",warning:"Shipped milestone should be later than dev trial."},ALL_DT_SHIPPED_MILESTONE_DESKTOP_RANGE={allEarlier:"dt_milestone_desktop_start",later:"shipped_milestone",warning:"Shipped milestone should be later than dev trial."},DT_ALL_SHIPPED_MILESTONE_ANDROID_RANGE={earlier:"dt_milestone_android_start",allLater:"shipped_android_milestone",warning:"Shipped milestone should be later than dev trial start milestone."},ALL_DT_SHIPPED_MILESTONE_ANDROID_RANGE={allEarlier:"dt_milestone_android_start",later:"shipped_android_milestone",warning:"Shipped milestone should be later than dev trial start milestone."},DT_ALL_SHIPPED_MILESTONE_IOS_RANGE={earlier:"dt_milestone_ios_start",allLater:"shipped_ios_milestone",warning:"Shipped milestone should be later than dev trial start milestone."},ALL_DT_SHIPPED_MILESTONE_IOS_RANGE={allEarlier:"dt_milestone_ios_start",later:"shipped_ios_milestone",warning:"Shipped milestone should be later than dev trial start milestone."},MULTI_URL_FIELD_ATTRS={title:"Enter one or more full URLs, one per line:\nhttps://...\nhttps://...",multiple:!0,placeholder:"https://...\nhttps://...",rows:4,cols:50,maxlength:5e3,chromedash_single_pattern:URL_REGEX,chromedash_split_pattern:"\\s+"},SHIPPED_HELP_TXT=x$1` First milestone to ship with this status. Applies
+to: Enabled by default, Deprecated, and Removed.`,SHIPPED_WEBVIEW_HELP_TXT=x$1` First milestone to ship with this status.
+Applies to Enabled by default, Deprecated, and Removed.`,ALL_FIELDS={name:{type:"input",attrs:TEXT_FIELD_ATTRS,required:!0,label:"Feature name",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1`
+ Capitalize only the first letter and the beginnings of proper nouns.
+
`,extra_help:x$1`
+ Each feature should have a unique name that is written as a noun phrase.
+
+
+
+ Capitalize only the first letter and the beginnings of proper nouns.
+
+
+ Avoid using verbs such as "add", "enhance", "deprecate", or "delete".
+ Instead, simply name the feature itself and use the feature type and
+ stage fields to indicate the intent of change.
+
+
+ Do not include markup or markdown because they will not be rendered..
+
+
+ Write keywords and identifiers as they would appear to a web
+ developer, not as they are in source code. In particular, do not use
+ static method/property syntax for instance methods/properties. For
+ example, for an instance method doStuff() on an interface
+ NewInterface, write "NewInterface's doStuff() method" (not
+ "NewInterface.doStuff() method"). Or for a method on a well-known
+ global like Document, write "document.doStuff()" (not
+ "Document.doStuff()").
+
+ This text will be used in the
+ enterprise release notes, which are publicly visible and primarily written for IT admins. All
+ Enterprise policies must be included in this summary section.
+
+
+ Explain what's changing from the point of view of an end-user,
+ developer, or administrator. Indicate what the motivation is for this
+ change, especially if there’s security or privacy benefits to the
+ change. If an admin should do something (like test or set a flag or an
+ enterprise policy), please explain. Finally, if the change has a
+ user-visible benefit (eg. better security or privacy), explain that
+ motivation. If there are already publicly visible comms (e.g. blog
+ posts), you should link to them here as well.
+
+ Text in the beta release post, the enterprise release notes, and other
+ external sources will be based on this text.
+
+
+ Write from a web developer's point of view. Begin with one line
+ explaining what the feature does. Add one or two lines explaining how
+ this feature helps developers. Write in a matter-of-fact manner and in
+ the present tense. (This summary will be visible long after your project
+ is finished.) Avoid language such as "a new feature" and "we propose".
+
+ `,extra_help:x$1`
+
+ Provide a one sentence description followed by one or two lines
+ explaining how this feature works and how it helps web developers.
+
+
+
+ Note: This text communicates with more than just the rest of Chromium
+ development. It's the part most visible to external readers and is used
+ in the beta release announcement, enterprise release notes, and other
+ communications.
+
+
+
+
+ Write from a web developer's point of view, not a browser developer's
+
+
+ Do not use markup or markdown because they will not be rendered.
+
+
+ Do not use hard or soft returns because they will not be rendered.
+
+
+ Avoid phrases such as "a new feature". Every feature on the site was
+ new when it was created. You don't need to repeat that information.
+
+
+
+ The first line should be a sentence fragment beginning with a verb.
+ (See below.) This is the rare exception to the requirement to always
+ use complete sentences.
+
+
+
+ "Conformance with spec" is not adequate. Most if not all features are
+ in conformance to spec.
+
+
+
+
Example
+
+ Splits the HTTP cache using the top frame origin (and possibly subframe
+ origin) to prevent documents from one origin from knowing whether a
+ resource from another origin was cached. The HTTP cache is currently one
+ per profile, with a single namespace for all resources and subresources
+ regardless of origin or renderer process. Splitting the cache on top
+ frame origins helps the browser deflect side-channel attacks where one
+ site can detect resources in another site's cache.
+
+ `,enterprise_extra_help:"",check:value=>value&&"string"==typeof value&&0value.length||5e3web-features project. If your feature is not listed,
+ propose a new web feature ID, then return to this tab and choose "Missing feature".`},category:{type:"select",choices:FEATURE_CATEGORIES,initial:FEATURE_CATEGORIES.MISC[0],label:"Category",usage:{},help_text:x$1` Select the most specific category. If unsure, leave as
+ "Miscellaneous".`},enterprise_product_category:{type:"radios",name:"enterprise_product_category",choices:ENTERPRISE_PRODUCT_CATEGORY,label:"Enterprise product category",usage:{},help_text:x$1` Select the appropriate category.`},feature_type:{type:"select",disabled:!0,choices:FEATURE_TYPES,label:"Feature type",usage:{},help_text:x$1` Feature type chosen at time of creation.
+
+
+ Note: The feature type field cannot be changed. If this
+ field needs to be modified, a new feature would need to be created.
+
`,check:(_value,getFieldValue)=>checkFeatureNameAndType(getFieldValue)},feature_type_radio_group:{name:"feature_type",type:"radios",choices:FEATURE_TYPES_WITHOUT_ENTERPRISE,label:"Feature type",usage:{},help_text:x$1`If all goes well, how will developers experience the change
+ you're planning to make to Chromium?
+
+
+ Note: The feature type field cannot be changed. If this
+ field needs to be modified, a new feature would need to be created.
+
`,check:(_value,getFieldValue)=>checkFeatureNameAndType(getFieldValue)},active_stage_id:{type:"select",computedChoices(formattedFeature){const result={};for(const stage of formattedFeature.stages){const name=unambiguousStageName(stage,formattedFeature);name&&(result[stage.id]=[stage.id,name])}return result},label:"Active stage",usage:{},help_text:x$1`The active stage opens by default in this feature's page.
+ And, it roughly indicates progress in the process.`},search_tags:{type:"input",attrs:TEXT_FIELD_ATTRS,required:!1,label:"Search tags",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Comma separated keywords used only in search.`},bug_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Tracking bug URL",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Tracking bug url (https://bugs.chromium.org/...). This bug
+ should have "Type=Feature" set and be world readable. Note: This field
+ only accepts one URL.
+
+
+ Create tracking bug`},launch_bug_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Launch URL",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Launch URL (https://launch.corp.google.com/...) to track
+ internal approvals, if any.
+
+
+ Create a launch.`},screenshot_links:{type:"attachments",attrs:MULTI_URL_FIELD_ATTRS,required:!1,label:"Screenshot link(s)",usage:{[FeatureType.Incubate]:new Set([UsageType.ReleaseNotes]),[FeatureType.Existing]:new Set([UsageType.ReleaseNotes]),[FeatureType.CodeChange]:new Set([UsageType.ReleaseNotes]),[FeatureType.Deprecation]:new Set([UsageType.ReleaseNotes]),[FeatureType.Enterprise]:new Set([UsageType.ReleaseNotes])},help_text:x$1` Optional: Links to screenshots showcasing this feature (one
+ URL per line). Be sure to link directly to the image with a URL ending in
+ .png, .gif, or .jpg, rather than linking to an HTML page that contains the
+ image. Or, use the upload button to upload an image to be served from
+ chromestatus.com. These will be shared publicly.`,check:async value=>{const warning={warning:`One or more urls are not actual images or requires the consumer some kind
+ of authentication to access them. Use a valid link to an actual image free
+ of authentication or upload your image.`},urls=value.split("\n").filter(x=>!!x).map(x=>x.trim());if(urls.length){if(urls.some(x=>{try{return new URL(x),!1}catch{return!0}}))return warning;const urlTypes=await Promise.all(urls.map(url=>fetch(url,{method:"HEAD"}).then(response=>response.blob()).then(blob=>blob.type).catch(()=>"error")));return urlTypes.some(type=>!type.startsWith("image"))?warning:void 0}}},first_enterprise_notification_milestone:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"First notification milestone",usage:{},help_text:x$1` Optional: Unless you're sure you need to use this, leave it
+ blank.
+
+ If you leave this blank, we will automatically find the right milestone.
+
+ If you're not ready to communicate this feature to enterprises yet, what
+ is the earliest milestone that you expect to be ready to communicate it?
+ You can change this later. In general, you should provide enterprises
+ notice at least 3 milestones before making an impactful change.`,check:(value,_,initialValue)=>checkFirstEnterpriseNotice(value,initialValue)},motivation:{type:"textarea",required:!1,label:"Motivation",usage:{[FeatureType.Incubate]:new Set([UsageType.Prototype]),[FeatureType.Existing]:new Set([UsageType.Prototype]),[FeatureType.Deprecation]:new Set([UsageType.DeprecateAndRemove])},help_text:x$1` Explain why the web needs this change. It may be useful to
+ describe what web developers are forced to do without it. When possible,
+ add links to your explainer (under
+ Explainer link(s)) backing up your
+ claims.
+ This text is sometimes included with the summary in the beta post,
+ enterprise release notes and other external documents. Write in a
+ matter-of-fact manner and in the present tense.
+
+
+ Example`},deprecation_motivation:{name:"motivation",type:"textarea",required:!1,label:"Motivation",usage:{[FeatureType.Deprecation]:new Set([UsageType.DeprecateAndRemove])},help_text:x$1` Deprecations and removals must have strong reasons, backed
+ up by measurements. There must be clear and actionable paths forward for
+ developers.
+
+ This text is sometimes included with the summary in the beta post,
+ enterprise release notes and other external documents. Write in a
+ matter-of-fact manner and in the present tense.
+
+ Please see
+
+ Removal guidelines.`},initial_public_proposal_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Initial public proposal URL",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Link to the first public proposal to create this feature.`,extra_help:x$1` If there isn't another obvious place to propose your
+ feature, create a
+
+ WICG proposal. You can use your proposal document to help you socialize the problem
+ with other vendors and developers.`},explainer_links:{type:"textarea",attrs:MULTI_URL_FIELD_ATTRS,required:!1,label:"Explainer link(s)",usage:{[FeatureType.Incubate]:ALL_FEATURE_TYPE_INCUBATE_INTENTS,[FeatureType.Deprecation]:ALL_FEATURE_TYPE_DEPRECATION_INTENTS},help_text:x$1`Link to explainer(s) (one URL per line). See the
+ launch process
+ for detailed advice, or expand the extra help here for a summary.`,extra_help:x$1`
+ Host your explainer somewhere like Github (and not Google Docs)
+ that makes it easy to file issues. Your organization may recommend a
+ particular place.
+
+
+ See the TAG guide to writing
+ Explainers
+ for several examples of good explainers and tips for effective
+ explainers.
+
+
+ If you've already made an initial public proposal (see above), post your
+ explainer to that thread. Otherwise, make an initial proposal based on
+ your explainer.
+
+
+ Once a second organization is interested in the WICG proposal, you can
+ move the explainer into the WICG. The
+ WICG co-chairs
+ can help you.
+
`,check:value=>checkNotGoogleDocs(value,"Explainers should not be hosted on Google Docs.")},spec_link:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Spec link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Link to the spec, if and when available. When implementing
+ a spec update, please link to a heading in a published spec rather than a
+ pull request when possible.`,extra_help:x$1`
+ Specifications should be written in the format and hosted in the URL space
+ expected by your target standards body. For example, the W3C expects
+ Respec or
+ Bikeshed
+ hosted on w3.org or in Github Pages. The IETF expects an
+ Internet-Draft
+ hosted in the
+ Datatracker.
+
`,check:value=>checkNotGoogleDocs(value,"Specifications should not be hosted on Google Docs.")},comments:{type:"textarea",name:"feature_notes",attrs:{rows:4},required:!1,label:"Comments",usage:{},help_text:x$1` Additional comments, caveats, info...`},standard_maturity:{type:"select",choices:STANDARD_MATURITY_CHOICES,initial:STANDARD_MATURITY_CHOICES.PROPOSAL_STD[0],label:"Standard maturity",usage:{},help_text:x$1` How far along is the standard that this feature implements?`},api_spec:{type:"checkbox",initial:!1,label:"API spec",usage:{},help_text:x$1` The spec document has details in a specification language
+ such as Web IDL, or there is an existing MDN page.`},automation_spec:{type:"checkbox",initial:!1,label:"Automation spec",usage:{},help_text:x$1` The platform has sufficient automation features for website
+ authors to test use of this new feature. These automation features can
+ include new automation APIs, like WebDriver BiDi modules, that are defined
+ in this feature's specification.`},spec_mentors:{type:"input",name:"spec_mentor_emails",attrs:MULTI_EMAIL_FIELD_ATTRS,required:!1,label:"Spec mentors",usage:{},help_text:x$1` Experienced
+
+ spec mentors
+ are available to help you improve your feature spec.`},intent_to_implement_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Intent to Prototype link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` After you have started the "Intent to Prototype" discussion
+ thread, link to it here.`},doc_links:{type:"textarea",attrs:MULTI_URL_FIELD_ATTRS,required:!1,label:"Doc link(s)",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Links to design doc(s) (one URL per line), if and when
+ available. [This is not required to send out an Intent to Prototype. Please
+ update the intent thread with the design doc when ready]. An explainer
+ and/or design doc is sufficient to start this process. [Note: Please include
+ links and data, where possible, to support any claims.`},measurement:{type:"textarea",attrs:{rows:4},required:!1,label:"Measurement",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` It's important to measure the adoption and success of
+ web-exposed features. Note here what measurements you have added to track
+ the success of this feature, such as a link to the UseCounter(s) you have
+ set up.`},availability_expectation:{type:"textarea",attrs:{rows:4},required:!1,label:"Availability expectation",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` What is your availability expectation for this feature?
+ Examples:`,extra_help:x$1`
+
+
+ Feature is available on Web Platform Baseline within 12 months of
+ launch in Chrome.
+
+
+
+ Feature is available only in Chromium browsers for the foreseeable
+ future.
+
+
+ `},adoption_expectation:{type:"textarea",attrs:{rows:4},required:!1,label:"Adoption expectation",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` What is your adoption expectation for this feature?
+ Examples:`,extra_help:x$1`
+
+
+ Feature is considered a best practice for some use case within 12
+ months of reaching Web Platform baseline.
+
+
+
+ Feature is used by specific partner(s) to provide functionality within
+ 12 months of launch in Chrome.
+
+
+
+ At least 3 major abstractions replace their use of an existing feature
+ with this feature within 24 months of reaching mainline.
+
+
+ `},adoption_plan:{type:"textarea",attrs:{rows:4},required:!1,label:"Adoption plan",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` What is the plan to achieve the stated expectations? Please
+ provide a plan that covers availability and adoption for the feature.`},security_review_status:{type:"select",choices:REVIEW_STATUS_CHOICES,initial:REVIEW_STATUS_CHOICES.REVIEW_PENDING[0],label:"Security review status",usage:{},help_text:x$1` Status of the security review.`},privacy_review_status:{type:"select",choices:REVIEW_STATUS_CHOICES,initial:REVIEW_STATUS_CHOICES.REVIEW_PENDING[0],label:"Privacy review status",usage:{},help_text:x$1`Status of the privacy review.`},tag_review:{type:"textarea",attrs:{rows:2},required:!1,label:"TAG specification review",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Link(s) to TAG specification review(s), or explanation why
+ this is not needed.`,extra_help:x$1`
+ The
+ W3C Technical Architecture Group
+ (TAG) is a special working group of the W3C that consists of a few
+ appointed and elected members, all of whom are experienced members of
+ the web standards community. The Blink launch process has a
+ formal requirement for requesting a TAG specification review
+ for all features. The review happens publicly on a GitHub issue.
+
+
+ You will likely have asked for an "Early design/incubation review" earlier in the process to get the TAG familiar with your feature.
+ This isn't that.
+
+
+ It's recommended that you file a TAG specification review as soon as
+ your specification is written, and at least a month ahead of sending an
+ Intent to Ship. There may be some work involved in preparing your
+ feature for review. See the
+ launch process
+ for help picking which kind of specification review to file, and then
+ look through that template to find what data to collect.
+
+
+ A large number of Intents to Ship are delayed because a TAG
+ specification review was only recently filed and engagement from the TAG
+ can take multiple weeks to multiple months. Note that the API owners can
+ approve shipping even if the TAG hasn't replied to your review request,
+ as long as you've made a reasonable effort to obtain their review with
+ enough time for them to give feedback.
+
`},tag_review_status:{type:"select",choices:REVIEW_STATUS_CHOICES,initial:REVIEW_STATUS_CHOICES.REVIEW_PENDING[0],label:"TAG specification review status",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1`Status of the TAG specification review.`},intent_to_ship_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Intent to Ship link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1`After you have started the "Intent to Ship" discussion
+ thread, link to it here.`},announcement_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Ready for Developer Testing link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1`After you have started the "Ready for Developer Testing"
+ discussion thread, link to it here.`},intent_to_experiment_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Intent to Experiment link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1`After you have started the "Intent to Experiment" discussion
+ thread, link to it here.`},intent_to_extend_experiment_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Intent to Extend Experiment link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1`If this feature has an "Intent to Extend Experiment"
+ discussion thread, link to it here.`},ot_extension__intent_to_extend_experiment_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!0,label:"Intent to Extend Experiment link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Link to the approved Intent to Extend Experiment, as per
+
+ the trial extension process .`},r4dt_url:{name:"intent_to_experiment_url",type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Request for Deprecation Trial link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1`After you have started the "Request for Deprecation Trial"
+ discussion thread, link to it here.`},interop_compat_risks:{type:"textarea",required:!1,label:"Interoperability and compatibility risks",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Describe the degree of
+
+ interoperability risk. For a new feature, the main risk is that it fails to become an
+ interoperable part of the web platform if other browsers do not implement
+ it. For a removal, please review our
+
+ principles of web compatibility.
+
+ Please include citation links below where possible. Examples include
+ resolutions from relevant standards bodies (e.g. W3C working group),
+ tracking bugs, or links to online conversations.
+
+ Example.`},safari_views:{type:"select",choices:VENDOR_VIEWS_COMMON,initial:VENDOR_VIEWS_COMMON.NO_PUBLIC_SIGNALS[0],label:"WebKit views",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` See
+
+ chromium.org/blink/launching-features/wide-review
+ `},safari_views_link:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"",displayLabel:"WebKit views link",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1`Citation link.`},safari_views_notes:{type:"textarea",attrs:{rows:2,placeholder:"Notes"},required:!1,label:"",displayLabel:"WebKit views notes",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:""},ff_views:{type:"select",choices:VENDOR_VIEWS_GECKO,initial:VENDOR_VIEWS_GECKO.NO_PUBLIC_SIGNALS[0],label:"Firefox views",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` See
+
+ chromium.org/blink/launching-features/wide-review
+ `},ff_views_link:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"",displayLabel:"Firefox views link",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Citation link.`},ff_views_notes:{type:"textarea",attrs:{rows:2,placeholder:"Notes"},required:!1,label:"",displayLabel:"Firefox views notes",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:""},web_dev_views:{type:"select",choices:WEB_DEV_VIEWS,initial:WEB_DEV_VIEWS.DEV_NO_SIGNALS[0],label:"Web / Framework developer views",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` If unsure, default to "No signals". See
+
+ https://goo.gle/developer-signals`},web_dev_views_link:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"",displayLabel:"Web / Framework developer views link",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Citation link.`},web_dev_views_notes:{type:"textarea",attrs:{rows:2,placeholder:"Notes"},required:!1,label:"",displayLabel:"Web / Framework developer views notes",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Reference known representative examples of opinions, both
+ positive and negative.`},other_views_notes:{type:"textarea",attrs:{rows:4,placeholder:"Notes"},required:!1,label:"Other views",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` For example, other browsers.`},ergonomics_risks:{type:"textarea",required:!1,label:"Ergonomics risks",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Are there any other platform APIs this feature will
+ frequently be used in tandem with? Could the default usage of this API make
+ it hard for Chrome to maintain good performance (i.e. synchronous return,
+ must run on a certain thread, guaranteed return timing)?`},activation_risks:{type:"textarea",required:!1,label:"Activation risks",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Will it be challenging for developers to take advantage of
+ this feature immediately, as-is? Would this feature benefit from having
+ polyfills, significant documentation and outreach, and/or libraries built on
+ top of it to make it easier to use?`},security_risks:{type:"textarea",required:!1,label:"Security Risks",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` List any security considerations that were taken into
+ account when designing this feature.`},webview_risks:{type:"textarea",required:!1,label:"WebView application risks",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Does this feature deprecate or change behavior of existing
+ APIs, such that it has potentially high risk for Android WebView-based
+ applications? (See
+
+ here
+ for a definition of "potentially high risk", information on why changes to
+ this platform carry higher risk, and general rules of thumb for which
+ changes have higher or lower risk) If so:
+
+
+ Please use a base::Feature killswitch (examples here) that can be flipped off in case of compat issues
+
+
Consider contacting android-webview-dev@chromium.org for advice
+
+ If you are not sure, just put "not sure" as the answer and the API
+ owners can help during the review of your Intent to Ship
+
+
`},experiment_goals:{type:"textarea",required:!1,label:"Experiment goals",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Which pieces of the API surface are you looking to gain
+ insight on? What metrics/measurement/feedback will you be using to
+ validate designs? Double check that your experiment makes sense given that
+ a large developer (e.g. a Google product or Facebook) likely can't use it
+ in production due to the limits enforced by origin trials.
+
+ If you send an Intent to Extend Origin Trial, highlight areas for
+ experimentation. They should not be an exact copy of the goals from the
+ first Intent to Experiment.`},experiment_timeline:{type:"textarea",attrs:{rows:2,placeholder:"This field is deprecated",disabled:!0},required:!1,label:"Experiment timeline",usage:{[FeatureType.Incubate]:new Set([UsageType.Experiment]),[FeatureType.Existing]:new Set([UsageType.Experiment]),[FeatureType.Deprecation]:new Set([UsageType.Experiment])},help_text:x$1` When does the experiment start and expire? Deprecated:
+ Please use the numeric fields above instead.`,deprecated:!0},ot_milestone_desktop_start:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"OT desktop start",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` First desktop milestone that will support an origin trial
+ of this feature.`,check:(_value,getFieldValue)=>checkMilestoneRanges([OT_MILESTONE_DESKTOP_RANGE,OT_ALL_SHIPPED_MILESTONE_DESKTOP_RANGE],getFieldValue)},ot_milestone_desktop_end:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"OT desktop end",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Last desktop milestone that will support an origin trial of
+ this feature.`,check:(_value,getFieldValue)=>checkMilestoneRanges([OT_MILESTONE_DESKTOP_RANGE],getFieldValue)},ot_milestone_android_start:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"OT Android start",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` First android milestone that will support an origin trial
+ of this feature.`,check:(_value,getFieldValue)=>checkMilestoneRanges([OT_MILESTONE_ANDROID_RANGE,OT_ALL_SHIPPED_MILESTONE_ANDROID_RANGE],getFieldValue)},ot_milestone_android_end:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"OT Android end",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Last android milestone that will support an origin trial of
+ this feature.`,check:(_value,getFieldValue)=>checkMilestoneRanges([OT_MILESTONE_ANDROID_RANGE],getFieldValue)},ot_milestone_webview_start:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"OT WebView start",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` First WebView milestone that will support an origin trial
+ of this feature.`,check:(_value,getFieldValue)=>checkMilestoneRanges([OT_MILESTONE_WEBVIEW_RANGE,OT_ALL_SHIPPED_MILESTONE_WEBVIEW_RANGE],getFieldValue)},ot_milestone_webview_end:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"OT WebView end",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Last WebView milestone that will support an origin trial of
+ this feature.`,check:(_value,getFieldValue)=>checkMilestoneRanges([OT_MILESTONE_WEBVIEW_RANGE],getFieldValue)},experiment_risks:{type:"textarea",required:!1,label:"Experiment risks",usage:{},help_text:x$1` When this experiment comes to an end are there any risks to
+ the sites that were using it, for example losing access to important storage
+ due to an experimental storage API?`},experiment_extension_reason:{type:"textarea",required:!1,label:"Experiment extension reason",usage:{[FeatureType.Incubate]:new Set([UsageType.Experiment]),[FeatureType.Existing]:new Set([UsageType.Experiment]),[FeatureType.Deprecation]:new Set([UsageType.Experiment])},help_text:x$1` If this is a repeated or extended experiment, explain why
+ it's being repeated or extended. Also, fill in discussion link fields below.`},extension_desktop_last:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!0,label:"Trial extension end milestone",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` The last desktop milestone in which the trial will be
+ available after extension.`},extension_android_last:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"Trial extension Android end",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` The last android milestone in which the trial will be
+ available after extension.`},extension_webview_last:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"Trial extension WebView end",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` The last WebView milestone in which the trial will be
+ available after extension.`},ot_extension__milestone_desktop_last:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!0,label:"Trial extension end milestone",usage:{},help_text:x$1` The last milestone in which the trial will be available
+ after extension.`,check:_value=>checkExtensionMilestoneIsValid(_value)},ongoing_constraints:{type:"textarea",required:!1,label:"Ongoing Constraints",usage:{[FeatureType.Incubate]:new Set([UsageType.Experiment]),[FeatureType.Existing]:new Set([UsageType.Experiment]),[FeatureType.Deprecation]:new Set([UsageType.Experiment])},help_text:x$1` Do you anticipate adding any ongoing technical constraints
+ to the codebase while implementing this feature? We prefer to avoid features
+ that require or assume a specific architecture. For most features, the
+ answer is "None."`},rollout_plan:{type:"select",choices:ROLLOUT_PLAN,initial:ROLLOUT_PLAN.ROLLOUT_100[0],label:"Rollout plan",usage:{[FeatureType.Incubate]:new Set([UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.Experiment,UsageType.Ship])},help_text:x$1`Normally, WP features that ship in a milestone go to all
+ users of that milestone. If your feature needs to roll out in any other way,
+ mark that here.`},origin_trial_feedback_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Origin trial feedback summary",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` If your feature was available as an origin trial, link to a
+ summary of usage and developer feedback. If not, leave this empty. DO NOT
+ USE FEEDBACK VERBATIM without prior consultation with the Origin Trials
+ team.`},ot_chromium_trial_name:{type:"input",attrs:TEXT_FIELD_ATTRS,required:!0,label:"Chromium trial name",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Name for the trial, given as the value of the property
+ "origin_trial_feature_name" as specified in
+ runtime_enabled_features.json5.
+
+
+ Note: This name should be unique and should not be used
+ by any previous origin trials!
+
`},ot_documentation_url:{type:"input",attrs:URL_FIELD_ATTRS,label:"Documentation link",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Link to more information to help developers use the trial's
+ feature (e.g. blog post, Github explainer, etc.).`},ot_creation__ot_documentation_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!0,label:"Documentation link",usage:{},help_text:x$1` Link to more information to help developers use the trial's
+ feature (e.g. blog post, Github explainer, etc.).`},ot_emails:{type:"input",attrs:MULTI_EMAIL_FIELD_ATTRS,required:!1,label:"Origin trial contacts",usage:{},help_text:x$1` List any other individuals or groups to include on the
+ contact list (e.g. for reminders on trial milestones). Mailing list emails
+ can be used here, but only email addresses of individuals will receive
+ access to view registrant data on
+ go/ot-registrants-dashboard.
+
+
+ Please prefer using "@google.com" domain email addresses for any
+ contacts that have one.
+
+
`},ot_has_third_party_support:{type:"checkbox",initial:!1,label:"Origin trial supports third party origins",usage:{},help_text:x$1` Whether this trial supports third party origins. See
+ this article
+ for more information. The feature should have
+ "origin_trial_allows_third_party" set to "true" in
+ runtime_enabled_features.json5`},ot_is_critical_trial:{type:"checkbox",initial:!1,label:"Critical origin trial",usage:{},help_text:x$1` See
+ go/running-an-origin-trial
+ for criteria and additional process requirements. The feature name must be
+ added to the "kHasExpiryGracePeriod" array in
+ manual_completion_origin_trial_features.cc`},ot_is_deprecation_trial:{type:"checkbox",initial:!1,label:"Deprecation trial",usage:{},help_text:x$1` Is this a deprecation trial? See the
+ deprecation trial section
+ for more information.`},ot_request_note:{type:"textarea",required:!1,label:"Anything else?",usage:{},help_text:x$1`
+ Let us know if you have any further questions or comments.
+
`},ot_webfeature_use_counter:{type:"input",attrs:{...TEXT_FIELD_ATTRS,placeholder:"e.g. \"kWebFeature\"",pattern:"k\\S*"},label:"UseCounter name",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` For measuring usage, this must be a single named value from
+ the WebFeature, WebDXFeature, or CSSSampleId enum, e.g. kWorkerStart. The
+ use counter must be landed in either
+ web_feature.mojom,
+ webdx_feature.mojom, or
+ css_property_id.mojom. Not required for deprecation trials.`},ot_webfeature_use_counter__type:{type:"radios",label:"Use counter type",choices:WEBFEATURE_USE_COUNTER_TYPES,usage:{},help_text:x$1`Which type of use counter the feature is using. This can be
+ determined by which file the use counter is defined in.`},ot_require_approvals:{type:"checkbox",initial:!1,label:"Trial participation requires approval",usage:{},help_text:x$1`
+ Will this trial require registrants to receive approval before
+ participating? Please reach out to origin-trials-support@google.com
+ beforehand to discuss options here.
+
`},ot_approval_buganizer_component:{type:"input",attrs:{type:"number"},required:!0,label:"Approvals Buganizer component ID",usage:{},help_text:x$1`Buganizer component ID used for approvals requests.`},ot_approval_buganizer_custom_field_id:{type:"input",attrs:{type:"number"},required:!0,label:"Approvals Buganizer custom field ID",usage:{},help_text:x$1`The Buganizer custom field ID for trial registration
+ approval. This custom field in Buganizer provides approval/rejection
+ rationales for registration requests under ot_approval_buganizer_component.`},ot_approval_group_email:{type:"input",required:!0,attrs:{...TEXT_FIELD_ATTRS,pattern:GOOGLE_EMAIL_ADDRESS_REGEX,placeholder:"ex. \"approval-requests@google.com\""},label:"Registration request notifications group",usage:{},help_text:x$1`
+ Google group email to be used for new registration request notifications.
+ Please supply a '@google.com' domain email address only.
+
+ Link to public documentation describing the requirements to be approved
+ for trial participation.
+
`},ot_creation__intent_to_experiment_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!0,label:"Intent to Experiment link",usage:{},help_text:x$1`Your "Intent to Experiment" discussion thread. The necessary
+ LGTMs should already have been received.`},ot_creation__milestone_desktop_first:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!0,label:"Trial milestone start",usage:{},help_text:x$1` First milestone that will support an origin trial of this
+ feature.`,check:(_value,getFieldValue)=>checkMilestoneRanges([OT_MILESTONE_DESKTOP_RANGE,OT_ALL_SHIPPED_MILESTONE_DESKTOP_RANGE],getFieldValue)},ot_creation__milestone_desktop_last:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!0,label:"Trial milestone end",usage:{},help_text:x$1` Last milestone that will support an origin trial of this
+ feature.`,check:(_value,getFieldValue)=>checkMilestoneRanges([OT_MILESTONE_DESKTOP_RANGE],getFieldValue)},ot_creation__bypass_file_checks:{type:"checkbox",initial:!1,label:"Bypass Chromium file checks (staging testing)",usage:{},help_text:x$1`This option should only be visible in ChromeStatus staging
+ environments. Allow this form to be submitted without verifying Chromium
+ code has landed.`},anticipated_spec_changes:{type:"textarea",attrs:{rows:4},required:!1,label:"Anticipated spec changes",usage:{[FeatureType.Incubate]:ALL_FEATURE_TYPE_INCUBATE_INTENTS,[FeatureType.Existing]:ALL_FEATURE_TYPE_EXISTING_INTENTS,[FeatureType.Deprecation]:ALL_FEATURE_TYPE_DEPRECATION_INTENTS},help_text:x$1` Open questions about a feature may be a source of future
+ web compat or interop issues. Please list open issues (e.g. links to known
+ github issues in the repo for the feature specification) whose resolution
+ may introduce web compat/interop risk (e.g., changing the naming or
+ structure of the API in a non-backward-compatible way).`},finch_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"Finch experiment",usage:{},help_text:x$1` If your feature will roll out gradually via a
+ Finch experiment, link to it
+ here.`},i2e_lgtms:{type:"input",attrs:{...MULTI_EMAIL_FIELD_ATTRS,placeholder:"This field is deprecated",disabled:!0},required:!1,label:"Intent to Experiment LGTM by",usage:{},help_text:x$1` Full email address of API owner who LGTM'd the Intent to
+ Experiment email thread.`,deprecated:!0},i2s_lgtms:{type:"input",attrs:{...MULTI_EMAIL_FIELD_ATTRS,placeholder:"This field is deprecated",disabled:!0},required:!1,label:"Intent to Ship LGTMs by",usage:{},help_text:x$1`
+ Comma separated list of email addresses of API owners who LGTM'd the
+ Intent to Ship email thread.
+ `,deprecated:!0},r4dt_lgtms:{name:"i2e_lgtms",type:"input",attrs:{...MULTI_EMAIL_FIELD_ATTRS,placeholder:"This field is deprecated",disabled:!0},required:!1,label:"Request for Deprecation Trial LGTM by",usage:{},help_text:x$1` Full email addresses of API owners who LGTM'd the Request
+ for Deprecation Trial email thread.`,deprecated:!0},debuggability:{type:"textarea",required:!1,label:"Debuggability",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Description of the DevTools debugging support for your
+ feature. Please follow the
+
+ DevTools support checklist
+ for guidance.`},all_platforms:{type:"checkbox",initial:!1,label:"Supported on all platforms?",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Will this feature be supported on all six Blink platforms
+ (Windows, Mac, Linux, ChromeOS, Android, and Android WebView)?`},all_platforms_descr:{type:"textarea",attrs:{rows:2},required:!1,label:"Platform support explanation",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Explain why this feature is, or is not, supported on all
+ platforms.`},wpt:{type:"checkbox",initial:!1,label:"Web Platform Tests",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Is this feature fully tested in Web Platform Tests?`},wpt_descr:{type:"textarea",required:!1,label:"Web Platform Tests or other automated test description",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Please link to the
+ results on wpt.fyi.
+ If any part of the feature is not tested by web-platform-tests, please
+ include links to other automated tests or links to issues, e.g. a
+ web-platform-tests issue with the "infra" label explaining why a certain
+ thing cannot be tested (example), a spec issue for some change that would make it possible to test. (example), or a Chromium issue to upstream some existing tests (example).`},sample_links:{type:"textarea",attrs:MULTI_URL_FIELD_ATTRS,required:!1,label:"Demo and sample links",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Links to demos and samples (one URL per line).`},non_oss_deps:{type:"textarea",required:!1,label:"Non-OSS dependencies",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Does the feature depend on any code or APIs outside the
+ Chromium open source repository and its open-source dependencies to
+ function? (e.g. server-side APIs, operating system APIs tailored to this
+ feature or closed-source code bundles) Yes or no. If yes, explain why this
+ is necessary.`},devrel:{type:"input",name:"devrel_emails",attrs:MULTI_EMAIL_FIELD_ATTRS,required:!1,label:"Developer relations emails",usage:{},help_text:x$1` Comma separated list of full email addresses.`},shipped_milestone:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"Chrome for desktop",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:SHIPPED_HELP_TXT,check:(_value,getFieldValue)=>checkMilestoneRanges([ALL_OT_SHIPPED_MILESTONE_DESKTOP_RANGE,ALL_DT_SHIPPED_MILESTONE_DESKTOP_RANGE],getFieldValue)},shipped_android_milestone:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"Chrome for Android",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:SHIPPED_HELP_TXT,check:(_value,getFieldValue)=>checkMilestoneRanges([ALL_OT_SHIPPED_MILESTONE_ANDROID_RANGE,ALL_DT_SHIPPED_MILESTONE_ANDROID_RANGE],getFieldValue)},shipped_ios_milestone:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"Chrome for iOS (RARE)",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:SHIPPED_HELP_TXT,check:(_value,getFieldValue)=>checkMilestoneRanges([ALL_DT_SHIPPED_MILESTONE_IOS_RANGE],getFieldValue)},shipped_webview_milestone:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"Android Webview",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:SHIPPED_WEBVIEW_HELP_TXT,check:(_value,getFieldValue)=>checkMilestoneRanges([ALL_OT_SHIPPED_MILESTONE_WEBVIEW_RANGE],getFieldValue)},requires_embedder_support:{type:"checkbox",initial:!1,label:"Requires embedder support",usage:{[FeatureType.Incubate]:ALL_FEATURE_TYPE_INCUBATE_INTENTS,[FeatureType.Existing]:ALL_FEATURE_TYPE_EXISTING_INTENTS,[FeatureType.Deprecation]:ALL_FEATURE_TYPE_DEPRECATION_INTENTS},help_text:x$1` Will this feature require support in //chrome? That
+ includes any code in //chrome, even if that is for functionality on top of
+ the spec. Other //content embedders will need to be aware of that
+ functionality. Please add a row to this
+
+ tracking spreadsheet.`},devtrial_instructions:{type:"input",attrs:URL_FIELD_ATTRS,required:!1,label:"DevTrial instructions",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` Link to a HOWTO or FAQ describing how developers can get
+ started using this feature in a DevTrial.
+
+
+ Example 1.
+
+ Example 2.`},dt_milestone_desktop_start:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"DevTrial on desktop",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` First milestone that allows web developers to try this
+ feature on desktop platforms by setting a flag. When flags are enabled by
+ default in preparation for shipping or removal, please use the fields in the
+ ship stage.`,check:(_value,getFieldValue)=>checkMilestoneRanges([DT_ALL_SHIPPED_MILESTONE_DESKTOP_RANGE],getFieldValue)},dt_milestone_android_start:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"DevTrial on Android",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` First milestone that allows web developers to try this
+ feature on Android by setting a flag. When flags are enabled by default in
+ preparation for shipping or removal, please use the fields in the ship
+ stage.`,check:(_value,getFieldValue)=>checkMilestoneRanges([DT_ALL_SHIPPED_MILESTONE_ANDROID_RANGE],getFieldValue)},dt_milestone_ios_start:{type:"input",attrs:MILESTONE_NUMBER_FIELD_ATTRS,required:!1,label:"DevTrial on iOS (RARE)",usage:ALL_INTENT_USAGE_BY_FEATURE_TYPE,help_text:x$1` First milestone that allows web developers to try this
+ feature on iOS by setting a flag. When flags are enabled by default in
+ preparation for shipping or removal, please use the fields in the ship
+ stage.`,check:(_value,getFieldValue)=>checkMilestoneRanges([DT_ALL_SHIPPED_MILESTONE_IOS_RANGE],getFieldValue)},flag_name:{type:"input",attrs:TEXT_FIELD_ATTRS,required:!1,label:"Flag name on about://flags",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` Name of the flag on about://flags that allows a web
+ developer to enable this feature in their own browser to try it out. E.g.,
+ "storage-buckets". These are defined in
+ about_flags.cc.`},finch_name:{type:"input",attrs:{...TEXT_FIELD_ATTRS,placeholder:"e.g. \"StorageBuckets\"",pattern:FINCH_NAMES_REGEX},required:!1,label:"Finch feature name",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` String name of the base::Feature defined via
+ the BASE_FEATURE macro in your feature implementation code.
+ E.g., "StorageBuckets". These names are used in
+ runtime_enabled_features.json5
+ (or
+ content_features.cc), and finch GCL files`},non_finch_justification:{type:"textarea",required:!1,label:"Non-finch justification",usage:{[FeatureType.Incubate]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.Existing]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship]),[FeatureType.CodeChange]:new Set([UsageType.DeveloperTesting,UsageType.PSA]),[FeatureType.Deprecation]:new Set([UsageType.DeveloperTesting,UsageType.Experiment,UsageType.Ship])},help_text:x$1` The
+ Flag Guarding Guidelines
+ require new features to have a finch flag. If your feature does not have a
+ finch flag, explain why.`},prefixed:{type:"checkbox",label:"Prefixed?",initial:!1,usage:{},help_text:""},display_name:{type:"input",attrs:TEXT_FIELD_ATTRS,required:!1,label:"Stage display name",usage:{},help_text:x$1`
+ Optional. Stage name to display on the feature detail page.
+
`,extra_help:x$1`
+ This name is only used for displaying stages on this site. Use this to
+ differentiate stages of the same type.
+
+ A brief description of the feature to interest web developers in joining
+ the trial (1-2 sentences). Shown as the trial description in the
+
+ Origin Trials Console .
+
`},ot_owner_email:{type:"input",required:!0,attrs:{...TEXT_FIELD_ATTRS,pattern:GOOGLE_EMAIL_ADDRESS_REGEX},usage:{},label:"Google point of contact",help_text:x$1`
+ A Googler contact for this origin trial. Please supply a '@google.com'
+ domain email address only.
+
`},ot_feedback_submission_url:{type:"input",attrs:URL_FIELD_ATTRS,required:!0,label:"Feature feedback link",usage:{},help_text:x$1` Link for developers to file feedback on the feature (e.g.
+ GitHub issues, or WICG page).`},shipping_year:{type:"input",attrs:{type:"number",min:2e3,max:2050},required:!0,label:"Estimated shipping year",usage:{},help_text:x$1` Estimate of the calendar year in which this will first ship
+ on any platform. E.g., 2024.`},enterprise_policies:{type:"input",attrs:MULTI_STRING_FIELD_ATTRS,required:!1,label:"Enterprise policies",usage:{[FeatureType.Incubate]:new Set([UsageType.CrossFunctionReview]),[FeatureType.Existing]:new Set([UsageType.CrossFunctionReview]),[FeatureType.CodeChange]:new Set([UsageType.CrossFunctionReview]),[FeatureType.Deprecation]:new Set([UsageType.CrossFunctionReview]),[FeatureType.Enterprise]:new Set([UsageType.CrossFunctionReview])},help_text:x$1` List the policies that are being introduced, removed, or
+ can be used to control the feature at this stage, if any.`,disabled:!0,deprecated:!0},enterprise_feature_categories:{type:"multiselect",choices:ENTERPRISE_FEATURE_CATEGORIES,required:!1,label:"Enterprise feature categories",usage:{},help_text:x$1` If your feature impacts enterprise users, select at least
+ one.`,enterprise_help_text:x$1` Select at least one.`},enterprise_impact:{type:"select",choices:ENTERPRISE_IMPACT,initial:ENTERPRISE_IMPACT.IMPACT_NONE[0],enterprise_initial:ENTERPRISE_IMPACT.IMPACT_MEDIUM[0],label:"Enterprise impact / risk",usage:{},help_text:x$1`
+ Low Risk: Important for Admin Awareness. Negligible disruption, but
+ provides value (new APIs, optional features, strictly additive) or
+ requires minor internal documentation updates. Select this to ensure the
+ feature is published in the Release Notes.
+
+ Med Risk:Noticeable impact. Potential to alter some workflows or
+ cause minor confusion/help desk calls. Admins may want to review and set a
+ policy. An escape hatch is often recommended.
+
+ High Risk: Significant disruption. Intentional "breaking changes"
+ or major new functionality that will require mandatory preparation,
+ testing, and communication from IT admins. Requires an escape hatch or
+ permanent policy.
+ `},rollout_milestone:{type:"input",attrs:{...MILESTONE_NUMBER_FIELD_ATTRS,min:100},required:!0,label:"Chrome milestone",usage:{},help_text:x$1` The milestone in which this stage rolls out to the stable
+ channel (even a 1% rollout). If you don't yet know which milestone it will
+ be, put in your best estimate. You can always change this later.`},rollout_platforms:{type:"multiselect",choices:PLATFORM_CATEGORIES,required:!0,label:"Rollout platforms",usage:{},help_text:x$1` The platform(s) affected by this stage`},rollout_details:{type:"textarea",always_markdown:!0,attrs:{rows:4},required:!1,label:"Rollout details (optional)",usage:{},help_text:x$1` Explain what specifically is changing in this milestone,
+ for the given platforms. Many features are composed of multiple stages on
+ different milestones. For example, you may have a stage that introduces a
+ change and a temporary policy to control it, then another stage on a
+ subsequent milestone that removes the policy. Alternatively, you may ship
+ the feature to different platforms in different milestones.`},rollout_stage_plan:{type:"select",choices:ROLLOUT_STAGE_PLAN_CATEGORIES,initial:ROLLOUT_STAGE_PLAN_CATEGORIES.ROLLOUT_STAGE_PLAN_SLOW[0],required:!0,label:"Rollout plan",usage:{},help_text:x$1` Select the type of rollout that matches what will happen in
+ the stage`},breaking_change:{type:"checkbox",label:"Breaking change",initial:!1,usage:{},help_text:x$1` This is a breaking change: customers or developers must
+ take action to continue using some existing functionaity.`},confidential:{type:"checkbox",label:"Confidential",initial:!0,usage:{},help_text:x$1`Most enterprise feature entries should be marked
+ confidential until they have been reviewed for publication. Confidential
+ entrys are only visible to admins, chromium contributors and the feature's
+ owners, contributors and creator.`},intent_cc_emails:{type:"input",attrs:MULTI_EMAIL_FIELD_ATTRS,required:!1,label:"Intent email CC list",usage:{},help_text:x$1`Add emails to the CC list of the intent email.
+ Comma separated list of full email addresses.`}};function categorizeFieldType(field){if(field.attrs===MULTI_URL_FIELD_ATTRS)return"multi-url";return field.attrs===URL_FIELD_ATTRS?"url":"checkbox"===field.type?"checkbox":"text"}function makeHumanReadable(fieldName){return fieldName=fieldName.replace("_"," "),fieldName.charAt(0).toUpperCase()+fieldName.slice(1)}function makeDisplaySpec(fieldName){const fieldProps=ALL_FIELDS[fieldName],displayName=fieldProps.label||fieldProps.displayLabel||makeHumanReadable(fieldName),fieldType=categorizeFieldType(fieldProps),deprecated=fieldProps.deprecated,alwaysMarkdown=fieldProps.always_markdown;return[fieldName,displayName,fieldType,deprecated,alwaysMarkdown]}function makeDisplaySpecs(fieldNames){return fieldNames.map(fieldName=>makeDisplaySpec(fieldName))}function findMinMilestone(fieldName,stageTypes,getFieldValue){let minMilestone=1/0;const feature=getFieldValue.feature;for(const stage of feature.stages)if(stageTypes.has(stage.stage_type)){const milestone=getFieldValue(fieldName,stage);null!=milestone&&""!==milestone&&(minMilestone=Math.min(minMilestone,milestone))}return minMilestone===1/0?void 0:minMilestone}function findMaxMilestone(fieldName,stageTypes,getFieldValue){let maxMilestone=-Infinity;const feature=getFieldValue.feature;for(const stage of feature.stages)if(stageTypes.has(stage.stage_type)){const milestone=getFieldValue(fieldName,stage);null!=milestone&&""!==milestone&&(maxMilestone=Math.max(maxMilestone,milestone))}return maxMilestone===-Infinity?void 0:maxMilestone}function checkEarlierBeforeAllLaterMilestones(fieldPair,getFieldValue){const{earlier,allLater,warning}=fieldPair,stageTypes=allLater&&SHIPPED_MILESTONE_FIELDS.has(allLater)?STAGE_TYPES_SHIPPING:null,earlierValue=getNumericValue(earlier,getFieldValue);if(stageTypes&&allLater){const laterValue=findMinMilestone(allLater,stageTypes,getFieldValue);if(null!=earlierValue&&null!=laterValue&&+earlierValue>=laterValue)return warning?{warning}:{error:`Earlier milestone #${earlierValue} should be before shipped milestone #${laterValue}.`}}}function checkAllEarlierBeforeLaterMilestone(fieldPair,getFieldValue){const{allEarlier,later,warning,error}=fieldPair,stageTypes=allEarlier&&OT_MILESTONE_START_FIELDS.has(allEarlier)?STAGE_TYPES_ORIGIN_TRIAL:allEarlier&&DT_MILESTONE_FIELDS.has(allEarlier)?STAGE_TYPES_DEV_TRIAL:null;if(stageTypes&&allEarlier){const earlierValue=findMaxMilestone(allEarlier,stageTypes,getFieldValue),laterValue=getNumericValue(later,getFieldValue);if(null!=earlierValue&&null!=laterValue&&earlierValue>=+laterValue)return warning?{warning}:{error:error||`Earlier milestone #${earlierValue} should be before shipped milestone #${laterValue}.`}}}function getNumericValue(name,getFieldValue){const value=getFieldValue(name,"current stage");return"string"==typeof value?""===value?void 0:+value:value}function checkMilestoneRanges(ranges,getFieldValue){let result;for(const range of ranges){const{earlier,allEarlier,later,allLater,warning,error}=range;if(allLater)result=checkEarlierBeforeAllLaterMilestones(range,getFieldValue);else if(allEarlier)result=checkAllEarlierBeforeLaterMilestone(range,getFieldValue);else{const earlierMilestone=getNumericValue(earlier,getFieldValue),laterMilestone=getNumericValue(later,getFieldValue);null!=earlierMilestone&&null!=laterMilestone&&laterMilestone<=earlierMilestone&&(result=warning?{warning}:{error:error||"Start milestone must be before end milestone"})}if(result)return result}}function checkFeatureNameAndType(getFieldValue){const name=((getFieldValue("name")||"")+"").toLowerCase(),featureType=+(getFieldValue("feature_type")||"0"),isdeprecationName=name.includes("deprecat")||name.includes("remov"),isdeprecationType=featureType===FEATURE_TYPES.FEATURE_TYPE_DEPRECATION_ID[0];if(isdeprecationName!==isdeprecationType)return isdeprecationName?{warning:`If the feature name contains "deprecate" or "remove",
+ the feature type should be "Feature deprecation"`}:{warning:`If the feature type is "Feature deprecation",
+ the feature name should contain "deprecate" or "remove"`}}async function checkFirstEnterpriseNotice(value,initialValue){if(!value)return;const newChannelStableDate=await window.csClient.getSpecifiedChannels(value,value).then(channels=>channels[value]?.stable_date),previousChannelStableDate=initialValue?await window.csClient.getSpecifiedChannels(initialValue,initialValue).then(channels=>channels[value]?.stable_date):void 0;return newChannelStableDate?previousChannelStableDate&&Date.parse(previousChannelStableDate)value[i]||"9"intValue?{error:"End milestone cannot be in the past."}:void 0}function checkNotGoogleDocs(value,warning="Avoid using Google Docs"){return /docs\.google\.com\/document/.test(value)?{warning}:void 0}var __decorate$S=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3${abbrev}`;statusIconName&&(statusIcon=x$1`
+
+ `);const overdue=0>this.gate.slo_initial_response_remaining,overdueIcon=overdue?x$1``:E$1,overdueTitle=overdue?". Overdue.":"";return x$1`
+
+ ${statusIcon}
+ ${teamName}
+ ${overdueIcon}
+
+ `}};__decorate$S([n$5({type:Object})],ChromedashGateChip.prototype,"feature",void 0),__decorate$S([n$5({type:Object})],ChromedashGateChip.prototype,"stage",void 0),__decorate$S([n$5({type:Object})],ChromedashGateChip.prototype,"gate",void 0),__decorate$S([n$5({type:Number})],ChromedashGateChip.prototype,"selectedGateId",void 0),ChromedashGateChip=__decorate$S([t$3("chromedash-gate-chip")],ChromedashGateChip);var __decorate$R=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3
+
+ Evaluate test coverage
+
+ `}};__decorate$R([n$5({type:Number})],ChromedashWPTEvalButton.prototype,"featureId",void 0),ChromedashWPTEvalButton=__decorate$R([t$3("chromedash-wpt-eval-button")],ChromedashWPTEvalButton);var __decorate$Q=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3g.id===gateId);if(!extensionGate||!GATE_APPROVED_REVIEW_STATES.includes(extensionGate.state))return;let extensionStage;for(const stage of this.feature.stages){const foundStage=stage.extensions.find(s=>s.id===extensionGate.stage_id);if(foundStage){extensionStage=foundStage;break}}extensionStage&&extensionStage.ot_action_requested&&openFinalizeExtensionDialog(this.feature.id,extensionStage,extensionStage.desktop_last,dialogTypes.FINALIZE_EXTENSION)}intializeGateColumn(){const rawQuery=parseRawQuery(window.location.search);if(!rawQuery.hasOwnProperty("gate"))return;const gateVal=+rawQuery.gate,foundGates=this.gates.filter(g=>g.id==gateVal);if(!foundGates.length)return;const gate=foundGates[0],foundStages=this.feature.stages.filter(s=>s.id===gate.stage_id||s.extensions.some(e=>e.id===gate.stage_id));if(!foundStages.length)return;let stage=foundStages[0];this.openStage=stage.id,gate.gate_type===GATE_TYPES.API_EXTEND_ORIGIN_TRIAL&&(stage=stage.extensions.find(e=>e.id===gate.stage_id)),this._fireEvent("show-gate-column",{feature:this.feature,stage:stage,gate:gate}),this.initializeExtensionDialog(rawQuery)}isAnyCollapsed(){const sections=this.renderRoot.querySelectorAll(".stage"),open=this.renderRoot.querySelectorAll(".stage[open]");return open.length{el.open=shouldOpen})}handleAddXfnGates(feStage){const prompt="Would you like to add gates for Privacy, Security, etc.? \n\nThis is needed if the API Owners ask you to add them, or if you send an \"Intent to Ship\" rather than a PSA.";confirm("Would you like to add gates for Privacy, Security, etc.? \n\nThis is needed if the API Owners ask you to add them, or if you send an \"Intent to Ship\" rather than a PSA.")&&window.csClient.addXfnGates(feStage.feature_id,feStage.id).then(()=>{this._fireEvent("refetch-needed",{})})}renderControls(){const editAllButton=x$1`
+
+ Edit all fields
+
+ `,toggleLabel=this.anyCollapsed?"Expand all":"Collapse all";return x$1`
+
+ ${this.canEdit&&this.feature.feature_type_int!==FEATURE_TYPES.FEATURE_TYPE_ENTERPRISE_ID[0]?E$1:E$1}
+ ${this.canEdit?editAllButton:E$1}
+
+ ${toggleLabel}
+
+ `}renderText(value,isMarkdown=!1){value=value+"";const markup=autolink(value,this.featureLinks,isMarkdown);return isMarkdown?x$1`${markup}`:value.length>LONG_TEXT||value.includes("\n")?x$1`${markup}`:x$1`${markup}`}renderUrl(value){return value.startsWith("http")?x$1``:this.renderText(value)}renderValue(fieldType,value,isMarkdown){if("checkbox"==fieldType)return this.renderText(value?"True":"False");return"url"==fieldType?this.renderUrl(value):"multi-url"==fieldType?x$1`
+
+
+ `}renderDotDotDotMenu(){if(!this.canDeleteFeature&&!this.canEditFeature)return E$1;let archiveItem=x$1``,suspendItem=x$1``,resumeItem=x$1``;return this.canDeleteFeature&&(archiveItem=x$1`
+
+ Archive feature
+
+ `),this.canEditFeature&&(this.isSuspended()?resumeItem=x$1`
+
+ Resume active development
+
+ `:suspendItem=x$1`
+
+ Suspend development
+
+ `),x$1`
+
+
+ ${suspendItem} ${resumeItem} ${archiveItem}
+
+ `}render(){return x$1`
+
+
+ ${this.renderDotDotDotMenu()}
+ ${this.feature.is_enterprise_featqcure?this.renderEnterpriseFeatureContent():this.renderFeatureContent()}
+ ${this.feature.is_enterprise_feature?this.renderEnterpriseFeatureStatus():this.renderFeatureStatus()}
+ ${this.renderHistory()}
+
+
+ `}};__decorate$N([n$5({attribute:!1})],ChromedashFeatureHighlights.prototype,"feature",void 0),__decorate$N([n$5({attribute:!1})],ChromedashFeatureHighlights.prototype,"featureLinks",void 0),__decorate$N([n$5({type:Boolean})],ChromedashFeatureHighlights.prototype,"canDeleteFeature",void 0),__decorate$N([n$5({type:Boolean})],ChromedashFeatureHighlights.prototype,"canEditFeature",void 0),ChromedashFeatureHighlights=__decorate$N([t$3("chromedash-feature-highlights")],ChromedashFeatureHighlights);var __decorate$M=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3{this.feature=feature,this.gates=gatesRes.gates,this.comments=commentRes.comments,this.process=process,this.progress=progress,starredFeatures.includes(this.featureId)&&(this.starred=!0),this.feature.name&&(document.title=`${this.feature.name} - ${this.appTitle}`),this.shippingInfo=await findClosestShippingDate(channels,feature.stages),this.loading=!1}).catch(error=>{error instanceof FeatureNotFoundError?this.loading=!1:showToastMessage("Some errors occurred. Please refresh the page or try again later.")}),window.csClient.getFeatureLinks(this.featureId).then(featureLinks=>{this.featureLinks=featureLinks?.data||[],featureLinks?.has_stale_links&&setTimeout(this.refetchFeatureLinks.bind(this),1e4)})}async refetchFeatureLinks(){const featureLinks=await window.csClient.getFeatureLinks(this.featureId,!1);this.featureLinks=featureLinks?.data||[]}refetch(){Promise.all([window.csClient.getFeature(this.featureId),window.csClient.getGates(this.featureId),window.csClient.getComments(this.featureId,null)]).then(([feature,gatesRes,commentRes])=>{this.feature=feature,this.gates=gatesRes.gates,this.comments=commentRes.comments}).catch(error=>{error instanceof FeatureNotFoundError?this.loading=!1:showToastMessage("Some errors occurred. Please refresh the page or try again later.")})}disconnectedCallback(){super.disconnectedCallback(),document.title=this.appTitle}handleStarClick(e){e.preventDefault(),window.csClient.setStar(this.featureId,!this.starred).then(()=>{this.starred=!this.starred})}handleShareClick(e){if(e.preventDefault(),navigator.share){const url="/feature/"+this.featureId;navigator.share({title:this.feature.name,text:this.feature.summary,url:url}).then(()=>{ga("send","social",{socialNetwork:"web",socialAction:"share",socialTarget:url})})}}handleCopyLinkClick(e){e.preventDefault();const url=e.currentTarget.href;navigator.clipboard.writeText(url).then(()=>{showToastMessage("Link copied")})}canDeleteFeature(){return this.user?.is_admin||userCanEdit(this.user,this.featureId)}handleArchiveFeature(){confirm("Archive feature? It will only be visible to users who can edit it")&&window.csClient.doDelete(`/features/${this.feature.id}`).then(resp=>{"Done"===resp.message&&(location.href="/features")})}handleSuspend(){if(confirm("Suspend development of this feature? It will not appear on the roadmap.")){const submitBody={feature_changes:{id:this.feature.id,impl_status_chrome:IMPLEMENTATION_STATUS.ON_HOLD[0]},stages:[],has_changes:!0};window.csClient.updateFeature(submitBody).then(resp=>{window.location.reload()})}}handleResume(){if(confirm("Resume active development of this feature? It will appear on the roadmap if it has milestones set.")){const submitBody={feature_changes:{id:this.feature.id,impl_status_chrome:IMPLEMENTATION_STATUS.PROPOSED[0]},stages:[],has_changes:!0};window.csClient.updateFeature(submitBody).then(resp=>{window.location.reload()})}}renderSkeletonSection(){return x$1`
+
+
+ User ${this.user.email} cannot edit this feature or request reviews.
+ But, ${this.paired_user.email} can do that.
+
+ To switch users: sign out and then sign in again.
+
+
+ `:console.error(`unknown form field type: ${type}`);return fieldHTML}renderUsageIcons(fieldUsageInfo,featureType){if(featureType===void 0)return[];const intentTypesUsed=fieldUsageInfo[featureType];if(!intentTypesUsed)return[];if(ALL_INTENT_USAGE_BY_FEATURE_TYPE[featureType]?.isSubsetOf(intentTypesUsed))return[x$1`
+ All
+ `];const intentIcons=[];for(const intentType of intentTypesUsed){const details=USAGE_TYPE_DETAILS[intentType];if(details){const tooltipText=`This field is used to populate the ${details.title} template`;intentIcons.push(x$1`
+ ${details.abbreviation}
+ `)}}return intentIcons}render(){if(this.fieldProps.deprecated&&!this.value)return E$1;const helpText=this.forEnterprise&&this.fieldProps.enterprise_help_text!==void 0?this.fieldProps.enterprise_help_text:this.fieldProps.help_text,extraHelpText=this.forEnterprise&&this.fieldProps.enterprise_extra_help!==void 0?this.fieldProps.enterprise_extra_help:this.fieldProps.extra_help,fadeInClass=this.shouldFadeIn?"fade-in":"";return x$1`
+ ${this.fieldProps.label?x$1`
+
+ To request a review, use the "Draft intent..." button above to generate an
+ intent messsage, and then post that message to blink-dev@chromium.org.
+
+
+ Be sure to update your feature entry in response to any suggestions on that
+ email thread.
+
+ Share it as a public document, as a file in your repository, or in any other
+ public format of your choice.
+
+
+ You can reuse the same filled-out questionnaire in the security review
+ below, across all stages of this ChromeStatus entry, and across all entries
+ related to the same API. If you updated an existing questionnaire to reflect
+ new changes to the API, please highlight them for an easier review.
+
+
+ If you believe your feature has no privacy impact and none of the
+ questions in the questionnaire apply, you can provide a justification
+ instead, e.g. "Removing a prefix from the API, no changes to functionality"
+ or "New CSS property that doesn't depend on the user state, therefore
+ doesn't reveal any user information". Note that if your reviewer disagrees
+ with the justification, they may ask you to fill out the questionnaire
+ nevertheless.
+
+ Share it as a public document, as a file in your repository, or in any other
+ public format of your choice.
+
+
+ You can reuse the same filled-out questionnaire in the privacy review above,
+ across all stages of this ChromeStatus entry, and across all entries related
+ to an API. If you updated an existing questionnaire to reflect new changes
+ to the API, please highlight them for an easier review.
+
+
+ If you believe your feature has no security impact and none of the
+ questions in the questionnaire apply, you can provide a justification
+ instead. Note that if your reviewer disagrees with the justification, they
+ may ask you to fill out the questionnaire nevertheless.
+
`,ENTERPRISE_SHIP_QUESTIONNAIRE=x$1`
+ (1) Does this launch include a breaking change? Does this launch
+ remove or modify existing behavior or does it interrupt an existing user
+ flow? (e.g. removing or restricting an API, or significant UI change).
+ Answer with one of the following options, and/or describe anything you're
+ unsure about:
+
+
+
+ No. There's no change visible to users, developers, or IT admins (e.g.
+ internal refactoring)
+
+
No. This launch is strictly additive functionality
+
+ Yes. Something that exists is changing or being removed (even if usage is
+ very small)
+
+
+ I don't know. Enterprise reviewers, please help me decide. The relevant
+ information is: ______
+
+
+
+ (2) Is there any other reason you expect that enterprises will care about
+ this launch?
+ (e.g. they may perceive a risk of data leaks if the browser is uploading new
+ information, or it may be a surprise to employees resulting in them calling
+ their help desk). Answer with one of the following options, and/or describe
+ anything you're unsure about:
+
+
+
No. Enterprises won't care about this
+
Yes. They'll probably care because ______
+
+ I don't know. Enterprise reviewers, please help me decide. The relevant
+ information is: ______
+
+
+
+ (3) Does your launch have an enterprise policy to control it, and will it
+ be available when this rolls out to stable (even to 1%)?
+ Only required if you answered Yes to either of the first 2 questions. Answer
+ with one of the following options, and/or describe anything you're unsure
+ about:
+
+
+
+ Yes. It's called ______. It will be a permanent policy, and it will be
+ available when stable rollout starts
+
+
+ Yes. It's called ______. This is a temporary transition period, so the
+ policy will stop working on milestone ___. It will be available when
+ stable rollout starts
+
+
+ No. A policy is infeasible because ______ (e.g. this launch is a change in
+ how we compile Chrome)
+
+
+ No. A policy isn't necessary because ______ (e.g. there's a better method
+ of control available to admins)
+
+
+
+ (4) Provide a brief title and description of this launch, which can be
+ shared with enterprises.
+ Only required if you answered Yes to either of the first 2 questions. This
+ may be added to browser release notes. Where applicable, explain the benefit
+ to users, and describe the policy to control it.
+
`,DEBUGGABILITY_ORIGIN_TRIAL_QUESTIONNAIRE=x$1`
+
+ (1) Does the introduction of the new Web Platform feature break Chrome
+ DevTools' existing developer experience?
+
+
+
+ (2) Does Chrome DevTools' existing set of tooling features interact with the
+ new Web Platform feature in an expected way?
+
+
+
+ (3) Would the new Web Platform feature's acceptance and/or adoption benefit
+ from adding a new developer workflow to Chrome DevTools?
+
+
+
+ (4) Can the feature be tested with a WebDriver BiDi module or other
+ appropriate automation?
+
+ (1) Does your feature have sufficient automated test coverage (Unit
+ tests, WPT, browser tests and other integration tests)?
+ Chrome requires at least 70% automation code coverage (dashboard) running on the main/release branch and 70% Changelist
+ code coverage in Gerrit? Do the automated tests have more than 93% green (flakiness < 7%) on CQ
+ and CI builders?
+
+
+
+ Yes. My feature met the minimum automated test coverage and health
+ requirements.
+
+
No. My feature does not meet the requirements since __________.
+
+
+ (2) How are performance tests conducted on Chromium builders? List
+ links to tests if any.
+
+
+ (3) Does this feature have non-automatable test cases that require manual
+ testing? Do you have a plan to get them tested?
+
+
+
No. All feature related test cases are automated.
+
+ Yes. There are non-automatable test cases and I have completed test
+ execution or allocated resources to ensure the coverage of these test
+ cases.
+
+
+ Yes. There are non-automatable test cases and my feature impacts Google
+ products.
+
+
+
+ (4) If your feature impacts Google products, please fill in
+ go/chrome-wp-test-survey.
+ Make a copy, answer the survey questions, and provide a link to your
+ document here.
+
`,GATE_QUESTIONNAIRES={[GATE_TYPES.API_PROTOTYPE]:BLINK_GENERIC_QUESTIONNAIRE,[GATE_TYPES.API_ORIGIN_TRIAL]:BLINK_GENERIC_QUESTIONNAIRE,[GATE_TYPES.API_EXTEND_ORIGIN_TRIAL]:BLINK_GENERIC_QUESTIONNAIRE,[GATE_TYPES.API_SHIP]:BLINK_GENERIC_QUESTIONNAIRE,[GATE_TYPES.API_PLAN]:BLINK_GENERIC_QUESTIONNAIRE,[GATE_TYPES.PRIVACY_ORIGIN_TRIAL]:PRIVACY_GENERIC_QUESTIONNAIRE,[GATE_TYPES.PRIVACY_SHIP]:PRIVACY_GENERIC_QUESTIONNAIRE,[GATE_TYPES.SECURITY_ORIGIN_TRIAL]:SECURITY_GENERIC_QUESTIONNAIRE,[GATE_TYPES.SECURITY_SHIP]:SECURITY_GENERIC_QUESTIONNAIRE,[GATE_TYPES.ENTERPRISE_SHIP]:ENTERPRISE_SHIP_QUESTIONNAIRE,[GATE_TYPES.ENTERPRISE_PLAN]:ENTERPRISE_SHIP_QUESTIONNAIRE,[GATE_TYPES.DEBUGGABILITY_ORIGIN_TRIAL]:DEBUGGABILITY_ORIGIN_TRIAL_QUESTIONNAIRE,[GATE_TYPES.DEBUGGABILITY_SHIP]:DEBUGGABILITY_SHIP_QUESTIONNAIRE,[GATE_TYPES.DEBUGGABILITY_PLAN]:DEBUGGABILITY_SHIP_QUESTIONNAIRE,[GATE_TYPES.TESTING_SHIP]:TESTING_SHIP_QUESTIONNAIRE,[GATE_TYPES.TESTING_PLAN]:TESTING_SHIP_QUESTIONNAIRE},LAUNCHING_FEATURES_URL="https://www.chromium.org/blink/launching-features/",BLINK_GENERIC_RATIONALE=x$1`
+ The API Owners review provides a final check on all aspects of your feature
+ and how you have followed the
+ Blink launch process.
+`,PRIVACY_GENERIC_RATIONALE=x$1`
+ The Web Platform privacy review puts you in touch with the privacy team so
+ that they can consult further with you when needed.
+`,SECURITY_GENERIC_RATIONALE=x$1`
+ The Web Platform Security review helps ensure that new or changed web APIs
+ uphold the security principles of the web - the same origin policy, no
+ cross-site leaks, compliance with CSP, CORS, permission norms, etc. It aims to
+ show that the API can be implemented safely. It doesn’t necessarily try to
+ prove that it has been implemented safely within Chromium - for Chrome team
+ features, that’s done by the Chrome launch review process.
+`,ENTERPRISE_GENERIC_RATIONALE=x$1`
+ The enterprise review helps identify the impact of your feature on
+ enterprises. Features need to be enterprise-friendly. That is:
+
+
+
Breaking changes need to have sufficient notice
+
+ Breaking changes need to have a soft deadline and transition period where
+ feasible
+
+
Admins need to have central controls where appropriate
+
+`,DEBUGGABILITY_GENERIC_RATIONALE=x$1`
+ The debuggability review helps identify opportunities to make your feature
+ more successful by integrating with Chrome Dev Tools.
+`,TESTING_GENERIC_RATIONALE=x$1`
+ The test review helps identify gaps in test coverage and ensures that all
+ crucial functionalities are thoroughly tested. This can lead to a more
+ polished final product and reduce the odds of missed defects and issues.
+`,GATE_RATIONALE={[GATE_TYPES.API_PROTOTYPE]:BLINK_GENERIC_RATIONALE,[GATE_TYPES.API_ORIGIN_TRIAL]:BLINK_GENERIC_RATIONALE,[GATE_TYPES.API_EXTEND_ORIGIN_TRIAL]:BLINK_GENERIC_RATIONALE,[GATE_TYPES.API_SHIP]:BLINK_GENERIC_RATIONALE,[GATE_TYPES.API_PLAN]:BLINK_GENERIC_RATIONALE,[GATE_TYPES.PRIVACY_ORIGIN_TRIAL]:PRIVACY_GENERIC_RATIONALE,[GATE_TYPES.PRIVACY_SHIP]:PRIVACY_GENERIC_RATIONALE,[GATE_TYPES.SECURITY_ORIGIN_TRIAL]:SECURITY_GENERIC_RATIONALE,[GATE_TYPES.SECURITY_SHIP]:SECURITY_GENERIC_RATIONALE,[GATE_TYPES.ENTERPRISE_SHIP]:ENTERPRISE_GENERIC_RATIONALE,[GATE_TYPES.ENTERPRISE_PLAN]:ENTERPRISE_GENERIC_RATIONALE,[GATE_TYPES.DEBUGGABILITY_ORIGIN_TRIAL]:DEBUGGABILITY_GENERIC_RATIONALE,[GATE_TYPES.DEBUGGABILITY_SHIP]:DEBUGGABILITY_GENERIC_RATIONALE,[GATE_TYPES.DEBUGGABILITY_PLAN]:DEBUGGABILITY_GENERIC_RATIONALE,[GATE_TYPES.TESTING_SHIP]:TESTING_GENERIC_RATIONALE,[GATE_TYPES.TESTING_PLAN]:TESTING_GENERIC_RATIONALE};var __decorate$G=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3Loading...
+
+
+ ${this.renderBooleanField("is_language_polyfill",x$1`This is a new JS language construct that has
+ already been polyfillable.`)}
+ ${this.renderBooleanField("is_api_polyfill",x$1`This is a new API that ergonomically provides a function
+ that was already polyfillable under the same conditions. By
+ "same conditions" we mean, for example, that if a polyfill was
+ only possible when the user has granted a certain permission, the
+ API respects the same permission.`)}
+ ${this.renderBooleanField("is_same_origin_css",x$1`This is a CSS addition or change such that the style
+ only depends on same-origin information and
+ NOT on user data. CSS changes are usually benign, however:
+ if the style relies on iframes or subresources, it could reveal
+ cross-origin information. If the style depends on user data, such
+ as browsing history (like :visited), cookies, or user input (like
+ hidden=until-found), the style could be used by the website to
+ read this data.`)}
+ ${this.renderStringField("launch_or_contact",x$1`If there is a Google-internal launch entry filed for this exact
+ same issue, enter its URL here. Or, if this has previously been
+ discussed with someone on the privacy team, enter their email
+ address. Or, enter "None".`)}
+ ${this.renderTextField("explanation",x$1`Required: If you checked any box above, explain why you
+ checked it, and provide any other relevant context.`)}
+
+
+ `}renderTestingForm(){return x$1`
+
+ Does your feature have WPT or other automated tests that cover the
+ following?
+
+ ${this.renderBooleanField("covers_existence",x$1`Feature existence. This is typically done with
+ surface-level tests like idlharness.js for APIs or
+ parsing-testcommon.js for CSS. These tests don’t verify actual
+ behavior.
+ API example.
+ CSS example.`)}
+ ${this.renderBooleanField("covers_common_cases",x$1`Common use cases. Use the feature in a realistic and
+ straightforward way and verify the expected behavior.
+ API example.
+ CSS example.
+ HTML example.`)}
+ ${this.renderBooleanField("covers_errors",x$1`Likely error scenarios. Test realistic error scenarios
+ like out-of-bounds inputs, network errors, or the user rejecting a
+ permission prompt.
+ API example.
+ CSS example.
+ HTML example. `)}
+ ${this.renderBooleanField("covers_invalidation",x$1`Invalidation. Rendering or other output often needs to
+ be invalidated when the inputs change. This kind of test is common
+ for CSS features, but can make sense for other features too. Often
+ called “dynamic” when an initial state is updated by script. Or,
+ if your feature needs no invalidation tests, check this box.
+ API example.
+ CSS example. `)}
+ ${this.renderBooleanField("covers_integration",x$1`Integration with other features. If the feature
+ integrates with other features in some meaningful way, test that
+ the combination of the two features behaves as expected. Or, if
+ your feature needs no integration tests, check this box.
+ API example.
+ CSS example.
+ HTML example. `)}
+
+
+ Please briefly explain why your feature does not require a review. Your
+ response will be posted as a comment on this review gate and it will
+ generate a notification to the reviewers. The ${this.gate.team_name}
+ reviewers will still evaluate whether to give an "N/A" response or do a
+ review.
+
+ Based on your answers to the survey questions, you may self-certify an
+ ${voteWord} for this gate. Alternatively, if you want to start a
+ consulation with the review team, you may request a full review.
+
+
+ Request full review
+ Self-certify ${voteWord}
+ `}render(){return void 0===this.gate?x$1`Loading gates...`:x$1`
+ ${this.renderContentWhenEligible()}
+ `}};__decorate$E([n$5({type:Object})],ChromedashSelfCertifyDialog.prototype,"gate",void 0),__decorate$E([n$5({type:Number})],ChromedashSelfCertifyDialog.prototype,"voteValue",void 0),__decorate$E([n$5({attribute:!1})],ChromedashSelfCertifyDialog.prototype,"resolve",void 0),ChromedashSelfCertifyDialog=__decorate$E([t$3("chromedash-self-certify-dialog")],ChromedashSelfCertifyDialog);var __decorate$D=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3{openSecondarySurveyDialog(gate,resolve)}):Promise.resolve()}async function openSecondarySurveyDialog(gate,resolve){secondarySurveyDialogEl||(secondarySurveyDialogEl=document.createElement("chromedash-secondary-survey-dialog"),document.body.appendChild(secondarySurveyDialogEl)),secondarySurveyDialogEl.gate=gate,secondarySurveyDialogEl.resolve=resolve,await secondarySurveyDialogEl.updateComplete,secondarySurveyDialogEl.show()}let ChromedashSecondarySurveyDialog=class ChromedashSecondarySurveyDialog extends i$4{constructor(){super(...arguments),this.resolve=()=>{console.log("Missing resolve action")}}static get styles(){return[...SHARED_STYLES,i$7`
+ ol {
+ padding-left: var(--content-padding-half);
+ }
+
+ ol li {
+ margin-bottom: var(--content-padding);
+ }
+ sl-button {
+ float: right;
+ margin: var(--content-padding-half);
+ }
+ `]}show(){this.renderRoot.querySelector("sl-dialog")?.show()}hide(){this.renderRoot.querySelector("sl-dialog")?.hide()}generateTestingComment(){const answer1=this.renderRoot.querySelector("#coverage").value,answer2=this.renderRoot.querySelector("#performance_tests").value,answer3=this.renderRoot.querySelector("#automation").value,answer4=this.renderRoot.querySelector("#impact").value,commentText=`Survey answers:
+> 1. Does your feature have sufficient automated
+> test coverage (Unit tests, WPT, browser tests
+> and other integration tests)?
+
+${answer1}
+
+> 2. How are performance tests conducted on
+> Chromium builders?
+
+${answer2}
+
+> 3. Does this feature have non-automatable test
+> cases that require manual testing? Do you have
+> a plan to get them tested?
+
+${answer3}
+
+> 4. If your feature impacts Google products,
+> please fill in go/chrome-wp-test-survey.
+
+${answer4}
+`;this.resolve(commentText)}handleGenerateComment(){isTestingGate(this.gate)&&this.generateTestingComment(),this.hide()}renderTestingContent(){const option1a="Yes. My feature met the minimum automated test coverage and health requirements.",option1b="No. My feature does not meet the requirements.",option3a="No. All feature related test cases are automated.",option3b="Yes. There are non-automatable test cases and I have completed test execution or allocated resources to ensure the coverage of these test cases.",option3c="Yes. There are non-automatable test cases and my feature impacts Google products.";return x$1`
+
+
+ Does your feature have sufficient automated test coverage (Unit
+ tests, WPT, browser tests and other integration tests)?
+ Chrome requires at least 70% automation code coverage (dashboard) running on the main/release branch and 70% Changelist
+ code coverage in Gerrit? Do the automated tests have more than 93% green (flakiness < 7%) on
+ CQ and CI builders?
+
+
+ ${"Yes. My feature met the minimum automated test coverage and health requirements."}
+ ${option1b}
+
+
+
+
+ How are performance tests conducted on Chromium builders? List
+ links to tests if any.
+
+
+
+
+
+
+ Does this feature have non-automatable test cases that require
+ manual testing? Do you have a plan to get them tested?
+
+
+ ${option3a}
+ ${option3b}
+ ${option3c}
+
+
+
+
+ If your feature impacts Google products, please fill in
+ go/chrome-wp-test-survey.
+ Make a copy, answer the survey questions, and provide a link to your
+ document here.
+
+
+ `}async handleReviewRequested(){const featureId=this.feature.id;window.csClient.getGates(featureId).then(gatesRes=>{for(const g of gatesRes.gates)g.id==this.gate.id&&(this.gate=g);maybeOpenCertifyDialog(this.gate,VOTE_NA_SELF).then(selfCertifying=>{selfCertifying?this.handleSelfCertify(VOTE_NA_SELF):maybeOpenSecondarySurveyDialog(this.gate).then(commentText=>{commentText&&this.postComment(commentText),this.handleFullReviewRequest()})})})}async handleNARequested(){const featureId=this.feature.id;window.csClient.getGates(featureId).then(gatesRes=>{for(const g of gatesRes.gates)g.id==this.gate.id&&(this.gate=g);maybeOpenCertifyDialog(this.gate,VOTE_NA_SELF).then(selfCertifying=>{selfCertifying?this.handleSelfCertify(VOTE_NA_SELF):this.handleFullNARequested()})})}handleFullNARequested(){openNaRationaleDialog(this.gate).then(rationale=>{this.handleNARequestSubmitted(rationale)})}async handleFullReviewRequest(){await window.csClient.setVote(this.feature.id,this.gate.id,GATE_REVIEW_REQUESTED),this._fireEvent("refetch-needed",{})}async handleSelfCertify(voteValue){await window.csClient.setVote(this.feature.id,this.gate.id,voteValue);const commentText="This \"N/A\" was self-certified.";await this.postComment("This \"N/A\" was self-certified."),this._fireEvent("refetch-needed",{})}async handleNARequestSubmitted(rationale){await window.csClient.setVote(this.feature.id,this.gate.id,GATE_NA_REQUESTED);const commentText="An \"N/A\" response is requested because: "+rationale;await this.postComment(commentText),this._fireEvent("refetch-needed",{})}userCanRequestReview(){return this.user&&(this.user.can_edit_all||this.user.editable_features.includes(this.feature.id))}userCanVote(){return this.user&&this.user.approvable_gate_types.includes(this.gate.gate_type)}renderAction(processStage,action){const label=action.name,url=action.url.replace("{feature_id}",this.feature.id).replace("{gate_id}",this.gate.id||0),checkCompletion=()=>somePendingPrereqs(action,this.progress)||somePendingGates(this.featureGates,this.stage)?void openPreflightDialog(this.feature,this.progress,this.process,action,processStage,this.stage,this.featureGates,url):void setTimeout(()=>{const draftWindow=window.open(url,"_blank");draftWindow.focus()}),loadThenCheckCompletion=()=>{Promise.all([window.csClient.getGates(this.feature.id)]).then(([gatesRes])=>{this.featureGates=gatesRes.gates,checkCompletion()}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later.")})};return x$1`
+ ${label}
+ `}renderReviewStatusPreparing(){if(!this.userCanRequestReview())return x$1` Review has not been requested yet. `;const processStage=findProcessStage(this.stage,this.process);return 0this.renderAction(processStage,act)):x$1`
+ Request review
+ Request N/A
+ `}renderReviewStatusNeedsWork(){const rereviewButton=this.userCanRequestReview()?x$1`
+
+ Re-request review
+
+ `:E$1;return x$1`
+
Reviewer has indicated a need for rework.
+ ${rereviewButton}
+ `}renderReviewRequest(){for(const v of this.votes)if(v.state===GATE_REVIEW_REQUESTED||v.state===GATE_NA_REQUESTED){const shortVoter=v.set_by.split("@")[0]+"@";return x$1`
+ ${shortVoter} requested on
+ ${renderAbsoluteDate(this.gate.requested_on)}
+ ${renderRelativeDate(this.gate.requested_on)}
+ `}return E$1}renderReviewStatusApproved(){return x$1`
+
+
+ Approved
+
+ `}renderReviewStatusNa(){return x$1`
+
+
+ N/a
+
+ `}renderReviewStatusNaSelf(){return x$1`
+
+
+ N/a (self-certified)
+
+ `}renderReviewStatusNaVerified(){return x$1`
+
+
+ N/a (self-certified then verified)
+
+ `}renderReviewStatusDenied(){return x$1`
+
+
+ Denied
+
+ `}renderReviewStatus(){return this.gate.state==GATE_PREPARING?this.renderReviewStatusPreparing():this.gate.state==VOTE_OPTIONS.NEEDS_WORK[0]?this.renderReviewStatusNeedsWork():this.gate.state==VOTE_OPTIONS.NA[0]?this.renderReviewStatusNa():this.gate.state==VOTE_NA_SELF?this.renderReviewStatusNaSelf():this.gate.state==VOTE_NA_VERIFIED?this.renderReviewStatusNaVerified():this.gate.state==VOTE_OPTIONS.APPROVED[0]?this.renderReviewStatusApproved():this.gate.state==VOTE_OPTIONS.DENIED[0]?this.renderReviewStatusDenied():E$1}renderSLOStatusSkeleton(){return x$1`
+
+ SLO initial response:
+ Loading...
+
+
+ SLO resolution:
+ Loading...
+
+ `}dayPhrase(count){return count+""+(1==count?" day":" days")}renderSLOSummary(limit,remaining,took){if("number"==typeof took)return x$1`took ${this.dayPhrase(took)}`;if("number"==typeof remaining){let msg=x$1`due today`,className="";return 0remaining&&(className="overdue",msg=x$1`${this.dayPhrase(-remaining)} overdue`),x$1`
+
+
+ ${msg}
+
+ `}return"number"==typeof limit?x$1`${this.dayPhrase(limit)} allowed`:E$1}renderSLOStatus(){const initialLimit=this.gate?.slo_initial_response,initialRemaining=this.gate?.slo_initial_response_remaining,initialTook=this.gate?.slo_initial_response_took,resolveLimit=this.gate?.slo_resolve,resolveRemaining=this.gate?.slo_resolve_remaining,resolveTook=this.gate?.slo_resolve_took,needsWorkStartedOn=this.gate?.needs_work_started_on,initialLine=x$1`
+
+
+ SLO initial response:
+ ${this.renderSLOSummary(initialLimit,initialRemaining,initialTook)}
+
+ Reviewers are encouraged to provide an initial review status update or a
+ comment within this number of weekdays.
+
+ `;let resolveLine=x$1`
+
+
+ SLO resolution:
+ ${this.renderSLOSummary(resolveLimit,resolveRemaining,resolveTook)}
+
+ Reviewers are encouraged to resolve the review within this number of
+ weekdays. If a reviewer responds with "Needs work", this clock pauses
+ until a feature owner clicks "Re-request review".
+
+ `,needsWorkLine=E$1;return"string"==typeof needsWorkStartedOn&&(resolveLine=E$1,needsWorkLine=x$1`
+
+
+ SLO resolution: Needs work since ${needsWorkStartedOn.split(" ")[0]}
+
+ A reviewer has asked the feature owner to do needed work. Check the
+ comments for a description of the needed work. The SLO clock is paused
+ until a feature owner clicks "Re-request review".
+
+ `),x$1`${initialLine} ${resolveLine} ${needsWorkLine}`}renderGateRationale(){const rationale=GATE_RATIONALE[this.gate?.gate_type];return rationale?x$1`
+
+ Why this gate?
+ ${rationale}
+
+ `:E$1}renderWarnings(){return this.gate&&["Privacy","WP Security"].includes(this.gate.team_name)?x$1`
+
+ Googlers: Please follow the instructions at
+ go/wp-launch-guidelines
+ (internal document) to determine whether you also require an internal
+ review.
+
+
+ `}gateHasIntentThread(){return"API Owners"===this.gate.team_name}canPostTo(threadArchiveUrl){return threadArchiveUrl&&(threadArchiveUrl.startsWith("https://groups.google.com/a/chromium.org/d/msgid/blink-dev/")||threadArchiveUrl.startsWith("https://groups.google.com/d/msgid/jrobbins-test"))}renderControls(){const canComment=this.user?.can_comment||this.userCanRequestReview();if(!canComment)return E$1;const postButton=x$1`
+ Post
+ `,checkboxLabel=this.stage.intent_thread_url?x$1`
+ Also post to
+ intent thread
+ `:"Also post to intent thread",postToThreadCheckbox=this.gateHasIntentThread()?x$1`
+ ${checkboxLabel}
+ `:E$1,escalation=this.gate.escalation_email?x$1`If needed, you can
+ email the team directly.`:E$1;return x$1`
+
+
${postButton} ${postToThreadCheckbox}
+
+ Comments will be visible publicly. Only reviewers will be notified when
+ a comment is posted. ${escalation}
+
+ The enterprise release notes focus on changes to the stable
+ channel. Please add a stage for each milestone where something is
+ changing on the stable channel. For finch rollouts, use the
+ milestone where the rollout starts.
+
+
+ For example, you may only have a single stage where you roll out
+ to 100% of users on milestone N.
+
+
A more complex example might look like this:
+
+
+ On milestone N-1, you introduce a flag for early testing of an
+ upcoming change, or start a deprecation origin trial
+
+
+ On milestone N, you start a finch rollout of a feature at 1% and
+ introduce an enterprise policy for it
+
+
On milestone N+3, you remove the enterprise policy
+ Use this form if your feature should be mentioned in the Enterprise
+ Release Notes.
+
+
+ `:x$1`
+
+
+ Please see the
+ Launching features
+ page for process instructions.
+
+
+
+ Googlers: Please follow the instructions at
+ go/wp-launch-guidelines
+ (internal document) to determine whether you also require an
+ internal review.
+
+ ${formFieldEls}
+ `}getForms(formattedFeature,feStages){let fieldsOnly=flattenSections(VERIFY_ACCURACY_METADATA_FIELDS);const formsToRender=[this.renderStageSection(formattedFeature,VERIFY_ACCURACY_METADATA_FIELDS.name,{},fieldsOnly)];let allFormFields=[...fieldsOnly];for(const feStage of feStages){const stageForm=this.getStageForm(feStage.stage_type);stageForm&&(fieldsOnly=flattenSections(stageForm),formsToRender.push(this.renderStageSection(formattedFeature,stageForm.name,feStage,fieldsOnly)),allFormFields=[...allFormFields,...fieldsOnly])}return fieldsOnly=flattenSections(VERIFY_ACCURACY_CONFIRMATION_FIELD),formsToRender.push(this.renderStageSection(formattedFeature,`${VERIFY_ACCURACY_CONFIRMATION_FIELD.name}`,{},fieldsOnly)),allFormFields=[...allFormFields,...fieldsOnly],[allFormFields,formsToRender]}getAllStageIds(){return this.feature.stages.map(feStage=>feStage.id)}renderForm(){const formattedFeature=formatFeatureForEdit(this.feature);this.fieldValues.feature=this.feature;const stageIds=this.getAllStageIds(),[allFormFields,formsToRender]=this.getForms(formattedFeature,this.feature.stages),title=this.feature.accurate_as_of?`Accuracy last verified ${this.feature.accurate_as_of.split(" ")[0]}.`:"Accuracy last verified at time of creation.",submitButtonTitle=this.submitting?"Submitting...":"Submit";return x$1`
+
+
+
+
+
${title}
+
+
+ Please review your information below and click 'Submit' to confirm
+ it is accurate,
+
even if no changes are made
+ !
+
+
+ ${formsToRender}
+
+
+
+
+
+
+
+ `}render(){return x$1`
+ ${this.renderSubheader()}
+ ${this.loading?this.renderSkeletons():this.renderForm()}
+ `}}__decorate$w([n$5({attribute:!1})],ChromedashGuideVerifyAccuracyPage.prototype,"featureId",void 0),__decorate$w([n$5({type:String})],ChromedashGuideVerifyAccuracyPage.prototype,"appTitle",void 0),__decorate$w([r$6()],ChromedashGuideVerifyAccuracyPage.prototype,"feature",void 0),__decorate$w([r$6()],ChromedashGuideVerifyAccuracyPage.prototype,"fieldValues",void 0),__decorate$w([r$6()],ChromedashGuideVerifyAccuracyPage.prototype,"loading",void 0),__decorate$w([r$6()],ChromedashGuideVerifyAccuracyPage.prototype,"previousStageTypeRendered",void 0),__decorate$w([r$6()],ChromedashGuideVerifyAccuracyPage.prototype,"sameTypeRendered",void 0),__decorate$w([r$6()],ChromedashGuideVerifyAccuracyPage.prototype,"submitting",void 0),customElements.define("chromedash-guide-verify-accuracy-page",ChromedashGuideVerifyAccuracyPage);var __decorate$v=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3{this.user=user,this.user||(!window.isPlaywright&&this.initializeGoogleSignIn(),"True"==this.devMode&&this.initializeTestingSignIn())}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later.")}).finally(()=>{this.loading=!1})):(window.isPlaywright||this.initializeGoogleSignIn(),void("True"==this.devMode&&this.initializeTestingSignIn()))}initializeGoogleSignIn(){google.accounts.id.initialize({client_id:this.googleSignInClientId,callback:this.handleCredentialResponse,use_fedcm_for_prompt:!0}),google.accounts.id.prompt();const signInButton=document.createElement("div");google.accounts.id.renderButton(signInButton,{type:"standard"});const appComponent=document.querySelector("chromedash-app");appComponent?appComponent.insertAdjacentElement("afterbegin",signInButton):this.insertAdjacentElement("afterbegin",signInButton)}initializeTestingSignIn(){const signInTestingButton=document.createElement("button");signInTestingButton.innerText="Sign in as example@chromium.org",signInTestingButton.setAttribute("type","button"),signInTestingButton.setAttribute("data-testid","dev-mode-sign-in-button"),signInTestingButton.setAttribute("style","margin-right: 300px; z-index:1000; background: lightblue; border: 1px solid blue;"),signInTestingButton.addEventListener("click",()=>{fetch("/dev/mock_login",{method:"POST"}).then(response=>{if(!response.ok)throw new Error(`Sign in failed! Response: ${response}`)}).then(()=>{setTimeout(()=>{redirectToCurrentPage()},1e3)}).catch(error=>{console.error("Sign in failed.",error)})});const signInButtonContainer=document.querySelector("chromedash-app");signInButtonContainer?signInButtonContainer.insertAdjacentElement("afterbegin",signInTestingButton):this.insertAdjacentElement("afterbegin",signInTestingButton)}handleCredentialResponse(credentialResponse){window.csClient.signIn(credentialResponse).then(()=>{setTimeout(()=>{redirectToCurrentPage()},1e3)}).catch(()=>{console.error("Sign in failed, so signing out to allow retry"),this.signOut()})}gotoSettings(){window.location.href="/settings"}signOut(){window.csClient.signOut().then(()=>{window.location.reload()})}isCurrentPage(href){return this.currentPage.startsWith(href)}_fireEvent(eventName,detail){const event=new CustomEvent(eventName,{bubbles:!0,composed:!0,detail});this.dispatchEvent(event)}handleDrawer(){this._fireEvent("drawer-clicked",{})}renderAccountMenu(){const alreadyOnNew=this.isCurrentPage("/guide/new")||this.isCurrentPage("/guide/enterprise/new");return x$1`
+ ${this.user?x$1`
+ ${this.user.can_create_feature&&!alreadyOnNew?x$1`
+
+ Create feature
+
+ `:E$1}
+
+
+ ${this.user.email}
+
+
+
+ Settings
+
+ Sign out
+
+
+ `:x$1` `}
+ `}render(){let accountMenu=x$1``;return IS_MOBILE||this.loading||(accountMenu=x$1`
+ `}};__decorate$u([n$5({type:String})],ChromedashIntentContent.prototype,"appTitle",void 0),__decorate$u([n$5({type:String})],ChromedashIntentContent.prototype,"subject",void 0),__decorate$u([n$5({type:String})],ChromedashIntentContent.prototype,"intentBody",void 0),ChromedashIntentContent=__decorate$u([t$3("chromedash-intent-content")],ChromedashIntentContent);var __decorate$t=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3{el.setAttribute(attr,attrs[attr])})}renderIntentCCEmailOption(){const fieldInfo=ALL_FIELDS.intent_cc_emails,defaultCCEmails=this.ownerEmails.join(",");return x$1`${fieldInfo.help_text}
+
+ `}submitIntent(){const ccEmailsInput=this.shadowRoot.querySelector("sl-input");if(!ccEmailsInput||ccEmailsInput.hasAttribute("data-user-invalid"))return;const submitButton=this.shadowRoot.querySelector("#submit-intent-button");submitButton&&submitButton.setAttribute("disabled",""),window.csClient.postIntentToBlinkDev(this.featureId,this.stageId,{gate_id:this.gateId,intent_cc_emails:ccEmailsInput?.value?.split(",")}).then(()=>{showToastMessage("Intent submitted! Check for your thread on blink-dev shortly."),setTimeout(()=>{window.location.href=`/feature/${this.featureId}`},3e3)}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later."),submitButton&&submitButton.removeAttribute("disabled")})}renderDialog(){return x$1`
+
+ This intent will be sent directly to
+ blink-dev.
+
+
+ ${this.renderIntentCCEmailOption()}
+
+ this.submitIntent()}
+ >Submit intent
+ `}render(){return this.renderDialog()}};__decorate$t([n$5({type:Number})],ChromedashPostIntentDialog.prototype,"featureId",void 0),__decorate$t([n$5({type:Number})],ChromedashPostIntentDialog.prototype,"stageId",void 0),__decorate$t([n$5({type:Number})],ChromedashPostIntentDialog.prototype,"gateId",void 0),__decorate$t([n$5({attribute:!1})],ChromedashPostIntentDialog.prototype,"ownerEmails",void 0),ChromedashPostIntentDialog=__decorate$t([t$3("chromedash-post-intent-dialog")],ChromedashPostIntentDialog);var __decorate$s=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3{if(this.feature=feature,document.title=`${this.feature.name} - ${this.appTitle}`,this.gateId){if(this.gate=gates.gates.find(gate=>gate.id===this.gateId),!this.gate)throw new Error("Invalid gate ID");for(const stage of this.feature.stages){if(this.stage)break;if(stage.id===this.gate.stage_id&&(this.stage=stage),!this.stage){const extensionStage=stage.extensions.find(e=>e.id===this.gate.stage_id);extensionStage&&(this.stage=extensionStage)}}}else if(this.stageId){const matchingStage=this.feature.stages.find(s=>s.id===this.stageId);if(!matchingStage)throw new Error(`No matching stage found for ID ${this.stageId}`);this.stage=matchingStage}else throw new Error("Invalid gate ID");return this.feature.unlisted&&(this.displayFeatureUnlistedWarning=!0),window.csClient.getIntentBody(this.featureId,this.stage.id,this.gateId)}).then(intentResp=>{this.subject=intentResp.subject,this.intentBody=intentResp.email_body,this.loading=!1}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later.")})}renderThreeLGTMSection(){return STAGE_TYPES_SHIPPING.has(this.stage?.stage_type)?x$1`
+
Obtain LGTMs from 3 API Owners
+
+ You will need three LGTMs from API owners. According to the
+ Blink Launch process
+ after that, you're free to ship your feature.
+
+ `:E$1}renderFeatureUnlistedAlert(){return this.displayFeatureUnlistedWarning?x$1`
+ Important: This feature is currently unlisted. Please only share feature
+ details with people who are collaborating with you on the feature.
+
+ Consider showing your draft intent email to your spec mentor or
+ sending it to spec-mentors@chromium.org. They can help make sure
+ that your intent email is ready for review.
+
+ `}};__decorate$s([n$5({type:String})],ChromedashIntentPreviewPage.prototype,"appTitle",void 0),__decorate$s([n$5({type:Number})],ChromedashIntentPreviewPage.prototype,"featureId",void 0),__decorate$s([n$5({type:Number})],ChromedashIntentPreviewPage.prototype,"stageId",void 0),__decorate$s([n$5({type:Number})],ChromedashIntentPreviewPage.prototype,"gateId",void 0),__decorate$s([r$6()],ChromedashIntentPreviewPage.prototype,"feature",void 0),__decorate$s([r$6()],ChromedashIntentPreviewPage.prototype,"stage",void 0),__decorate$s([r$6()],ChromedashIntentPreviewPage.prototype,"gate",void 0),__decorate$s([r$6()],ChromedashIntentPreviewPage.prototype,"loading",void 0),__decorate$s([r$6()],ChromedashIntentPreviewPage.prototype,"subject",void 0),__decorate$s([r$6()],ChromedashIntentPreviewPage.prototype,"intentBody",void 0),__decorate$s([r$6()],ChromedashIntentPreviewPage.prototype,"displayFeatureUnlistedWarning",void 0),ChromedashIntentPreviewPage=__decorate$s([t$3("chromedash-intent-preview-page")],ChromedashIntentPreviewPage);var __decorate$r=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3Please login to see the content of this page. `}};ChromedashLoginRequiredPage=__decorate$r([t$3("chromedash-login-required-page")],ChromedashLoginRequiredPage);var __decorate$q=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3{this.starredFeatures=new Set(starredFeatures)}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later.")})}refetch(){const tables=Array.from(this.renderRoot.querySelectorAll("chromedash-feature-table"));for(const table of tables)table.refetch()}handleStarToggle(e){const newStarredFeatures=new Set(this.starredFeatures);window.csClient.setStar(e.detail.featureId,e.detail.doStar).then(()=>{e.detail.doStar?newStarredFeatures.add(e.detail.featureId):newStarredFeatures.delete(e.detail.featureId),this.starredFeatures=newStarredFeatures}).catch(()=>{showToastMessage("Unable to star the Feature. Please Try Again.")})}userCanApprove(){return this.user&&(this.user.is_admin||0
+
+
+
+ `}renderPendingAndRecentApprovals(){const adminNotice=this.user?.is_admin?x$1`
You see all pending approvals because you're a site admin.
`:E$1,pendingBox=this.renderBox("Features pending my approval","pending-approval-by:me","approvals","gate.requested_on"),recentBox=this.renderBox("Recently reviewed features","is:recently-reviewed","normal","-gate.reviewed_on",!1);return[adminNotice,pendingBox,recentBox]}renderIStarred(){return this.renderBox("Features I starred","starred-by:me","normal")}renderICanEdit(){return this.renderBox("Features I can edit","can_edit:me","normal")}render(){return x$1`
+
+
My features
+
+
+ This page will soon be removed from our site.
+ Please use one of the "My features" options in the main menu.
+
+
+ ${this.userCanApprove()?this.renderPendingAndRecentApprovals():E$1}
+ ${this.renderICanEdit()} ${this.renderIStarred()}
+ `}};__decorate$q([n$5({attribute:!1})],ChromedashMyFeaturesPage.prototype,"user",void 0),__decorate$q([n$5({type:Number})],ChromedashMyFeaturesPage.prototype,"selectedGateId",void 0),__decorate$q([r$6()],ChromedashMyFeaturesPage.prototype,"starredFeatures",void 0),ChromedashMyFeaturesPage=__decorate$q([t$3("chromedash-myfeatures-page")],ChromedashMyFeaturesPage);var __decorate$p=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3=this.fieldValues.length)throw new Error("Out of bounds index when updating field values.");this.fieldValues[index].touched=!0,this.fieldValues[index].value=value,"ot_require_approvals"===this.fieldValues[index].name?(this.showApprovalsFields=!this.showApprovalsFields,this.requestUpdate()):"ot_is_deprecation_trial"===this.fieldValues[index].name&&(this.isDeprecationTrial=value,this.requestUpdate())}handleUseCounterTypeUpdate(event){this.webfeatureUseCounterType=parseInt(event.detail.value)}fetchData(){this.loading=!0,Promise.all([window.csClient.getFeature(this.featureId),window.csClient.getStage(this.featureId,this.stageId),window.csClient.getGates(this.featureId)]).then(([feature,stage,gatesRes])=>{this.feature=feature,this.stage=stage,this.stage.ot_setup_status&&this.stage.ot_setup_status!==OT_SETUP_STATUS_OPTIONS.OT_NOT_CREATED&&(window.location.href=`/feature/${this.featureId}`);const relevantGates=gatesRes.gates.filter(g=>g.stage_id===this.stage.id);relevantGates.forEach(g=>{GATE_APPROVED_REVIEW_STATES.includes(g.state)||(window.location.href=`/feature/${this.featureId}`)}),this.feature.name&&(document.title=`${this.feature.name} - ${this.appTitle}`),this.setFieldValues(),this.loading=!1})}addOptionalApprovalsFields(){const insertIndex=this.fieldValues.findIndex(fieldInfo=>"ot_require_approvals"===fieldInfo.name)+1;this.fieldValues.splice(insertIndex,0,{name:"ot_approval_buganizer_component",touched:!0,value:"",stageId:this.stage.id,isApprovalsField:!0},{name:"ot_approval_buganizer_custom_field_id",touched:!0,value:"",stageId:this.stage.id,isApprovalsField:!0},{name:"ot_approval_group_email",touched:!0,value:"",stageId:this.stage.id,isApprovalsField:!0},{name:"ot_approval_criteria_url",touched:!0,value:"",stageId:this.stage.id,isApprovalsField:!0})}addAdditionalFields(){this.fieldValues.push({name:"ot_action_requested",touched:!0,value:!0,stageId:this.stage.id,alwaysHidden:!0}),"Chrome Platform Status"!==this.appTitle&&this.fieldValues.push({name:"ot_creation__bypass_file_checks",touched:!0,value:!1,stageId:this.stage.id,alwaysHidden:!1})}setFieldValues(){const section=ORIGIN_TRIAL_CREATION_FIELDS.sections[0];this.fieldValues=section.fields.map(field=>{const featureJSONKey=ALL_FIELDS[field].name||field;let value=getStageValue(this.stage,featureJSONKey);return"ot_owner_email"!==featureJSONKey||value?"ot_require_approvals"===featureJSONKey&&(this.showApprovalsFields=!!value):value=[this.userEmail],{name:featureJSONKey,touched:!0,value,stageId:this.stage.id}}),this.addOptionalApprovalsFields(),this.addAdditionalFields()}disconnectedCallback(){super.disconnectedCallback(),document.title=this.appTitle}async registerHandlers(el){if(el){await el.updateComplete;const submitButton=this.renderRoot.querySelector("input[id=submit-button]");submitButton?.form?.addEventListener("submit",event=>{this.handleFormSubmit(event)}),setupScrollToHash(this)}}checkWebfeatureUseCounter(field,errors){field.checkMessage=errors.ot_webfeature_use_counter?x$1`
+ Error: ${errors.ot_webfeature_use_counter}
+ `:E$1}checkChromiumTrialName(field,errors){field.checkMessage=errors.ot_chromium_trial_name?x$1`
+ Error: ${errors.ot_chromium_trial_name}
+ `:E$1}checkThirdPartySupport(field,errors){field.checkMessage=errors.ot_has_third_party_support?x$1`
+
+ Error: ${errors.ot_has_third_party_support}
+ `:E$1}checkCriticalTrial(field,errors){field.checkMessage=errors.ot_is_critical_trial?x$1`
+
+ Error: ${errors.ot_is_critical_trial}
+ `:E$1}handleChromiumChecks(errors){for(const field of this.fieldValues)"ot_webfeature_use_counter"===field.name?this.checkWebfeatureUseCounter(field,errors):"ot_chromium_trial_name"===field.name?this.checkChromiumTrialName(field,errors):"ot_has_third_party_support"===field.name?this.checkThirdPartySupport(field,errors):"ot_is_critical_trial"===field.name&&this.checkCriticalTrial(field,errors)}async handleFormSubmit(e){e.preventDefault(),this.showApprovalsFields||this.fieldValues.forEach(fieldInfo=>{fieldInfo.isApprovalsField&&(fieldInfo.touched=!1)});const useCounterField=this.fieldValues.find(fv=>"ot_webfeature_use_counter"===fv.name);this.isDeprecationTrial&&(useCounterField.touched=!1);const featureSubmitBody=formatFeatureChanges(this.fieldValues,this.featureId),stageSubmitBody=featureSubmitBody.stages[0];if("ot_webfeature_use_counter"in stageSubmitBody){let useCounterPrefix="";this.webfeatureUseCounterType===USE_COUNTER_TYPE_WEBDXFEATURE?useCounterPrefix="WebDXFeature::":this.webfeatureUseCounterType===USE_COUNTER_TYPE_CSS_PROPERTY_ID&&(useCounterPrefix="CSSSampleId::"),stageSubmitBody.ot_webfeature_use_counter.value=`${useCounterPrefix}${stageSubmitBody.ot_webfeature_use_counter.value}`}this.submitting=!0,window.csClient.createOriginTrial(this.featureId,this.stageId,stageSubmitBody).then(resp=>{resp.errors?(this.handleChromiumChecks(resp.errors),showToastMessage("Some issues were found with the given inputs. Check input errors and try again."),this.submitting=!1,this.requestUpdate()):(showToastMessage("Creation request submitted!"),setTimeout(()=>{window.location.href=`/feature/${this.featureId}`},1e3))})}handleCancelClick(){window.location.href=`/feature/${this.featureId}`}renderSkeletons(){return x$1`
+
+ Please make sure this data is correct before submission! If you
+ are not sure about any information on this form, contact
+ origin-trials-support@google.com
+
+
+ ${this.renderFields()}
+
+
+
+
+
+
+
+ `}render(){return x$1`
+ ${this.renderSubheader()}
+ ${this.loading?this.renderSkeletons():this.renderForm()}
+ `}};__decorate$p([n$5({type:Number})],ChromedashOTCreationPage.prototype,"stageId",void 0),__decorate$p([n$5({type:Number})],ChromedashOTCreationPage.prototype,"featureId",void 0),__decorate$p([n$5({attribute:!1})],ChromedashOTCreationPage.prototype,"feature",void 0),__decorate$p([n$5({type:String})],ChromedashOTCreationPage.prototype,"appTitle",void 0),__decorate$p([n$5({type:String})],ChromedashOTCreationPage.prototype,"userEmail",void 0),__decorate$p([r$6()],ChromedashOTCreationPage.prototype,"loading",void 0),__decorate$p([r$6()],ChromedashOTCreationPage.prototype,"submitting",void 0),__decorate$p([r$6()],ChromedashOTCreationPage.prototype,"fieldValues",void 0),__decorate$p([r$6()],ChromedashOTCreationPage.prototype,"showApprovalsFields",void 0),__decorate$p([r$6()],ChromedashOTCreationPage.prototype,"isDeprecationTrial",void 0),__decorate$p([r$6()],ChromedashOTCreationPage.prototype,"webfeatureUseCounterType",void 0),__decorate$p([r$6()],ChromedashOTCreationPage.prototype,"stage",void 0),ChromedashOTCreationPage=__decorate$p([t$3("chromedash-ot-creation-page")],ChromedashOTCreationPage);var __decorate$o=function(decorators,target,key,desc){var c=arguments.length,r=3>c?target:null===desc?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;0<=i;i--)(d=decorators[i])&&(r=(3>c?d(r):3=this.fieldValues.length)throw new Error("Out of bounds index when updating field values.");this.fieldValues[index].touched=!0,this.fieldValues[index].value=value,"ot_extension__milestone_desktop_last"==this.fieldValues[index].name&&this.getChromeScheduleDate(event.detail.value)}openMilestoneExplanationDialog(){openInfoDialog(dialogTypes.END_MILESTONE_EXPLANATION)}updateMilestoneDate(milestone){const milestoneDiv=this.renderRoot.querySelector("#milestone-date"),milestoneTextEl=this.renderRoot.querySelector("#milestone-date-text"),date=new Date(this.endMilestoneDateValues[milestone]);milestoneDiv&&milestoneTextEl&&(milestoneDiv.style.display="block",milestoneTextEl.innerHTML=`For milestone ${milestone}, this trial will end on ${date.toLocaleDateString()}.`)}async getChromeScheduleDate(milestone){const milestoneDiv=this.renderRoot.querySelector("#milestone-date");if(milestoneDiv&&(milestoneDiv.style.display="none",!!extensionMilestoneIsValid(milestone,this.currentMilestone))){if(!(milestone in this.endMilestoneDateValues)){const milestonePlusTwo=parseInt(milestone)+2,resp=await fetch(`https://chromiumdash.appspot.com/fetch_milestone_schedule?mstone=${milestonePlusTwo}`),respJson=await resp.json();this.endMilestoneDateValues[milestone]=respJson.mstones[0].late_stable_date}this.updateMilestoneDate(milestone)}}fetchData(){this.loading=!0,Promise.all([window.csClient.getFeature(this.featureId),window.csClient.getStage(this.featureId,this.stageId)]).then(([feature,stage])=>{this.feature=feature,this.stage=stage,this.feature.name&&(document.title=`${this.feature.name} - ${this.appTitle}`),this.loading=!1}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later.")}),fetch("https://chromiumdash.appspot.com/fetch_milestone_schedule").then(resp=>resp.json()).then(scheduleInfo=>{this.currentMilestone=parseInt(scheduleInfo.mstones[0].mstone)})}disconnectedCallback(){super.disconnectedCallback(),document.title=this.appTitle}async registerHandlers(el){if(el){await el.updateComplete;const submitButton=this.renderRoot.querySelector("input[id=submit-button]");submitButton?.form?.addEventListener("submit",event=>{this.handleFormSubmit(event)}),setupScrollToHash(this)}}handleFormSubmit(e){e.preventDefault();const featureSubmitBody=formatFeatureChanges(this.fieldValues,this.featureId),stageSubmitBody=featureSubmitBody.stages[0];let newStageId=null;window.csClient.createStage(this.featureId,stageSubmitBody).then(resp=>(newStageId=resp.stage_id,window.csClient.getGates(this.featureId))).then(resp=>{const gate=resp.gates.find(gate=>gate.stage_id===newStageId);showToastMessage("Extension request started!"),newStageId&&gate?setTimeout(()=>{window.location.href=`/feature/${this.featureId}?gate=${gate.id}`},1e3):setTimeout(()=>{window.location.href=`/feature/${this.featureId}`},1e3)}).catch(()=>{showToastMessage("Some errors occurred. Please refresh the page or try again later.")})}handleCancelClick(e){e.preventDefault(),window.location.href=`/feature/${this.featureId}`}renderSkeletons(){return x$1`
+
+ The percentage numbers indicate the
+ percentage of Chrome page loads (across all channels and platforms)
+ that use the ${"css"==this.type?"property":"feature"} at least
+ once. Data is collected via Chrome's
+ anonymous usage statistics.
+
+ Note: on 2017-10-26 the underlying metrics were switched over to
+ a newer collection system which is
+ more accurate. This is also the reason for the abrupt spike around 2017-10-26.
+
+ `;return x$1`
+
+
+
+
+ Percentage of page loads over time
+
+
+ The chart below shows the percentage of page loads (in Chrome) that use
+ this feature at least once. Data is across all channels and platforms.
+ Newly added use counters that are not on Chrome stable yet only have
+ data from the Chrome channels they're on.
+
+
+ ${this.showAllHistoricalData?note2017:E$1}
+
+ Adoption of the feature on top sites
+
+
+ The chart below shows the adoption of the feature by the top URLs on the
+ internet. Data from
+ HTTP Archive.
+
+
+
+ Note: The jump around July and December 2018 are because the
+ corpus of URLs crawled by HTTP Archive increased. These jumps have no
+ correlation with the jump in the top graph. See the
+ announcement
+ for more details.
+
+
+ Copy and run this command in
+ BigQuery
+ to produce similar results:
+
+ `}};_SlTreeItem.styles=[component_styles_default,tree_item_styles_default],_SlTreeItem.dependencies={"sl-checkbox":SlCheckbox,"sl-icon":SlIcon,"sl-spinner":SlSpinner},__decorateClass([r$6()],_SlTreeItem.prototype,"indeterminate",2),__decorateClass([r$6()],_SlTreeItem.prototype,"isLeaf",2),__decorateClass([r$6()],_SlTreeItem.prototype,"loading",2),__decorateClass([r$6()],_SlTreeItem.prototype,"selectable",2),__decorateClass([n$5({type:Boolean,reflect:!0})],_SlTreeItem.prototype,"expanded",2),__decorateClass([n$5({type:Boolean,reflect:!0})],_SlTreeItem.prototype,"selected",2),__decorateClass([n$5({type:Boolean,reflect:!0})],_SlTreeItem.prototype,"disabled",2),__decorateClass([n$5({type:Boolean,reflect:!0})],_SlTreeItem.prototype,"lazy",2),__decorateClass([e$6("slot:not([name])")],_SlTreeItem.prototype,"defaultSlot",2),__decorateClass([e$6("slot[name=children]")],_SlTreeItem.prototype,"childrenSlot",2),__decorateClass([e$6(".tree-item__item")],_SlTreeItem.prototype,"itemElement",2),__decorateClass([e$6(".tree-item__children")],_SlTreeItem.prototype,"childrenContainer",2),__decorateClass([e$6(".tree-item__expand-button slot")],_SlTreeItem.prototype,"expandButtonSlot",2),__decorateClass([watch("loading",{waitUntilFirstUpdate:!0})],_SlTreeItem.prototype,"handleLoadingChange",1),__decorateClass([watch("disabled")],_SlTreeItem.prototype,"handleDisabledChange",1),__decorateClass([watch("selected")],_SlTreeItem.prototype,"handleSelectedChange",1),__decorateClass([watch("expanded",{waitUntilFirstUpdate:!0})],_SlTreeItem.prototype,"handleExpandedChange",1),__decorateClass([watch("expanded",{waitUntilFirstUpdate:!0})],_SlTreeItem.prototype,"handleExpandAnimation",1),__decorateClass([watch("lazy",{waitUntilFirstUpdate:!0})],_SlTreeItem.prototype,"handleLazyChange",1);var SlTreeItem=_SlTreeItem;setDefaultAnimation("tree-item.expand",{keyframes:[{height:"0",opacity:"0",overflow:"hidden"},{height:"auto",opacity:"1",overflow:"hidden"}],options:{duration:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)"}}),setDefaultAnimation("tree-item.collapse",{keyframes:[{height:"auto",opacity:"1",overflow:"hidden"},{height:"0",opacity:"0",overflow:"hidden"}],options:{duration:200,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)"}}),SlTreeItem.define("sl-tree-item");var tree_styles_default=i$7`
+ :host {
+ /*
+ * These are actually used by tree item, but we define them here so they can more easily be set and all tree items
+ * stay consistent.
+ */
+ --indent-guide-color: var(--sl-color-neutral-200);
+ --indent-guide-offset: 0;
+ --indent-guide-style: solid;
+ --indent-guide-width: 0;
+ --indent-size: var(--sl-spacing-large);
+
+ display: block;
+
+ /*
+ * Tree item indentation uses the "em" unit to increment its width on each level, so setting the font size to zero
+ * here removes the indentation for all the nodes on the first level.
+ */
+ font-size: 0;
+ }
+`;function clamp(value,min,max){const noNegativeZero=n=>Object.is(n,-0)?0:n;return valuemax?noNegativeZero(max):noNegativeZero(value)}function syncCheckboxes(changedTreeItem,initialSync=!1){function syncParentItem(treeItem){const children=treeItem.getChildrenItems({includeDisabled:!1});if(children.length){const allChecked=children.every(item=>item.selected),allUnchecked=children.every(item=>!item.selected&&!item.indeterminate);treeItem.selected=allChecked,treeItem.indeterminate=!allChecked&&!allUnchecked}}function syncAncestors(treeItem){const parentItem=treeItem.parentElement;SlTreeItem.isTreeItem(parentItem)&&(syncParentItem(parentItem),syncAncestors(parentItem))}function syncDescendants(treeItem){for(const childItem of treeItem.getChildrenItems())childItem.selected=initialSync?treeItem.selected||childItem.selected:!childItem.disabled&&treeItem.selected,syncDescendants(childItem);initialSync&&syncParentItem(treeItem)}syncDescendants(changedTreeItem),syncAncestors(changedTreeItem)}var SlTree=class extends ShoelaceElement{constructor(){super(),this.selection="single",this.clickTarget=null,this.localize=new LocalizeController(this),this.initTreeItem=item=>{item.selectable="multiple"===this.selection,["expand","collapse"].filter(status=>!!this.querySelector(`[slot="${status}-icon"]`)).forEach(status=>{const existingIcon=item.querySelector(`[slot="${status}-icon"]`),expandButtonIcon=this.getExpandButtonIcon(status);if(expandButtonIcon)if(null===existingIcon)item.append(expandButtonIcon);else if(existingIcon.hasAttribute("data-default"))existingIcon.replaceWith(expandButtonIcon);else;})},this.handleTreeChanged=mutations=>{for(const mutation of mutations){const addedNodes=[...mutation.addedNodes].filter(SlTreeItem.isTreeItem),removedNodes=[...mutation.removedNodes].filter(SlTreeItem.isTreeItem);addedNodes.forEach(this.initTreeItem),this.lastFocusedItem&&removedNodes.includes(this.lastFocusedItem)&&(this.lastFocusedItem=null)}},this.handleFocusOut=event=>{const relatedTarget=event.relatedTarget;relatedTarget&&this.contains(relatedTarget)||(this.tabIndex=0)},this.handleFocusIn=event=>{const target=event.target;event.target===this&&this.focusItem(this.lastFocusedItem||this.getAllTreeItems()[0]),SlTreeItem.isTreeItem(target)&&!target.disabled&&(this.lastFocusedItem&&(this.lastFocusedItem.tabIndex=-1),this.lastFocusedItem=target,this.tabIndex=-1,target.tabIndex=0)},this.addEventListener("focusin",this.handleFocusIn),this.addEventListener("focusout",this.handleFocusOut),this.addEventListener("sl-lazy-change",this.handleSlotChange)}async connectedCallback(){super.connectedCallback(),this.setAttribute("role","tree"),this.setAttribute("tabindex","0"),await this.updateComplete,this.mutationObserver=new MutationObserver(this.handleTreeChanged),this.mutationObserver.observe(this,{childList:!0,subtree:!0})}disconnectedCallback(){var _a;super.disconnectedCallback(),null==(_a=this.mutationObserver)?void 0:_a.disconnect()}getExpandButtonIcon(status){const slot="expand"===status?this.expandedIconSlot:this.collapsedIconSlot,icon=slot.assignedElements({flatten:!0})[0];if(icon){const clone=icon.cloneNode(!0);return[clone,...clone.querySelectorAll("[id]")].forEach(el=>el.removeAttribute("id")),clone.setAttribute("data-default",""),clone.slot=`${status}-icon`,clone}return null}selectItem(selectedItem){const previousSelection=[...this.selectedItems];if("multiple"===this.selection)selectedItem.selected=!selectedItem.selected,selectedItem.lazy&&(selectedItem.expanded=!0),syncCheckboxes(selectedItem);else if("single"===this.selection||selectedItem.isLeaf){const items=this.getAllTreeItems();for(const item of items)item.selected=item===selectedItem}else"leaf"===this.selection&&(selectedItem.expanded=!selectedItem.expanded);const nextSelection=this.selectedItems;(previousSelection.length!==nextSelection.length||nextSelection.some(item=>!previousSelection.includes(item)))&&Promise.all(nextSelection.map(el=>el.updateComplete)).then(()=>{this.emit("sl-selection-change",{detail:{selection:nextSelection}})})}getAllTreeItems(){return[...this.querySelectorAll("sl-tree-item")]}focusItem(item){null==item?void 0:item.focus()}handleKeyDown(event){if(!["ArrowDown","ArrowUp","ArrowRight","ArrowLeft","Home","End","Enter"," "].includes(event.key))return;if(event.composedPath().some(el=>{var _a;return["input","textarea"].includes(null==(_a=null==el?void 0:el.tagName)?void 0:_a.toLowerCase())}))return;const items=this.getFocusableItems(),isLtr="ltr"===this.localize.dir(),isRtl="rtl"===this.localize.dir();if(0item.matches(":focus")),activeItem=items[activeItemIndex],focusItemAt=index=>{const item=items[clamp(index,0,items.length-1)];this.focusItem(item)},toggleExpand=expanded=>{activeItem.expanded=expanded};"ArrowDown"===event.key?focusItemAt(activeItemIndex+1):"ArrowUp"===event.key?focusItemAt(activeItemIndex-1):isLtr&&"ArrowRight"===event.key||isRtl&&"ArrowLeft"===event.key?!activeItem||activeItem.disabled||activeItem.expanded||activeItem.isLeaf&&!activeItem.lazy?focusItemAt(activeItemIndex+1):toggleExpand(!0):isLtr&&"ArrowLeft"===event.key||isRtl&&"ArrowRight"===event.key?!activeItem||activeItem.disabled||activeItem.isLeaf||!activeItem.expanded?focusItemAt(activeItemIndex-1):toggleExpand(!1):"Home"===event.key?focusItemAt(0):"End"===event.key?focusItemAt(items.length-1):("Enter"===event.key||" "===event.key)&&!activeItem.disabled&&this.selectItem(activeItem)}}handleClick(event){const target=event.target,treeItem=target.closest("sl-tree-item"),isExpandButton=event.composedPath().some(el=>{var _a;return null==(_a=null==el?void 0:el.classList)?void 0:_a.contains("tree-item__expand-button")});!treeItem||treeItem.disabled||target!==this.clickTarget||(isExpandButton?treeItem.expanded=!treeItem.expanded:this.selectItem(treeItem))}handleMouseDown(event){this.clickTarget=event.target}handleSlotChange(){const items=this.getAllTreeItems();items.forEach(this.initTreeItem)}async handleSelectionChange(){const isSelectionMultiple="multiple"===this.selection,items=this.getAllTreeItems();this.setAttribute("aria-multiselectable",isSelectionMultiple?"true":"false");for(const item of items)item.selectable=isSelectionMultiple;isSelectionMultiple&&(await this.updateComplete,[...this.querySelectorAll(":scope > sl-tree-item")].forEach(treeItem=>syncCheckboxes(treeItem,!0)))}get selectedItems(){const items=this.getAllTreeItems(),isSelected=item=>item.selected;return items.filter(isSelected)}getFocusableItems(){const items=this.getAllTreeItems(),collapsedItems=new Set;return items.filter(item=>{var _a;if(item.disabled)return!1;const parent=null==(_a=item.parentElement)?void 0:_a.closest("[role=treeitem]");return parent&&(!parent.expanded||parent.loading||collapsedItems.has(parent))&&collapsedItems.add(item),!collapsedItems.has(item)})}render(){return x$1`
+
+ ${count} reviews of ${this.reviewLatencyList.length} distinct features
+ in the past 90 days.
+
+
Latency is measured in weekdays from request to initial response.
+ `}renderFeatureReviewsRow(reviewLatency){const gateLatency={};for(const gr of reviewLatency.gate_reviews){let display=gr.latency_days;-1===gr.latency_days?display="":-2==gr.latency_days&&(display="Pending"),gateLatency[gr.gate_type]=display}return x$1`
+
Comments
+ +${autolink(this.feature.comments,this.featureLinks)}
+