wagtail 7.1.2__py3-none-any.whl → 7.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
wagtail/__init__.py CHANGED
@@ -6,7 +6,7 @@ from wagtail.utils.version import get_semver_version, get_version
6
6
 
7
7
  # major.minor.patch.release.number
8
8
  # release must be one of alpha, beta, rc, or final
9
- VERSION = (7, 1, 2, "final", 1)
9
+ VERSION = (7, 1, 3, "final", 1)
10
10
 
11
11
  __version__ = get_version(VERSION)
12
12
 
@@ -1 +1 @@
1
- (()=>{"use strict";var e,t={2294:(e,t,i)=>{var n=i(6931),s=i.n(n),l=i(2427),a=i.n(l),o=i(4327),r=i(1238),c=i(1002);class d{constructor(e,t,i,n,l,d){this.blockDef=e,this.type=e.name;const h=$(`\n <div class="w-field__wrapper" data-field-wrapper>\n <div class="${(0,o.Z)(this.blockDef.meta.classname)}" data-field>\n <div class="w-field__errors" id="${i}-errors" data-field-errors>\n <svg class="icon icon-warning w-field__errors-icon" aria-hidden="true" hidden><use href="#icon-warning"></use></svg>\n </div>\n <div class="w-field__help" id="${i}-helptext" data-field-help></div>\n <div class="w-field__input" data-field-input>\n <div data-streamfield-widget></div>\n </div>\n </div>\n </div>\n `);$(t).replaceWith(h);const u=h.find("[data-streamfield-widget]").get(0);this.element=h[0],this.field=this.element.querySelector("[data-field]"),this.parentCapabilities=d||new Map,this.prefix=i;const p={attributes:this.getAttributes()};try{this.widget=this.blockDef.widget.render(u,i,i,n,this.parentCapabilities,p)}catch(e){return console.error(e),void this.setError({messages:["This widget failed to render, please check the console for details."]})}if(this.idForLabel=this.widget.idForLabel,this.blockDef.meta.helpText){const e=document.createElement("p");e.classList.add("help"),e.innerHTML=this.blockDef.meta.helpText,this.field.querySelector("[data-field-help]").appendChild(e)}if(window.comments&&this.blockDef.meta.showAddCommentButton){const t=document.createElement("button");t.type="button",t.setAttribute("aria-label",e.meta.strings.ADD_COMMENT),t.setAttribute("data-comment-add",""),t.classList.add("w-field__comment-button","w-field__comment-button--add"),s().render(a().createElement(a().Fragment,null,a().createElement(r.A,{name:"comment-add"}),a().createElement(r.A,{name:"comment-add-reversed"})),t),this.field.classList.add("w-field--commentable"),this.field.querySelector("[data-field-input]").appendChild(t),window.comments.initAddCommentButton(t)}l&&this.setError(l),(0,c.$)(this.field,this.blockDef.meta.attrs||{})}setCapabilityOptions(e,t){Object.assign(this.parentCapabilities.get(e),t),this.widget&&this.widget.setCapabilityOptions&&this.widget.setCapabilityOptions(e,t)}setState(e){this.widget&&this.widget.setState(e)}setError(e){const t=this.field.querySelector("[data-field-errors]");if(t.querySelectorAll(".error-message").forEach((e=>e.remove())),this.widget?.setInvalid?.(!!e),e){this.field.classList.add("w-field--error"),t.querySelector(".icon").removeAttribute("hidden");const i=document.createElement("p");i.classList.add("error-message");const n=document.createTextNode(e.messages.join(" "));i.appendChild(n),t.appendChild(i)}else this.field.classList.remove("w-field--error"),t.querySelector(".icon").setAttribute("hidden","true")}getAttributes(){const e=this.prefix,t={};return this.blockDef.meta.helpText&&(t["aria-describedby"]=`${e}-helptext`),this.blockDef.meta.required&&(t.required=""),this.blockDef.meta.maxLength&&(t.maxLength=this.blockDef.meta.maxLength),t}getState(){return this.widget.getState()}getValue(){return this.widget.getValue()}getTextLabel(e){return this.widget.getTextLabel?this.widget.getTextLabel(e):null}focus(e){this.widget&&this.widget.focus(e)}}class h{constructor(e,t,i){this.name=e,this.widget=t,this.meta=i}render(e,t,i,n,s){return new d(this,e,t,i,n,s)}}class u{constructor(e,t){this.blockDef=e;const i=document.createElement("div");this.blockDef.meta.html?i.innerHTML=this.blockDef.meta.html:i.innerHTML=(0,o.Z)(this.blockDef.meta.text),t.replaceWith(i),(0,c.$)(i,this.blockDef.meta.attrs||{})}setState(e){}setError(e){}getState(){return null}getValue(){return null}focus(){}}class p{constructor(e,t){this.name=e,this.meta=t}render(e){return new u(this,e)}}var m=i(4188),b=i(4545),f=i(2833);class g{constructor(e){this.props=e}render(){const e=document.createElement("template"),{panelId:t,headingId:i,contentId:n,blockDef:s,blockTypeIcon:l,blockTypeLabel:a,collapsed:o}=this.props;return e.innerHTML=`\n <section class="w-panel w-panel--nested${o?" collapsed":""}" id="${t}" aria-labelledby="${i}" data-panel>\n <div class="w-panel__header">\n <a class="w-panel__anchor w-panel__anchor--prefix" href="#${t}" aria-labelledby="${i}" data-panel-anchor>\n <svg class="icon icon-link w-panel__icon" aria-hidden="true">\n <use href="#icon-link"></use>\n </svg>\n </a>\n <button class="w-panel__toggle" type="button" aria-label="${(0,f.AP)("Toggle section")}" aria-describedby="${i}" data-panel-toggle aria-controls="${n}" aria-expanded="true">\n <svg class="icon icon-${l} w-panel__icon" aria-hidden="true">\n <use href="#icon-${l}"></use>\n </svg>\n </button>\n <h2 class="w-panel__heading w-panel__heading--label" aria-level="3" id="${i}" data-panel-heading>\n <span class="c-sf-block__type">${a}</span>\n ${s?.meta.required?'<span class="w-required-mark" data-panel-required>*</span>':""}\n <span data-panel-heading-text class="c-sf-block__title"></span>\n </h2>\n <a class="w-panel__anchor w-panel__anchor--suffix" href="#${t}" aria-labelledby="${i}">\n <svg class="icon icon-link w-panel__icon" aria-hidden="true">\n <use href="#icon-link"></use>\n </svg>\n </a>\n <div class="w-panel__divider"></div>\n <div class="w-panel__controls" data-panel-controls></div>\n </div>\n <div id="${n}" class="w-panel__content">\n ${s?"<div data-streamfield-block></div>":""}\n </div>\n </section>\n `,e.content.firstElementChild}}const k=(e,t=!("true"===e.getAttribute("aria-expanded")))=>{const i=document.querySelector(`#${e.getAttribute("aria-controls")}`);i&&(e.setAttribute("aria-expanded",`${t}`),t?i.removeAttribute("hidden"):"onbeforematch"in document.body?i.setAttribute("hidden","until-found"):i.setAttribute("hidden",""),e.dispatchEvent(new CustomEvent("commentAnchorVisibilityChange",{bubbles:!0})),e.dispatchEvent(new CustomEvent("wagtail:panel-toggle",{bubbles:!0,cancelable:!1,detail:{expanded:t}})))};function v(e){const t=e.closest("[data-panel]"),i=document.querySelector(`#${e.getAttribute("aria-controls")}`);if(!i||!t||t.collapsibleInitialised)return;t.collapsibleInitialised=!0;const n=k.bind(null,e),s=t.classList.contains("collapsed"),l=i.querySelector('[aria-invalid="true"], .error, .w-field--error'),a=s&&!l;a&&n(!1),e.addEventListener("click",n.bind(null,void 0));const o=t.querySelector("[data-panel-heading]");o&&o.addEventListener("click",n.bind(null,void 0)),i.addEventListener("beforematch",n.bind(null,!0)),e.dispatchEvent(new CustomEvent("wagtail:panel-init",{bubbles:!0,cancelable:!1,detail:{expanded:!a}}))}class w{constructor(e,t,i,n,s){const l=n||{};this.blockDef=e,this.type=e.name,this.childBlocks={};let a="";if(this.blockDef.collapsible&&(a=new g({panelId:i+"-section",headingId:i+"-heading",contentId:i+"-content",blockTypeIcon:(0,o.Z)(e.meta.icon),blockTypeLabel:(0,o.Z)(e.meta.label),collapsed:e.meta.collapsed}).render().outerHTML),e.meta.formTemplate){const n=e.meta.formTemplate.replace(/__PREFIX__/g,i);let o;a?(o=$(a),$(t).replaceWith(o),o=this.#e(o,i),o.append(n)):(o=$(n),$(t).replaceWith(o));const r=s?.blockErrors||{};this.blockDef.childBlockDefs.forEach((e=>{const t=o.find('[data-structblock-child="'+e.name+'"]').get(0),n=e.render(t,i+"-"+e.name,l[e.name],r[e.name]);this.childBlocks[e.name]=n})),this.container=o}else{let e=$(`\n <div class="${(0,o.Z)(this.blockDef.meta.classname||"")}">\n </div>\n `);e.append(a),$(t).replaceWith(e),this.blockDef.collapsible&&(e=this.#e(e,i)),this.blockDef.meta.helpText&&e.append(`\n <div class="c-sf-help">\n <div class="help">\n ${this.blockDef.meta.helpText}\n </div>\n </div>\n `),this.blockDef.childBlockDefs.forEach((t=>{let n="";t instanceof this.blockDef.constructor||(n=`<label class="w-field__label">${(0,o.Z)(t.meta.label)}${t.meta.required?'<span class="w-required-mark">*</span>':""}</label>`);const a=$(`\n <div data-contentpath="${t.name}">\n ${n}\n <div data-streamfield-block></div>\n </div>\n `);e.append(a);const r=a.find("[data-streamfield-block]").get(0),c=a.find("label").get(0),d=s?.blockErrors||{},h=t.render(r,i+"-"+t.name,l[t.name],d[t.name],new Map);this.childBlocks[t.name]=h,h.idForLabel&&c.setAttribute("for",h.idForLabel)})),this.container=e}this.blockDef.collapsible&&this.setTextLabel(),(0,c.$)(this.container[0],this.blockDef.meta.attrs||{})}#e(e,t){const i=e.find("[data-panel-toggle]")[0],n=e.find("[data-panel-heading-text]")[0];return v(i),this.setTextLabel=()=>{const e=this.getTextLabel({maxLength:50});n.textContent=e||""},i.addEventListener("wagtail:panel-toggle",this.setTextLabel),e.find(`#${t}-content`)}setState(e){for(const t in e)this.childBlocks[t].setState(e[t])}setError(e){if(!e)return;const t=this.container[0];if((0,b.$)(t),e.messages&&(0,b.U)(t,e.messages),e.blockErrors)for(const t in e.blockErrors)(0,m.$)(e.blockErrors,t)&&this.childBlocks[t].setError(e.blockErrors[t])}getState(){const e={};for(const t in this.childBlocks)e[t]=this.childBlocks[t].getState();return e}getDuplicatedState(){const e={};for(const t in this.childBlocks){const i=this.childBlocks[t];e[t]=void 0===i.getDuplicatedState?i.getState():i.getDuplicatedState()}return e}getValue(){const e={};for(const t in this.childBlocks)e[t]=this.childBlocks[t].getValue();return e}getTextLabel(e){if("string"==typeof this.blockDef.meta.labelFormat)return this.blockDef.meta.labelFormat.replace(/\{(\w+)\}/g,((t,i)=>{const n=this.childBlocks[i];return n&&n.getTextLabel?n.getTextLabel(e):""}));for(const t of this.blockDef.childBlockDefs){const i=this.childBlocks[t.name];if(i.getTextLabel){const t=i.getTextLabel(e);if(t)return t}}return null}focus(e){if(this.blockDef.childBlockDefs.length){const t=this.blockDef.childBlockDefs[0].name;this.childBlocks[t].focus(e)}}}class D{constructor(e,t,i){this.name=e,this.childBlockDefs=t,this.meta=i,this.collapsible=!0}render(e,t,i,n){return new w(this,e,t,i,n)}}const x={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let y;const C=new Uint8Array(16),E=[];for(let e=0;e<256;++e)E.push((e+256).toString(16).slice(1));const B=function(e,t,i){if(x.randomUUID&&!t&&!e)return x.randomUUID();const n=(e=e||{}).random??e.rng?.()??function(){if(!y){if("undefined"==typeof crypto||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");y=crypto.getRandomValues.bind(crypto)}return y(C)}();if(n.length<16)throw new Error("Random bytes length must be >= 16");if(n[6]=15&n[6]|64,n[8]=63&n[8]|128,t){if((i=i||0)<0||i+16>t.length)throw new RangeError(`UUID byte range ${i}:${i+15} is out of buffer bounds`);for(let e=0;e<16;++e)t[i+e]=n[e];return t}return function(e,t=0){return(E[e[t+0]]+E[e[t+1]]+E[e[t+2]]+E[e[t+3]]+"-"+E[e[t+4]]+E[e[t+5]]+"-"+E[e[t+6]]+E[e[t+7]]+"-"+E[e[t+8]]+E[e[t+9]]+"-"+E[e[t+10]]+E[e[t+11]]+E[e[t+12]]+E[e[t+13]]+E[e[t+14]]+E[e[t+15]]).toLowerCase()}(n)};var _=i(246),S=i(9675);class I{constructor(e){this.sequenceChild=e}render(e){const t=this.sequenceChild.strings[this.labelIdentifier]||this.labelIdentifier;this.dom=$(`\n <button type="button" class="button button--icon text-replace white" data-streamfield-action="${this.labelIdentifier}" title="${(0,o.Z)(t)}">\n <svg class="icon icon-${(0,o.Z)(this.icon)}" aria-hidden="true">\n <use href="#icon-${(0,o.Z)(this.icon)}"></use>\n </svg>\n </button>\n `),this.dom.on("click",(()=>(this.onClick&&this.onClick(),!1))),$(e).append(this.dom),this.enableEvent&&this.sequenceChild.addEventListener(this.enableEvent,(()=>{this.enable()})),this.disableEvent&&this.sequenceChild.addEventListener(this.disableEvent,(()=>{this.disable()})),this.initiallyDisabled&&this.disable()}enable(){this.dom.removeAttr("disabled")}disable(){this.dom.attr("disabled","true")}}class q extends I{enableEvent="enableMoveUp";disableEvent="disableMoveUp";initiallyDisabled=!0;icon="arrow-up";labelIdentifier="MOVE_UP";onClick(){this.sequenceChild.moveUp()}}class L extends I{enableEvent="enableMoveDown";disableEvent="disableMoveDown";initiallyDisabled=!0;icon="arrow-down";labelIdentifier="MOVE_DOWN";onClick(){this.sequenceChild.moveDown()}}class T extends I{enableEvent="enableDrag";disableEvent="disableDrag";initiallyDisabled=!1;icon="grip";labelIdentifier="DRAG"}class A extends I{enableEvent="enableDuplication";disableEvent="disableDuplication";icon="copy";labelIdentifier="DUPLICATE";onClick(){this.sequenceChild.duplicate({animate:!0})}}class M extends I{icon="bin";labelIdentifier="DELETE";onClick(){this.sequenceChild.delete({animate:!0})}}class U extends EventTarget{constructor(e,t,i,n,s,l,a,r){super(),this.blockDef=e,this.type=e.name,this.prefix=i,this.index=n,this.id=s,this.sequence=a;const c=r&&r.animate,d=r&&r.focus,h=r&&r.collapsed;this.strings=r&&r.strings||{};const u=`block-${s}-section`,p=`block-${s}-heading`,m=`block-${s}-content`,b=(0,o.Z)(this.blockDef.meta.icon),f=(0,o.Z)(this.blockDef.meta.label),k=new g({panelId:u,headingId:p,contentId:m,blockDef:e,blockTypeIcon:b,blockTypeLabel:f}).render(),w=$(`\n <div data-streamfield-child ${this.id?`data-contentpath="${(0,o.Z)(this.id)}"`:"data-contentpath-disabled"}>\n <input type="hidden" name="${this.prefix}-deleted" value="">\n <input type="hidden" name="${this.prefix}-order" value="${n}">\n <input type="hidden" name="${this.prefix}-type" value="${(0,o.Z)(this.type||"")}">\n <input type="hidden" name="${this.prefix}-id" value="${(0,o.Z)(this.id||"")}">\n ${k.outerHTML}\n </div>\n `);$(t).replaceWith(w),this.element=w.get(0);const x=w.find("[data-streamfield-block]").get(0);this.actionsContainerElement=w.find("[data-panel-controls]").get(0),this.titleElement=w.find("[data-panel-heading-text]"),this.toggleElement=this.element.querySelector("[data-panel-toggle]"),this.deletedInput=w.find(`input[name="${this.prefix}-deleted"]`),this.indexInput=w.find(`input[name="${this.prefix}-order"]`),this.addActionButton(new q(this)),this.addActionButton(new L(this)),this.addActionButton(new T(this)),this.addActionButton(new A(this)),this.addActionButton(new M(this));const y=new Map;y.set("duplicate",{enabled:!0,fn:this.duplicate}),y.set("split",{enabled:!0,fn:this.split.bind(this)}),y.set("addSibling",{enabled:!0,fn:this.addSibling.bind(this),blockGroups:this.sequence.getBlockGroups(),getBlockCount:this.sequence.getBlockCount.bind(this.sequence),getBlockMax:this.sequence.getBlockMax.bind(this.sequence)}),this.blockDef instanceof D&&(this.blockDef.collapsible=!1),this.block=this.blockDef.render(x,this.prefix+"-value",l,void 0,y),v(this.element.querySelector("[data-panel-toggle]")),h&&this.collapse(),this.toggleElement.addEventListener("wagtail:panel-toggle",(()=>{const e=this.getTextLabel({maxLength:70});this.titleElement.text(e||"")}));const C=this.getTextLabel({maxLength:70});this.titleElement.text(C||""),c?(w.hide(),setTimeout((()=>{w.slideDown(),d&&this.block.focus({soft:!0})}),10)):d&&this.block.focus({soft:!0})}addActionButton(e){e.render(this.actionsContainerElement)}addSibling(e){this.sequence._onRequestInsert(this.index+1,e)}moveUp(){this.sequence.moveBlockUp(this.index)}moveDown(){this.sequence.moveBlockDown(this.index)}duplicate(e){this.sequence.duplicateBlock(this.index,e)}delete(e){this.sequence.deleteBlock(this.index,e)}markDeleted({animate:e=!1}){this.deletedInput.val("1"),e?$(this.element).slideUp().dequeue().fadeOut().attr("aria-hidden","true"):$(this.element).hide().attr("aria-hidden","true");const t=this.getContentPath();t&&window.comments.commentApp&&window.comments.commentApp.invalidateContentPath(t)}getContentPath(){return window.comments?.getContentPath(this.element)}enableDuplication(){this.dispatchEvent(new Event("enableDuplication")),this.block&&this.block.setCapabilityOptions&&this.block.setCapabilityOptions("duplicate",{enabled:!0})}disableDuplication(){this.dispatchEvent(new Event("disableDuplication")),this.block&&this.block.setCapabilityOptions&&this.block.setCapabilityOptions("duplicate",{enabled:!1})}enableSplit(){this.block&&this.block.setCapabilityOptions&&this.block.setCapabilityOptions("split",{enabled:!0})}disableSplit(){this.block&&this.block.setCapabilityOptions&&this.block.setCapabilityOptions("split",{enabled:!1})}enableMoveUp(){this.dispatchEvent(new Event("enableMoveUp"))}disableMoveUp(){this.dispatchEvent(new Event("disableMoveUp"))}enableMoveDown(){this.dispatchEvent(new Event("enableMoveDown"))}disableMoveDown(){this.dispatchEvent(new Event("disableMoveDown"))}setIndex(e){this.index=e,this.indexInput.val(e)}setError(e){this.block.setError(e),e&&k(this.toggleElement,!0)}focus(e){this.block.focus(e)}getTextLabel(e){return this.block.getTextLabel?this.block.getTextLabel(e):null}collapse(){k(this.toggleElement,!1)}getDuplicatedState(){return{id:B(),value:void 0===this.block.getDuplicatedState?this.block.getState():this.block.getDuplicatedState()}}}class O{constructor(e,t){this.index=t&&t.index,this.onRequestInsert=t&&t.onRequestInsert}setIndex(e){this.index=e}delete({animate:e=!1}){e?$(this.element).slideUp().attr("aria-hidden","true"):$(this.element).hide().attr("aria-hidden","true")}}class P{_createChild(e,t,i,n,s,l,a,o){throw new Error("not implemented")}_createInsertionControl(e,t){throw new Error("not implemented")}_getChildDataForInsertion(e){throw new Error("not implemented")}getBlockGroups(){throw new Error("not implemented")}clear(){this.countInput.val(0),this.sequenceContainer.empty(),this.children=[],this.blockCounter=0;const e=document.createElement("div");this.sequenceContainer.append(e),this.inserters=[this._createInsertionControl(e,{index:0,onRequestInsert:(e,t)=>{this._onRequestInsert(e,t)},strings:this.blockDef.meta.strings})],this.blockCountChanged()}_onRequestInsert(e,t){const[i,n,s]=this._getChildDataForInsertion(t);this._insert(i,n,s||null,e,{animate:!0,focus:!0})}blockCountChanged(){}_insert(e,t,i,n,s){const l=this.prefix+"-"+this.blockCounter,a=s&&s.animate,o=s&&s.focus,r=s&&s.collapsed;this.blockCounter+=1;const c=this.inserters[n].element,d=document.createElement("div"),h=document.createElement("div");$(d).insertAfter(c),$(h).insertAfter(d),(0,S.y)(n,this.children.length).forEach((e=>{this.children[e].setIndex(e+1)})),(0,S.y)(n+1,this.inserters.length).forEach((e=>{this.inserters[e].setIndex(e+1)}));const u=this._createChild(e,d,l,n,i,t,this,{animate:a,focus:o,collapsed:r,strings:this.blockDef.meta.strings});this.children.splice(n,0,u);const p=this._createInsertionControl(h,{index:n+1,onRequestInsert:(e,t)=>{this._onRequestInsert(e,t)},strings:this.blockDef.meta.strings,animate:a});this.inserters.splice(n+1,0,p),this.countInput.val(this.blockCounter);const m=0===n,b=n===this.children.length-1;return m||(u.enableMoveUp(),b&&this.children[n-1].enableMoveDown()),b||(u.enableMoveDown(),m&&this.children[n+1].enableMoveUp()),this.blockCountChanged(),u}deleteBlock(e,t){const i=t&&t.animate;this.children[e].markDeleted({animate:i}),this.inserters[e].delete({animate:i}),this.children.splice(e,1),this.inserters.splice(e,1),(0,S.y)(e,this.children.length).forEach((e=>{this.children[e].setIndex(e)})),(0,S.y)(e,this.inserters.length).forEach((e=>{this.inserters[e].setIndex(e)})),0===e&&this.children.length>0&&this.children[0].disableMoveUp(),e===this.children.length&&this.children.length>0&&this.children[this.children.length-1].disableMoveDown(),this.blockCountChanged()}initDragNDrop(){this.sortable=_.Ay.create(this.sequenceContainer.get(0),{handle:'[data-streamfield-action="DRAG"]',animation:200,draggable:"[data-streamfield-child]",onEnd:e=>{const{oldDraggableIndex:t,newDraggableIndex:i}=e;t!==i&&this.moveBlock(t,i)},setData:e=>{e.setData("application/vnd.wagtail.type","sf-block")}})}moveBlock(e,t){if(e===t)return;const i=this.inserters[e],n=this.children[e];t>e?$(i.element).insertAfter(this.children[t].element):$(i.element).insertBefore(this.inserters[t].element),$(n.element).insertAfter(i.element),this.inserters.splice(e,1),this.inserters.splice(t,0,i),this.children.splice(e,1),this.children.splice(t,0,n),t>e?(0,S.y)(e,t+1).forEach((e=>{this.inserters[e].setIndex(e),this.children[e].setIndex(e)})):(0,S.y)(t,e+1).forEach((e=>{this.inserters[e].setIndex(e),this.children[e].setIndex(e)}));const s=this.children.length-1;0===e&&(n.enableMoveUp(),this.children[0].disableMoveUp()),e===s&&(n.enableMoveDown(),this.children[s].disableMoveDown()),0===t&&(n.disableMoveUp(),this.children[1].enableMoveUp()),t===s&&(n.disableMoveDown(),this.children[s-1].enableMoveDown())}moveBlockUp(e){this.moveBlock(e,e-1)}moveBlockDown(e){this.moveBlock(e,e+1)}setState(e){this.clear(),e.forEach(((e,t)=>{this.insert(e,t)}))}getState(){return this.children.map((e=>e.getState()))}getDuplicatedState(){return this.children.map((e=>e.getDuplicatedState()))}getValue(){return this.children.map((e=>e.getValue()))}getTextLabel(e){const t=e&&e.maxLength;let i="";for(const e of this.children){const n=e.getTextLabel({maxLength:t});if(n)if(i){const e=i+", "+n;if(t&&e.length>t-1)return i.endsWith("…")||(i+="…"),i;i=e}else i=n}return i}focus(e){this.children.length&&this.children[0].focus(e)}}class R extends U{getState(){return{id:this.id||null,value:this.block.getState()}}getValue(){return this.block.getValue()}setState({value:e,id:t}){this.block.setState(e),this.id=void 0===t?null:t}setValue(e){this.block.setState(e)}split(e,t,i,n){this.sequence.splitBlock(this.index,e,t,i,n)}}class F extends O{constructor(e,t){super(e,t),this.onRequestInsert=t&&t.onRequestInsert;const i=t&&t.animate,n=(0,o.Z)(t.strings.ADD),s=$(`\n <button type="button" title="${n}" data-streamfield-list-add class="c-sf-add-button">\n <svg class="icon icon-plus" aria-hidden="true"><use href="#icon-plus"></use></svg>\n </button>\n `);$(e).replaceWith(s),this.element=s.get(0),s.click((()=>{this.onRequestInsert&&this.onRequestInsert(this.index)})),i&&s.hide().slideDown()}enable(){$(this.element).removeAttr("disabled")}disable(){$(this.element).attr("disabled","true")}}class V extends P{constructor(e,t,i,n,s){super(),this.blockDef=e,this.type=e.name,this.prefix=i;const l=$(`\n <div class="${(0,o.Z)(this.blockDef.meta.classname||"")}">\n <input type="hidden" name="${(0,o.Z)(i)}-count" data-streamfield-list-count value="0">\n\n <div data-streamfield-list-container></div>\n </div>\n `);$(t).replaceWith(l),this.blockDef.meta.helpText&&$(`\n <div class="c-sf-help">\n <div class="help">\n ${this.blockDef.meta.helpText}\n </div>\n </div>\n `).insertBefore(l),this.children=[],this.inserters=[],this.blockCounter=0,this.countInput=l.find("[data-streamfield-list-count]"),this.sequenceContainer=l.find("[data-streamfield-list-container]"),this.container=l,this.setState(n||[]),this.blockDef.meta.collapsed&&this.children.forEach((e=>{e.collapse()})),s&&this.setError(s),this.initDragNDrop(),(0,c.$)(this.container[0],this.blockDef.meta.attrs||{})}setState(e){this.clear(),e.forEach((({value:e,id:t},i)=>{const n=void 0===t?B():t;this.insert(e,i,{id:t||n})}))}_getChildDataForInsertion(){return[this.blockDef.childBlockDef,this.blockDef.initialChildState,B()]}_createChild(e,t,i,n,s,l,a,o){return new R(e,t,i,n,s,l,a,o)}_createInsertionControl(e,t){return new F(e,t)}blockCountChanged(){super.blockCountChanged();const e=[],t=this.blockDef.meta.maxNum;if("number"==typeof t&&this.children.length>t){const i=(0,f.AP)("The maximum number of items is %(max_num)d").replace("%(max_num)d",`${t}`);e.push(i)}const i=this.blockDef.meta.minNum;if("number"==typeof i&&this.children.length<i){const t=(0,f.AP)("The minimum number of items is %(min_num)d").replace("%(min_num)d",`${i}`);e.push(t)}e.length?this.setError({messages:e}):this.setError({})}insert(e,t,i){return this._insert(this.blockDef.childBlockDef,e,i?.id,t,i)}duplicateBlock(e,t){const i=this.children[e],{id:n,value:s}=i.getDuplicatedState(),l=t&&t.animate;this.insert(s,e+1,{animate:l,focus:!0,collapsed:i.collapsed,id:n})}splitBlock(e,t,i,n,s){const l=this.children[e],a=s&&s.animate;l.setValue(t);const o=this.insert(i,e+1,{animate:a,focus:!0,collapsed:l.collapsed}),r=l.getContentPath(),c=o.getContentPath(),d=window.comments?.commentApp;r&&c&&d&&d.utils.selectCommentsForContentPathFactory(r)(d.store.getState()).forEach((e=>{n(e)&&d.updateContentPath(e.localId,c)}))}setError(e){if(!e)return;const t=this.container[0];(0,b.$)(t),e.messages&&(0,b.U)(t,e.messages),e.blockErrors&&Object.entries(e.blockErrors).forEach((([e,t])=>{this.children[e].setError(t)}))}getBlockGroups(){return[["",[this.blockDef.childBlockDef]]]}getBlockCount(){return this.children.length}getBlockMax(){return this.blockDef.meta.maxNum||0}}class Z{constructor(e,t,i,n){this.name=e,this.childBlockDef=t,this.initialChildState=i,this.meta=n}render(e,t,i,n){return new V(this,e,t,i,n)}}var N=i(7381),j=i(4549),W=i(2891);const H={name:"hideOnEsc",defaultValue:!0,fn({hide:e}){function t(t){"Escape"===t.key&&e()}return{onShow(){document.addEventListener("keydown",t)},onHide(){document.removeEventListener("keydown",t)}}}};W.Controller;class G extends U{getState(){return{type:this.type,value:this.block.getState(),id:this.id||null}}getDuplicatedState(){return{...super.getDuplicatedState(),type:this.type}}setState({type:e,value:t,id:i}){this.type=e,this.block.setState(t),this.id=void 0===i?null:i}getValue(){return{type:this.type,value:this.block.getValue(),id:this.id||null}}split(e,t,i,n){this.sequence.splitBlock(this.index,e,t,i,n)}}class z extends O{constructor(e,t){super(e,t),this.groupedChildBlockDefs=t.groupedChildBlockDefs;const i=$(`\n <div>\n <button type="button" title="${j.Mn}" class="c-sf-add-button">\n <svg class="icon icon-plus" aria-hidden="true"><use href="#icon-plus"></use></svg>\n </button>\n </div>\n `);$(e).replaceWith(i),this.element=i.get(0),this.addButton=i.find("button");const n=this.blockItems;1!==n.length||1!==n[0].items.length?(this.combobox=document.createElement("div"),this.tooltip=(0,N.Ay)(this.addButton.get(0),{content:this.combobox,trigger:"click",interactive:!0,maxWidth:"none",theme:"dropdown",arrow:!1,placement:"bottom",plugins:[H],onShow:this.renderMenu.bind(this),onHidden:()=>{s().render(null,this.combobox)}})):this.addButton.click((()=>{this.onRequestInsert&&this.onRequestInsert(this.index,n[0].items[0])}))}get blockItems(){return this.groupedChildBlockDefs.map((([e,t])=>({label:e||"",type:e||"",items:t.map((e=>({type:e.name,label:e.meta.label,description:e.meta.description,icon:e.meta.icon,blockDefId:e.meta.blockDefId,isPreviewable:e.meta.isPreviewable})))})))}renderMenu(){const e=this.blockItems;s().render(a().createElement(j.Ay,{label:j.qc,placeholder:j.qc,items:e,getItemLabel:(e,t)=>t.label,getItemDescription:e=>e.label,getSearchFields:e=>[e.label,e.type],noResultsText:j.b5,onSelect:this.onSelectBlock.bind(this)}),this.combobox)}onSelectBlock(e){this.onRequestInsert&&this.onRequestInsert(this.index,{type:e.selectedItem.type}),this.close()}open(){this.addButton.attr("aria-expanded","true"),this.tooltip.show()}close(){this.addButton.attr("aria-expanded","false"),this.tooltip.hide()}}class X extends P{constructor(e,t,i,n,s){super(),this.blockDef=e,this.type=e.name,this.prefix=i;const l=$(`\n <div class="${(0,o.Z)(this.blockDef.meta.classname||"")}">\n <input type="hidden" name="${(0,o.Z)(i)}-count" data-streamfield-stream-count value="0">\n <div data-streamfield-stream-container></div>\n </div>\n `);$(t).replaceWith(l),this.blockDef.meta.helpText&&$(`\n <div class="c-sf-help">\n <div class="help">\n ${this.blockDef.meta.helpText}\n </div>\n </div>\n `).insertBefore(l),this.container=l,this.element=l.get(0),this.children=[],this.childBlockCounts=new Map,this.inserters=[],this.blockCounter=0,this.countInput=l.find("[data-streamfield-stream-count]"),this.sequenceContainer=l.find("[data-streamfield-stream-container]"),this.setState(n||[]),this.blockDef.meta.collapsed&&this.children.forEach((e=>{e.collapse()})),s&&this.setError(s),this.initDragNDrop(),(0,c.$)(this.container[0],this.blockDef.meta.attrs||{})}getBlockGroups(){return this.blockDef.groupedChildBlockDefs}getBlockCount(e){return e?(this.childBlockCounts.has(e)||this._updateBlockCount(e),this.childBlockCounts.get(e)||0):this.children.length}getBlockMax(e){return e?this.blockDef.meta.blockCounts[e]?.max_num:this.blockDef.meta.maxNum}_updateBlockCount(e){const t=this.children.filter((t=>t.type===e)).length;this.childBlockCounts.set(e,t)}blockCountChanged(){super.blockCountChanged(),this.childBlockCounts.clear();const e=[],t=this.blockDef.meta.maxNum;if("number"==typeof t&&this.children.length>t){const i=(0,f.AP)("The maximum number of items is %(max_num)d").replace("%(max_num)d",`${t}`);e.push(i)}const i=this.blockDef.meta.minNum;if("number"==typeof i&&this.children.length<i){const t=(0,f.AP)("The minimum number of items is %(min_num)d").replace("%(min_num)d",`${i}`);e.push(t)}for(const[t,i]of Object.entries(this.blockDef.meta.blockCounts)){const n=i.max_num;if("number"==typeof n&&this.getBlockCount(t)>n){const i=this.blockDef.childBlockDefsByName[t],s=(0,f.AP)("The maximum number of items is %(max_num)d").replace("%(max_num)d",`${n}`),l=`${i.meta.label}: ${s}`;e.push(l)}const s=i.min_num;if("number"==typeof s&&this.getBlockCount(t)<s){const i=this.blockDef.childBlockDefsByName[t],n=(0,f.AP)("The minimum number of items is %(min_num)d").replace("%(min_num)d",`${s}`),l=`${i.meta.label}: ${n}`;e.push(l)}}e.length?this.setError({messages:e}):this.setError({})}_createChild(e,t,i,n,s,l,a,o){return new G(e,t,i,n,s,l,a,o)}_createInsertionControl(e,t){return t.groupedChildBlockDefs=this.blockDef.groupedChildBlockDefs,new z(e,t)}insert({type:e,value:t,id:i},n,s){const l=this.blockDef.childBlockDefsByName[e];return this._insert(l,t,i,n,s)}_getChildDataForInsertion({type:e}){return[this.blockDef.childBlockDefsByName[e],this.blockDef.initialChildStates[e],B()]}duplicateBlock(e,t){const i=this.children[e],n=i.getDuplicatedState(),s=t&&t.animate;this.insert(n,e+1,{animate:s,focus:!0,collapsed:i.collapsed})}splitBlock(e,t,i,n,s){const l=this.children[e],a=s&&s.animate,o=l.getState(),r=this.insert({type:o.type,id:B(),value:i},e+1,{animate:a,focus:!0,collapsed:l.collapsed});l.setState({type:o.type,id:o.id||null,value:t});const c=l.getContentPath(),d=r.getContentPath(),h=window.comments?.commentApp;c&&d&&h&&h.utils.selectCommentsForContentPathFactory(c)(h.store.getState()).forEach((e=>{n(e)&&h.updateContentPath(e.localId,d)}))}setState(e){super.setState(e)}setError(e){if(!e)return;const t=this.container[0];if((0,b.$)(t),e.messages&&(0,b.U)(t,e.messages),e.blockErrors)for(const t in e.blockErrors)(0,m.$)(e.blockErrors,t)&&this.children[t].setError(e.blockErrors[t])}}class J{constructor(e,t,i,n){this.name=e,this.groupedChildBlockDefs=t,this.initialChildStates=i,this.childBlockDefsByName={},this.groupedChildBlockDefs.forEach((([e,t])=>{t.forEach((e=>{this.childBlockDefsByName[e.name]=e}))})),this.meta=n}render(e,t,i,n){return new X(this,e,t,i,n)}}const K=window.wagtailStreamField||{};K.blocks={FieldBlock:d,FieldBlockDefinition:h,StaticBlock:u,StaticBlockDefinition:p,StructBlock:w,StructBlockDefinition:D,ListBlock:V,ListBlockDefinition:Z,StreamBlock:X,StreamBlockDefinition:J},window.telepath.register("wagtail.blocks.FieldBlock",h),window.telepath.register("wagtail.blocks.StaticBlock",p),window.telepath.register("wagtail.blocks.StructBlock",D),window.telepath.register("wagtail.blocks.ListBlock",Z),window.telepath.register("wagtail.blocks.StreamBlock",J),window.wagtailStreamField=K}},i={};function n(e){var s=i[e];if(void 0!==s)return s.exports;var l=i[e]={exports:{}};return t[e](l,l.exports,n),l.exports}n.m=t,e=[],n.O=(t,i,s,l)=>{if(!i){var a=1/0;for(d=0;d<e.length;d++){for(var[i,s,l]=e[d],o=!0,r=0;r<i.length;r++)(!1&l||a>=l)&&Object.keys(n.O).every((e=>n.O[e](i[r])))?i.splice(r--,1):(o=!1,l<a&&(a=l));if(o){e.splice(d--,1);var c=s();void 0!==c&&(t=c)}}return t}l=l||0;for(var d=e.length;d>0&&e[d-1][2]>l;d--)e[d]=e[d-1];e[d]=[i,s,l]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.j=591,(()=>{var e={591:0};n.O.j=t=>0===e[t];var t=(t,i)=>{var s,l,[a,o,r]=i,c=0;if(a.some((t=>0!==e[t]))){for(s in o)n.o(o,s)&&(n.m[s]=o[s]);if(r)var d=r(n)}for(t&&t(i);c<a.length;c++)l=a[c],n.o(e,l)&&e[l]&&e[l][0](),e[l]=0;return n.O(d)},i=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];i.forEach(t.bind(null,0)),i.push=t.bind(null,i.push.bind(i))})();var s=n.O(void 0,[321],(()=>n(2294)));s=n.O(s)})();
1
+ (()=>{"use strict";var e,t={2294:(e,t,i)=>{var n=i(6931),s=i.n(n),l=i(2427),a=i.n(l),o=i(4327),r=i(1238),c=i(1002);class d{constructor(e,t,i,n,l,d){this.blockDef=e,this.type=e.name;const h=$(`\n <div class="w-field__wrapper" data-field-wrapper>\n <div class="${(0,o.Z)(this.blockDef.meta.classname)}" data-field>\n <div class="w-field__errors" id="${i}-errors" data-field-errors>\n <svg class="icon icon-warning w-field__errors-icon" aria-hidden="true" hidden><use href="#icon-warning"></use></svg>\n </div>\n <div class="w-field__help" id="${i}-helptext" data-field-help></div>\n <div class="w-field__input" data-field-input>\n <div data-streamfield-widget></div>\n </div>\n </div>\n </div>\n `);$(t).replaceWith(h);const u=h.find("[data-streamfield-widget]").get(0);this.element=h[0],this.field=this.element.querySelector("[data-field]"),this.parentCapabilities=d||new Map,this.prefix=i;const p={attributes:this.getAttributes()};try{this.widget=this.blockDef.widget.render(u,i,i,n,this.parentCapabilities,p)}catch(e){return console.error(e),void this.setError({messages:["This widget failed to render, please check the console for details."]})}if(this.idForLabel=this.widget.idForLabel,this.blockDef.meta.helpText){const e=document.createElement("p");e.classList.add("help"),e.innerHTML=this.blockDef.meta.helpText,this.field.querySelector("[data-field-help]").appendChild(e)}if(window.comments&&this.blockDef.meta.showAddCommentButton){const t=document.createElement("button");t.type="button",t.setAttribute("aria-label",e.meta.strings.ADD_COMMENT),t.setAttribute("data-comment-add",""),t.classList.add("w-field__comment-button","w-field__comment-button--add"),s().render(a().createElement(a().Fragment,null,a().createElement(r.A,{name:"comment-add"}),a().createElement(r.A,{name:"comment-add-reversed"})),t),this.field.classList.add("w-field--commentable"),this.field.querySelector("[data-field-input]").appendChild(t),window.comments.initAddCommentButton(t)}l&&this.setError(l),(0,c.$)(this.field,this.blockDef.meta.attrs||{})}setCapabilityOptions(e,t){Object.assign(this.parentCapabilities.get(e),t),this.widget&&this.widget.setCapabilityOptions&&this.widget.setCapabilityOptions(e,t)}setState(e){this.widget&&this.widget.setState(e)}setError(e){const t=this.field.querySelector("[data-field-errors]");if(t.querySelectorAll(".error-message").forEach((e=>e.remove())),this.widget?.setInvalid?.(!!e),e){this.field.classList.add("w-field--error"),t.querySelector(".icon").removeAttribute("hidden");const i=document.createElement("p");i.classList.add("error-message");const n=document.createTextNode(e.messages.join(" "));i.appendChild(n),t.appendChild(i)}else this.field.classList.remove("w-field--error"),t.querySelector(".icon").setAttribute("hidden","true")}getAttributes(){const e=this.prefix,t={};return this.blockDef.meta.helpText&&(t["aria-describedby"]=`${e}-helptext`),this.blockDef.meta.required&&(t.required=""),this.blockDef.meta.maxLength&&(t.maxLength=this.blockDef.meta.maxLength),t}getState(){return this.widget.getState()}getValue(){return this.widget.getValue()}getTextLabel(e){return this.widget.getTextLabel?this.widget.getTextLabel(e):null}focus(e){this.widget&&this.widget.focus(e)}}class h{constructor(e,t,i){this.name=e,this.widget=t,this.meta=i}render(e,t,i,n,s){return new d(this,e,t,i,n,s)}}class u{constructor(e,t){this.blockDef=e;const i=document.createElement("div");this.blockDef.meta.html?i.innerHTML=this.blockDef.meta.html:i.innerHTML=(0,o.Z)(this.blockDef.meta.text),t.replaceWith(i),(0,c.$)(i,this.blockDef.meta.attrs||{})}setState(e){}setError(e){}getState(){return null}getValue(){return null}focus(){}}class p{constructor(e,t){this.name=e,this.meta=t}render(e){return new u(this,e)}}var m=i(4188),b=i(4545),f=i(2833);class g{constructor(e){this.props=e}render(){const e=document.createElement("template"),{panelId:t,headingId:i,contentId:n,blockDef:s,blockTypeIcon:l,blockTypeLabel:a,collapsed:o}=this.props;return e.innerHTML=`\n <section class="w-panel w-panel--nested${o?" collapsed":""}" id="${t}" aria-labelledby="${i}" data-panel>\n <div class="w-panel__header">\n <a class="w-panel__anchor w-panel__anchor--prefix" href="#${t}" aria-labelledby="${i}" data-panel-anchor>\n <svg class="icon icon-link w-panel__icon" aria-hidden="true">\n <use href="#icon-link"></use>\n </svg>\n </a>\n <button class="w-panel__toggle" type="button" aria-label="${(0,f.AP)("Toggle section")}" aria-describedby="${i}" data-panel-toggle aria-controls="${n}" aria-expanded="true">\n <svg class="icon icon-${l} w-panel__icon" aria-hidden="true">\n <use href="#icon-${l}"></use>\n </svg>\n </button>\n <h2 class="w-panel__heading w-panel__heading--label" aria-level="3" id="${i}" data-panel-heading>\n <span class="c-sf-block__type">${a}</span>\n ${s?.meta.required?'<span class="w-required-mark" data-panel-required>*</span>':""}\n <span data-panel-heading-text class="c-sf-block__title"></span>\n </h2>\n <a class="w-panel__anchor w-panel__anchor--suffix" href="#${t}" aria-labelledby="${i}">\n <svg class="icon icon-link w-panel__icon" aria-hidden="true">\n <use href="#icon-link"></use>\n </svg>\n </a>\n <div class="w-panel__divider"></div>\n <div class="w-panel__controls" data-panel-controls></div>\n </div>\n <div id="${n}" class="w-panel__content">\n ${s?"<div data-streamfield-block></div>":""}\n </div>\n </section>\n `,e.content.firstElementChild}}const k=(e,t=!("true"===e.getAttribute("aria-expanded")))=>{const i=document.querySelector(`#${e.getAttribute("aria-controls")}`);i&&(e.setAttribute("aria-expanded",`${t}`),t?i.removeAttribute("hidden"):"onbeforematch"in document.body?i.setAttribute("hidden","until-found"):i.setAttribute("hidden",""),e.dispatchEvent(new CustomEvent("commentAnchorVisibilityChange",{bubbles:!0})),e.dispatchEvent(new CustomEvent("wagtail:panel-toggle",{bubbles:!0,cancelable:!1,detail:{expanded:t}})))};function v(e){const t=e.closest("[data-panel]"),i=document.querySelector(`#${e.getAttribute("aria-controls")}`);if(!i||!t||t.collapsibleInitialised)return;t.collapsibleInitialised=!0;const n=k.bind(null,e),s=t.classList.contains("collapsed"),l=i.querySelector('[aria-invalid="true"], .error, .w-field--error'),a=s&&!l;a&&n(!1),e.addEventListener("click",n.bind(null,void 0));const o=t.querySelector("[data-panel-heading]");o&&o.addEventListener("click",n.bind(null,void 0)),i.addEventListener("beforematch",n.bind(null,!0)),e.dispatchEvent(new CustomEvent("wagtail:panel-init",{bubbles:!0,cancelable:!1,detail:{expanded:!a}}))}class w{constructor(e,t,i,n,s){const l=n||{};this.blockDef=e,this.type=e.name,this.childBlocks={};let a="";if(this.blockDef.collapsible&&(a=new g({panelId:`block_group-${i}-section`,headingId:`block_group-${i}-heading`,contentId:`block_group-${i}-content`,blockTypeIcon:(0,o.Z)(e.meta.icon),blockTypeLabel:(0,o.Z)(e.meta.label),collapsed:e.meta.collapsed}).render().outerHTML),e.meta.formTemplate){const n=e.meta.formTemplate.replace(/__PREFIX__/g,i);let o;a?(o=$(a),$(t).replaceWith(o),o=this.#e(o,i),o.append(n)):(o=$(n),$(t).replaceWith(o));const r=s?.blockErrors||{};this.blockDef.childBlockDefs.forEach((e=>{const t=o.find('[data-structblock-child="'+e.name+'"]').get(0),n=e.render(t,i+"-"+e.name,l[e.name],r[e.name]);this.childBlocks[e.name]=n})),this.container=o}else{let e=$(`\n <div class="${(0,o.Z)(this.blockDef.meta.classname||"")}">\n </div>\n `);e.append(a),$(t).replaceWith(e),this.blockDef.collapsible&&(e=this.#e(e,i)),this.blockDef.meta.helpText&&e.append(`\n <div class="c-sf-help">\n <div class="help">\n ${this.blockDef.meta.helpText}\n </div>\n </div>\n `),this.blockDef.childBlockDefs.forEach((t=>{let n="";t instanceof this.blockDef.constructor||(n=`<label class="w-field__label">${(0,o.Z)(t.meta.label)}${t.meta.required?'<span class="w-required-mark">*</span>':""}</label>`);const a=$(`\n <div data-contentpath="${t.name}">\n ${n}\n <div data-streamfield-block></div>\n </div>\n `);e.append(a);const r=a.find("[data-streamfield-block]").get(0),c=a.find("label").get(0),d=s?.blockErrors||{},h=t.render(r,i+"-"+t.name,l[t.name],d[t.name],new Map);this.childBlocks[t.name]=h,h.idForLabel&&c.setAttribute("for",h.idForLabel)})),this.container=e}this.blockDef.collapsible&&this.setTextLabel(),(0,c.$)(this.container[0],this.blockDef.meta.attrs||{})}#e(e,t){const i=e.find("[data-panel-toggle]")[0],n=e.find("[data-panel-heading-text]")[0];return v(i),this.setTextLabel=()=>{const e=this.getTextLabel({maxLength:50});n.textContent=e||""},i.addEventListener("wagtail:panel-toggle",this.setTextLabel),e.find(`#block_group-${t}-content`)}setState(e){for(const t in e)this.childBlocks[t].setState(e[t])}setError(e){if(!e)return;const t=this.container[0];if((0,b.$)(t),e.messages&&(0,b.U)(t,e.messages),e.blockErrors)for(const t in e.blockErrors)(0,m.$)(e.blockErrors,t)&&this.childBlocks[t].setError(e.blockErrors[t])}getState(){const e={};for(const t in this.childBlocks)e[t]=this.childBlocks[t].getState();return e}getDuplicatedState(){const e={};for(const t in this.childBlocks){const i=this.childBlocks[t];e[t]=void 0===i.getDuplicatedState?i.getState():i.getDuplicatedState()}return e}getValue(){const e={};for(const t in this.childBlocks)e[t]=this.childBlocks[t].getValue();return e}getTextLabel(e){if("string"==typeof this.blockDef.meta.labelFormat)return this.blockDef.meta.labelFormat.replace(/\{(\w+)\}/g,((t,i)=>{const n=this.childBlocks[i];return n&&n.getTextLabel?n.getTextLabel(e):""}));for(const t of this.blockDef.childBlockDefs){const i=this.childBlocks[t.name];if(i.getTextLabel){const t=i.getTextLabel(e);if(t)return t}}return null}focus(e){if(this.blockDef.childBlockDefs.length){const t=this.blockDef.childBlockDefs[0].name;this.childBlocks[t].focus(e)}}}class D{constructor(e,t,i){this.name=e,this.childBlockDefs=t,this.meta=i,this.collapsible=!0}render(e,t,i,n){return new w(this,e,t,i,n)}}const x={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let y;const C=new Uint8Array(16),E=[];for(let e=0;e<256;++e)E.push((e+256).toString(16).slice(1));const B=function(e,t,i){if(x.randomUUID&&!t&&!e)return x.randomUUID();const n=(e=e||{}).random??e.rng?.()??function(){if(!y){if("undefined"==typeof crypto||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");y=crypto.getRandomValues.bind(crypto)}return y(C)}();if(n.length<16)throw new Error("Random bytes length must be >= 16");if(n[6]=15&n[6]|64,n[8]=63&n[8]|128,t){if((i=i||0)<0||i+16>t.length)throw new RangeError(`UUID byte range ${i}:${i+15} is out of buffer bounds`);for(let e=0;e<16;++e)t[i+e]=n[e];return t}return function(e,t=0){return(E[e[t+0]]+E[e[t+1]]+E[e[t+2]]+E[e[t+3]]+"-"+E[e[t+4]]+E[e[t+5]]+"-"+E[e[t+6]]+E[e[t+7]]+"-"+E[e[t+8]]+E[e[t+9]]+"-"+E[e[t+10]]+E[e[t+11]]+E[e[t+12]]+E[e[t+13]]+E[e[t+14]]+E[e[t+15]]).toLowerCase()}(n)};var _=i(246),S=i(9675);class I{constructor(e){this.sequenceChild=e}render(e){const t=this.sequenceChild.strings[this.labelIdentifier]||this.labelIdentifier;this.dom=$(`\n <button type="button" class="button button--icon text-replace white" data-streamfield-action="${this.labelIdentifier}" title="${(0,o.Z)(t)}">\n <svg class="icon icon-${(0,o.Z)(this.icon)}" aria-hidden="true">\n <use href="#icon-${(0,o.Z)(this.icon)}"></use>\n </svg>\n </button>\n `),this.dom.on("click",(()=>(this.onClick&&this.onClick(),!1))),$(e).append(this.dom),this.enableEvent&&this.sequenceChild.addEventListener(this.enableEvent,(()=>{this.enable()})),this.disableEvent&&this.sequenceChild.addEventListener(this.disableEvent,(()=>{this.disable()})),this.initiallyDisabled&&this.disable()}enable(){this.dom.removeAttr("disabled")}disable(){this.dom.attr("disabled","true")}}class q extends I{enableEvent="enableMoveUp";disableEvent="disableMoveUp";initiallyDisabled=!0;icon="arrow-up";labelIdentifier="MOVE_UP";onClick(){this.sequenceChild.moveUp()}}class L extends I{enableEvent="enableMoveDown";disableEvent="disableMoveDown";initiallyDisabled=!0;icon="arrow-down";labelIdentifier="MOVE_DOWN";onClick(){this.sequenceChild.moveDown()}}class T extends I{enableEvent="enableDrag";disableEvent="disableDrag";initiallyDisabled=!1;icon="grip";labelIdentifier="DRAG"}class A extends I{enableEvent="enableDuplication";disableEvent="disableDuplication";icon="copy";labelIdentifier="DUPLICATE";onClick(){this.sequenceChild.duplicate({animate:!0})}}class M extends I{icon="bin";labelIdentifier="DELETE";onClick(){this.sequenceChild.delete({animate:!0})}}class U extends EventTarget{constructor(e,t,i,n,s,l,a,r){super(),this.blockDef=e,this.type=e.name,this.prefix=i,this.index=n,this.id=s,this.sequence=a;const c=r&&r.animate,d=r&&r.focus,h=r&&r.collapsed;this.strings=r&&r.strings||{};const u=`block-${s}-section`,p=`block-${s}-heading`,m=`block-${s}-content`,b=(0,o.Z)(this.blockDef.meta.icon),f=(0,o.Z)(this.blockDef.meta.label),k=new g({panelId:u,headingId:p,contentId:m,blockDef:e,blockTypeIcon:b,blockTypeLabel:f}).render(),w=$(`\n <div data-streamfield-child ${this.id?`data-contentpath="${(0,o.Z)(this.id)}"`:"data-contentpath-disabled"}>\n <input type="hidden" name="${this.prefix}-deleted" value="">\n <input type="hidden" name="${this.prefix}-order" value="${n}">\n <input type="hidden" name="${this.prefix}-type" value="${(0,o.Z)(this.type||"")}">\n <input type="hidden" name="${this.prefix}-id" value="${(0,o.Z)(this.id||"")}">\n ${k.outerHTML}\n </div>\n `);$(t).replaceWith(w),this.element=w.get(0);const x=w.find("[data-streamfield-block]").get(0);this.actionsContainerElement=w.find("[data-panel-controls]").get(0),this.titleElement=w.find("[data-panel-heading-text]"),this.toggleElement=this.element.querySelector("[data-panel-toggle]"),this.deletedInput=w.find(`input[name="${this.prefix}-deleted"]`),this.indexInput=w.find(`input[name="${this.prefix}-order"]`),this.addActionButton(new q(this)),this.addActionButton(new L(this)),this.addActionButton(new T(this)),this.addActionButton(new A(this)),this.addActionButton(new M(this));const y=new Map;y.set("duplicate",{enabled:!0,fn:this.duplicate}),y.set("split",{enabled:!0,fn:this.split.bind(this)}),y.set("addSibling",{enabled:!0,fn:this.addSibling.bind(this),blockGroups:this.sequence.getBlockGroups(),getBlockCount:this.sequence.getBlockCount.bind(this.sequence),getBlockMax:this.sequence.getBlockMax.bind(this.sequence)}),this.blockDef instanceof D&&(this.blockDef.collapsible=!1),this.block=this.blockDef.render(x,this.prefix+"-value",l,void 0,y),v(this.element.querySelector("[data-panel-toggle]")),h&&this.collapse(),this.toggleElement.addEventListener("wagtail:panel-toggle",(()=>{const e=this.getTextLabel({maxLength:70});this.titleElement.text(e||"")}));const C=this.getTextLabel({maxLength:70});this.titleElement.text(C||""),c?(w.hide(),setTimeout((()=>{w.slideDown(),d&&this.block.focus({soft:!0})}),10)):d&&this.block.focus({soft:!0})}addActionButton(e){e.render(this.actionsContainerElement)}addSibling(e){this.sequence._onRequestInsert(this.index+1,e)}moveUp(){this.sequence.moveBlockUp(this.index)}moveDown(){this.sequence.moveBlockDown(this.index)}duplicate(e){this.sequence.duplicateBlock(this.index,e)}delete(e){this.sequence.deleteBlock(this.index,e)}markDeleted({animate:e=!1}){this.deletedInput.val("1"),e?$(this.element).slideUp().dequeue().fadeOut().attr("aria-hidden","true"):$(this.element).hide().attr("aria-hidden","true");const t=this.getContentPath();t&&window.comments.commentApp&&window.comments.commentApp.invalidateContentPath(t)}getContentPath(){return window.comments?.getContentPath(this.element)}enableDuplication(){this.dispatchEvent(new Event("enableDuplication")),this.block&&this.block.setCapabilityOptions&&this.block.setCapabilityOptions("duplicate",{enabled:!0})}disableDuplication(){this.dispatchEvent(new Event("disableDuplication")),this.block&&this.block.setCapabilityOptions&&this.block.setCapabilityOptions("duplicate",{enabled:!1})}enableSplit(){this.block&&this.block.setCapabilityOptions&&this.block.setCapabilityOptions("split",{enabled:!0})}disableSplit(){this.block&&this.block.setCapabilityOptions&&this.block.setCapabilityOptions("split",{enabled:!1})}enableMoveUp(){this.dispatchEvent(new Event("enableMoveUp"))}disableMoveUp(){this.dispatchEvent(new Event("disableMoveUp"))}enableMoveDown(){this.dispatchEvent(new Event("enableMoveDown"))}disableMoveDown(){this.dispatchEvent(new Event("disableMoveDown"))}setIndex(e){this.index=e,this.indexInput.val(e)}setError(e){this.block.setError(e),e&&k(this.toggleElement,!0)}focus(e){this.block.focus(e)}getTextLabel(e){return this.block.getTextLabel?this.block.getTextLabel(e):null}collapse(){k(this.toggleElement,!1)}getDuplicatedState(){return{id:B(),value:void 0===this.block.getDuplicatedState?this.block.getState():this.block.getDuplicatedState()}}}class O{constructor(e,t){this.index=t&&t.index,this.onRequestInsert=t&&t.onRequestInsert}setIndex(e){this.index=e}delete({animate:e=!1}){e?$(this.element).slideUp().attr("aria-hidden","true"):$(this.element).hide().attr("aria-hidden","true")}}class P{_createChild(e,t,i,n,s,l,a,o){throw new Error("not implemented")}_createInsertionControl(e,t){throw new Error("not implemented")}_getChildDataForInsertion(e){throw new Error("not implemented")}getBlockGroups(){throw new Error("not implemented")}clear(){this.countInput.val(0),this.sequenceContainer.empty(),this.children=[],this.blockCounter=0;const e=document.createElement("div");this.sequenceContainer.append(e),this.inserters=[this._createInsertionControl(e,{index:0,onRequestInsert:(e,t)=>{this._onRequestInsert(e,t)},strings:this.blockDef.meta.strings})],this.blockCountChanged()}_onRequestInsert(e,t){const[i,n,s]=this._getChildDataForInsertion(t);this._insert(i,n,s||null,e,{animate:!0,focus:!0})}blockCountChanged(){}_insert(e,t,i,n,s){const l=this.prefix+"-"+this.blockCounter,a=s&&s.animate,o=s&&s.focus,r=s&&s.collapsed;this.blockCounter+=1;const c=this.inserters[n].element,d=document.createElement("div"),h=document.createElement("div");$(d).insertAfter(c),$(h).insertAfter(d),(0,S.y)(n,this.children.length).forEach((e=>{this.children[e].setIndex(e+1)})),(0,S.y)(n+1,this.inserters.length).forEach((e=>{this.inserters[e].setIndex(e+1)}));const u=this._createChild(e,d,l,n,i,t,this,{animate:a,focus:o,collapsed:r,strings:this.blockDef.meta.strings});this.children.splice(n,0,u);const p=this._createInsertionControl(h,{index:n+1,onRequestInsert:(e,t)=>{this._onRequestInsert(e,t)},strings:this.blockDef.meta.strings,animate:a});this.inserters.splice(n+1,0,p),this.countInput.val(this.blockCounter);const m=0===n,b=n===this.children.length-1;return m||(u.enableMoveUp(),b&&this.children[n-1].enableMoveDown()),b||(u.enableMoveDown(),m&&this.children[n+1].enableMoveUp()),this.blockCountChanged(),u}deleteBlock(e,t){const i=t&&t.animate;this.children[e].markDeleted({animate:i}),this.inserters[e].delete({animate:i}),this.children.splice(e,1),this.inserters.splice(e,1),(0,S.y)(e,this.children.length).forEach((e=>{this.children[e].setIndex(e)})),(0,S.y)(e,this.inserters.length).forEach((e=>{this.inserters[e].setIndex(e)})),0===e&&this.children.length>0&&this.children[0].disableMoveUp(),e===this.children.length&&this.children.length>0&&this.children[this.children.length-1].disableMoveDown(),this.blockCountChanged()}initDragNDrop(){this.sortable=_.Ay.create(this.sequenceContainer.get(0),{handle:'[data-streamfield-action="DRAG"]',animation:200,draggable:"[data-streamfield-child]",onEnd:e=>{const{oldDraggableIndex:t,newDraggableIndex:i}=e;t!==i&&this.moveBlock(t,i)},setData:e=>{e.setData("application/vnd.wagtail.type","sf-block")}})}moveBlock(e,t){if(e===t)return;const i=this.inserters[e],n=this.children[e];t>e?$(i.element).insertAfter(this.children[t].element):$(i.element).insertBefore(this.inserters[t].element),$(n.element).insertAfter(i.element),this.inserters.splice(e,1),this.inserters.splice(t,0,i),this.children.splice(e,1),this.children.splice(t,0,n),t>e?(0,S.y)(e,t+1).forEach((e=>{this.inserters[e].setIndex(e),this.children[e].setIndex(e)})):(0,S.y)(t,e+1).forEach((e=>{this.inserters[e].setIndex(e),this.children[e].setIndex(e)}));const s=this.children.length-1;0===e&&(n.enableMoveUp(),this.children[0].disableMoveUp()),e===s&&(n.enableMoveDown(),this.children[s].disableMoveDown()),0===t&&(n.disableMoveUp(),this.children[1].enableMoveUp()),t===s&&(n.disableMoveDown(),this.children[s-1].enableMoveDown())}moveBlockUp(e){this.moveBlock(e,e-1)}moveBlockDown(e){this.moveBlock(e,e+1)}setState(e){this.clear(),e.forEach(((e,t)=>{this.insert(e,t)}))}getState(){return this.children.map((e=>e.getState()))}getDuplicatedState(){return this.children.map((e=>e.getDuplicatedState()))}getValue(){return this.children.map((e=>e.getValue()))}getTextLabel(e){const t=e&&e.maxLength;let i="";for(const e of this.children){const n=e.getTextLabel({maxLength:t});if(n)if(i){const e=i+", "+n;if(t&&e.length>t-1)return i.endsWith("…")||(i+="…"),i;i=e}else i=n}return i}focus(e){this.children.length&&this.children[0].focus(e)}}class R extends U{getState(){return{id:this.id||null,value:this.block.getState()}}getValue(){return this.block.getValue()}setState({value:e,id:t}){this.block.setState(e),this.id=void 0===t?null:t}setValue(e){this.block.setState(e)}split(e,t,i,n){this.sequence.splitBlock(this.index,e,t,i,n)}}class F extends O{constructor(e,t){super(e,t),this.onRequestInsert=t&&t.onRequestInsert;const i=t&&t.animate,n=(0,o.Z)(t.strings.ADD),s=$(`\n <button type="button" title="${n}" data-streamfield-list-add class="c-sf-add-button">\n <svg class="icon icon-plus" aria-hidden="true"><use href="#icon-plus"></use></svg>\n </button>\n `);$(e).replaceWith(s),this.element=s.get(0),s.click((()=>{this.onRequestInsert&&this.onRequestInsert(this.index)})),i&&s.hide().slideDown()}enable(){$(this.element).removeAttr("disabled")}disable(){$(this.element).attr("disabled","true")}}class V extends P{constructor(e,t,i,n,s){super(),this.blockDef=e,this.type=e.name,this.prefix=i;const l=$(`\n <div class="${(0,o.Z)(this.blockDef.meta.classname||"")}">\n <input type="hidden" name="${(0,o.Z)(i)}-count" data-streamfield-list-count value="0">\n\n <div data-streamfield-list-container></div>\n </div>\n `);$(t).replaceWith(l),this.blockDef.meta.helpText&&$(`\n <div class="c-sf-help">\n <div class="help">\n ${this.blockDef.meta.helpText}\n </div>\n </div>\n `).insertBefore(l),this.children=[],this.inserters=[],this.blockCounter=0,this.countInput=l.find("[data-streamfield-list-count]"),this.sequenceContainer=l.find("[data-streamfield-list-container]"),this.container=l,this.setState(n||[]),this.blockDef.meta.collapsed&&this.children.forEach((e=>{e.collapse()})),s&&this.setError(s),this.initDragNDrop(),(0,c.$)(this.container[0],this.blockDef.meta.attrs||{})}setState(e){this.clear(),e.forEach((({value:e,id:t},i)=>{const n=void 0===t?B():t;this.insert(e,i,{id:t||n})}))}_getChildDataForInsertion(){return[this.blockDef.childBlockDef,this.blockDef.initialChildState,B()]}_createChild(e,t,i,n,s,l,a,o){return new R(e,t,i,n,s,l,a,o)}_createInsertionControl(e,t){return new F(e,t)}blockCountChanged(){super.blockCountChanged();const e=[],t=this.blockDef.meta.maxNum;if("number"==typeof t&&this.children.length>t){const i=(0,f.AP)("The maximum number of items is %(max_num)d").replace("%(max_num)d",`${t}`);e.push(i)}const i=this.blockDef.meta.minNum;if("number"==typeof i&&this.children.length<i){const t=(0,f.AP)("The minimum number of items is %(min_num)d").replace("%(min_num)d",`${i}`);e.push(t)}e.length?this.setError({messages:e}):this.setError({})}insert(e,t,i){return this._insert(this.blockDef.childBlockDef,e,i?.id,t,i)}duplicateBlock(e,t){const i=this.children[e],{id:n,value:s}=i.getDuplicatedState(),l=t&&t.animate;this.insert(s,e+1,{animate:l,focus:!0,collapsed:i.collapsed,id:n})}splitBlock(e,t,i,n,s){const l=this.children[e],a=s&&s.animate;l.setValue(t);const o=this.insert(i,e+1,{animate:a,focus:!0,collapsed:l.collapsed}),r=l.getContentPath(),c=o.getContentPath(),d=window.comments?.commentApp;r&&c&&d&&d.utils.selectCommentsForContentPathFactory(r)(d.store.getState()).forEach((e=>{n(e)&&d.updateContentPath(e.localId,c)}))}setError(e){if(!e)return;const t=this.container[0];(0,b.$)(t),e.messages&&(0,b.U)(t,e.messages),e.blockErrors&&Object.entries(e.blockErrors).forEach((([e,t])=>{this.children[e].setError(t)}))}getBlockGroups(){return[["",[this.blockDef.childBlockDef]]]}getBlockCount(){return this.children.length}getBlockMax(){return this.blockDef.meta.maxNum||0}}class Z{constructor(e,t,i,n){this.name=e,this.childBlockDef=t,this.initialChildState=i,this.meta=n}render(e,t,i,n){return new V(this,e,t,i,n)}}var N=i(7381),j=i(4549),W=i(2891);const H={name:"hideOnEsc",defaultValue:!0,fn({hide:e}){function t(t){"Escape"===t.key&&e()}return{onShow(){document.addEventListener("keydown",t)},onHide(){document.removeEventListener("keydown",t)}}}};W.Controller;class G extends U{getState(){return{type:this.type,value:this.block.getState(),id:this.id||null}}getDuplicatedState(){return{...super.getDuplicatedState(),type:this.type}}setState({type:e,value:t,id:i}){this.type=e,this.block.setState(t),this.id=void 0===i?null:i}getValue(){return{type:this.type,value:this.block.getValue(),id:this.id||null}}split(e,t,i,n){this.sequence.splitBlock(this.index,e,t,i,n)}}class z extends O{constructor(e,t){super(e,t),this.groupedChildBlockDefs=t.groupedChildBlockDefs;const i=$(`\n <div>\n <button type="button" title="${j.Mn}" class="c-sf-add-button">\n <svg class="icon icon-plus" aria-hidden="true"><use href="#icon-plus"></use></svg>\n </button>\n </div>\n `);$(e).replaceWith(i),this.element=i.get(0),this.addButton=i.find("button");const n=this.blockItems;1!==n.length||1!==n[0].items.length?(this.combobox=document.createElement("div"),this.tooltip=(0,N.Ay)(this.addButton.get(0),{content:this.combobox,trigger:"click",interactive:!0,maxWidth:"none",theme:"dropdown",arrow:!1,placement:"bottom",plugins:[H],onShow:this.renderMenu.bind(this),onHidden:()=>{s().render(null,this.combobox)}})):this.addButton.click((()=>{this.onRequestInsert&&this.onRequestInsert(this.index,n[0].items[0])}))}get blockItems(){return this.groupedChildBlockDefs.map((([e,t])=>({label:e||"",type:e||"",items:t.map((e=>({type:e.name,label:e.meta.label,description:e.meta.description,icon:e.meta.icon,blockDefId:e.meta.blockDefId,isPreviewable:e.meta.isPreviewable})))})))}renderMenu(){const e=this.blockItems;s().render(a().createElement(j.Ay,{label:j.qc,placeholder:j.qc,items:e,getItemLabel:(e,t)=>t.label,getItemDescription:e=>e.label,getSearchFields:e=>[e.label,e.type],noResultsText:j.b5,onSelect:this.onSelectBlock.bind(this)}),this.combobox)}onSelectBlock(e){this.onRequestInsert&&this.onRequestInsert(this.index,{type:e.selectedItem.type}),this.close()}open(){this.addButton.attr("aria-expanded","true"),this.tooltip.show()}close(){this.addButton.attr("aria-expanded","false"),this.tooltip.hide()}}class X extends P{constructor(e,t,i,n,s){super(),this.blockDef=e,this.type=e.name,this.prefix=i;const l=$(`\n <div class="${(0,o.Z)(this.blockDef.meta.classname||"")}">\n <input type="hidden" name="${(0,o.Z)(i)}-count" data-streamfield-stream-count value="0">\n <div data-streamfield-stream-container></div>\n </div>\n `);$(t).replaceWith(l),this.blockDef.meta.helpText&&$(`\n <div class="c-sf-help">\n <div class="help">\n ${this.blockDef.meta.helpText}\n </div>\n </div>\n `).insertBefore(l),this.container=l,this.element=l.get(0),this.children=[],this.childBlockCounts=new Map,this.inserters=[],this.blockCounter=0,this.countInput=l.find("[data-streamfield-stream-count]"),this.sequenceContainer=l.find("[data-streamfield-stream-container]"),this.setState(n||[]),this.blockDef.meta.collapsed&&this.children.forEach((e=>{e.collapse()})),s&&this.setError(s),this.initDragNDrop(),(0,c.$)(this.container[0],this.blockDef.meta.attrs||{})}getBlockGroups(){return this.blockDef.groupedChildBlockDefs}getBlockCount(e){return e?(this.childBlockCounts.has(e)||this._updateBlockCount(e),this.childBlockCounts.get(e)||0):this.children.length}getBlockMax(e){return e?this.blockDef.meta.blockCounts[e]?.max_num:this.blockDef.meta.maxNum}_updateBlockCount(e){const t=this.children.filter((t=>t.type===e)).length;this.childBlockCounts.set(e,t)}blockCountChanged(){super.blockCountChanged(),this.childBlockCounts.clear();const e=[],t=this.blockDef.meta.maxNum;if("number"==typeof t&&this.children.length>t){const i=(0,f.AP)("The maximum number of items is %(max_num)d").replace("%(max_num)d",`${t}`);e.push(i)}const i=this.blockDef.meta.minNum;if("number"==typeof i&&this.children.length<i){const t=(0,f.AP)("The minimum number of items is %(min_num)d").replace("%(min_num)d",`${i}`);e.push(t)}for(const[t,i]of Object.entries(this.blockDef.meta.blockCounts)){const n=i.max_num;if("number"==typeof n&&this.getBlockCount(t)>n){const i=this.blockDef.childBlockDefsByName[t],s=(0,f.AP)("The maximum number of items is %(max_num)d").replace("%(max_num)d",`${n}`),l=`${i.meta.label}: ${s}`;e.push(l)}const s=i.min_num;if("number"==typeof s&&this.getBlockCount(t)<s){const i=this.blockDef.childBlockDefsByName[t],n=(0,f.AP)("The minimum number of items is %(min_num)d").replace("%(min_num)d",`${s}`),l=`${i.meta.label}: ${n}`;e.push(l)}}e.length?this.setError({messages:e}):this.setError({})}_createChild(e,t,i,n,s,l,a,o){return new G(e,t,i,n,s,l,a,o)}_createInsertionControl(e,t){return t.groupedChildBlockDefs=this.blockDef.groupedChildBlockDefs,new z(e,t)}insert({type:e,value:t,id:i},n,s){const l=this.blockDef.childBlockDefsByName[e];return this._insert(l,t,i,n,s)}_getChildDataForInsertion({type:e}){return[this.blockDef.childBlockDefsByName[e],this.blockDef.initialChildStates[e],B()]}duplicateBlock(e,t){const i=this.children[e],n=i.getDuplicatedState(),s=t&&t.animate;this.insert(n,e+1,{animate:s,focus:!0,collapsed:i.collapsed})}splitBlock(e,t,i,n,s){const l=this.children[e],a=s&&s.animate,o=l.getState(),r=this.insert({type:o.type,id:B(),value:i},e+1,{animate:a,focus:!0,collapsed:l.collapsed});l.setState({type:o.type,id:o.id||null,value:t});const c=l.getContentPath(),d=r.getContentPath(),h=window.comments?.commentApp;c&&d&&h&&h.utils.selectCommentsForContentPathFactory(c)(h.store.getState()).forEach((e=>{n(e)&&h.updateContentPath(e.localId,d)}))}setState(e){super.setState(e)}setError(e){if(!e)return;const t=this.container[0];if((0,b.$)(t),e.messages&&(0,b.U)(t,e.messages),e.blockErrors)for(const t in e.blockErrors)(0,m.$)(e.blockErrors,t)&&this.children[t].setError(e.blockErrors[t])}}class J{constructor(e,t,i,n){this.name=e,this.groupedChildBlockDefs=t,this.initialChildStates=i,this.childBlockDefsByName={},this.groupedChildBlockDefs.forEach((([e,t])=>{t.forEach((e=>{this.childBlockDefsByName[e.name]=e}))})),this.meta=n}render(e,t,i,n){return new X(this,e,t,i,n)}}const K=window.wagtailStreamField||{};K.blocks={FieldBlock:d,FieldBlockDefinition:h,StaticBlock:u,StaticBlockDefinition:p,StructBlock:w,StructBlockDefinition:D,ListBlock:V,ListBlockDefinition:Z,StreamBlock:X,StreamBlockDefinition:J},window.telepath.register("wagtail.blocks.FieldBlock",h),window.telepath.register("wagtail.blocks.StaticBlock",p),window.telepath.register("wagtail.blocks.StructBlock",D),window.telepath.register("wagtail.blocks.ListBlock",Z),window.telepath.register("wagtail.blocks.StreamBlock",J),window.wagtailStreamField=K}},i={};function n(e){var s=i[e];if(void 0!==s)return s.exports;var l=i[e]={exports:{}};return t[e](l,l.exports,n),l.exports}n.m=t,e=[],n.O=(t,i,s,l)=>{if(!i){var a=1/0;for(d=0;d<e.length;d++){for(var[i,s,l]=e[d],o=!0,r=0;r<i.length;r++)(!1&l||a>=l)&&Object.keys(n.O).every((e=>n.O[e](i[r])))?i.splice(r--,1):(o=!1,l<a&&(a=l));if(o){e.splice(d--,1);var c=s();void 0!==c&&(t=c)}}return t}l=l||0;for(var d=e.length;d>0&&e[d-1][2]>l;d--)e[d]=e[d-1];e[d]=[i,s,l]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.j=591,(()=>{var e={591:0};n.O.j=t=>0===e[t];var t=(t,i)=>{var s,l,[a,o,r]=i,c=0;if(a.some((t=>0!==e[t]))){for(s in o)n.o(o,s)&&(n.m[s]=o[s]);if(r)var d=r(n)}for(t&&t(i);c<a.length;c++)l=a[c],n.o(e,l)&&e[l]&&e[l][0](),e[l]=0;return n.O(d)},i=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];i.forEach(t.bind(null,0)),i.push=t.bind(null,i.push.bind(i))})();var s=n.O(void 0,[321],(()=>n(2294)));s=n.O(s)})();
@@ -213,11 +213,23 @@ def build_absolute_url(context, url):
213
213
  Returns the absolute URL of the given URL based on the request's host.
214
214
  If the request doesn't exist in the context, falls back to
215
215
  WAGTAILADMIN_BASE_URL as the base URL.
216
- If the given URL is already absolute, returns it unchanged.
216
+ If the given URL is already absolute, or the request is a dummy preview
217
+ request, returns it unchanged.
217
218
  """
218
219
  request = context.get("request")
220
+ # If request is not found in the context, e.g. in notification emails,
221
+ # fall back to WAGTAILADMIN_BASE_URL.
219
222
  if not request:
220
223
  return urljoin(get_admin_base_url(), url)
224
+ # With a dummy preview request, the host has been overwritten to be the page
225
+ # Site's host, which may not have been configured correctly. We don't want
226
+ # to fall back to WAGTAILADMIN_BASE_URL either, as that may be different
227
+ # from the original request's host in multi-site instances and may result in
228
+ # users having to log in again. So we just return the URL unchanged.
229
+ if getattr(request, "is_dummy", False):
230
+ return url
231
+ # Rewrite relative URLs to absolute URLs based on the request's host, but
232
+ # leave absolute URLs unchanged.
221
233
  return request.build_absolute_uri(url)
222
234
 
223
235
 
@@ -1,6 +1,7 @@
1
1
  import datetime
2
2
  from functools import wraps
3
3
 
4
+ from django.contrib.auth.models import Permission
4
5
  from django.test import TestCase, override_settings
5
6
  from django.urls import reverse
6
7
  from django.utils import timezone
@@ -358,6 +359,47 @@ class TestPreview(WagtailTestUtils, TestCase):
358
359
  self.assertTemplateUsed(response, "tests/event_page.html")
359
360
  self.assertContains(response, "Placeholder title")
360
361
 
362
+ def test_preview_on_create_without_permissions(self):
363
+ # Remove privileges from user
364
+ self.user.is_superuser = False
365
+ self.user.user_permissions.add(
366
+ Permission.objects.get(
367
+ content_type__app_label="wagtailadmin", codename="access_admin"
368
+ )
369
+ )
370
+ self.user.save()
371
+
372
+ preview_url = reverse(
373
+ "wagtailadmin_pages:preview_on_add",
374
+ args=("tests", "eventpage", self.home_page.id),
375
+ )
376
+
377
+ response = self.client.post(
378
+ preview_url,
379
+ self.post_data,
380
+ )
381
+ self.assertEqual(response.status_code, 302)
382
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
383
+
384
+ def test_preview_on_create_get_without_permissions(self):
385
+ # Remove privileges from user
386
+ self.user.is_superuser = False
387
+ self.user.user_permissions.add(
388
+ Permission.objects.get(
389
+ content_type__app_label="wagtailadmin", codename="access_admin"
390
+ )
391
+ )
392
+ self.user.save()
393
+
394
+ preview_url = reverse(
395
+ "wagtailadmin_pages:preview_on_add",
396
+ args=("tests", "eventpage", self.home_page.id),
397
+ )
398
+
399
+ response = self.client.get(preview_url)
400
+ self.assertEqual(response.status_code, 302)
401
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
402
+
361
403
  def test_preview_on_edit_with_m2m_field(self):
362
404
  preview_url = reverse(
363
405
  "wagtailadmin_pages:preview_on_edit", args=(self.event_page.id,)
@@ -414,6 +456,36 @@ class TestPreview(WagtailTestUtils, TestCase):
414
456
  self.assertContains(response, "<li>Parties</li>")
415
457
  self.assertContains(response, "<li>Holidays</li>")
416
458
 
459
+ soup = self.get_soup(response.content)
460
+ userbar = soup.select_one("wagtail-userbar")
461
+ self.assertIsNotNone(userbar)
462
+ template = soup.select_one("#wagtail-userbar-template")
463
+ self.assertIsNotNone(template)
464
+
465
+ # Previews use a dummy request object, so the userbar should use
466
+ # relative URLs to avoid using the wrong host.
467
+ admin_url = reverse("wagtailadmin_home")
468
+ admin_link = template.select_one(f'a[href$="{admin_url}"]')
469
+ self.assertIsNotNone(admin_link)
470
+ self.assertEqual(admin_link["href"], admin_url)
471
+
472
+ css_links = soup.select("link[rel='stylesheet']")
473
+ self.assertEqual(
474
+ [link.get("href") for link in css_links],
475
+ [
476
+ versioned_static("wagtailadmin/css/core.css"),
477
+ "/path/to/my/custom.css",
478
+ ],
479
+ )
480
+ scripts = soup.select("script[src]")
481
+ self.assertEqual(
482
+ [script.get("src") for script in scripts],
483
+ [
484
+ versioned_static("wagtailadmin/js/vendor.js"),
485
+ versioned_static("wagtailadmin/js/userbar.js"),
486
+ ],
487
+ )
488
+
417
489
  def test_preview_on_edit_with_valid_then_invalid_data(self):
418
490
  preview_url = reverse(
419
491
  "wagtailadmin_pages:preview_on_edit", args=(self.event_page.id,)
@@ -557,6 +629,45 @@ class TestPreview(WagtailTestUtils, TestCase):
557
629
  response = self.client.get(preview_url)
558
630
  self.assertEqual(response.status_code, 200)
559
631
 
632
+ def test_preview_on_edit_without_permissions(self):
633
+ # Remove privileges from user
634
+ self.user.is_superuser = False
635
+ self.user.user_permissions.add(
636
+ Permission.objects.get(
637
+ content_type__app_label="wagtailadmin", codename="access_admin"
638
+ )
639
+ )
640
+ self.user.save()
641
+
642
+ preview_url = reverse(
643
+ "wagtailadmin_pages:preview_on_edit", args=(self.event_page.id,)
644
+ )
645
+
646
+ response = self.client.post(
647
+ preview_url,
648
+ self.post_data,
649
+ )
650
+ self.assertEqual(response.status_code, 302)
651
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
652
+
653
+ def test_preview_on_edit_get_without_permissions(self):
654
+ # Remove privileges from user
655
+ self.user.is_superuser = False
656
+ self.user.user_permissions.add(
657
+ Permission.objects.get(
658
+ content_type__app_label="wagtailadmin", codename="access_admin"
659
+ )
660
+ )
661
+ self.user.save()
662
+
663
+ preview_url = reverse(
664
+ "wagtailadmin_pages:preview_on_edit", args=(self.event_page.id,)
665
+ )
666
+
667
+ response = self.client.get(preview_url)
668
+ self.assertEqual(response.status_code, 302)
669
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
670
+
560
671
  def test_preview_on_create_clear_preview_data(self):
561
672
  preview_session_key = "wagtail-preview-tests-eventpage-{}".format(
562
673
  self.home_page.id
@@ -17,13 +17,16 @@ from wagtail.blocks.base import Block
17
17
  from wagtail.models import PreviewableMixin, RevisionMixin
18
18
  from wagtail.utils.decorators import xframe_options_sameorigin_override
19
19
 
20
+ from .permissions import PermissionCheckedMixin
20
21
 
21
- class PreviewOnEdit(View):
22
+
23
+ class PreviewOnEdit(PermissionCheckedMixin, View):
22
24
  model = None
23
25
  form_class = None
24
26
  http_method_names = ("post", "get", "delete")
25
27
  preview_expiration_timeout = 60 * 60 * 24 # seconds
26
28
  session_key_prefix = "wagtail-preview-"
29
+ permission_required = "change"
27
30
 
28
31
  def setup(self, request, *args, **kwargs):
29
32
  super().setup(request, *args, **kwargs)
@@ -54,6 +57,8 @@ class PreviewOnEdit(View):
54
57
 
55
58
  def get_object(self):
56
59
  obj = get_object_or_404(self.model, pk=unquote(str(self.kwargs["pk"])))
60
+ if not self.user_has_permission_for_instance(self.permission_required, obj):
61
+ raise PermissionDenied
57
62
  if isinstance(obj, RevisionMixin):
58
63
  obj = obj.get_latest_revision_as_object()
59
64
  return obj
@@ -136,6 +141,8 @@ class PreviewOnEdit(View):
136
141
 
137
142
 
138
143
  class PreviewOnCreate(PreviewOnEdit):
144
+ permission_required = "add"
145
+
139
146
  @property
140
147
  def session_key(self):
141
148
  app_label = self.model._meta.app_label
@@ -30,9 +30,13 @@ class PreviewOnEdit(GenericPreviewOnEdit):
30
30
  return "{}{}".format(self.session_key_prefix, self.kwargs["page_id"])
31
31
 
32
32
  def get_object(self):
33
- return get_object_or_404(
33
+ page = get_object_or_404(
34
34
  Page, id=self.kwargs["page_id"]
35
35
  ).get_latest_revision_as_object()
36
+ page_perms = page.permissions_for_user(self.request.user)
37
+ if not page_perms.can_edit():
38
+ raise PermissionDenied
39
+ return page
36
40
 
37
41
  def get_form(self, query_dict):
38
42
  form_class = self.object.get_edit_handler().get_form_class()
@@ -87,6 +91,11 @@ class PreviewOnCreate(PreviewOnEdit):
87
91
 
88
92
  page = content_type.model_class()()
89
93
  parent_page = get_object_or_404(Page, id=parent_page_id).specific
94
+
95
+ parent_page_perms = parent_page.permissions_for_user(self.request.user)
96
+ if not parent_page_perms.can_add_subpage():
97
+ raise PermissionDenied
98
+
90
99
  # We need to populate treebeard's path / depth fields in order to
91
100
  # pass validation. We can't make these 100% consistent with the rest
92
101
  # of the tree without making actual database changes (such as
@@ -1,3 +1,4 @@
1
+ from django.contrib.auth.models import Permission
1
2
  from django.test import TestCase
2
3
  from django.urls import reverse
3
4
 
@@ -118,6 +119,34 @@ class TestGenericSiteSettingPreview(WagtailTestUtils, TestCase):
118
119
  )
119
120
  self.assertNotContains(response, versioned_static("wagtailadmin/js/icons.js"))
120
121
 
122
+ def test_preview_on_edit_without_permission(self):
123
+ # Remove privileges from user
124
+ self.user.is_superuser = False
125
+ self.user.user_permissions.add(
126
+ Permission.objects.get(
127
+ content_type__app_label="wagtailadmin", codename="access_admin"
128
+ )
129
+ )
130
+ self.user.save()
131
+
132
+ response = self.client.post(self.preview_on_edit_url, self.post_data)
133
+ self.assertEqual(response.status_code, 302)
134
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
135
+
136
+ def test_preview_on_edit_get_without_permission(self):
137
+ # Remove privileges from user
138
+ self.user.is_superuser = False
139
+ self.user.user_permissions.add(
140
+ Permission.objects.get(
141
+ content_type__app_label="wagtailadmin", codename="access_admin"
142
+ )
143
+ )
144
+ self.user.save()
145
+
146
+ response = self.client.get(self.preview_on_edit_url)
147
+ self.assertEqual(response.status_code, 302)
148
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
149
+
121
150
 
122
151
  class TestSiteSettingPreview(TestGenericSiteSettingPreview):
123
152
  model = PreviewableSiteSetting
@@ -198,6 +198,7 @@ class PreviewOnEdit(preview.PreviewOnEdit):
198
198
  self.app_name = app_name
199
199
  self.model_name = model_name
200
200
  self.model = get_model_from_url_params(app_name, model_name)
201
+ self.permission_policy = self.model.get_permission_policy()
201
202
  self.pk = kwargs.get("pk")
202
203
  super().setup(request, app_name, model_name, *args, **kwargs)
203
204
 
@@ -205,9 +206,14 @@ class PreviewOnEdit(preview.PreviewOnEdit):
205
206
  self.site = None
206
207
  if issubclass(self.model, BaseSiteSetting):
207
208
  self.site = get_object_or_404(Site, pk=self.pk)
208
- return self.model.for_site(self.site)
209
+ obj = self.model.for_site(self.site)
209
210
  else:
210
- return get_object_or_404(self.model, pk=self.pk)
211
+ obj = get_object_or_404(self.model, pk=self.pk)
212
+
213
+ if not self.user_has_permission_for_instance(self.permission_required, obj):
214
+ raise PermissionDenied
215
+
216
+ return obj
211
217
 
212
218
  def get_extra_request_attrs(self):
213
219
  attrs = super().get_extra_request_attrs()
@@ -405,6 +405,31 @@ class TestDocumentIndexViewSearch(WagtailTestUtils, TransactionTestCase):
405
405
  self.assertIn("ordering", response.context)
406
406
  self.assertEqual(response.context["ordering"], ordering)
407
407
 
408
+ def test_order_by_usage_count_disabled_when_searching(self):
409
+ # Ordering by usage count not currently available when searching,
410
+ # due to https://github.com/wagtail/django-modelsearch/issues/51
411
+ doc1 = models.Document.objects.create(title="Used twice document")
412
+ doc2 = models.Document.objects.create(title="Used once document")
413
+ VariousOnDeleteModel.objects.create(protected_document=doc1)
414
+ VariousOnDeleteModel.objects.create(protected_document=doc1)
415
+ VariousOnDeleteModel.objects.create(protected_document=doc2)
416
+
417
+ response = self.client.get(
418
+ reverse("wagtaildocs:index"),
419
+ {"q": "used", "ordering": "-usage_count"},
420
+ )
421
+ self.assertEqual(response.status_code, 200)
422
+ context = response.context
423
+ # Will fall back to default ordering (by title)
424
+ self.assertSequenceEqual(context["page_obj"].object_list, [doc2, doc1])
425
+
426
+ soup = self.get_soup(response.content)
427
+ ths = soup.select("main table th")
428
+ self.assertTrue(ths)
429
+ usage_count_th = ths[-1]
430
+ self.assertEqual(usage_count_th.text.strip(), "Usage")
431
+ self.assertIsNone(usage_count_th.select_one("a"))
432
+
408
433
 
409
434
  class TestDocumentIndexResultsView(WagtailTestUtils, TransactionTestCase):
410
435
  def setUp(self):
@@ -118,7 +118,9 @@ class IndexView(generic.IndexView):
118
118
  "usage_count",
119
119
  label=_("Usage"),
120
120
  width="16%",
121
- sort_key="usage_count",
121
+ # Ordering by usage count not currently available when searching,
122
+ # due to https://github.com/wagtail/django-modelsearch/issues/51
123
+ sort_key="usage_count" if not self.is_searching else None,
122
124
  ),
123
125
  ]
124
126
  if self.filters and "collection_id" in self.filters.filters:
@@ -796,6 +796,32 @@ class TestImageIndexViewSearch(WagtailTestUtils, TransactionTestCase):
796
796
  "Expected a ul element with class 'listing horiz images' in grid layout when searching for images.",
797
797
  )
798
798
 
799
+ def test_order_by_usage_count_disabled_when_searching(self):
800
+ # Ordering by usage count not currently available when searching,
801
+ # due to https://github.com/wagtail/django-modelsearch/issues/51
802
+ VariousOnDeleteModel.objects.create(protected_image=self.kitten_image)
803
+ VariousOnDeleteModel.objects.create(protected_image=self.kitten_image)
804
+ VariousOnDeleteModel.objects.create(protected_image=self.puppy_image)
805
+
806
+ response = self.client.get(
807
+ reverse("wagtailimages:index"),
808
+ {"q": "cute", "ordering": "-usage_count", "layout": "list"},
809
+ )
810
+ self.assertEqual(response.status_code, 200)
811
+ context = response.context
812
+ # Will fall back to default ordering (by -created_at)
813
+ self.assertSequenceEqual(
814
+ context["page_obj"].object_list,
815
+ [self.puppy_image, self.kitten_image],
816
+ )
817
+
818
+ soup = self.get_soup(response.content)
819
+ ths = soup.select("main table th")
820
+ self.assertTrue(ths)
821
+ usage_count_th = ths[-1]
822
+ self.assertEqual(usage_count_th.text.strip(), "Usage")
823
+ self.assertIsNone(usage_count_th.select_one("a"))
824
+
799
825
 
800
826
  class TestImageListingResultsView(WagtailTestUtils, TransactionTestCase):
801
827
  fixtures = ["test_empty.json"]
@@ -80,7 +80,13 @@ class IndexView(generic.IndexView):
80
80
  return getattr(settings, "WAGTAILIMAGES_INDEX_PAGE_SIZE", 30)
81
81
 
82
82
  def get_valid_orderings(self):
83
- return self.ORDERING_OPTIONS
83
+ orderings = self.ORDERING_OPTIONS.copy()
84
+ if self.is_searching:
85
+ # Ordering by usage count not currently available when searching,
86
+ # due to https://github.com/wagtail/django-modelsearch/issues/51
87
+ orderings.pop("usage_count", None)
88
+ orderings.pop("-usage_count", None)
89
+ return orderings.keys()
84
90
 
85
91
  def get_base_queryset(self):
86
92
  # Get images (filtered by user permission)
@@ -172,7 +178,9 @@ class IndexView(generic.IndexView):
172
178
  UsageCountColumn(
173
179
  "usage_count",
174
180
  label=_("Usage"),
175
- sort_key="usage_count",
181
+ # Ordering by usage count not currently available when searching,
182
+ # due to https://github.com/wagtail/django-modelsearch/issues/51
183
+ sort_key="usage_count" if not self.is_searching else None,
176
184
  width="16%",
177
185
  ),
178
186
  ]
@@ -1,5 +1,6 @@
1
1
  import datetime
2
2
 
3
+ from django.contrib.auth.models import Permission
3
4
  from django.test import TestCase, override_settings
4
5
  from django.urls import reverse
5
6
  from django.utils import timezone
@@ -145,6 +146,32 @@ class TestPreview(WagtailTestUtils, TestCase):
145
146
  self.assertNotContains(response, "<li>Parties</li>")
146
147
  self.assertContains(response, "<li>Holidays</li>")
147
148
 
149
+ def test_preview_on_create_without_permissions(self):
150
+ # Remove privileges from user
151
+ self.user.is_superuser = False
152
+ self.user.user_permissions.add(
153
+ Permission.objects.get(
154
+ content_type__app_label="wagtailadmin", codename="access_admin"
155
+ )
156
+ )
157
+ self.user.save()
158
+ response = self.client.post(self.preview_on_add_url, self.post_data)
159
+ self.assertEqual(response.status_code, 302)
160
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
161
+
162
+ def test_preview_on_create_get_without_permissions(self):
163
+ # Remove privileges from user
164
+ self.user.is_superuser = False
165
+ self.user.user_permissions.add(
166
+ Permission.objects.get(
167
+ content_type__app_label="wagtailadmin", codename="access_admin"
168
+ )
169
+ )
170
+ self.user.save()
171
+ response = self.client.get(self.preview_on_add_url)
172
+ self.assertEqual(response.status_code, 302)
173
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
174
+
148
175
  def test_preview_on_edit_with_m2m_field(self):
149
176
  response = self.client.post(self.preview_on_edit_url, self.post_data)
150
177
 
@@ -262,6 +289,32 @@ class TestPreview(WagtailTestUtils, TestCase):
262
289
  self.client.session,
263
290
  )
264
291
 
292
+ def test_preview_on_edit_without_permissions(self):
293
+ # Remove privileges from user
294
+ self.user.is_superuser = False
295
+ self.user.user_permissions.add(
296
+ Permission.objects.get(
297
+ content_type__app_label="wagtailadmin", codename="access_admin"
298
+ )
299
+ )
300
+ self.user.save()
301
+ response = self.client.post(self.preview_on_edit_url, self.post_data)
302
+ self.assertEqual(response.status_code, 302)
303
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
304
+
305
+ def test_preview_on_edit_get_without_permissions(self):
306
+ # Remove privileges from user
307
+ self.user.is_superuser = False
308
+ self.user.user_permissions.add(
309
+ Permission.objects.get(
310
+ content_type__app_label="wagtailadmin", codename="access_admin"
311
+ )
312
+ )
313
+ self.user.save()
314
+ response = self.client.get(self.preview_on_edit_url)
315
+ self.assertEqual(response.status_code, 302)
316
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
317
+
265
318
  def test_preview_on_create_clear_preview_data(self):
266
319
  # Set a fake preview session data for the page
267
320
  self.client.session[self.session_key_prefix] = "test data"
@@ -329,22 +382,36 @@ class TestPreview(WagtailTestUtils, TestCase):
329
382
  host = "other.example.com:8000"
330
383
  response = self.client.get(self.preview_on_edit_url, headers={"host": host})
331
384
 
385
+ # Snippets have no concept of the current site or fully qualified URLs,
386
+ # so the original request's host should be preserved.
387
+ self.assertEqual(
388
+ response.context["request"].get_host(),
389
+ "other.example.com:8000",
390
+ )
391
+
332
392
  # Check the HTML response
333
393
  self.assertEqual(response.status_code, 200)
334
394
  self.assertTemplateUsed(response, "tests/previewable_model.html")
335
395
  soup = self.get_soup(response.content)
336
396
  userbar = soup.select_one("wagtail-userbar")
337
397
  self.assertIsNotNone(userbar)
338
-
339
- # Absolute URLs to static assets should be rendered with the original
340
- # request's host as the base URL, as snippets have no concept of the
341
- # current site or fully qualified URLs.
342
-
398
+ template = soup.select_one("#wagtail-userbar-template")
399
+ self.assertIsNotNone(template)
400
+
401
+ # Previews use a dummy request object, so the userbar should use
402
+ # relative URLs to avoid using the wrong host.
403
+ admin_url = reverse("wagtailadmin_home")
404
+ admin_link = template.select_one(f'a[href$="{admin_url}"]')
405
+ self.assertIsNotNone(admin_link)
406
+ self.assertEqual(admin_link["href"], admin_url)
407
+
408
+ # Previews use a dummy request object, so the userbar should use
409
+ # relative URLs to avoid using the wrong host.
343
410
  css_links = soup.select("link[rel='stylesheet']")
344
411
  self.assertEqual(
345
412
  [link.get("href") for link in css_links],
346
413
  [
347
- f"http://{host}{versioned_static('wagtailadmin/css/core.css')}",
414
+ versioned_static("wagtailadmin/css/core.css"),
348
415
  "/path/to/my/custom.css",
349
416
  ],
350
417
  )
@@ -352,8 +419,8 @@ class TestPreview(WagtailTestUtils, TestCase):
352
419
  self.assertEqual(
353
420
  [script.get("src") for script in scripts],
354
421
  [
355
- f"http://{host}{versioned_static('wagtailadmin/js/vendor.js')}",
356
- f"http://{host}{versioned_static('wagtailadmin/js/userbar.js')}",
422
+ versioned_static("wagtailadmin/js/vendor.js"),
423
+ versioned_static("wagtailadmin/js/userbar.js"),
357
424
  ],
358
425
  )
359
426
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wagtail
3
- Version: 7.1.2
3
+ Version: 7.1.3
4
4
  Summary: A Django content management system.
5
5
  Author-email: Wagtail core team + contributors <hello@wagtail.org>
6
6
  License-Expression: BSD-3-Clause
@@ -1,4 +1,4 @@
1
- wagtail/__init__.py,sha256=BBIoM7whvONWJ5LX9MMJD8dLEsFskx8Mh2lhmf7D47k,724
1
+ wagtail/__init__.py,sha256=7FkA0d7gbKQnh05IKUgOKsZLF576TFg6JAodTT776MI,724
2
2
  wagtail/apps.py,sha256=k2s8N-lR_xaZjV246fn9O0k8kZRLY7mCl7WvKu8rOKI,654
3
3
  wagtail/compat.py,sha256=5z6X9d-h_VUFt44kuZ-Cw00e9Be5vIXy7yqAdfuv3Mc,1452
4
4
  wagtail/coreutils.py,sha256=TDEnjObxSXciXUcDfgguqp4cQ5bEn4KTp0Frn3TcQW8,22006
@@ -411,7 +411,7 @@ wagtail/admin/static/wagtailadmin/js/vendor.js,sha256=FWnKv7eIv73JtSlt0kM1gj7ZXr
411
411
  wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt,sha256=N88JjVRAOsxJNQWTv9ZFQYxNMAY3yz5QZK8w45VHrSE,1608
412
412
  wagtail/admin/static/wagtailadmin/js/wagtailadmin.js,sha256=tsxgw7XncqNtVOBT8dJOL4UYZs_a7bNFsXUcucyFZv4,11941
413
413
  wagtail/admin/static/wagtailadmin/js/workflow-action.js,sha256=QXw-1Fm6dFSnBl3CCVhKX6WeGVopZQrxJzX8VArzFCQ,3593
414
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js,sha256=rpp2Vy8YjSGXWFhImbDGfehH7wZovwaRnTgq3BEm4PE,33492
414
+ wagtail/admin/static/wagtailadmin/js/telepath/blocks.js,sha256=NJWcgzrnvgXoWZ5wew_Xs3l3wXqLICyX1dy-nA1Pv9A,33546
415
415
  wagtail/admin/static/wagtailadmin/js/telepath/telepath.js,sha256=IoVnLhsR95NQa1Cf5qlUD85O2SkopZ4DqWyTXeblZ1I,1553
416
416
  wagtail/admin/static/wagtailadmin/js/telepath/widgets.js,sha256=KeNDTD0NdKM28rSkWhPr7xc-YAMy-wB9jDBN_EMUqjo,5609
417
417
  wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-modal.js,sha256=gMeRT8v8u07duDoy-WTGS0t97HQqCy5K5vs8nksjXVM,3891
@@ -853,7 +853,7 @@ wagtail/admin/templates/wagtailadmin/workflows/task_chooser/includes/create_tab.
853
853
  wagtail/admin/templates/wagtailadmin/workflows/task_chooser/includes/results.html,sha256=7W_V7kYE1ob8s6fXhoaUO2m_9ZpDfThQyI9imexMiXA,3099
854
854
  wagtail/admin/templates/wagtailadmin/workflows/task_chooser/includes/select_task_type.html,sha256=E6rb0esD2jG2XZwn0x5ywW6HTBTwZV1Ft8dSlLrkQCo,809
855
855
  wagtail/admin/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
856
- wagtail/admin/templatetags/wagtailadmin_tags.py,sha256=80Cdl-k3Gf_RlE7FiY_mfUhDOR2383nFdUEQAHpAz0E,46558
856
+ wagtail/admin/templatetags/wagtailadmin_tags.py,sha256=WgTd9tQJ8c1yaMqVrm3sIcwUIxPsjBbZgxCPmhnYB4c,47291
857
857
  wagtail/admin/templatetags/wagtailuserbar.py,sha256=EBAiHKbXAjvvfavVuXbgHwcZdjR3hxkycEtRI0K2thA,1166
858
858
  wagtail/admin/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
859
859
  wagtail/admin/tests/benches.py,sha256=7zdQSI4Ns0IV2u3WGQTsz25MmMHoT4HEpfii1n4XtQ8,3023
@@ -919,7 +919,7 @@ wagtail/admin/tests/pages/test_page_locking.py,sha256=7CMYaBVzbvSdsLMtXNOoVYnG0i
919
919
  wagtail/admin/tests/pages/test_page_search.py,sha256=VTVOvgIH1IicUsuTCWHnKRKowMJBRWhAX8M7_YK1Tbg,13133
920
920
  wagtail/admin/tests/pages/test_page_usage.py,sha256=5kdKxoffOuz8cnPNPsqQbisT4QwlNdgyJZAXKGZPAdg,5091
921
921
  wagtail/admin/tests/pages/test_parent_page_chooser_view.py,sha256=W_cFg5qmbxdaXvR6hkhvPnbQmmnSWjmu3_I5HoIIHt4,6055
922
- wagtail/admin/tests/pages/test_preview.py,sha256=aAhc4D8X6Ee35oR_-ltVzb_ikKqvxdDGZxoTsl9YrSo,39916
922
+ wagtail/admin/tests/pages/test_preview.py,sha256=MZ6VMMsLVFcoBtywzcEpLFjXUvWTgLrsQw6KJeaKR5M,43818
923
923
  wagtail/admin/tests/pages/test_reorder_page.py,sha256=FTw5XLai3dcdb5LAbGDpJc5LGZzAyGXaRVNaC94-MCw,8755
924
924
  wagtail/admin/tests/pages/test_revisions.py,sha256=mmMbazjzfCn644dujr-uGnsJ8UuHb2qM12RwlfyZiqQ,26340
925
925
  wagtail/admin/tests/pages/test_unpublish_page.py,sha256=Vu2zq74xcwYPQeMFI9zN2mXh27Iee13LSwnmiALTQgo,9682
@@ -982,7 +982,7 @@ wagtail/admin/views/generic/mixins.py,sha256=bgnI-gpYWN4fRJ0UiK7gvP-kwhjaxpA_Xhz
982
982
  wagtail/admin/views/generic/models.py,sha256=lVvSx-VdnSA5LRciC7GYGgVri19KWxKOYC5zXkMjf_o,52136
983
983
  wagtail/admin/views/generic/multiple_upload.py,sha256=KiE9T9Uv_EuMr2_MbHzSWJ2W3uaw3djwAnUXgxsjJ38,13383
984
984
  wagtail/admin/views/generic/permissions.py,sha256=LETkWYmN1DjGC8rNYXplkqSZj3TIHEdYf3iWFVZ2jbE,1788
985
- wagtail/admin/views/generic/preview.py,sha256=7-yMGBCeo7pBwsfFQ2i3OudvaX5suN421VQ85nm9ImA,7840
985
+ wagtail/admin/views/generic/preview.py,sha256=BIxEw-lccuNNO6ww_f_WbMWZbFNKXF9mNWGbS5Vz4LI,8101
986
986
  wagtail/admin/views/generic/usage.py,sha256=leJNFgfZ7tXugIFyuuQ-oMlBKmq0xlTCybH3WtozqnA,5085
987
987
  wagtail/admin/views/generic/workflow.py,sha256=wx5EukIJPNNGEGmWFHlP21_hUUNkwiefp6qVd6LZrvY,9947
988
988
  wagtail/admin/views/pages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -997,7 +997,7 @@ wagtail/admin/views/pages/listing.py,sha256=Fx7UMoJSMI1dxfpCWQ2FXVmM6zX4pReZvM8W
997
997
  wagtail/admin/views/pages/lock.py,sha256=Z4FxvYyr0eDJj5kgoCJfk-WgwgXhip6_I2CabaG4J1c,1209
998
998
  wagtail/admin/views/pages/move.py,sha256=l8DSb6EGXau6kdD8gVUo9e-E8lfrIlP72Fi4S43T2OI,5940
999
999
  wagtail/admin/views/pages/ordering.py,sha256=cabaYVsfbHZoxNkGQUqP5klUSlnZDisSFbPko1mX8kM,1633
1000
- wagtail/admin/views/pages/preview.py,sha256=MNAqFjHEzq6r05aWV2wziz14Srnzq2LaVTe49mE8e0k,4191
1000
+ wagtail/admin/views/pages/preview.py,sha256=YbZX-VWBeHg9nTrSJBeLDuJVy_mTyvXYu-dms2LqKeM,4519
1001
1001
  wagtail/admin/views/pages/revisions.py,sha256=paEcUjkDDrGgGnQNhwgSM4uanGcLClxb7KlFlEunGEM,4651
1002
1002
  wagtail/admin/views/pages/search.py,sha256=_OUbbXQfKNB6Qq2n1T95CE5liyVJwLFfb018GUPDiRM,5098
1003
1003
  wagtail/admin/views/pages/unpublish.py,sha256=p_lYd6x8k35UlFIhrZzEjQ6m68qbiHAWyvZrgCg4EoY,3716
@@ -1572,7 +1572,7 @@ wagtail/contrib/settings/jinja2tags.py,sha256=-TNRxY9KxB0mpmndp02dGTTRs8XLmGXonH
1572
1572
  wagtail/contrib/settings/models.py,sha256=xNez5kfXd1B7xzLCWPYZtyIJfVM3KDvdgAq6OVw4WU0,6867
1573
1573
  wagtail/contrib/settings/registry.py,sha256=YfUQHUGZYZb-vdzJhYCPqB6ifDbd7OM6EC4vhqtZs-w,4735
1574
1574
  wagtail/contrib/settings/urls.py,sha256=c3es6uw4G2Mv6Auyp7IqByTqd6uI08wT9ubA3myNy9I,505
1575
- wagtail/contrib/settings/views.py,sha256=tYOw_v0_1skRnvQ1jqKyAIjdr0dLAzEK7vxunAL-0cc,7609
1575
+ wagtail/contrib/settings/views.py,sha256=dyYsBiUey33el_ymU__nA2-h8_3K2k2btolwtlglJxQ,7816
1576
1576
  wagtail/contrib/settings/wagtail_hooks.py,sha256=IJynK_Kv3tSTuvUqfN3AmmaogGvzgyKC9n9UUqrZsyc,243
1577
1577
  wagtail/contrib/settings/locale/af/LC_MESSAGES/django.mo,sha256=RUNArieX_RjkKIb2kwGF4KfTlYrfxMi-HTNkhuroQEk,478
1578
1578
  wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.mo,sha256=C_Ql1k1JAEx97xv-oLHzDIG8iIFC7JzKgy-3A9WGjX4,1219
@@ -1706,7 +1706,7 @@ wagtail/contrib/settings/tests/generic/test_admin.py,sha256=eZuhr3VLRcCre1_46oMU
1706
1706
  wagtail/contrib/settings/tests/generic/test_model.py,sha256=OeU6OAt9PFibKFt6kHWTAWCuTr7jDcFyJQplwoGzo7M,5276
1707
1707
  wagtail/contrib/settings/tests/generic/test_templates.py,sha256=Pvm0ZwMBkCf1Z8EYiJ9Xyv_NEY4OScfDawFwU6oTUbc,7250
1708
1708
  wagtail/contrib/settings/tests/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1709
- wagtail/contrib/settings/tests/shared/test_preview.py,sha256=3HGiZqhpRAqqVaTTEJtMNfVfW1QROFj6B84G0QEPw1w,7707
1709
+ wagtail/contrib/settings/tests/shared/test_preview.py,sha256=nTU3JkKXK3oHou5AXjYg8-6FUMDmWGueorZPTHliWY4,8820
1710
1710
  wagtail/contrib/settings/tests/site_specific/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1711
1711
  wagtail/contrib/settings/tests/site_specific/base.py,sha256=F0AGRh-k87W5qaYtX_hOLX9fX_DQn8V1rA3vM5lG9_Q,1186
1712
1712
  wagtail/contrib/settings/tests/site_specific/test_admin.py,sha256=bgQBB7KEVQrnol6kUFcbDbMJpVN0uWiKUt8h2ZQ2huA,34263
@@ -2295,7 +2295,7 @@ wagtail/documents/templates/wagtaildocs/homepage/site_summary_documents.html,sha
2295
2295
  wagtail/documents/templates/wagtaildocs/multiple/add.html,sha256=AiuaKyYjWECttx3SHUtw1K_tl4aWGe8m_0A-g_zTMdk,3952
2296
2296
  wagtail/documents/templates/wagtaildocs/permissions/includes/document_permissions_formset.html,sha256=bwbdR2-jPyg1uVql59bBRDgfKo5g8gaE9-aoymezsEg,305
2297
2297
  wagtail/documents/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2298
- wagtail/documents/tests/test_admin_views.py,sha256=25D28BdaejcdGt7Ygx2Vakbc-WjgFyXTpd7p0HYFTdw,93118
2298
+ wagtail/documents/tests/test_admin_views.py,sha256=FvaO-Us90eTkV2z-087BK2W3zvzQYIXDXEEIWF2ROqM,94328
2299
2299
  wagtail/documents/tests/test_blocks.py,sha256=509OJU996WRPhOZvqwf2vSsT2NGjCQho7VIOpOneItE,1035
2300
2300
  wagtail/documents/tests/test_collection_privacy.py,sha256=FAGleO345qWJH1rN6OXW6PE8Pca6yOQzNi25XSmP_o8,7236
2301
2301
  wagtail/documents/tests/test_document_chooser.py,sha256=eR-UluZyhabH2v3_PCHpXqzMuJzsu0ehASJDAVRvzZI,11959
@@ -2313,7 +2313,7 @@ wagtail/documents/tests/test_bulk_actions/test_bulk_add_to_collection.py,sha256=
2313
2313
  wagtail/documents/tests/test_bulk_actions/test_bulk_delete.py,sha256=p6EESH8XZLaE1fng-64Cn8SiTmi7o12I_mR35bjjnDE,5106
2314
2314
  wagtail/documents/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2315
2315
  wagtail/documents/views/chooser.py,sha256=Rolu4Rc8YhXRl2Puw--xoQKyGHKtMDR0jqCsgtNr494,6113
2316
- wagtail/documents/views/documents.py,sha256=dGNq1eL3NAH8lQqZlZ0CQI6uTDcdCo4cTV5MjJQYh2E,10969
2316
+ wagtail/documents/views/documents.py,sha256=Vag92JhSdQo4hxelG6pJ2BfjQxHlG3O_ILTSMIYGWoQ,11167
2317
2317
  wagtail/documents/views/multiple.py,sha256=eM0KcOQgIomaKRHGhqm0UcTWO8E94EgiN57p4WJlTWo,4568
2318
2318
  wagtail/documents/views/serve.py,sha256=dJeFpgOQ8FuB___DRqbdYC1NtflOB0lrvO03h2-Ifg4,6008
2319
2319
  wagtail/documents/views/bulk_actions/__init__.py,sha256=fDYVsKqg9AIt1GvNtgyi5RFlchzJeCuqxUno7fU3zAs,216
@@ -2698,7 +2698,7 @@ wagtail/images/templates/wagtailimages/widgets/image_chooser.html,sha256=_3z32qo
2698
2698
  wagtail/images/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2699
2699
  wagtail/images/templatetags/wagtailimages_tags.py,sha256=ueSKaTR0QwTQ_f-Nrzb6ToAUfteadFbUu1mzaAht2cM,7096
2700
2700
  wagtail/images/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2701
- wagtail/images/tests/test_admin_views.py,sha256=a6nVkHVhgaPR0NEyyRaorisPCsvl186aVlxpgSgy9SY,154073
2701
+ wagtail/images/tests/test_admin_views.py,sha256=0Ad1zI9mStimOCpnZq_eskNGKOhYdZbYEEMbQOjI7jQ,155249
2702
2702
  wagtail/images/tests/test_api_fields.py,sha256=CgCLk6PcIwXH4qcT9mBdsn43luD2CAiVZ6j4mxVadyQ,971
2703
2703
  wagtail/images/tests/test_blocks.py,sha256=sgItFWEZY0aR403QoYbPLfrpMpTuoQRpVxm-Qh73WEU,18491
2704
2704
  wagtail/images/tests/test_form_overrides.py,sha256=3MlQ9ROurqKphajUT1_VPaH1aE6HCdfwYVzAFCHB9D8,3405
@@ -2730,7 +2730,7 @@ wagtail/images/tests/test_bulk_actions/test_bulk_add_to_collection.py,sha256=jkz
2730
2730
  wagtail/images/tests/test_bulk_actions/test_bulk_delete.py,sha256=i-HHw66TKkAM3f1StSNa32WRAim9hxxytK8QZJSR6r4,5120
2731
2731
  wagtail/images/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2732
2732
  wagtail/images/views/chooser.py,sha256=lpYy2U9MnoYXpnrsMg046Yefqvy89YbVBm70U1a9ZHI,11939
2733
- wagtail/images/views/images.py,sha256=zq_QKpKIIR4IIn3Z4JQYWB0jDOwCuWUfuJysdnyiHic,15778
2733
+ wagtail/images/views/images.py,sha256=C31BNJxvp-MJ-sm5gbh7xvuZ4a0oyxKof19DOpLBOKw,16308
2734
2734
  wagtail/images/views/multiple.py,sha256=rIul64JcDN74gKTpqBXc3E9lRgB6XtAWOW3-adQCox0,6267
2735
2735
  wagtail/images/views/serve.py,sha256=dUU8WUOedPonJoXG_TFz4p8vF_veVuW2TXKKhArsNDo,3422
2736
2736
  wagtail/images/views/bulk_actions/__init__.py,sha256=fDYVsKqg9AIt1GvNtgyi5RFlchzJeCuqxUno7fU3zAs,216
@@ -3564,7 +3564,7 @@ wagtail/snippets/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
3564
3564
  wagtail/snippets/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3565
3565
  wagtail/snippets/tests/test_locking.py,sha256=QdaRVuX47tCbwoA62KYNJm9qxH33ekKs-nai5UeYDp4,25370
3566
3566
  wagtail/snippets/tests/test_management.py,sha256=GQw8HCZSJWny8giAUua_5-RstN7U_QGcsOkVuG72YHM,894
3567
- wagtail/snippets/tests/test_preview.py,sha256=GY5aoTyDCELLWCPgtKpnS7wdM8UvPCch30LpyK7mwe0,29395
3567
+ wagtail/snippets/tests/test_preview.py,sha256=ni_wHAAK6wKhys9yliNT67RGRTTlT2cVpLDJBhS0V40,32158
3568
3568
  wagtail/snippets/tests/test_snippets.py,sha256=W5JU-_Kau2BIwijIAOIY5NyZ-7i6pUg0O-iJ7xCLopM,238304
3569
3569
  wagtail/snippets/tests/test_usage.py,sha256=3Re4NCdt0M4WfzvUruJmpYEV0FsZ7lWkyAw7ZLyc6Lw,8642
3570
3570
  wagtail/snippets/tests/test_viewset.py,sha256=8ACZV_5ZTs3g6gSzyNGRqe1xJLXsGmbXVGSrcQGHnbk,67040
@@ -4065,9 +4065,9 @@ wagtail/utils/timestamps.py,sha256=wqaIvdtZLUENAYiCP9jN8QPPeud305BlPNJiyTNvxkM,1
4065
4065
  wagtail/utils/urlpatterns.py,sha256=RDhVScxdm-RV4HSMjWElyrbEoTPsXu841_SKMgoFKtY,629
4066
4066
  wagtail/utils/utils.py,sha256=nQhfy-fOiZfUFr67kTX4nF_2VVH7_MDtjTDOzZdpPTE,1407
4067
4067
  wagtail/utils/version.py,sha256=jYCDKIGJD3bZHTpgXMXu14oSBArQnf2WVU979D8V4b0,1552
4068
- wagtail-7.1.2.dist-info/licenses/LICENSE,sha256=0aiL7_RJ2YkOjscmRI7opwmuURrY6h8MR0B24nrdRQU,1512
4069
- wagtail-7.1.2.dist-info/METADATA,sha256=E9YaCw_Tj8DXuj8b_NJXCM5aTMQfNVwPMQApAXBaIqA,12425
4070
- wagtail-7.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
4071
- wagtail-7.1.2.dist-info/entry_points.txt,sha256=R14Z0xKoufNcDaku0EWDKM-K8J4ap0EImO8C-df8HVM,53
4072
- wagtail-7.1.2.dist-info/top_level.txt,sha256=zcKgvuRTi0gSgVzJ1qMoERCwhQ_i0n9bkyxza3oh9as,8
4073
- wagtail-7.1.2.dist-info/RECORD,,
4068
+ wagtail-7.1.3.dist-info/licenses/LICENSE,sha256=0aiL7_RJ2YkOjscmRI7opwmuURrY6h8MR0B24nrdRQU,1512
4069
+ wagtail-7.1.3.dist-info/METADATA,sha256=-XJYFNiKsd-dNG82Ldwk55WM1PHHwVh-pBT_p89hCaw,12425
4070
+ wagtail-7.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
4071
+ wagtail-7.1.3.dist-info/entry_points.txt,sha256=R14Z0xKoufNcDaku0EWDKM-K8J4ap0EImO8C-df8HVM,53
4072
+ wagtail-7.1.3.dist-info/top_level.txt,sha256=zcKgvuRTi0gSgVzJ1qMoERCwhQ_i0n9bkyxza3oh9as,8
4073
+ wagtail-7.1.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5