objs-core 2.3.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +572 -618
- package/objs-extension/README.md +32 -0
- package/objs-extension/background.js +110 -0
- package/objs-extension/bridge.js +193 -0
- package/objs-extension/icons/icon128.png +0 -0
- package/objs-extension/lib/objs-inject.js +5308 -0
- package/objs-extension/manifest.json +18 -0
- package/objs-extension/sidepanel.css +455 -0
- package/objs-extension/sidepanel.html +56 -0
- package/objs-extension/sidepanel.js +908 -0
- package/objs.built.js +475 -120
- package/objs.built.min.js +63 -54
- package/objs.d.ts +584 -525
- package/objs.global.js +5308 -0
- package/objs.global.min.js +98 -0
- package/objs.js +593 -134
- package/package.json +73 -70
package/objs.built.min.js
CHANGED
|
@@ -1,67 +1,74 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Objs-core library
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.4.1
|
|
4
4
|
* @author Roman Torshin
|
|
5
5
|
* @license Apache-2.0
|
|
6
|
-
*/const ee=!0,t=n=>{let e={els:[],ie:{},delegated:{},parented:{},store:{},refs:{},_refsByIndex:[],states:[],isDebug:!1,currentState:"",savedStates:{},isRoot:!1,_parent:null},i=1,r=2,p=3,L="boolean",g="object",k="function",m="string",R="number",b="notEmptyString",h="undefined",v="dangerouslySetInnerHTML",I,l=t.D,T=-1,o=0,c=0,f=typeof process<"u"||t.D===t.DocumentMVP,a=0,u=0;const D=e,w=s=>typeof s,$=(s,d)=>{for(const x in s)Object.hasOwn(s,x)&&d(x,s)},S=t.onError,A=s=>t.verify(s),y=(s,d="")=>(...x)=>{(t.debug||e.isDebug)&&console.log(d?`${d}()`:s,x.length?"with "+x.join(", "):"without parameters");try{const O=s(x[0],x[i],x[r],x[p]);return O!==I?O:e}catch(O){S(O,d)}},N=s=>{for(a=o;a<=T;a++)s()},q=s=>s?.els?s.el:(w(s)!==g&&(s=t.first(s).el),s),j=(s=!0,d=e.els)=>{const x=d.length;if(e.length=x,T=x-i,o=0,e.el=x?d[0]:I,e.last=x?d[T]:I,s&&($(e.states,(O,E)=>{delete e[E[O]]}),e.states=[],e.ie={}),Array.isArray(e._refsByIndex)){const O=e._refsByIndex.length;if(O>x)$(e._refsByIndex,E=>{const C=+E;C>=x&&delete e._refsByIndex[C]}),e._refsByIndex.length=x;else if(O<x)for(let E=O;E<x;E++)e._refsByIndex[E]={}}};e.reset=t;const P=s=>{if(f||!s.querySelectorAll)return;const d=s.querySelectorAll("[data-o-init]"),x={};d.forEach(O=>{const E=O.getAttribute("data-o-init");E!==null&&(x[E]||(x[E]=[]),x[E].push(O))}),$(x,O=>{const E=t.inits[O];E&&E.getSSR(Number(O),x[O])})},X=(s,d,x)=>{$(d,O=>{let E=d[O];w(E)===k&&(E=E(x)),O==="append"&&w(E)===g&&(E.els&&(E=[E]),E[0]?.els&&(valueBuff=[],$(E,C=>{valueBuff.push(...E[C].els)}),E=valueBuff)),E!==I&&s.getAttribute(O)!==E&&!["tag","tagName","name","sample","state","events","ssr","nodeName","revertChildren","root","ref"].includes(O)&&(["html","innerHTML"].includes(O)?(s.innerHTML=E,!f&&P(s)):O==="className"?s.setAttribute("class",E):O==="dataset"&&w(E)===g?$(E,C=>{s.dataset[C]=E[C]}):O==="toggleClass"?s.classList.toggle(E):O==="addClass"?w(E)===g?s.classList.add(...E):s.classList.add(E):O==="removeClass"?s.classList.remove(E):O==="style"&&w(E)===g?$(E,C=>{s.style[C]=E[C]}):(O==="append"||O==="children"||O==="childNodes")&&w(E)===g?$(E.length?E:[E],C=>{O==="append"||!s.childNodes[C]?s.appendChild(E[C]):s.childNodes[C]!==E[C]&&s.childNodes[C].replaceWith(E[C])}):s.setAttribute(O,E))}),s.dataset.oState=d.state,t.autotag&&d.name&&(s.dataset[t.autotag]=t.camelToKebab(d.name))};e.debug=y(()=>{e.isDebug=!0},"debug ON"),e.saveAs=y(s=>{A([[s,[b]]]),t.getSaved[s]?(t.debug||e.isDebug)&&console.warn("the key exists (not saved):"+s):t.getSaved[s]=e},"saveAs"),e.unmount=()=>((t.debug||e.isDebug)&&console.log("unmount() for initID:"+e.initID),w(e.remove)===k?e.remove():e.els?.length&&e.els.forEach(s=>{s?.parentNode&&s.parentNode.removeChild(s)}),t.inits[e.initID]=void 0,e={},!0),e.init=y(s=>{A([[s,[g,k]]]);const d=e.initID||t.inits.length||0;if(e.initID=d,j(),t.inits[e.initID]=e,w(s)==="function"){e.render=y(C=>{const _=l.createElement("div");setTimeout(()=>{t.reactRender(s,_,C)}),e.add(_)});return}(w(s)!==g||s.render===I)&&(s={render:s}),$(s,C=>{e?.render&&C==="render"||(e.states.push(C),e[C]=y((_=[{}])=>{e.currentState=C;const F=s[C]||{tag:"div"},B=Array.isArray(e.els)?e.els.slice(o,T+i):[],z=B.length?B:e.els||[];w(F)===g&&(F.state=C,F["data-o-init"]=d);const V=(H,U={})=>{const M=w(F)===k?F(U):F;if(w(M)===g)return l.createElement(M.tag||M.tagName||"div");const J=l.createElement("div");return J.innerHTML=M,J.children.length>i||!J.firstElementChild?(J.dataset.oInit=H,J):(J.firstElementChild.dataset.oInit=H,J.firstElementChild)},Y=_;Array.isArray(_)||(_=[_]),_.length||(_=[_]);const G=!z[0]&&C==="render";_=_.map((H,U)=>{const M=Object.assign({},w(H)===g?H:{},{self:e,o:t,i:H.i===I?U:H.i,parent:e._parent,data:Array.isArray(Y)?Y[U]:Y});return G&&(!F.ssr||f)&&z.push(V(d,M)),M}),G&&(e.els=z,j(!1));const Q=()=>{$(F.events,H=>{e.on(H,F.events[H])})};z&&(u=z.length===_.length,z.map((H,U)=>{_[u?U:0].i=U+o;const M=w(F)===k?F(_[u?U:0]):F;w(M)===g&&(M.state=C,G&&(M["data-o-init"]=d,M["data-o-init-i"]=U,M.events&&(e._hydrateEvents=e._hydrateEvents||[],e._hydrateEvents[U]=M.events)),X(H,M,_[u?U:0]))}),G&&(e._refsByIndex=[],e.refs={},e.els.forEach((H,U)=>{if(!H.querySelectorAll)return;const M={};H.querySelectorAll("[ref]").forEach(J=>{const Z=J.getAttribute("ref"),K=t(J);M[Z]=K,U===0&&(e.refs[Z]=K)}),e._refsByIndex[U]=M}),!f&&e._hydrateEvents&&(e._hydrateEvents.forEach((H,U)=>{H&&(e.select(U),$(H,M=>{const J=H[M];if(w(J)===g&&J.targetRef&&w(J.handler)===k){const K=(e._refsByIndex?.[U]??e.refs)?.[J.targetRef];K&&K.on(M,J.handler)}else w(J)===k&&e.on(M,J)}))}),e.all()))),G&&w(F)===g&&F.events&&!f&&!F.ssr&&Q()}))});const x=s.render||s,O=!f&&w(x)===g&&x.events,E=!f&&e._hydrateEvents&&e._hydrateEvents.length;(O||E)&&(e.initSSRAfterGettingSSR=()=>{e._refsByIndex=[],e.refs={},e.els.forEach((C,_)=>{if(!C.querySelectorAll)return;const F={};C.querySelectorAll("[ref]").forEach(B=>{const z=B.getAttribute("ref"),V=t(B);F[z]=V,_===0&&(e.refs[z]=V),B.removeAttribute("ref")}),e._refsByIndex[_]=F,_===0&&(e.refs=F)}),O&&$(x.events,C=>{e.on(C,x.events[C])}),e._hydrateEvents&&(e._hydrateEvents.forEach((C,_)=>{C&&(e.select(_),$(C,F=>{const B=C[F];if(w(B)===g&&B.targetRef&&w(B.handler)===k){const V=(e._refsByIndex?.[_]??e.refs)?.[B.targetRef];V&&V.on(F,B.handler)}else w(B)===k&&e.on(F,B)}))}),e.all())})},"init"),e.connect=y((s,d="render",x)=>{A([[s,[g]],[d,[b]],[x,[m,h]]]),s.connect(D,d,x)},"connect"),e.getSSR=y((s,d)=>{A([[s,[R,h]]]);const x=s!==void 0?s:e.initID;if(f||w(s)===h&&w(e.initID)===h)return;const O=d&&d.length?d:t.D.querySelectorAll(`[data-o-init="${x}"]`);O.length&&(e.els=Array.from(O),s!==void 0&&(e.initID=s,t.inits[s]=e),j(!1),w(e.initSSRAfterGettingSSR)===k?e.initSSRAfterGettingSSR():d&&d.length&&(e._refsByIndex=[],e.refs={},e.els.forEach((E,C)=>{if(!E.querySelectorAll)return;const _={};E.querySelectorAll("[ref]").forEach(F=>{const B=F.getAttribute("ref");_[B]=t(F),C===0&&(e.refs[B]=_[B]),F.removeAttribute("ref")}),e._refsByIndex[C]=_,C===0&&(e.refs=_)})))},"getSSR"),e.initState=y((s,d)=>{A([[s,[g]],[d,[g,h]]]),e.init(s).render(d)},"initState");const W=(s,d,x)=>{const O=s.attributes,E={tagName:s.tagName.toLowerCase()};for(const C of O)E[C.nodeName]=C.value;if(x){E.innerHTML=s.innerHTML,E.revertChildren=[];const C=s.querySelectorAll("[data-o-init]");for(const _ of C){const F=_.getAttribute("data-o-init");E.revertChildren.push(F),t.inits[F]?.saveState(d,!1)}}return E};return e.saveState=y((s,d=!0)=>{if(A([[s,[b,h]],[d,[L]]]),!e.el)throw Error("saveState(): There are no elements to save");const x=s||"fastSavedState",O={els:[],parentNode:e.el.parentNode,root:d};N(()=>{O.els.push(W(e.els[a],x,d))}),O.ie=Object.assign({},e.ie),O.delegated=Object.assign({},e.delegated),O.store=Object.assign({},e.store),e.isRoot=e.isRoot||d,e.savedStates[x]=O},"saveState"),e.revertState=y(s=>{A([[s,[b,h]]]);const d=s||"fastSavedState";if(!e.savedStates[d])throw Error(`revertState(): The state "${d}" should have been saved by saveState()`);const x=e.savedStates[d];e.offAll(),e.offDelegate(),e.store=Object.assign({},x.store),x.els.forEach((O,E)=>{if(!e.els[E]){const C=t.D.createElement(O.tagName);x.parentNode&&(E?e.els[E-1].after(C):x.parentNode.append(C)),e.add(C)}X(e.els[E],O)}),e.delegated=Object.assign({},x.delegated),e.ie=Object.assign({},x.ie),e.onAll(),$(x.delegated,O=>{x.delegated[O].forEach(E=>{N(()=>{e.els[a].addEventListener(O,E)})})}),e.currentState=d,x.root&&x.els.forEach(({rootElement:O})=>{O.revertChildren.forEach(E=>{t.inits[E]?.revertState(d),t('[data-o-init="'+E+'"]').els.forEach((C,_)=>{C.replaceWith(t.inits[E]?.els[_])})})})},"revertState"),e.loseState=y(s=>{A([[s,[b]]]),e.savedStates[s]&&(delete e.savedStates[s],N(()=>{const d=e.els[a].querySelectorAll("[data-o-init]");for(const x of d){const O=x.getAttribute("data-o-init");t.inits[O]?.loseState(s)}}))},"sample"),e.sample=y((s="render")=>(A([[s,[b]]]),{[s]:W(e.els[o])}),"sample"),e.select=y(s=>{let d=s;d!=null&&w(d)===g&&d.target&&e.els.length&&(d=e.els.findIndex(x=>x===d.target||x.contains(d.target)),d<0&&(d=0)),A([[d,[R,h]]]),d===I&&(d=e.length-i),T=d,o=d,e.el=e.els[d],c=i,Array.isArray(e._refsByIndex)&&e._refsByIndex[d]&&(e.refs=e._refsByIndex[d])},"select"),e.all=y(()=>{T=e.length-i,o=0,e.el=e.els[0],c=0,Array.isArray(e._refsByIndex)&&e._refsByIndex.length&&(e.refs=e._refsByIndex[0]||{})},"all"),e.remove=y(s=>{if(A([[s,[R,h]]]),s===I&&c&&(s=o),s!==I){const d=e.els[s];d?.parentNode?d.parentNode.removeChild(d):d===void 0&&s>=e.els.length&&t.onError&&t.onError("remove("+s+"): index out of bounds","remove")}else N(()=>{const d=e.els[a];d?.parentNode&&d.parentNode.removeChild(d)});j(!1)},"remove"),e.skip=y(s=>{A([[s,[R,h]]]),s===I&&(s=o),e.els.splice(s,i),Array.isArray(e._refsByIndex)&&e._refsByIndex.splice(s,i),j()},"skip"),e.add=y(s=>{A([[s,[m,g,R]]]),e.initID===I&&(w(s)==="string"&&s!==""?e.els.push(...Array.from(l.querySelectorAll(s))):w(s)===g?s.tagName?e.els.push(s):s.els?e.els.push(...s.els):s.length&&s[0].tagName&&e.els.push(...s):w(s)==="number"&&t.inits[s]&&(e=t.inits[s]),j(!1),e.initID!==I&&e.dataset({oInit:e.initID}))},"add"),e.appendInside=y(s=>{A([[s,[g,b]]]),s?.els&&(e._parent=s),N(()=>{q(s).appendChild(e.els[a])})},"appendInside"),e.appendBefore=y(s=>{A([[s,[g,b]]]),N(()=>{q(s).parentNode.insertBefore(e.els[a],q(s))})},"appendBefore"),e.appendAfter=y(s=>{A([[s,[g,b]]]),N(()=>{q(s).after(...e.els)})},"appendAfter"),e.find=y((s="")=>{A([[s,m]]);const d=[];return N(()=>{d.push(...Array.from(e.els[a].querySelectorAll(":scope "+s)))}),t(d)},"find"),e.first=y((s="")=>{A([[s,m]]);let d=I;const x=[];return N(()=>{d=e.els[a].querySelector(s),d&&x.push(d)}),t(x)},"first"),e.attr=y((s,d)=>{if(d!==null&&A([[s,m],[d,[m,h]]]),d===I){const x=[];return N(()=>{x[a]=e.els[a].getAttribute(s)}),c?x[0]:x}else N(d!==null?()=>{e.els[a].setAttribute(s,d)}:()=>{e.els[a].removeAttribute(s)})},"attr"),e.attrs=y(()=>{const s=[];return N(()=>{const d={};[...e.els[a].attributes].forEach(x=>{d[x.nodeName]=x.nodeValue}),s.push(d)}),c?s[0]:s},"attrs"),e.dataset=y(s=>{if(A([[s,[g,h]]]),typeof s===g)N(()=>{$(s,d=>{e.els[a].dataset[d]=s[d]})});else{const d=[];return N(()=>{d.push({...e.els[a].dataset})}),c?d[0]:d}},"dataset"),e.style=y(s=>{s!==null&&A([[s,[m,h]]]),e.attr("style",s)},"style"),e.css=y((s={})=>{if(s===null){e.style(null);return}A([[s,g]]);let d="";$(s,x=>{d+=x+":"+s[x].replace('"',"'")+";"}),e.style(d||null)},"css"),e.setClass=y(s=>{A([[s,m]]),N(()=>{e.els[a].setAttribute("class",s)})},"setClass"),e.addClass=y((...s)=>{N(()=>{e.els[a].classList.add(...s)})},"addClass"),e.removeClass=y((...s)=>{N(()=>{e.els[a].classList.remove(...s)})},"removeClass"),e.toggleClass=y((s,d)=>{A([[s,b],[d,[L,h]]]),N(()=>{e.els[a].classList.toggle(s,d)})},"toggleClass"),e.haveClass=s=>{A([[s,b]]);let d=!0;return N(()=>{e.els[a].classList.contains(s)||(d=!1)}),(e.isDebug||t.debug)&&console.log("haveClass() with",s),d},e.innerHTML=y(s=>{if(A([[s,[m,h]]]),s!==I)N(()=>{e.els[a].innerHTML=s});else{let d="";return N(()=>{d+=f&&e.els[a].innerHTML.length===0?t.D.parseElement(e.els[a],!1):e.els[a].innerHTML}),d}},"innerHTML"),e.innerText=y(s=>{A([[s,[m]]]),N(()=>{e.els[a].innerText=s})},"innerText"),e.textContent=y(s=>{A([[s,[m]]]),N(()=>{e.els[a].textContent=s})},"textContent"),e.html=y(s=>{if(A([[s,[m,h]]]),s!==void 0)e.innerHTML(s);else{let d="";return N(()=>{d+=f?e.els[a].outerHTML():e.els[a].outerHTML}),d}},"html"),e.toString=function(){return e.html()},e[Symbol.toPrimitive]=function(s){return s==="string"||s==="default"?e.html():s==="number"?e.els?.length??0:e.html()},e.val=y(s=>{if(s===void 0)return e.el?.value;N(()=>{e.els[a].value=s})},"val"),e.forEach=y(s=>{A([[s,[k]]]),N(()=>{s({self:e,i:a,o:t,el:e.els[a]})})},"forEach"),e.prepareFor=y((s,d)=>{A([[s,[g,k,h]],[d,[k,h]]]);const x=s&&w(s)===g&&s.createElement;if(!x&&w(s)!==k)throw Error("prepareFor(): pass React (full object) or React.createElement as first argument");const O=x?s.createElement:s,E=x?s.useEffect:void 0;return C=>{if(C.ref===I)throw Error("No ref property to convert Objs to React");const _=Object.assign({},C),F=O("div",{ref:C.ref});return delete _.ref,E(()=>{$(_,B=>{if(B.substring(0,1)==="on"){const z=t.camelToKebab(B).split("-")[1];e.on(z,_[B]),delete _[B]}}),e.render(_),e.appendInside(F.ref.current)},[]),F}},"prepareFor"),e.on=y((s,d,x,O)=>{A([[s,[b]],[d,[k]],[x,[g,h]],[O,[L,h]]]),s.split(", ").forEach(E=>{N(()=>{e.els[a].addEventListener(E,d,x,O)}),e.ie[E]||(e.ie[E]=[]),e.ie[E].push([d,x,O])})},"on"),e.off=y((s,d,x)=>{A([[s,[b]],[d,[k]],[x,[g,h]]]),s.split(", ").forEach(O=>{N(()=>{e.els[a].removeEventListener(O,d,x)}),e.ie[O]&&(e.ie[O]=e.ie[O].filter(E=>E[0]!==d))})},"off"),e.onDelegate=y((s,d,x)=>{A([[s,[b]],[d,[b]],[x,[k]]]),s.split(", ").forEach(O=>{const E=C=>{const _=C.target.closest(d);_&&(C.delegate=_,C.objs=e,x(C))};N(()=>{e.els[a].addEventListener(O,E)}),e.delegated[O]||(e.delegated[O]=[]),e.delegated[O].push(E)})},"onDelegate"),e.offDelegate=y(s=>{A([[s,[b]]]),$(e.delegated,d=>{if(!s||s===d)for(;e.delegated[d].length;){const x=e.delegated[d].pop();N(()=>{e.els[a].removeEventListener(d,x)})}}),e.delegated={}},"offDelegate"),e.onParent=y((s,d,x)=>{A([[s,[b]],[d,[b,g]],[x,[k]]]);const O=w(d)===g?d:t.D.querySelector(d);s.split(", ").forEach(E=>{const C=_=>{_.objs=e,x(_)};O.addEventListener(E,C),e.parented[E]||(e.parented[E]=[]),e.parented[E].push(C)})},"onParent"),e.offParent=y((s,d)=>{A([[s,[b]],[d,[b,g]]]);const x=w(d)===g?d:t.D.querySelector(d);$(e.parented,O=>{(!s||s===O)&&(e.parented[O].forEach(E=>{x.removeEventListener(O,E)}),delete e.parented[O])})},"offParent"),e.onAll=y((s,d)=>{A([[s,[b,h]],[d,[L,h]]]),$(e.ie,(x,O)=>{(!s||s===x)&&O[x].forEach(E=>{N(()=>{d?e.els[a].removeEventListener(x,E[0]):e.els[a].addEventListener(x,E[0],E[i],E[r])})})})},"onAll"),e.offAll=y(s=>{A([[s,[b]]]),e.onAll(s,i)},"offAll"),n&&e.add(n),e.take=s=>{if(A([[s,[m,g,R]]]),e.add(s),e.el){const d=e.el.dataset.oInit;if(d!==I&&t.inits[d])return e.length===i?(u=e.els[0],Object.assign(e,t.inits[d]),e.els=[u]):e=t.inits[d],j(!1,e.els),e}},e};t.first=n=>(t.verify([[n,["notEmptyString"]]]),t.debug&&console.log(n," -> ","o.first()"),t(t.D.querySelector(n)).select(0)),t.inits=[],t.getSaved={},t.errors=[],t.showErrors=!1,t.logErrors=()=>{t.errors.length?t.errors.forEach(n=>console.error(n)):console.log("No errors")},t.onError=(n,e)=>{t.showErrors?console.error(n,e):(t.errors.push(n),e&&t.errors.push(e))},t.reactRender=()=>new Error("React render function is not defined"),t.autotag=void 0,t.reactQA=n=>({["data-"+(t.autotag||"qa")]:n.replace(/([A-Z])/g,(e,i)=>"-"+i.toLowerCase()).replace(/^-/,"")}),t.specialTypes={notEmptyString:(n,e)=>e==="string"&&n.length,array:n=>Array.isArray(n),promise:n=>n instanceof Promise||!!(n&&typeof n.then=="function")},t.verify=(n,e=!1)=>{for(const i of n){const r=typeof i[0];let p=Array.isArray(i[1])?i[1]:[i[1]],L=!1;if(p.includes(r))return!0;p=p.filter(g=>!!t.specialTypes[g]);for(const g of p)if(L=t.specialTypes[g](i[0],r),L)return!0}return e?!1:new Error("Type verification failed")},t.safeVerify=n=>t.verify(n,!0),t.init=(n,e)=>t().init(n,e),t.initState=(n,e)=>t().init(n).render(e),t.take=n=>t().take(n),t.getStates=()=>t.inits.reduce((n,e)=>(n.push(e?.states),n),[]),t.getStores=()=>t.inits.reduce((n,e)=>(n.push(e?.store),n),[]),t.getListeners=()=>t.inits.reduce((n,e)=>(n.push(e?.ie),n),[]),t.createStore=n=>{const e=Object.assign({},n);return e._defaults=Object.assign({},n),e._listeners=[],e.subscribe=function(i,r){return this._listeners.push(p=>i[r]?.(p)),this},e.notify=function(){this._listeners.forEach(i=>i(this))},e.reset=function(){const i={_listeners:1,subscribe:1,notify:1,_defaults:1,reset:1};for(const r of Object.keys(this._defaults))i[r]||(this[r]=this._defaults[r])},e},t.U=void 0,t.W=2,t.H=100,t.F=!1,t.C=(n,e)=>Object.hasOwn(n,e),t.kebabToCamel=n=>n.replace(/-./g,e=>e.toUpperCase()[1]),t.camelToKebab=n=>n.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),t.route=(n,e)=>{t.verify([[n,["notEmptyString","function","boolean"]],[e,["function","object"]]]);const i=typeof n=="function"?n(window.location.pathname):n;return i===!0||window.location.pathname===i?e?typeof e=="function"?(e(),!0):e:t:typeof e=="function"?!1:{}},t.router=(n={})=>{t.verify([[n,["object"]]]);for(const e in n)if(t.C(n,e)&&window.location.pathname===e)return typeof n[e]=="function"?(n[e](),!0):n[e];return!1},t.DocumentMVP={addEventListener:()=>{},parseElement:(n,e=!0)=>{t.verify([[n,["object","string"]],[e,["boolean"]]]);const i=(r,p="")=>{let L="";for(const g in r)t.C(r,g)&&(L+=` ${p}${t.camelToKebab(g)}="${typeof r[g]!="object"?r[g]:Object.entries(r[g]).map(k=>`${k[0]}: ${k[1]};`).join(" ")}"`);return L};if(typeof n=="string")return n;if(e){const r=["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"],p=n.tagName.toLowerCase(),L=n.attributes["data-o-init"],g=L!==void 0?` data-o-init="${L}"`:"";return`<${p}${n.className?` class="${n.className}"`:""}${i(n.attributes)}${g}${i(n.dataset,"data-")}${r.includes(p)?"/":""}>${r.includes(p)?"":n.innerHTML.length?n.innerHTML:n.children.map(k=>t.D.parseElement(k)).join("")}${r.includes(p)?"":`</${p}>`}`}return n.innerHTML.length?n.innerHTML:n.children.map(r=>t.D.parseElement(r)).join("")},createElement:n=>{t.verify([[n,["notEmptyString"]]]);const e={tagName:n.toUpperCase(),attributes:{},innerHTML:"",children:[],dataset:{},className:"",classArray:[],style:{},addEventListener:()=>{},removeEventListener:()=>{}};return e.classList={add:(...i)=>{t.verify([[i,["array"]]]),e.classArray.push(i),e.className=e.classArray.join(" ")},has:i=>(t.verify([[i,["notEmptyString"]]]),e.classArray.includes(i)),remove:i=>{t.verify([[i,["notEmptyString"]]]),e.classArray=e.classArray.filter(r=>i!==r),e.className=e.classArray.join(" ")}},e.classList.toggle=i=>{t.verify([[i,["notEmptyString"]]]),e.classList.has(i)?e.classList.remove(i):e.classList.add(i)},e.setAttribute=(i,r)=>{t.verify([[i,["notEmptyString"]],[r,["string","number","boolean","undefined"]]]),e.attributes[i]=r},e.getAttribute=i=>(t.verify([[i,["notEmptyString"]]]),e.attributes[i]),e.removeAttribute=i=>{t.verify([[i,["notEmptyString"]]]),delete e.attributes[i]},e.appendChild=i=>{t.verify([[i,["object"]]]),e.children.push(i),e.firstElementChild=e.children[0]},e.outerHTML=()=>t.D.parseElement(e),e}},t.D=typeof document<"u"&&typeof process>"u"?document:t.DocumentMVP,t.setCookie=(n,e="",i={})=>{if(t.verify([[n,["notEmptyString"]],[e,["string","number","boolean"]],[i,["object"]]]),t.D.cookie===void 0){console.log("Cookies are not supported on server side");return}let r=encodeURIComponent(n)+"="+encodeURIComponent(e);i={path:"/",...i},i.expires instanceof Date?i.expires=i.expires.toUTCString():typeof i.expires=="number"&&(i.expires=new Date(i.expires).toUTCString());for(const p in i){r+="; "+p;const L=i[p];L!==!0&&(r+="="+L)}t.D.cookie=r},t.getCookie=n=>{if(t.verify([[n,["notEmptyString"]]]),t.D.cookie===void 0){console.log("Cookies are not supported on server side");return}const e=t.D.cookie.match(RegExp("(?:^|; )"+n.replace(/([.$?*|{}()[\]\\/+^])/g,"\\$1")+"=([^;]*)"));return e?decodeURIComponent(e[1]):void 0},t.deleteCookie=n=>{t.verify([[n,["notEmptyString"]]]),t.setCookie(n,"",{"max-age":0})},t.clearCookies=()=>{if(t.D.cookie===void 0){console.log("Cookies are not supported on server side");return}const n=t.D.cookie.split(";");for(;n.length;){let e=n.pop();for(;e.charAt(0)===" ";)e=e.substring(1);const i=e.split("=")[0];t.deleteCookie(i)}},t.clearLocalStorage=n=>{if(t.verify([[n,["boolean","undefined"]]]),!(typeof localStorage>"u"))if(n)localStorage.clear();else for(let e=localStorage.length-1;e>=0;e--){const i=localStorage.key(e);i.indexOf("oInc-")===-1&&i.indexOf("oTest-")===-1&&localStorage.removeItem(i)}},t.clearSessionStorage=n=>{if(t.verify([[n,["boolean","undefined"]]]),!(typeof sessionStorage>"u"))if(!n)sessionStorage.clear();else for(let e=sessionStorage.length-1;e>=0;e--){const i=sessionStorage.key(e);i&&i.indexOf("oTest-")===0&&sessionStorage.removeItem(i)}},t.clearTestsStorage=()=>{t.clearSessionStorage(1)},t.clearAfterTests=()=>{t.clearCookies(),t.clearLocalStorage(!1),t.clearTestsStorage()},t.ajax=(n,e={})=>{t.verify([[n,["notEmptyString"]],[e,["object"]]]);const i=new URLSearchParams;if(e.data&&typeof e.data=="object"){for(const r in e.data)t.C(e.data,r)&&(typeof e.data[r]=="object"?i.set(r,encodeURIComponent(JSON.stringify(e.data[r]))):i.set(r,e.data[r]));e.method.toLowerCase()==="get"?n+="?"+i.toString():e.body||(e.body=i),delete e.data}return e.headers||(e.headers={"X-Requested-With":"XMLHttpRequest"}),fetch(n,e)},t.get=(n,e={})=>(t.verify([[n,["notEmptyString"]],[e,["object"]]]),t.ajax(n,{...e,method:"GET"})),t.post=(n,e={})=>(t.verify([[n,["notEmptyString"]],[e,["object"]]]),t.ajax(n,{...e,method:"POST"})),t.newLoader=n=>{t.verify([[n,["promise","undefined"]]]);let e=[],i=null,r=!1,p=!1;const L=g=>{r=!1,p=!1,i=null,setTimeout(()=>{g.then(k=>{r=!0,!k.ok&&typeof k.ok<"u"?(p=!0,e.forEach(([m,R,b])=>{b&&m[b](k)})):typeof k.json=="function"?k.json().then(m=>{i=m,e.forEach(([R,b])=>{R[b](i)})}):(i=k,e.forEach(([m,R])=>{m[R](i)}))}).catch(k=>{p=!0,e.forEach(([m,R,b])=>{b&&m[b](k)})})},33)};return n&&L(n),{reload:L,isObjsLoader:!0,listeners:e,isFinished:()=>r,getStore:()=>i,connect:(g,k="render",m)=>{t.verify([[g,["object"]],[k,["notEmptyString"]],[m,["string","undefined"]]]),r?p?m&&g[m]():typeof g[k]=="function"&&g[k](i):e.push([g,k,m])},disconnect:g=>{t.verify([[g,["object"]]]),e=e.filter(([k])=>k!==g)}}},t.getParams=n=>{t.verify([[n,["string","undefined"]]]);const e={},i=new URLSearchParams(window.location.search).entries();for(const r of i)e[r[0]]=r[1];return n?e[n]:e},t.incCache=!0,t.incCacheExp=1e3*60*60*24,t.incTimeout=6e3,t.incSource="",t.incForce=t.F,t.incAsync=!0,t.incCors=t.F,t.incSeparator="?",t.incFns={},t.incSet=[0],t.incReady=[0],t.incN=0,t.incGetHash=n=>n.split(t.incSeparator)[1]||"",t.incCheck=(n=0,e,i=0)=>(t.verify([[n,["number"]],[e,["number","undefined"]],[i,["number"]]]),!i&&n&&e===t.U&&t.incReady[n]?t.incSet[n]===1:t.incReady[n]===t.U||t.incReady[n][e]===t.U?t.F:(t.incReady[n][e].loaded=i,t.incFns[t.incReady[n][e].name]=i,t.incReady[n][0]+=i,n&&t.incReady[n].length===t.incReady[n][0]&&(typeof t.incSet[n]=="function"&&t.incSet[n](n),t.incSet[n]=1),t.incSet[n]===1)),t.incCacheClear=(n=t.F)=>{t.verify([[n,["boolean"]]]);for(const e in t.incFns)t.C(t.incFns,e)&&(localStorage.removeItem("oInc-"+e),localStorage.removeItem("oInc-"+e+"-expires"));return n&&(t.incReady.forEach((e,i)=>{i&&e.forEach((r,p)=>{p&&t("#oInc-"+i+"-"+p).remove()})}),t.incN=0,t.incFns={},t.incSet=[0],t.incReady=[0]),!0},t.inc=(n,e,i)=>{if(t.verify([[n,["object","undefined"]],[e,["function","undefined"]],[i,["function","undefined"]]]),typeof localStorage>"u")return;let r=0,p=0,L="",g=!1;const k="function",m=-1;if(typeof n!="object"||!n)return t.incSet[0];t.incSet[0]++;const R=t.incSet[0];t.incSet[R]=e||0,t.incReady[R]=[];const b=t.incReady[R];b[0]=1;const h={};for(const v in n)if(t.C(n,v)){if(v==="preload"){g=!0;continue}L=t.incGetHash(n[v]),r++,t.incN++;const I=n[v].indexOf(".css")>m?"style":"script";if(n[v]=(t.incSource?t.incSource+"/":"")+n[v],Number.isNaN(Number(v))&&t.C(t.incFns,v)&&t.incFns[v]&&!t.incForce){b[r]={name:v,loaded:1},p++;continue}if(b[r]={name:v,loaded:0},Number.isNaN(Number(v))&&(t.incFns[v]=0),Number.isNaN(Number(v))&&t.incCache&&(n[v].substring(0,4)!=="http"||!t.incCors)&&window.location.protocol!=="file:"&&(n[v].indexOf(".css")>m||n[v].indexOf(".js")>m)){const l=localStorage,T=l.getItem("oInc-"+v),o=l.getItem("oInc-"+v+"-expires"),c=l.getItem("oInc-"+v+"-hash");T&&o&&Date.now()<o&&c===L?(g||t.initState({tag:I,id:"oInc-"+R+"-"+r,innerHTML:T,"data-o-inc":R}).appendInside("head"),b[r].loaded=1,t.incFns[v]=1,p++):(h[v]=r,t.get(n[v],{mode:t.incCors?"cors":"same-origin"}).then(f=>{if(f.status!==200){t.onError&&t.onError({message:t.incSource+n[v]+" was not loaded"});return}f.text().then(a=>{l.setItem("oInc-"+v,a),l.setItem("oInc-"+v+"-expires",Date.now()+t.incCacheExp),l.setItem("oInc-"+v+"-hash",L),g||t.initState({tag:I,id:"oInc-"+R+"-"+h[v],innerHTML:a,"data-o-inc":R}).appendInside("head"),t.incCheck(R,h[v],1)})}))}else{const l={tag:I,id:"oInc-"+R+"-"+r,"data-o-inc":R,async:t.incAsync,onload:"o.incCheck("+R+","+r+",1)"};n[v].indexOf(".css")>m?(l.tag="link",l.rel="stylesheet",l.href=n[v]):(n[v].indexOf(".js")>m||(l.tag="img",l.style="display:none;"),l.src=n[v]),t.initState(l).appendInside(l.style?"body":"head")}}return b[0]+=p,r!==0&&(p===r?typeof e===k&&e(R):setTimeout(v=>{t.incReady[v]&&t.incReady[v].length<t.incReady[v][0]&&(t.incSet[v]=0,typeof i===k&&i(R))},t.incTimeout,R)),t.incSet[0]},t.connectRedux=(n,e,i,r="render")=>{t.verify([[n,["object"]],[e,["function"]],[i,["object"]],[r,["notEmptyString"]]]);const p=()=>{if(typeof i[r]=="function"){const L=e(n.getState());i[r](L!==null&&typeof L=="object"?L:{value:L})}};return p(),n.subscribe(p)},t.connectMobX=(n,e,i,r,p="render")=>(t.verify([[n,["object"]],[e,["object"]],[i,["function"]],[r,["object"]],[p,["notEmptyString"]]]),n.autorun(()=>{if(typeof r[p]=="function"){const L=i(e);r[p](L!==null&&typeof L=="object"?L:{value:L})}})),t.ObjsContext=null,t.withReactContext=(n,e,i,r,p="render")=>function(){const g=n.useContext(e);return n.useEffect(()=>{if(typeof r[p]=="function"){const k=i(g);r[p](k!==null&&typeof k=="object"?k:{value:k})}},[g]),null},t.debug=!1,t.sleep=n=>new Promise(e=>setTimeout(e,n)),t.tLog=[],t.tRes=[],t.tStatus=[],t.tFns=[],t.tShowOk=t.F,t.tStyled=t.F,t.tTime=2e3,t.tests=[],t.tExpectedSteps={},t.tFinalized={},t.tAutolog=t.F,t.tBeforeEach=void 0,t.tAfterEach=void 0,t.addTest=(n,...e)=>{t.verify([[n,["notEmptyString"]],[e,["array"]]]);let i={};e.length&&typeof e[e.length-1]=="object"&&!Array.isArray(e[e.length-1])&&(i=e.pop());const r=t.tests.length;return t.tests[r]={title:n,tests:e,hooks:i},{run:()=>{typeof i.before=="function"&&(t.tBeforeEach=i.before),typeof i.after=="function"&&(t.tAfterEach=i.after),t.runTest(r)},autorun:()=>{typeof i.before=="function"&&(t.tBeforeEach=i.before),typeof i.after=="function"&&(t.tAfterEach=i.after),t.runTest(r,!0)},testId:r}},t.updateLogs=()=>{for(let n=0;n<t.tests.length;n++)t.tLog[n]=t.tLog[testN]=sessionStorage.getItem(`oTest-Log-${testN}`)||"";return t.tLog},t.runTest=(n=0,e,i)=>{if(t.verify([[n,["number"]],[e,["boolean","undefined"]],[i,["boolean","undefined"]]]),!t.tests[n])return;i||(sessionStorage?.removeItem(`oTest-Log-${n}`),sessionStorage?.removeItem(`oTest-Res-${n}`),sessionStorage?.removeItem(`oTest-Status-${n}`)),sessionStorage?.setItem("oTest-Run",n),e?sessionStorage?.setItem("oTest-Autorun",e):sessionStorage?.removeItem("oTest-Autorun");const r=t.tests[n];let p=r.tests.pop();typeof p!="function"&&(r.tests.push(p),p=()=>{}),r.tests.push(L=>{p(L),sessionStorage.setItem("dddd",1),sessionStorage?.removeItem("oTest-Run"),e&&t.runTest(n+1,e)}),t.test(r.title,...r.tests)},t.tPre='<div style="font-family:monospace;text-align:left;">',t.tOk='<span style="background:#cfc;padding: 0 15px;">OK</span> ',t.tXx='<div style="background:#fcc;padding:3px;">',t.tDc="</div>",t.test=(n="",...e)=>{t.verify([[n,["notEmptyString"]],[e,["array"]]]);const i=sessionStorage?.getItem("oTest-Run"),r=i||t.tLog.length;let p=0,L="\u251C OK: ",g="\u251C \u2718 ",k=`
|
|
7
|
-
`,
|
|
8
|
-
`,
|
|
9
|
-
`,
|
|
10
|
-
`;return}
|
|
11
|
-
`,
|
|
12
|
-
`,
|
|
13
|
-
`,
|
|
14
|
-
`):(
|
|
15
|
-
`);let
|
|
16
|
-
`,typeof t.tFns[p]=="function"&&t.tFns[p](p)}},sessionStorage?.getItem("oTest-Run")&&window?.addEventListener("load",()=>{t.runTest(sessionStorage?.getItem("oTest-Run"),sessionStorage?.getItem("oTest-Autorun")||t.F,!0)},!1),t.measure=n=>{if(!n)return{};const e=n.getBoundingClientRect(),i=window.getComputedStyle(n);return{width:e.width,height:e.height,top:e.top,left:e.left,visible:i.display!=="none"&&i.visibility!=="hidden"&&e.width>0,opacity:i.opacity,zIndex:i.zIndex}},t.assertVisible=n=>!!t.measure(n).visible,t.assertSize=(n,e={})=>{if(!n)return"element is null";const i=t.measure(n);if(e.w!==void 0&&Math.round(i.width)!==e.w)return`width: expected ${e.w}, got ${Math.round(i.width)}`;if(e.h!==void 0&&Math.round(i.height)!==e.h)return`height: expected ${e.h}, got ${Math.round(i.height)}`;const r=p=>{const L=window.getComputedStyle(n).getPropertyValue(p);return L?parseFloat(L):0};return e.padding!==void 0&&r("padding-top")!==e.padding?`padding: expected ${e.padding}, got ${r("padding-top")}`:e.paddingTop!==void 0&&r("padding-top")!==e.paddingTop?`paddingTop: expected ${e.paddingTop}, got ${r("padding-top")}`:e.paddingRight!==void 0&&r("padding-right")!==e.paddingRight?`paddingRight: expected ${e.paddingRight}, got ${r("padding-right")}`:e.paddingBottom!==void 0&&r("padding-bottom")!==e.paddingBottom?`paddingBottom: expected ${e.paddingBottom}, got ${r("padding-bottom")}`:e.paddingLeft!==void 0&&r("padding-left")!==e.paddingLeft?`paddingLeft: expected ${e.paddingLeft}, got ${r("padding-left")}`:e.margin!==void 0&&r("margin-top")!==e.margin?`margin: expected ${e.margin}, got ${r("margin-top")}`:e.marginTop!==void 0&&r("margin-top")!==e.marginTop?`marginTop: expected ${e.marginTop}, got ${r("margin-top")}`:e.marginRight!==void 0&&r("margin-right")!==e.marginRight?`marginRight: expected ${e.marginRight}, got ${r("margin-right")}`:e.marginBottom!==void 0&&r("margin-bottom")!==e.marginBottom?`marginBottom: expected ${e.marginBottom}, got ${r("margin-bottom")}`:e.marginLeft!==void 0&&r("margin-left")!==e.marginLeft?`marginLeft: expected ${e.marginLeft}, got ${r("margin-left")}`:!0},t.recorder={active:!1,actions:[],mocks:{},initialData:{},assertions:[],observeRoot:null,_originalFetch:null,_listeners:[],_observer:null},t.recordingAssertionDebug=!1,t.startRecording=(n,e,i)=>{if(t.recorder.active)return;const r=["click","mouseover","scroll","input","change","submit","keydown","focus","blur"],p={click:100,mouseover:50,scroll:30,input:50,change:50,submit:100,keydown:50,focus:50,blur:50},L=e||r,g=Object.assign({},p,i||{}),k={scroll:30,mouseover:50,keydown:50,focus:50,blur:50},m=t.recorder;m.active=!0,m.actions=[],m.mocks={},m.stepDelays=g,m.initialData={url:window.location.href,timestamp:Date.now()},m.observeRoot=n||null,m.assertions=[],m.removedElements=[],t.inits.forEach((l,T)=>{l?.store&&(m.initialData["init_"+T]=JSON.parse(JSON.stringify(l.store)))}),m._originalFetch=window.fetch,window.fetch=async(l,T={})=>{const o=(T.method||"GET").toUpperCase();let c;try{c=T.body?JSON.parse(T.body):void 0}catch{c=T.body}const f=await m._originalFetch(l,T),a=f.clone();let u;try{u=await a.json()}catch{u=await a.text().catch(()=>null)}const D=o+":"+l;return m.mocks[D]={url:l,method:o,request:c,response:u,status:f.status},f},m._originalXHROpen=XMLHttpRequest.prototype.open,m._originalXHRSend=XMLHttpRequest.prototype.send,XMLHttpRequest.prototype.open=function(l,T){return this._oMethod=(l||"GET").toUpperCase(),this._oUrl=T,m._originalXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(l){const T=()=>{if(this.readyState!==4)return;let o;try{o=l?JSON.parse(l):void 0}catch{o=l}let c;try{const a=this.responseText;c=a?JSON.parse(a):null}catch{c=this.responseText??null}const f=(this._oMethod||"GET")+":"+(this._oUrl||"");m.mocks[f]={url:this._oUrl,method:this._oMethod,request:o,response:c,status:this.status}};return this.addEventListener("readystatechange",T),m._originalXHRSend.apply(this,arguments)},m.websocketEvents=[],m._originalWebSocket=window.WebSocket,window.WebSocket=function(l,T){const o=new m._originalWebSocket(l,T),c=m.websocketEvents.length;m.websocketEvents.push({url:typeof l=="string"?l:String(l),protocol:Array.isArray(T)?T[0]:T,open:!0,messages:[]}),o.addEventListener("message",a=>{const u=typeof a.data=="string"?a.data:String(a.data);m.websocketEvents[c].messages.push({dir:"in",data:u})}),o.addEventListener("close",()=>{m.websocketEvents[c].open=!1});const f=o.send.bind(o);return o.send=function(a){const u=typeof a=="string"?a:String(a);return m.websocketEvents[c].messages.push({dir:"out",data:u}),f(a)},o};const R={"data-o-init":1,"data-o-init-i":1,"data-o-state":1},b=(l,T)=>{if(t.D.querySelectorAll(l).length<=1)return l;let o=T;for(;o&&o!==t.D.body;){let c=o.id?"#"+o.id:null;if(!c&&o.attributes){const f=t.autotag?"data-"+t.autotag:null;if(f){const a=o.getAttribute(f);a!=null&&(c=`[${f}="${a}"]`)}if(!c){for(const a of o.attributes)if(a.name.startsWith("data-")&&!R[a.name]){c=`[${a.name}="${a.value}"]`;break}}}if(c){const f=c+" "+l;if(t.D.querySelectorAll(f).length===1)return f}o=o.parentElement}return l},h=l=>{if(!l||l.nodeType!==1)return"";let T="";if(l.dataset){const o=t.autotag&&l.dataset[t.autotag];o&&(T=b(`[data-${t.autotag}="${o}"]`,l.parentElement))}if(!T&&l.tagName){const o=l.id?"#"+l.id:l.className?l.tagName.toLowerCase()+"."+[...l.classList].join("."):l.tagName.toLowerCase();T=l.id?o:b(o,l.parentElement)}return T},v=n&&t.D.querySelector(n)||t.D.body;m._observer=new MutationObserver(l=>{const T=m.actions.length-1;if(T<0)return;const o=m.actions[T];t.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[recording] MutationObserver batch:",{actionIdx:T,lastAction:o?{type:o.type,target:o.target}:null,mutationTypes:l.map(c=>c.type),addedCount:l.reduce((c,f)=>c+(f.addedNodes?.length||0),0),removedCount:l.reduce((c,f)=>c+(f.removedNodes?.length||0),0)}),l.forEach(c=>{const f=(a,u)=>{let D,w;if(a&&v&&v.querySelectorAll(a).length>1){let S=u;for(;S&&S!==v&&S.nodeType===1;){const A=t.autotag&&S.dataset&&S.dataset[t.autotag];if(A){const y=`[data-${t.autotag}="${A}"]`,N=v.querySelectorAll(y);if(N.length>1){const q=[...N].indexOf(S);if(q!==-1){D=y,w=q;break}}}S=S.parentElement}}return{listSelector:D,index:w}};if(c.type==="childList"&&(c.addedNodes.forEach(a=>{if(a.nodeType!==1||!a.offsetParent)return;const u=h(a);if(!u||m.assertions.some(A=>A.actionIdx===T&&A.selector===u&&A.type==="visible"))return;const D=(a.textContent?.trim()||"").slice(0,80)||void 0,{listSelector:w,index:$}=f(u,a),S={actionIdx:T,type:"visible",selector:u,text:D};w!=null&&(S.listSelector=w),$!=null&&(S.index=$),m.assertions.push(S),t.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[recording] +visible assertion:",{actionIdx:T,lastAction:o?.type+" "+o?.target,selector:u,text:(D||"").slice(0,40),index:$,listSelector:w})}),c.removedNodes.forEach(a=>{if(a.nodeType!==1)return;const u=h(a);if(!u)return;const D=(a.textContent?.trim()||"").slice(0,80)||void 0,w=c.target;let $;a.previousSibling?$=Array.from(w.children).indexOf(a.previousSibling)+1:a.nextSibling?$=Array.from(w.children).indexOf(a.nextSibling):$=0;let S;if(t.autotag&&a.dataset?.[t.autotag]){const y=a.dataset[t.autotag];S=`[data-${t.autotag}="${y}"]`}const A={actionIdx:T,type:"removed",selector:u,text:D};S&&(A.listSelector=S),A.index=$,m.removedElements.push(A),t.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[recording] +removed element:",{actionIdx:T,lastAction:o?.type+" "+o?.target,selector:u,text:(D||"").slice(0,40),index:$,listSelector:S})})),c.type==="attributes"){const a=c.attributeName;if(!a)return;const u=h(c.target);if(!u)return;const w={class:"class",style:"style",hidden:"hidden",disabled:"disabled","aria-expanded":"aria-expanded","aria-checked":"aria-checked"}[a];if(!w||m.assertions.some(q=>q.actionIdx===T&&q.selector===u&&q.type===w))return;const{listSelector:$,index:S}=f(u,c.target),A=c.target;let y;w==="class"?y=A.className:w==="style"?y=A.style?.cssText||A.getAttribute("style")||"":w==="hidden"?y=A.hidden:w==="disabled"?y=A.disabled===!0:w==="aria-expanded"?y=A.getAttribute("aria-expanded"):w==="aria-checked"&&(y=A.getAttribute("aria-checked"));const N={actionIdx:T,type:w,selector:u};w==="class"?N.className=y:w==="style"?N.style=y:w==="hidden"?N.hidden=y:w==="disabled"?N.disabled=y:w==="aria-expanded"?N.ariaExpanded=y:w==="aria-checked"&&(N.ariaChecked=y),$!=null&&(N.listSelector=$),S!=null&&(N.index=S),m.assertions.push(N),t.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[recording] +attr assertion:",{actionIdx:T,lastAction:o?.type+" "+o?.target,selector:u,type:w,value:y,index:S,listSelector:$})}})}),m._observer.observe(v,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","hidden","disabled","aria-expanded","aria-checked"]});const I={};L.forEach(l=>{const T=o=>{const c=o.target;if(n&&v&&c?.nodeType===1&&!v.contains(c))return;let f="";if(c?.dataset){const j=t.autotag&&c.dataset[t.autotag];j&&(f=b(`[data-${t.autotag}="${j}"]`,c.parentElement))}if(!f&&c?.tagName){const j=c.id?"#"+c.id:c.className?c.tagName.toLowerCase()+"."+[...c.classList].join("."):c.tagName.toLowerCase();f=c.id?j:b(j,c.parentElement)}let a,u;if(f&&v&&v.querySelectorAll(f).length>1){let P=c;for(;P&&P!==v&&P.nodeType===1;){const X=t.autotag&&P.dataset&&P.dataset[t.autotag];if(X){const W=`[data-${t.autotag}="${X}"]`,s=v.querySelectorAll(W);if(s.length>1){const d=[...s].indexOf(P);if(d!==-1){a=W,u=d;break}}}P=P.parentElement}}const D=c?.tagName?c.tagName.toLowerCase()+(c.type?":"+c.type:""):void 0,w=l==="scroll"?window.scrollY:void 0,$=l==="input"||l==="change"?c?.value:void 0,S=l==="change"&&(c?.type==="checkbox"||c?.type==="radio")?c?.checked:void 0,A=l==="keydown"?c?.key:void 0,y=l==="keydown"?c?.code:void 0,N=l==="click"||l==="change"||l==="submit"?0:g[l]!==void 0?g[l]:k[l]??0,q=()=>{if((l==="blur"||l==="focus")&&f){const P=m.actions.length-1,X=P>=0?m.actions[P]:null;if(X){if(X.target===f&&X.listSelector==null==(a==null)&&X.targetIndex==null==(u==null)&&(X.targetIndex==null||X.targetIndex===u))return;for(const s of m.removedElements)if(s.actionIdx===P&&(s.selector===f||f.startsWith(s.selector+" ")||f.startsWith(s.selector+">")))return}}const j={type:l,target:f,time:Date.now()};D&&(j.targetType=D),w!==void 0&&(j.scrollY=w),$!==void 0&&(j.value=$),S!==void 0&&(j.checked=S),A!==void 0&&(j.key=A),y!==void 0&&(j.code=y),a!=null&&(j.listSelector=a),u!=null&&(j.targetIndex=u),m.actions.push(j)};N===0?q():(clearTimeout(I[l]),I[l]=setTimeout(q,N))};t.D.addEventListener(l,T,!0),m._listeners.push({ev:l,handler:T})})},t.stopRecording=()=>{const n=t.recorder;return n.active=!1,n._originalFetch&&(window.fetch=n._originalFetch,n._originalFetch=null),n._originalXHROpen&&(XMLHttpRequest.prototype.open=n._originalXHROpen,XMLHttpRequest.prototype.send=n._originalXHRSend,n._originalXHROpen=null,n._originalXHRSend=null),n._originalWebSocket&&(window.WebSocket=n._originalWebSocket,n._originalWebSocket=null),n._listeners.forEach(({ev:e,handler:i})=>{t.D.removeEventListener(e,i,!0)}),n._listeners=[],n._observer&&(n._observer.disconnect(),n._observer=null),{actions:[...n.actions],mocks:{...n.mocks},initialData:{...n.initialData},stepDelays:{...n.stepDelays},assertions:[...n.assertions||[]],removedElements:[...n.removedElements||[]],observeRoot:n.observeRoot||null,websocketEvents:[...n.websocketEvents||[]]}},t.clearRecording=n=>{if(n!==void 0)sessionStorage?.removeItem("oTest-Recording-"+n);else for(let e=sessionStorage?.length-1;e>=0;e--){const i=sessionStorage?.key(e);i&&i.indexOf("oTest-Recording-")===0&&sessionStorage?.removeItem(i)}},t.runRecordingAssertions=(n,e,i,r)=>{const p=r&&r.assertions,L=p??(n.assertions||[]).filter(o=>i==null||o.actionIdx===i);t.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[runRecordingAssertions] run:",{actionIdx:i,scope:i==null?"teardown (all)":"per-action",assertionsCount:L.length,assertions:L.map(o=>({actionIdx:o.actionIdx,type:o.type,selector:o.selector,index:o.index,text:(o.text||"").slice(0,40)}))});const g=new Set,k=L.filter(o=>{const c=`${o.selector}|${o.type}|${o.actionIdx}|${o.index??""}`;return g.has(c)?!1:(g.add(c),!0)}),R=(()=>{if(e!=null)return typeof e=="string"?t.D.querySelector(e)||t.D.body:e;const o=n.observeRoot;return o&&t.D.querySelector(o)||t.D.body})(),b=o=>(o||"").trim().replace(/\s+/g," "),h=o=>o?b(o.textContent||""):"",v=r?.removedElements||[],I=o=>{if(!v.length||i==null)return!1;const c=b(o.text||"");for(const f of v)if(!(f.actionIdx>i)&&b(f.text||"")===c&&f.selector===o.selector&&!(o.listSelector!=null&&f.listSelector!==o.listSelector)&&!(o.index!=null&&f.index!==o.index))return!0;return!1};let l=0;const T=[];for(const o of k){if(I(o)){l+=1,t.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[runRecordingAssertions] skip (explicit removed):",{actionIdx:o.actionIdx,selector:o.selector,text:(o.text||"").slice(0,40)});continue}let c=null,f=!1;if(o.listSelector!=null&&o.index!=null){const a=R.querySelectorAll(o.listSelector),u=b(o.text||""),D=$=>{const S=a[$];return S?(o.selector!==o.listSelector?S.querySelector(o.selector):S)||(o.selector!==o.listSelector?S:null):null};let w=a[o.index];if(!w&&o.index>0&&(w=a[o.index-1]),w){if(c=D(o.index)||(o.index>0?D(o.index-1):null),!c&&o.selector!==o.listSelector&&(c=w),o.type==="visible"&&u&&c){const $=h(c);if($.indexOf(u)===-1&&u.indexOf($)===-1)for(let A=0;A<a.length;A++){const y=D(A);if(y&&h(y).indexOf(u)!==-1){c=y,w=a[A];break}}}}else f=!0}else{const a=R.querySelectorAll(o.selector);c=a.length>0?a[0]:t.D.querySelector(o.selector)}if(o.type==="visible"){const a=c&&c.nodeType===1&&(c.offsetParent!==null||c.getBoundingClientRect&&c.getBoundingClientRect().width>0),u=b(o.text||""),D=h(c),w=D,$=!u||D.indexOf(u)!==-1||w.indexOf(u)!==-1||u.length>0&&u.indexOf(D)!==-1;if(a&&$)l+=1;else{const S=f?`index out of bounds (list has ${R.querySelectorAll(o.listSelector||o.selector).length} items, assertion expected index ${o.index})`:c?a?$?"fail":"text mismatch":"not visible":"element not found";T.push({selector:o.selector,message:S}),typeof console<"u"&&console.warn&&console.warn("[runRecordingAssertions] visible failed:",{actionIdx:o.actionIdx,selector:o.selector,listSelector:o.listSelector,index:o.index,expectedText:o.text||"(any)",actualText:D.slice(0,80),message:S})}}else if(o.type==="class"){const a=(o.className||"").trim().split(/\s+/).filter(Boolean);if(c&&(a.length===0||a.every(D=>c.classList?.contains(D))))l+=1;else{const D=f?`index out of bounds (list has ${R.querySelectorAll(o.listSelector).length} items, expected index ${o.index})`:c?`expected class "${o.className}"`:"element not found";T.push({selector:o.selector,message:D}),typeof console<"u"&&console.warn&&console.warn("[runRecordingAssertions] failed:",{type:o.type,selector:o.selector,actionIdx:o.actionIdx,listSelector:o.listSelector,index:o.index,itemsInRoot:o.listSelector?R.querySelectorAll(o.listSelector).length:"-",message:D})}}else if(o.type==="style"){const a=(o.style||"").trim(),u=(c?.style?.cssText||c?.getAttribute?.("style")||"").trim();if(c&&(!a||u.indexOf(a)!==-1||a===u))l+=1;else{const w=c?`expected style "${a.slice(0,60)}..."`:"element not found";T.push({selector:o.selector,message:w})}}else if(o.type==="hidden")if(c&&c.hidden===o.hidden)l+=1;else{const u=c?`expected hidden=${o.hidden}`:"element not found";T.push({selector:o.selector,message:u})}else if(o.type==="disabled")if(c&&c.disabled===o.disabled)l+=1;else{const u=c?`expected disabled=${o.disabled}`:"element not found";T.push({selector:o.selector,message:u})}else if(o.type==="aria-expanded"){const a=c?.getAttribute?.("aria-expanded");if(c&&(o.ariaExpanded==null||String(a)===String(o.ariaExpanded)))l+=1;else{const D=c?`expected aria-expanded="${o.ariaExpanded}"`:"element not found";T.push({selector:o.selector,message:D})}}else if(o.type==="aria-checked"){const a=c?.getAttribute?.("aria-checked");if(c&&(o.ariaChecked==null||String(a)===String(o.ariaChecked)))l+=1;else{const D=c?`expected aria-checked="${o.ariaChecked}"`:"element not found";T.push({selector:o.selector,message:D})}}}return{passed:l,total:k.length,failures:T}},t.exportTest=(n,e={})=>{const i=e.delay!==void 0?e.delay:16,r={actions:n.actions,assertions:n.assertions||[],observeRoot:n.observeRoot||null},p=n.observeRoot?`(o.D.querySelector('${n.observeRoot.replace(/'/g,"\\'")}') || o.D.body)`:"o.D.body",L=b=>{if(b.listSelector!=null&&b.targetIndex!=null){const h=JSON.stringify(b.listSelector),v=b.target===b.listSelector,I=v?h:JSON.stringify(b.target);return` const items = o.D.querySelectorAll(${h});
|
|
17
|
-
const item = items[${
|
|
6
|
+
*/const __DEV__=!0,o=query=>{let result={els:[],ie:{},delegated:{},parented:{},store:{},refs:{},_refsByIndex:[],states:[],isDebug:!1,currentState:"",savedStates:{},isRoot:!1,_parent:null},ONE=1,TWO=2,THREE=3,booleanType="boolean",objectType="object",functionType="function",stringType="string",numberType="number",notEmptyStringType="notEmptyString",undefinedType="undefined",_reactProp="dangerouslySetInnerHTML",u,D=o.D,start=-1,finish=0,select=0,ssr=typeof process<"u"||o.D===o.DocumentMVP,i=0,j=0;const self=result,type=obj=>typeof obj,cycleObj=(obj,func)=>{for(const item in obj)Object.hasOwn(obj,item)&&func(item,obj)},error=o.onError,typeVerify=pairs=>o.verify(pairs),returner=(f,name="")=>(...a)=>{(o.debug||result.isDebug)&&console.log(name?`${name}()`:f,a.length?"with "+a.join(", "):"without parameters");try{const res=f(a[0],a[ONE],a[TWO],a[THREE]);return res!==u?res:result}catch(err){error(err,name)}},iterator=f=>{for(i=finish;i<=start;i++)f()},toEl=el=>el?.els?el.el:(type(el)!==objectType&&(el=o.first(el).el),el),setResultVals=(clearStates=!0,els=result.els)=>{const ln=els.length;if(result.length=ln,start=ln-ONE,finish=0,result.el=ln?els[0]:u,result.last=ln?els[start]:u,clearStates&&(cycleObj(result.states,(i2,state)=>{delete result[state[i2]]}),result.states=[],result.ie={}),Array.isArray(result._refsByIndex)){const currentLen=result._refsByIndex.length;if(currentLen>ln)cycleObj(result._refsByIndex,k=>{const idx=+k;idx>=ln&&delete result._refsByIndex[idx]}),result._refsByIndex.length=ln;else if(currentLen<ln)for(let idx=currentLen;idx<ln;idx++)result._refsByIndex[idx]={}}};result.reset=o;const hydrateDataOInitIn=containerEl=>{if(ssr||!containerEl.querySelectorAll)return;const nodes=containerEl.querySelectorAll("[data-o-init]"),byId={};nodes.forEach(node=>{const id=node.getAttribute("data-o-init");id!==null&&(byId[id]||(byId[id]=[]),byId[id].push(node))}),cycleObj(byId,id=>{const inst=o.inits[id];inst&&inst.getSSR(Number(id),byId[id])})},transform=(el,state,props)=>{cycleObj(state,s=>{let value=state[s];type(value)===functionType&&(value=value(props)),s==="append"&&type(value)===objectType&&(value.els&&(value=[value]),value[0]?.els&&(valueBuff=[],cycleObj(value,i2=>{valueBuff.push(...value[i2].els)}),value=valueBuff)),value!==u&&el.getAttribute(s)!==value&&!["tag","tagName","name","sample","state","events","ssr","nodeName","revertChildren","root","ref"].includes(s)&&(["html","innerHTML"].includes(s)?(el.innerHTML=value,!ssr&&hydrateDataOInitIn(el)):s==="className"?el.setAttribute("class",value):s==="dataset"&&type(value)===objectType?cycleObj(value,data=>{el.dataset[data]=value[data]}):s==="toggleClass"?el.classList.toggle(value):s==="addClass"?type(value)===objectType?el.classList.add(...value):el.classList.add(value):s==="removeClass"?el.classList.remove(value):s==="style"&&type(value)===objectType?cycleObj(value,data=>{el.style[data]=value[data]}):(s==="append"||s==="children"||s==="childNodes")&&type(value)===objectType?cycleObj(value.length?value:[value],j2=>{s==="append"||!el.childNodes[j2]?el.appendChild(value[j2]):el.childNodes[j2]!==value[j2]&&el.childNodes[j2].replaceWith(value[j2])}):el.setAttribute(s,value))}),el.dataset.oState=state.state,o.autotag&&state.name&&(el.dataset[o.autotag]=o.camelToKebab(state.name))};result.debug=returner(()=>{result.isDebug=!0},"debug ON"),result.saveAs=returner(key=>{typeVerify([[key,[notEmptyStringType]]]),o.getSaved[key]?(o.debug||result.isDebug)&&console.warn("the key exists (not saved):"+key):o.getSaved[key]=result},"saveAs"),result.unmount=()=>((o.debug||result.isDebug)&&console.log("unmount() for initID:"+result.initID),type(result.remove)===functionType?result.remove():result.els?.length&&result.els.forEach(el=>{el?.parentNode&&el.parentNode.removeChild(el)}),o.inits[result.initID]=void 0,result={},!0),result.init=returner(states=>{typeVerify([[states,[objectType,functionType]]]);const initN=result.initID||o.inits.length||0;if(result.initID=initN,setResultVals(),o.inits[result.initID]=result,type(states)==="function"){result.render=returner(props=>{const root=D.createElement("div");setTimeout(()=>{o.reactRender(states,root,props)}),result.add(root)});return}(type(states)!==objectType||states.render===u)&&(states={render:states}),cycleObj(states,state=>{result?.render&&state==="render"||(result.states.push(state),result[state]=returner((props=[{}])=>{result.currentState=state;const data=states[state]||{tag:"div"},slice=Array.isArray(result.els)?result.els.slice(finish,start+ONE):[],els=slice.length?slice:result.els||[];type(data)===objectType&&(data.state=state,data["data-o-init"]=initN);const newEl=(n,prop={})=>{const resolved=type(data)===functionType?data(prop):data;if(type(resolved)===objectType)return D.createElement(resolved.tag||resolved.tagName||"div");const newElem=D.createElement("div");return newElem.innerHTML=resolved,newElem.children.length>ONE||!newElem.firstElementChild?(newElem.dataset.oInit=n,newElem):(newElem.firstElementChild.dataset.oInit=n,newElem.firstElementChild)},rawData=props;Array.isArray(props)||(props=[props]),props.length||(props=[props]);const creation=!els[0]&&state==="render";props=props.map((prop,i2)=>{const newProp=Object.assign({},type(prop)===objectType?prop:{},{self:result,o,i:prop.i===u?i2:prop.i,parent:result._parent,data:Array.isArray(rawData)?rawData[i2]:rawData});return creation&&(!data.ssr||ssr)&&els.push(newEl(initN,newProp)),newProp}),creation&&(result.els=els,setResultVals(!1));const initSSR=()=>{cycleObj(data.events,event=>{result.on(event,data.events[event])})};els&&(j=els.length===props.length,els.map((el,i2)=>{props[j?i2:0].i=i2+finish;const buff=type(data)===functionType?data(props[j?i2:0]):data;type(buff)===objectType&&(buff.state=state,creation&&(buff["data-o-init"]=initN,buff["data-o-init-i"]=i2,buff.events&&(result._hydrateEvents=result._hydrateEvents||[],result._hydrateEvents[i2]=buff.events)),transform(el,buff,props[j?i2:0]))}),creation&&(result._refsByIndex=[],result.refs={},result.els.forEach((el,idx)=>{if(!el.querySelectorAll)return;const refsForEl={};el.querySelectorAll("[ref]").forEach(refEl=>{const refName=refEl.getAttribute("ref"),refInstance=o(refEl);refsForEl[refName]=refInstance,idx===0&&(result.refs[refName]=refInstance)}),result._refsByIndex[idx]=refsForEl}),!ssr&&result._hydrateEvents&&(result._hydrateEvents.forEach((evts,idx)=>{evts&&(result.select(idx),cycleObj(evts,event=>{const spec=evts[event];if(type(spec)===objectType&&spec.targetRef&&type(spec.handler)===functionType){const ref=(result._refsByIndex?.[idx]??result.refs)?.[spec.targetRef];ref&&ref.on(event,spec.handler)}else type(spec)===functionType&&result.on(event,spec)}))}),result.all()))),creation&&type(data)===objectType&&data.events&&!ssr&&!data.ssr&&initSSR()}))});const renderState=states.render||states,hasStateEvents=!ssr&&type(renderState)===objectType&&renderState.events,hasHydrateEvents=!ssr&&result._hydrateEvents&&result._hydrateEvents.length;(hasStateEvents||hasHydrateEvents)&&(result.initSSRAfterGettingSSR=()=>{result._refsByIndex=[],result.refs={},result.els.forEach((el,idx)=>{if(!el.querySelectorAll)return;const refsForEl={};el.querySelectorAll("[ref]").forEach(refEl=>{const refName=refEl.getAttribute("ref"),refInstance=o(refEl);refsForEl[refName]=refInstance,idx===0&&(result.refs[refName]=refInstance),refEl.removeAttribute("ref")}),result._refsByIndex[idx]=refsForEl,idx===0&&(result.refs=refsForEl)}),hasStateEvents&&cycleObj(renderState.events,event=>{result.on(event,renderState.events[event])}),result._hydrateEvents&&(result._hydrateEvents.forEach((evts,idx)=>{evts&&(result.select(idx),cycleObj(evts,event=>{const spec=evts[event];if(type(spec)===objectType&&spec.targetRef&&type(spec.handler)===functionType){const ref=(result._refsByIndex?.[idx]??result.refs)?.[spec.targetRef];ref&&ref.on(event,spec.handler)}else type(spec)===functionType&&result.on(event,spec)}))}),result.all())})},"init"),result.connect=returner((loader,state="render",fail)=>{typeVerify([[loader,[objectType]],[state,[notEmptyStringType]],[fail,[stringType,undefinedType]]]),loader.connect(self,state,fail)},"connect"),result.getSSR=returner((initId,fromEls)=>{typeVerify([[initId,[numberType,undefinedType]]]);const effectiveId=initId!==void 0?initId:result.initID;if(ssr||type(initId)===undefinedType&&type(result.initID)===undefinedType)return;const ssrEls=fromEls&&fromEls.length?fromEls:o.D.querySelectorAll(`[data-o-init="${effectiveId}"]`);ssrEls.length&&(result.els=Array.from(ssrEls),initId!==void 0&&(result.initID=initId,o.inits[initId]=result),setResultVals(!1),type(result.initSSRAfterGettingSSR)===functionType?result.initSSRAfterGettingSSR():fromEls&&fromEls.length&&(result._refsByIndex=[],result.refs={},result.els.forEach((el,idx)=>{if(!el.querySelectorAll)return;const refsForEl={};el.querySelectorAll("[ref]").forEach(refEl=>{const refName=refEl.getAttribute("ref");refsForEl[refName]=o(refEl),idx===0&&(result.refs[refName]=refsForEl[refName]),refEl.removeAttribute("ref")}),result._refsByIndex[idx]=refsForEl,idx===0&&(result.refs=refsForEl)})))},"getSSR"),result.initState=returner((state,props)=>{typeVerify([[state,[objectType]],[props,[objectType,undefinedType]]]),result.init(state).render(props)},"initState");const parseState=(el,stateId,root)=>{const attrs=el.attributes,stateData={tagName:el.tagName.toLowerCase()};for(const attr of attrs)stateData[attr.nodeName]=attr.value;if(root){stateData.innerHTML=el.innerHTML,stateData.revertChildren=[];const initedChildren=el.querySelectorAll("[data-o-init]");for(const child of initedChildren){const initId=child.getAttribute("data-o-init");stateData.revertChildren.push(initId),o.inits[initId]?.saveState(stateId,!1)}}return stateData};return result.saveState=returner((stateId,root=!0)=>{if(typeVerify([[stateId,[notEmptyStringType,undefinedType]],[root,[booleanType]]]),!result.el)throw Error("saveState(): There are no elements to save");const targetState=stateId||"fastSavedState",stateRevert={els:[],parentNode:result.el.parentNode,root};iterator(()=>{stateRevert.els.push(parseState(result.els[i],targetState,root))}),stateRevert.ie=Object.assign({},result.ie),stateRevert.delegated=Object.assign({},result.delegated),stateRevert.store=Object.assign({},result.store),result.isRoot=result.isRoot||root,result.savedStates[targetState]=stateRevert},"saveState"),result.revertState=returner(state=>{typeVerify([[state,[notEmptyStringType,undefinedType]]]);const targetState=state||"fastSavedState";if(!result.savedStates[targetState])throw Error(`revertState(): The state "${targetState}" should have been saved by saveState()`);const stateRevert=result.savedStates[targetState];result.offAll(),result.offDelegate(),result.store=Object.assign({},stateRevert.store),stateRevert.els.forEach((elData,index)=>{if(!result.els[index]){const newEl=o.D.createElement(elData.tagName);stateRevert.parentNode&&(index?result.els[index-1].after(newEl):stateRevert.parentNode.append(newEl)),result.add(newEl)}transform(result.els[index],elData)}),result.delegated=Object.assign({},stateRevert.delegated),result.ie=Object.assign({},stateRevert.ie),result.onAll(),cycleObj(stateRevert.delegated,ev=>{stateRevert.delegated[ev].forEach(f=>{iterator(()=>{result.els[i].addEventListener(ev,f)})})}),result.currentState=targetState,stateRevert.root&&stateRevert.els.forEach(({rootElement})=>{rootElement.revertChildren.forEach(initId=>{o.inits[initId]?.revertState(targetState),o('[data-o-init="'+initId+'"]').els.forEach((el,index)=>{el.replaceWith(o.inits[initId]?.els[index])})})})},"revertState"),result.loseState=returner(stateId=>{typeVerify([[stateId,[notEmptyStringType]]]),result.savedStates[stateId]&&(delete result.savedStates[stateId],iterator(()=>{const initedChildren=result.els[i].querySelectorAll("[data-o-init]");for(const child of initedChildren){const initId=child.getAttribute("data-o-init");o.inits[initId]?.loseState(stateId)}}))},"sample"),result.sample=returner((state="render")=>(typeVerify([[state,[notEmptyStringType]]]),{[state]:parseState(result.els[finish])}),"sample"),result.select=returner(i2=>{let idx=i2;idx!=null&&type(idx)===objectType&&idx.target&&result.els.length&&(idx=result.els.findIndex(el=>el===idx.target||el.contains(idx.target)),idx<0&&(idx=0)),typeVerify([[idx,[numberType,undefinedType]]]),idx===u&&(idx=result.length-ONE),start=idx,finish=idx,result.el=result.els[idx],select=ONE,Array.isArray(result._refsByIndex)&&result._refsByIndex[idx]&&(result.refs=result._refsByIndex[idx])},"select"),result.all=returner(()=>{start=result.length-ONE,finish=0,result.el=result.els[0],select=0,Array.isArray(result._refsByIndex)&&result._refsByIndex.length&&(result.refs=result._refsByIndex[0]||{})},"all"),result.remove=returner(j2=>{if(typeVerify([[j2,[numberType,undefinedType]]]),j2===u&&select&&(j2=finish),j2!==u){const el=result.els[j2];el?.parentNode?el.parentNode.removeChild(el):el===void 0&&j2>=result.els.length&&o.onError&&o.onError("remove("+j2+"): index out of bounds","remove")}else iterator(()=>{const el=result.els[i];el?.parentNode&&el.parentNode.removeChild(el)});setResultVals(!1)},"remove"),result.skip=returner(j2=>{typeVerify([[j2,[numberType,undefinedType]]]),j2===u&&(j2=finish),result.els.splice(j2,ONE),Array.isArray(result._refsByIndex)&&result._refsByIndex.splice(j2,ONE),setResultVals()},"skip"),result.add=returner(el=>{typeVerify([[el,[stringType,objectType,numberType]]]),result.initID===u&&(type(el)==="string"&&el!==""?result.els.push(...Array.from(D.querySelectorAll(el))):type(el)===objectType?el.tagName?result.els.push(el):el.els?result.els.push(...el.els):el.length&&el[0].tagName&&result.els.push(...el):type(el)==="number"&&o.inits[el]&&(result=o.inits[el]),setResultVals(!1),result.initID!==u&&result.dataset({oInit:result.initID}))},"add"),result.appendInside=returner(el=>{typeVerify([[el,[objectType,notEmptyStringType]]]),el?.els&&(result._parent=el),iterator(()=>{toEl(el).appendChild(result.els[i])})},"appendInside"),result.appendBefore=returner(el=>{typeVerify([[el,[objectType,notEmptyStringType]]]),iterator(()=>{toEl(el).parentNode.insertBefore(result.els[i],toEl(el))})},"appendBefore"),result.appendAfter=returner(el=>{typeVerify([[el,[objectType,notEmptyStringType]]]),iterator(()=>{toEl(el).after(...result.els)})},"appendAfter"),result.find=returner((innerQuery="")=>{typeVerify([[innerQuery,stringType]]);const newEls=[];return iterator(()=>{newEls.push(...Array.from(result.els[i].querySelectorAll(":scope "+innerQuery)))}),o(newEls)},"find"),result.first=returner((innerQuery="")=>{typeVerify([[innerQuery,stringType]]);let buff=u;const newEls=[];return iterator(()=>{buff=result.els[i].querySelector(innerQuery),buff&&newEls.push(buff)}),o(newEls)},"first"),result.attr=returner((attr,val)=>{if(val!==null&&typeVerify([[attr,stringType],[val,[stringType,undefinedType]]]),val===u){const attrs=[];return iterator(()=>{attrs[i]=result.els[i].getAttribute(attr)}),select?attrs[0]:attrs}else iterator(val!==null?()=>{result.els[i].setAttribute(attr,val)}:()=>{result.els[i].removeAttribute(attr)})},"attr"),result.attrs=returner(()=>{const res=[];return iterator(()=>{const obj={};[...result.els[i].attributes].forEach(attr=>{obj[attr.nodeName]=attr.nodeValue}),res.push(obj)}),select?res[0]:res},"attrs"),result.dataset=returner(values=>{if(typeVerify([[values,[objectType,undefinedType]]]),typeof values===objectType)iterator(()=>{cycleObj(values,data=>{result.els[i].dataset[data]=values[data]})});else{const res=[];return iterator(()=>{res.push({...result.els[i].dataset})}),select?res[0]:res}},"dataset"),result.style=returner(val=>{val!==null&&typeVerify([[val,[stringType,undefinedType]]]),result.attr("style",val)},"style"),result.css=returner((styles={})=>{if(styles===null){result.style(null);return}typeVerify([[styles,objectType]]);let val="";cycleObj(styles,style=>{val+=style+":"+styles[style].replace('"',"'")+";"}),result.style(val||null)},"css"),result.cssMerge=returner((styles={})=>{if(styles===null){result.style(null);return}typeVerify([[styles,objectType]]);const normKey=k=>k.indexOf("-")!==-1?k:o.camelToKebab(k),parseStyleAttr=s=>{const out={};if(!s||typeof s!==stringType)return out;const parts=s.split(";");for(let p=0;p<parts.length;p++){const part=parts[p],idx=part.indexOf(":");if(idx===-1)continue;const key=part.slice(0,idx).trim(),val=part.slice(idx+1).trim();key&&(out[key]=val)}return out};iterator(()=>{const el=result.els[i],merged=parseStyleAttr(el.getAttribute("style"));cycleObj(styles,style=>{const k=normKey(style),v=styles[style];v===null||v===u?delete merged[k]:merged[k]=String(v).replace('"',"'")});let serialized="";cycleObj(merged,k=>{serialized+=k+":"+merged[k]+";"}),serialized?el.setAttribute("style",serialized):el.removeAttribute("style")})},"cssMerge"),result.setClass=returner(cl=>{typeVerify([[cl,stringType]]),iterator(()=>{result.els[i].setAttribute("class",cl)})},"setClass"),result.addClass=returner((...cls)=>{iterator(()=>{result.els[i].classList.add(...cls)})},"addClass"),result.removeClass=returner((...cls)=>{iterator(()=>{result.els[i].classList.remove(...cls)})},"removeClass"),result.toggleClass=returner((cl,check)=>{typeVerify([[cl,notEmptyStringType],[check,[booleanType,undefinedType]]]),iterator(()=>{result.els[i].classList.toggle(cl,check)})},"toggleClass"),result.haveClass=cl=>{typeVerify([[cl,notEmptyStringType]]);let res=!0;return iterator(()=>{result.els[i].classList.contains(cl)||(res=!1)}),(result.isDebug||o.debug)&&console.log("haveClass() with",cl),res},result.innerHTML=returner(html=>{if(typeVerify([[html,[stringType,undefinedType]]]),html!==u)iterator(()=>{result.els[i].innerHTML=html});else{let res="";return iterator(()=>{res+=ssr&&result.els[i].innerHTML.length===0?o.D.parseElement(result.els[i],!1):result.els[i].innerHTML}),res}},"innerHTML"),result.innerText=returner(text=>{typeVerify([[text,[stringType]]]),iterator(()=>{result.els[i].innerText=text})},"innerText"),result.textContent=returner(text=>{typeVerify([[text,[stringType]]]),iterator(()=>{result.els[i].textContent=text})},"textContent"),result.html=returner(value=>{if(typeVerify([[value,[stringType,undefinedType]]]),value!==void 0)result.innerHTML(value);else{let html="";return iterator(()=>{html+=ssr?result.els[i].outerHTML():result.els[i].outerHTML}),html}},"html"),result.toString=function(){return result.html()},result[Symbol.toPrimitive]=function(hint){return hint==="string"||hint==="default"?result.html():hint==="number"?result.els?.length??0:result.html()},result.val=returner(value=>{if(value===void 0)return result.el?.value;iterator(()=>{result.els[i].value=value})},"val"),result.forEach=returner(f=>{typeVerify([[f,[functionType]]]),iterator(()=>{f({self:result,i,o,el:result.els[i]})})},"forEach"),result.prepareFor=returner((reactArg,ReactComponent)=>{typeVerify([[reactArg,[objectType,functionType,undefinedType]],[ReactComponent,[functionType,undefinedType]]]);const isFullReact=reactArg&&type(reactArg)===objectType&&reactArg.createElement;if(!isFullReact&&type(reactArg)!==functionType)throw Error("prepareFor(): pass React (full object) or React.createElement as first argument");const createElement=isFullReact?reactArg.createElement:reactArg,useEffect=isFullReact?reactArg.useEffect:void 0;return p=>{if(p.ref===u)throw Error("No ref property to convert Objs to React");const props=Object.assign({},p),reactElement=createElement("div",{ref:p.ref});return delete props.ref,useEffect(()=>{cycleObj(props,key=>{if(key.substring(0,1)==="on"){const e=o.camelToKebab(key).split("-")[1];result.on(e,props[key]),delete props[key]}}),result.render(props),result.appendInside(reactElement.ref.current)},[]),reactElement}},"prepareFor"),result.on=returner((a,b,c,d)=>{typeVerify([[a,[notEmptyStringType]],[b,[functionType]],[c,[objectType,undefinedType]],[d,[booleanType,undefinedType]]]),a.split(", ").forEach(ev=>{iterator(()=>{result.els[i].addEventListener(ev,b,c,d)}),result.ie[ev]||(result.ie[ev]=[]),result.ie[ev].push([b,c,d])})},"on"),result.off=returner((a,b,c)=>{typeVerify([[a,[notEmptyStringType]],[b,[functionType]],[c,[objectType,undefinedType]]]),a.split(", ").forEach(ev=>{iterator(()=>{result.els[i].removeEventListener(ev,b,c)}),result.ie[ev]&&(result.ie[ev]=result.ie[ev].filter(f=>f[0]!==b))})},"off"),result.onDelegate=returner((e,selector,f)=>{typeVerify([[e,[notEmptyStringType]],[selector,[notEmptyStringType]],[f,[functionType]]]),e.split(", ").forEach(ev=>{const delegateCheck=event=>{const delegate=event.target.closest(selector);delegate&&(event.delegate=delegate,event.objs=result,f(event))};iterator(()=>{result.els[i].addEventListener(ev,delegateCheck)}),result.delegated[ev]||(result.delegated[ev]=[]),result.delegated[ev].push(delegateCheck)})},"onDelegate"),result.offDelegate=returner(e=>{typeVerify([[e,[notEmptyStringType]]]),cycleObj(result.delegated,ev=>{if(!e||e===ev)for(;result.delegated[ev].length;){const f=result.delegated[ev].pop();iterator(()=>{result.els[i].removeEventListener(ev,f)})}}),result.delegated={}},"offDelegate"),result.onParent=returner((e,selector,f)=>{typeVerify([[e,[notEmptyStringType]],[selector,[notEmptyStringType,objectType]],[f,[functionType]]]);const parent=type(selector)===objectType?selector:o.D.querySelector(selector);e.split(", ").forEach(ev=>{const parentCheck=event=>{event.objs=result,f(event)};parent.addEventListener(ev,parentCheck),result.parented[ev]||(result.parented[ev]=[]),result.parented[ev].push(parentCheck)})},"onParent"),result.offParent=returner((e,query2)=>{typeVerify([[e,[notEmptyStringType]],[query2,[notEmptyStringType,objectType]]]);const parent=type(query2)===objectType?query2:o.D.querySelector(query2);cycleObj(result.parented,ev=>{(!e||e===ev)&&(result.parented[ev].forEach(f=>{parent.removeEventListener(ev,f)}),delete result.parented[ev])})},"offParent"),result.onAll=returner((type2,off)=>{typeVerify([[type2,[notEmptyStringType,undefinedType]],[off,[booleanType,undefinedType]]]),cycleObj(result.ie,(ev,events)=>{(!type2||type2===ev)&&events[ev].forEach(data=>{iterator(()=>{off?result.els[i].removeEventListener(ev,data[0]):result.els[i].addEventListener(ev,data[0],data[ONE],data[TWO])})})})},"onAll"),result.offAll=returner(type2=>{typeVerify([[type2,[notEmptyStringType]]]),result.onAll(type2,ONE)},"offAll"),query&&result.add(query),result.take=innerQuery=>{if(typeVerify([[innerQuery,[stringType,objectType,numberType]]]),result.add(innerQuery),result.el){const initID=result.el.dataset.oInit;if(initID!==u&&o.inits[initID])return result.length===ONE?(j=result.els[0],Object.assign(result,o.inits[initID]),result.els=[j]):result=o.inits[initID],setResultVals(!1,result.els),result}},result};o.first=query=>(o.verify([[query,["notEmptyString"]]]),o.debug&&console.log(query," -> ","o.first()"),o(o.D.querySelector(query)).select(0)),o.inits=[],o.getSaved={},o.errors=[],o.showErrors=!1,o.logErrors=()=>{o.errors.length?o.errors.forEach(e=>console.error(e)):console.log("No errors")},o.onError=(e,name)=>{o.showErrors?console.error(e,name):(o.errors.push(e),name&&o.errors.push(name))},o.reactRender=()=>new Error("React render function is not defined"),o.autotag=void 0,o.reactQA=name=>({["data-"+(o.autotag||"qa")]:name.replace(/([A-Z])/g,(_,l)=>"-"+l.toLowerCase()).replace(/^-/,"")}),o.specialTypes={notEmptyString:(val,type)=>type==="string"&&val.length,array:val=>Array.isArray(val),promise:val=>val instanceof Promise||!!(val&&typeof val.then=="function")},o.verify=(pairs,safe=!1)=>{for(const pair of pairs){const type=typeof pair[0];let expectedTypes=Array.isArray(pair[1])?pair[1]:[pair[1]],isValid=!1;if(expectedTypes.includes(type))return!0;expectedTypes=expectedTypes.filter(t=>!!o.specialTypes[t]);for(const expectedType of expectedTypes)if(isValid=o.specialTypes[expectedType](pair[0],type),isValid)return!0}return safe?!1:new Error("Type verification failed")},o.safeVerify=pairs=>o.verify(pairs,!0),o.init=(states,reactRender)=>o().init(states,reactRender),o.initState=(state,props)=>o().init(state).render(props),o.take=query=>o().take(query),o.getStates=()=>o.inits.reduce((acc,result)=>(acc.push(result?.states),acc),[]),o.getStores=()=>o.inits.reduce((acc,result)=>(acc.push(result?.store),acc),[]),o.getListeners=()=>o.inits.reduce((acc,result)=>(acc.push(result?.ie),acc),[]),o.createStore=defaults=>{const store=Object.assign({},defaults);return store._defaults=Object.assign({},defaults),store._listeners=[],store.subscribe=function(component,stateName){return this._listeners.push(data=>component[stateName]?.(data)),this},store.notify=function(){this._listeners.forEach(fn=>fn(this))},store.reset=function(){const skip={_listeners:1,subscribe:1,notify:1,_defaults:1,reset:1};for(const key of Object.keys(this._defaults))skip[key]||(this[key]=this._defaults[key])},store},o.U=void 0,o.W=2,o.H=100,o.F=!1,o.C=(a,b)=>Object.hasOwn(a,b),o.kebabToCamel=str=>str.replace(/-./g,m=>m.toUpperCase()[1]),o.camelToKebab=str=>str.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),o.route=(path,task)=>{o.verify([[path,["notEmptyString","function","boolean"]],[task,["function","object"]]]);const result=typeof path=="function"?path(window.location.pathname):path;return result===!0||window.location.pathname===result?task?typeof task=="function"?(task(),!0):task:o:typeof task=="function"?!1:{}},o.router=(routes={})=>{o.verify([[routes,["object"]]]);for(const route in routes)if(o.C(routes,route)&&window.location.pathname===route)return typeof routes[route]=="function"?(routes[route](),!0):routes[route];return!1},o.DocumentMVP={addEventListener:()=>{},parseElement:(elem,outer=!0)=>{o.verify([[elem,["object","string"]],[outer,["boolean"]]]);const attrToStr=(attrs,prefix="")=>{let attrStr="";for(const attr in attrs)o.C(attrs,attr)&&(attrStr+=` ${prefix}${o.camelToKebab(attr)}="${typeof attrs[attr]!="object"?attrs[attr]:Object.entries(attrs[attr]).map(e=>`${e[0]}: ${e[1]};`).join(" ")}"`);return attrStr};if(typeof elem=="string")return elem;if(outer){const selfClosing=["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"],tagName=elem.tagName.toLowerCase(),dataOInit=elem.attributes["data-o-init"],dataOInitAttr=dataOInit!==void 0?` data-o-init="${dataOInit}"`:"";return`<${tagName}${elem.className?` class="${elem.className}"`:""}${attrToStr(elem.attributes)}${dataOInitAttr}${attrToStr(elem.dataset,"data-")}${selfClosing.includes(tagName)?"/":""}>${selfClosing.includes(tagName)?"":elem.innerHTML.length?elem.innerHTML:elem.children.map(el=>o.D.parseElement(el)).join("")}${selfClosing.includes(tagName)?"":`</${tagName}>`}`}return elem.innerHTML.length?elem.innerHTML:elem.children.map(el=>o.D.parseElement(el)).join("")},createElement:tag=>{o.verify([[tag,["notEmptyString"]]]);const elem={tagName:tag.toUpperCase(),attributes:{},innerHTML:"",children:[],dataset:{},className:"",classArray:[],style:{},addEventListener:()=>{},removeEventListener:()=>{}};return elem.classList={add:(...cl)=>{o.verify([[cl,["array"]]]),elem.classArray.push(cl),elem.className=elem.classArray.join(" ")},has:cl=>(o.verify([[cl,["notEmptyString"]]]),elem.classArray.includes(cl)),remove:cl=>{o.verify([[cl,["notEmptyString"]]]),elem.classArray=elem.classArray.filter(listed=>cl!==listed),elem.className=elem.classArray.join(" ")}},elem.classList.toggle=cl=>{o.verify([[cl,["notEmptyString"]]]),elem.classList.has(cl)?elem.classList.remove(cl):elem.classList.add(cl)},elem.setAttribute=(attr,val)=>{o.verify([[attr,["notEmptyString"]],[val,["string","number","boolean","undefined"]]]),elem.attributes[attr]=val},elem.getAttribute=attr=>(o.verify([[attr,["notEmptyString"]]]),elem.attributes[attr]),elem.removeAttribute=attr=>{o.verify([[attr,["notEmptyString"]]]),delete elem.attributes[attr]},elem.appendChild=el=>{o.verify([[el,["object"]]]),elem.children.push(el),elem.firstElementChild=elem.children[0]},elem.outerHTML=()=>o.D.parseElement(elem),elem}},o.D=typeof document<"u"&&typeof process>"u"?document:o.DocumentMVP,o.setCookie=(title,value="",params={})=>{if(o.verify([[title,["notEmptyString"]],[value,["string","number","boolean"]],[params,["object"]]]),o.D.cookie===void 0){console.log("Cookies are not supported on server side");return}let str=encodeURIComponent(title)+"="+encodeURIComponent(value);params={path:"/",...params},params.expires instanceof Date?params.expires=params.expires.toUTCString():typeof params.expires=="number"&&(params.expires=new Date(params.expires).toUTCString());for(const key in params){str+="; "+key;const r=params[key];r!==!0&&(str+="="+r)}o.D.cookie=str},o.getCookie=title=>{if(o.verify([[title,["notEmptyString"]]]),o.D.cookie===void 0){console.log("Cookies are not supported on server side");return}const val=o.D.cookie.match(RegExp("(?:^|; )"+title.replace(/([.$?*|{}()[\]\\/+^])/g,"\\$1")+"=([^;]*)"));return val?decodeURIComponent(val[1]):void 0},o.deleteCookie=title=>{o.verify([[title,["notEmptyString"]]]),o.setCookie(title,"",{"max-age":0})},o.clearCookies=()=>{if(o.D.cookie===void 0){console.log("Cookies are not supported on server side");return}const ca=o.D.cookie.split(";");for(;ca.length;){let c=ca.pop();for(;c.charAt(0)===" ";)c=c.substring(1);const key=c.split("=")[0];o.deleteCookie(key)}},o.clearLocalStorage=all=>{if(o.verify([[all,["boolean","undefined"]]]),!(typeof localStorage>"u"))if(all)localStorage.clear();else for(let i=localStorage.length-1;i>=0;i--){const key=localStorage.key(i);key.indexOf("oInc-")===-1&&key.indexOf("oTest-")===-1&&localStorage.removeItem(key)}},o.clearSessionStorage=onlyTests=>{if(o.verify([[onlyTests,["boolean","undefined"]]]),!(typeof sessionStorage>"u"))if(!onlyTests)sessionStorage.clear();else for(let i=sessionStorage.length-1;i>=0;i--){const key=sessionStorage.key(i);key&&key.indexOf("oTest-")===0&&sessionStorage.removeItem(key)}},o.clearTestsStorage=()=>{o.clearSessionStorage(1)},o.clearAfterTests=()=>{o.clearCookies(),o.clearLocalStorage(!1),o.clearTestsStorage()},o.ajax=(url,props={})=>{o.verify([[url,["notEmptyString"]],[props,["object"]]]);const row=new URLSearchParams;if(props.data&&typeof props.data=="object"){for(const param in props.data)o.C(props.data,param)&&(typeof props.data[param]=="object"?row.set(param,encodeURIComponent(JSON.stringify(props.data[param]))):row.set(param,props.data[param]));props.method.toLowerCase()==="get"?url+="?"+row.toString():props.body||(props.body=row),delete props.data}return props.headers||(props.headers={"X-Requested-With":"XMLHttpRequest"}),fetch(url,props)},o.get=(url,props={})=>(o.verify([[url,["notEmptyString"]],[props,["object"]]]),o.ajax(url,{...props,method:"GET"})),o.post=(url,props={})=>(o.verify([[url,["notEmptyString"]],[props,["object"]]]),o.ajax(url,{...props,method:"POST"})),o.newLoader=promise=>{o.verify([[promise,["promise","undefined"]]]);let listeners=[],data=null,finished=!1,error=!1;const reload=p=>{finished=!1,error=!1,data=null,setTimeout(()=>{p.then(response=>{finished=!0,!response.ok&&typeof response.ok<"u"?(error=!0,listeners.forEach(([listener,_state,fail])=>{fail&&listener[fail](response)})):typeof response.json=="function"?response.json().then(jsonData=>{data=jsonData,listeners.forEach(([listener,state])=>{listener[state](data)})}):(data=response,listeners.forEach(([listener,state])=>{listener[state](data)}))}).catch(err=>{error=!0,listeners.forEach(([listener,_state,fail])=>{fail&&listener[fail](err)})})},33)};return promise&&reload(promise),{reload,isObjsLoader:!0,listeners,isFinished:()=>finished,getStore:()=>data,connect:(listener,state="render",fail)=>{o.verify([[listener,["object"]],[state,["notEmptyString"]],[fail,["string","undefined"]]]),finished?error?fail&&listener[fail]():typeof listener[state]=="function"&&listener[state](data):listeners.push([listener,state,fail])},disconnect:listener=>{o.verify([[listener,["object"]]]),listeners=listeners.filter(([l])=>l!==listener)}}},o.getParams=key=>{o.verify([[key,["string","undefined"]]]);const params={},paramsRaw=new URLSearchParams(window.location.search).entries();for(const entry of paramsRaw)params[entry[0]]=entry[1];return key?params[key]:params},o.incCache=!0,o.incCacheExp=1e3*60*60*24,o.incTimeout=6e3,o.incSource="",o.incForce=o.F,o.incAsync=!0,o.incCors=o.F,o.incSeparator="?",o.incFns={},o.incSet=[0],o.incReady=[0],o.incN=0,o.incGetHash=path=>path.split(o.incSeparator)[1]||"",o.incCheck=(set=0,fnId,loaded=0)=>(o.verify([[set,["number"]],[fnId,["number","undefined"]],[loaded,["number"]]]),!loaded&&set&&fnId===o.U&&o.incReady[set]?o.incSet[set]===1:o.incReady[set]===o.U||o.incReady[set][fnId]===o.U?o.F:(o.incReady[set][fnId].loaded=loaded,o.incFns[o.incReady[set][fnId].name]=loaded,o.incReady[set][0]+=loaded,set&&o.incReady[set].length===o.incReady[set][0]&&(typeof o.incSet[set]=="function"&&o.incSet[set](set),o.incSet[set]=1),o.incSet[set]===1)),o.incCacheClear=(all=o.F)=>{o.verify([[all,["boolean"]]]);for(const name in o.incFns)o.C(o.incFns,name)&&(localStorage.removeItem("oInc-"+name),localStorage.removeItem("oInc-"+name+"-expires"));return all&&(o.incReady.forEach((val,i)=>{i&&val.forEach((_a,j)=>{j&&o("#oInc-"+i+"-"+j).remove()})}),o.incN=0,o.incFns={},o.incSet=[0],o.incReady=[0]),!0},o.inc=(sources,callBack,callBad)=>{if(o.verify([[sources,["object","undefined"]],[callBack,["function","undefined"]],[callBad,["function","undefined"]]]),typeof localStorage>"u")return;let sourcesN=0,sourcesReady=0,hash="",preload=!1;const f="function",no=-1;if(typeof sources!="object"||!sources)return o.incSet[0];o.incSet[0]++;const setN=o.incSet[0];o.incSet[setN]=callBack||0,o.incReady[setN]=[];const fnsStatus=o.incReady[setN];fnsStatus[0]=1;const fnId={};for(const name in sources)if(o.C(sources,name)){if(name==="preload"){preload=!0;continue}hash=o.incGetHash(sources[name]),sourcesN++,o.incN++;const tag=sources[name].indexOf(".css")>no?"style":"script";if(sources[name]=(o.incSource?o.incSource+"/":"")+sources[name],Number.isNaN(Number(name))&&o.C(o.incFns,name)&&o.incFns[name]&&!o.incForce){fnsStatus[sourcesN]={name,loaded:1},sourcesReady++;continue}if(fnsStatus[sourcesN]={name,loaded:0},Number.isNaN(Number(name))&&(o.incFns[name]=0),Number.isNaN(Number(name))&&o.incCache&&(sources[name].substring(0,4)!=="http"||!o.incCors)&&window.location.protocol!=="file:"&&(sources[name].indexOf(".css")>no||sources[name].indexOf(".js")>no)){const ls=localStorage,script=ls.getItem("oInc-"+name),cacheSavedTill=ls.getItem("oInc-"+name+"-expires"),cacheHash=ls.getItem("oInc-"+name+"-hash");script&&cacheSavedTill&&Date.now()<cacheSavedTill&&cacheHash===hash?(preload||o.initState({tag,id:"oInc-"+setN+"-"+sourcesN,innerHTML:script,"data-o-inc":setN}).appendInside("head"),fnsStatus[sourcesN].loaded=1,o.incFns[name]=1,sourcesReady++):(fnId[name]=sourcesN,o.get(sources[name],{mode:o.incCors?"cors":"same-origin"}).then(response=>{if(response.status!==200){o.onError&&o.onError({message:o.incSource+sources[name]+" was not loaded"});return}response.text().then(script2=>{ls.setItem("oInc-"+name,script2),ls.setItem("oInc-"+name+"-expires",Date.now()+o.incCacheExp),ls.setItem("oInc-"+name+"-hash",hash),preload||o.initState({tag,id:"oInc-"+setN+"-"+fnId[name],innerHTML:script2,"data-o-inc":setN}).appendInside("head"),o.incCheck(setN,fnId[name],1)})}))}else{const state={tag,id:"oInc-"+setN+"-"+sourcesN,"data-o-inc":setN,async:o.incAsync,onload:"o.incCheck("+setN+","+sourcesN+",1)"};sources[name].indexOf(".css")>no?(state.tag="link",state.rel="stylesheet",state.href=sources[name]):(sources[name].indexOf(".js")>no||(state.tag="img",state.style="display:none;"),state.src=sources[name]),o.initState(state).appendInside(state.style?"body":"head")}}return fnsStatus[0]+=sourcesReady,sourcesN!==0&&(sourcesReady===sourcesN?typeof callBack===f&&callBack(setN):setTimeout(set=>{o.incReady[set]&&o.incReady[set].length<o.incReady[set][0]&&(o.incSet[set]=0,typeof callBad===f&&callBad(setN))},o.incTimeout,setN)),o.incSet[0]},o.connectRedux=(store,selector,component,state="render")=>{o.verify([[store,["object"]],[selector,["function"]],[component,["object"]],[state,["notEmptyString"]]]);const update=()=>{if(typeof component[state]=="function"){const val=selector(store.getState());component[state](val!==null&&typeof val=="object"?val:{value:val})}};return update(),store.subscribe(update)},o.connectMobX=(mobx,observable,accessor,component,state="render")=>(o.verify([[mobx,["object"]],[observable,["object"]],[accessor,["function"]],[component,["object"]],[state,["notEmptyString"]]]),mobx.autorun(()=>{if(typeof component[state]=="function"){const val=accessor(observable);component[state](val!==null&&typeof val=="object"?val:{value:val})}})),o.ObjsContext=null,o.withReactContext=(React,Context,selector,component,state="render")=>function(){const value=React.useContext(Context);return React.useEffect(()=>{if(typeof component[state]=="function"){const val=selector(value);component[state](val!==null&&typeof val=="object"?val:{value:val})}},[value]),null},o.debug=!1,o.sleep=ms=>new Promise(r=>setTimeout(r,ms)),o.tLog=[],o.tRes=[],o.tStatus=[],o.tFns=[],o.tShowOk=o.F,o.tStyled=o.F,o.tTime=2e3,o.tests=[],o.tExpectedSteps={},o.tFinalized={},o.tAutolog=o.F,o.tBeforeEach=void 0,o.tAfterEach=void 0,o.addTest=(title,...tests)=>{o.verify([[title,["notEmptyString"]],[tests,["array"]]]);let hooks={};tests.length&&typeof tests[tests.length-1]=="object"&&!Array.isArray(tests[tests.length-1])&&(hooks=tests.pop());const testId=o.tests.length;return o.tests[testId]={title,tests,hooks},{run:()=>{typeof hooks.before=="function"&&(o.tBeforeEach=hooks.before),typeof hooks.after=="function"&&(o.tAfterEach=hooks.after),o.runTest(testId)},autorun:()=>{typeof hooks.before=="function"&&(o.tBeforeEach=hooks.before),typeof hooks.after=="function"&&(o.tAfterEach=hooks.after),o.runTest(testId,!0)},testId}},o.updateLogs=()=>{for(let i=0;i<o.tests.length;i++)o.tLog[i]=o.tLog[testN]=sessionStorage.getItem(`oTest-Log-${testN}`)||"";return o.tLog},o.runTest=(testId=0,autoRun,savePrev)=>{if(o.verify([[testId,["number"]],[autoRun,["boolean","undefined"]],[savePrev,["boolean","undefined"]]]),!o.tests[testId])return;savePrev||(sessionStorage?.removeItem(`oTest-Log-${testId}`),sessionStorage?.removeItem(`oTest-Res-${testId}`),sessionStorage?.removeItem(`oTest-Status-${testId}`)),sessionStorage?.setItem("oTest-Run",testId),autoRun?sessionStorage?.setItem("oTest-Autorun",autoRun):sessionStorage?.removeItem("oTest-Autorun");const testSession=o.tests[testId];let lastTest=testSession.tests.pop();typeof lastTest!="function"&&(testSession.tests.push(lastTest),lastTest=()=>{}),testSession.tests.push(testN2=>{lastTest(testN2),sessionStorage.setItem("dddd",1),sessionStorage?.removeItem("oTest-Run"),autoRun&&o.runTest(testId+1,autoRun)}),o.test(testSession.title,...testSession.tests)},o.tPre='<div style="font-family:monospace;text-align:left;">',o.tOk='<span style="background:#cfc;padding: 0 15px;">OK</span> ',o.tXx='<div style="background:#fcc;padding:3px;">',o.tDc="</div>",o.test=(title="",...tests)=>{o.verify([[title,["notEmptyString"]],[tests,["array"]]]);const testSession=sessionStorage?.getItem("oTest-Run"),testN2=testSession||o.tLog.length;let waits=0,preOk="\u251C OK: ",preXx="\u251C \u2718 ",posOk=`
|
|
7
|
+
`,posXx=`
|
|
8
|
+
`,row="",num=tests.length,done=0;const log=(line="",error=!1,log2=!1)=>{o.tAutolog&&(error?console.error(line):(o.tShowOk||log2)&&console.log(line))};let opts={};if(typeof tests[num-1]=="function"&&(o.tFns[testN2]=tests[num-1],num--),num>0&&typeof tests[num-1]=="object"&&!Array.isArray(tests[num-1])&&(tests[num-1].sync!==void 0||tests[num-1].confirmOnFailure!==void 0)&&(opts=tests[num-1],num--),testSession){o.tLog[testN2]=sessionStorage.getItem(`oTest-Log-${testN2}`)||"",o.tRes[testN2]=sessionStorage.getItem(`oTest-Res-${testN2}`)||!1,o.tStatus[testN2]=JSON.parse(sessionStorage.getItem(`oTest-Status-${testN2}`)||"[]");for(let i=0;i<o.tStatus[testN2].length;i++){const s=o.tStatus[testN2][i];(s===!0||s===!1)&&done++}}o.tStyled&&(preOk=o.tPre+o.tOk,preXx=o.tPre+o.tXx,posOk=o.tDc,posXx=posOk+posOk),(!testSession||o.tLog[testN2].length===0)&&(log("\u2552 "+title+" #"+testN2,!1,!0),o.tStyled?o.tLog[testN2]="<div><b>"+title+" #"+testN2+"</b></div>":o.tLog[testN2]="\u2552 "+title+" #"+testN2+`
|
|
9
|
+
`,o.tRes[testN2]=o.F,o.tStatus[testN2]=[]),o.tExpectedSteps[testN2]=num,o.tFinalized[testN2]=!1;const showConfirmOnFailureOverlay=(stepIdx,msg)=>new Promise(resolve=>{const box=o.overlay({innerHTML:`<div style="display:flex;flex-direction:column;gap:8px;"><div style="cursor:grab;">Step ${stepIdx+1} failed: ${msg||"error"}. Continue testing?</div><div style="display:flex;gap:8px;"><button class="o-cf-continue" style="padding:6px 12px;background:#2563eb;color:#fff;border:none;border-radius:6px;cursor:pointer;">Continue</button><button class="o-cf-stop" style="padding:6px 12px;background:#dc2626;color:#fff;border:none;border-radius:6px;cursor:pointer;">Stop</button></div></div>`,timeout:opts.confirmOnFailureTimeout||void 0,onClose:r=>resolve(r||{continue:!1}),excludeDragSelector:".o-cf-continue, .o-cf-stop"});box.first(".o-cf-continue").on("click",()=>{box._overlayCleanup(),resolve({continue:!0})}),box.first(".o-cf-stop").on("click",()=>{box._overlayCleanup(),resolve({continue:!1})})}),finalize=()=>{if(o.tFinalized[testN2])return;if(waits>0){row="\u251C ",row+="DONE "+done+"/"+num+", waiting: "+waits,log(row,!0),o.tStyled?o.tLog[testN2]+=o.tPre+'<div style="color:orange;"><b>DONE '+done+"/"+num+", waiting: "+waits+"</b>"+o.tDc+o.tDc:o.tLog[testN2]+=row+`
|
|
10
|
+
`;return}o.tFinalized[testN2]=!0;const anyFailed=o.tStatus[testN2].some(s=>s===!1);o.tRes[testN2]=!anyFailed&&done===num,row="\u2558 ",row+="DONE "+done+"/"+num,log(row,done!==num),log(),o.tStyled?o.tLog[testN2]+=o.tPre+'<div style="color:'+(done!==num?"red":"green")+';"><b>DONE '+done+"/"+num+"</b>"+o.tDc+o.tDc:o.tLog[testN2]+=row+`
|
|
11
|
+
`,testSession&&(sessionStorage.setItem(`oTest-Log-${testN2}`,o.tLog[testN2]),sessionStorage.setItem(`oTest-Res-${testN2}`,o.tRes[testN2]),sessionStorage.setItem(`oTest-Status-${testN2}`,JSON.stringify(o.tStatus[testN2]))),typeof o.tFns[testN2]=="function"&&o.tFns[testN2](testN2)};if(opts.sync||opts.confirmOnFailure)return(async()=>{for(let i=o.tStatus[testN2].length;i<num;i++){const testInfo={n:testN2,i,title:tests[i][0],tShowOk:o.tShowOk,tStyled:o.tStyled};let res=tests[i][1];if(typeof res>"u"){o.tStyled?o.tLog[testN2]+="<div>"+testInfo.title+"</div>":o.tLog[testN2]+=testInfo.title+`
|
|
12
|
+
`,log("\u251C "+testInfo.title,!1,!0),o.tStatus[testN2][i]=!0,done++;continue}if(typeof o.tBeforeEach=="function"&&o.tBeforeEach(testInfo),typeof res=="function")try{res=res(testInfo)}catch(error){res=error.message,o.onError&&o.onError(error)}if(typeof o.tAfterEach=="function"&&o.tAfterEach(testInfo,res),res&&typeof res.then=="function"){try{const value=await res,ok=value===!0||value==null||value&&typeof value=="object"&&value.ok===!0,msg=value&&value.errors&&value.errors.length?value.errors.join("; "):typeof value=="string"?value:"";if(o.testUpdate(testInfo,ok,ok?"":msg?": "+msg:""),done++,!ok&&opts.confirmOnFailure&&!(await showConfirmOnFailureOverlay(i,msg)).continue)break}catch(err){if(o.testUpdate(testInfo,!1,err.message||"Promise rejected"),opts.confirmOnFailure&&!(await showConfirmOnFailureOverlay(i,err.message||"Promise rejected")).continue)break}continue}if(typeof o.tStatus[testN2][i]>"u")o.tStatus[testN2][i]=typeof res=="string"?o.F:res;else{sessionStorage.setItem(`oTest-Status-${testN2}`,JSON.stringify(o.tStatus[testN2]));return}if(res===!0)done++,o.tShowOk&&(o.tLog[testN2]+=preOk+tests[i][0]+posOk,log("\u251C OK: "+tests[i][0]));else if(res!==o.U){if(o.tLog[testN2]+=preXx+tests[i][0]+(res!==o.F?": "+res:"")+posXx,log("\u251C \u2718 "+tests[i][0]+(res!==o.F?": "+res:""),!0),opts.confirmOnFailure&&!(await showConfirmOnFailureOverlay(i,typeof res=="string"?res:"")).continue)break}else{waits++,setTimeout(info=>{info.title+=" (timeout)",o.testUpdate(info)},o.tTime,testInfo);return}}finalize()})(),testN2;for(let i=o.tStatus[testN2].length;i<num;i++){const testInfo={n:testN2,i,title:tests[i][0],tShowOk:o.tShowOk,tStyled:o.tStyled};let res=tests[i][1];if(typeof res>"u"){o.tStyled?o.tLog[testN2]+="<div>"+testInfo.title+"</div>":o.tLog[testN2]+=testInfo.title+`
|
|
13
|
+
`,log("\u251C "+testInfo.title,!1,!0),o.tStatus[testN2][i]=!0,done++;continue}if(typeof o.tBeforeEach=="function"&&o.tBeforeEach(testInfo),typeof res=="function")try{res=res(testInfo)}catch(error){res=error.message,o.onError&&o.onError(error)}if(typeof o.tAfterEach=="function"&&o.tAfterEach(testInfo,res),res&&typeof res.then=="function"){waits++;const timeoutId=setTimeout(()=>{testInfo.title+=" (timeout)",o.testUpdate(testInfo)},o.tTime);res.then(value=>{clearTimeout(timeoutId);const ok=value===!0||value&&value.ok===!0,msg=value&&value.errors&&value.errors.length?value.errors.join("; "):typeof value=="string"?value:"";o.testUpdate(testInfo,ok,ok?"":msg?": "+msg:"")}).catch(err=>{clearTimeout(timeoutId),o.testUpdate(testInfo,!1,err.message||"Promise rejected")});continue}if(typeof o.tStatus[testN2][i]>"u")o.tStatus[testN2][i]=typeof res=="string"?o.F:res;else{sessionStorage.setItem(`oTest-Status-${testN2}`,JSON.stringify(o.tStatus[testN2]));return}res===!0?(done++,o.tShowOk&&(o.tLog[testN2]+=preOk+tests[i][0]+posOk,log("\u251C OK: "+tests[i][0]))):res!==o.U?(o.tLog[testN2]+=preXx+tests[i][0]+(res!==o.F?": "+res:"")+posXx,log("\u251C \u2718 "+tests[i][0]+(res!==o.F?": "+res:""),!0)):(waits++,setTimeout(info=>{info.title+=" (timeout)",o.testUpdate(info)},o.tTime,testInfo))}return finalize(),testN2},o.testUpdate=(info,res=o.F,suff="")=>{o.verify([[info,["object"]],[res,["boolean","string"]],[suff,["string"]]]);let row="";const testN2=info.n,log=(line="",error=!1)=>{o.tAutolog&&(error?console.error(line):console.log(line))};if(o.tStatus[testN2][info.i]===o.U||o.tStatus[testN2][info.i]===null){o.tStatus[testN2][info.i]=res===!0,res===!0?info.tShowOk&&(row="\u251C OK: "+info.title+suff,log(row),info.tStyled?o.tLog[testN2]+=o.tPre+o.tOk+info.title+suff+o.tDc:o.tLog[testN2]+=row+`
|
|
14
|
+
`):(o.tRes[testN2]=o.F,row="\u251C \u2718 "+info.title+(res?": "+res:"")+suff,log(row,!0),info.tStyled?o.tLog[testN2]+=o.tPre+o.tXx+info.title+suff+(res?": "+res:"")+o.tDc+o.tDc:o.tLog[testN2]+=row+`
|
|
15
|
+
`);let fails=0,n=0;for(const s of o.tStatus[testN2]){if(s===o.U||s===null)return;s||fails++,n++}const expectedSteps=o.tests[testN2]?.tests?.length??o.tExpectedSteps[testN2]??Number.MAX_SAFE_INTEGER;if(n<expectedSteps){sessionStorage?.getItem("oTest-Run")===testN2&&(sessionStorage.setItem(`oTest-Log-${testN2}`,o.tLog[testN2]),sessionStorage.setItem(`oTest-Res-${testN2}`,o.tRes[testN2]),sessionStorage.setItem(`oTest-Status-${testN2}`,JSON.stringify(o.tStatus[testN2])));return}if(o.tFinalized[testN2])return;o.tFinalized[testN2]=!0,sessionStorage?.getItem("oTest-Run")===testN2&&(sessionStorage.setItem(`oTest-Log-${testN2}`,o.tLog[testN2]),sessionStorage.setItem(`oTest-Res-${testN2}`,o.tRes[testN2]),sessionStorage.setItem(`oTest-Status-${testN2}`,JSON.stringify(o.tStatus[testN2]))),o.tRes[testN2]=!fails,row=fails?"FAILED "+fails+"/"+n:"DONE "+n+"/"+n,log("\u2558 "+row,!!fails),log(),info.tStyled?o.tLog[testN2]+=o.tPre+'<b style="color:'+(fails?"red":"green")+';">'+row+"</b>"+o.tDc:o.tLog[testN2]+="\u2558 "+row+`
|
|
16
|
+
`,typeof o.tFns[testN2]=="function"&&o.tFns[testN2](testN2)}},sessionStorage?.getItem("oTest-Run")&&window?.addEventListener("load",()=>{o.runTest(sessionStorage?.getItem("oTest-Run"),sessionStorage?.getItem("oTest-Autorun")||o.F,!0)},!1),o.measure=el=>{if(!el)return{};const rect=el.getBoundingClientRect(),style=window.getComputedStyle(el);return{width:rect.width,height:rect.height,top:rect.top,left:rect.left,visible:style.display!=="none"&&style.visibility!=="hidden"&&rect.width>0,opacity:style.opacity,zIndex:style.zIndex}},o.assertVisible=el=>!!o.measure(el).visible,o.assertSize=(el,expected={})=>{if(!el)return"element is null";const m=o.measure(el);if(expected.w!==void 0&&Math.round(m.width)!==expected.w)return`width: expected ${expected.w}, got ${Math.round(m.width)}`;if(expected.h!==void 0&&Math.round(m.height)!==expected.h)return`height: expected ${expected.h}, got ${Math.round(m.height)}`;const getPx=prop=>{const v=window.getComputedStyle(el).getPropertyValue(prop);return v?parseFloat(v):0};return expected.padding!==void 0&&getPx("padding-top")!==expected.padding?`padding: expected ${expected.padding}, got ${getPx("padding-top")}`:expected.paddingTop!==void 0&&getPx("padding-top")!==expected.paddingTop?`paddingTop: expected ${expected.paddingTop}, got ${getPx("padding-top")}`:expected.paddingRight!==void 0&&getPx("padding-right")!==expected.paddingRight?`paddingRight: expected ${expected.paddingRight}, got ${getPx("padding-right")}`:expected.paddingBottom!==void 0&&getPx("padding-bottom")!==expected.paddingBottom?`paddingBottom: expected ${expected.paddingBottom}, got ${getPx("padding-bottom")}`:expected.paddingLeft!==void 0&&getPx("padding-left")!==expected.paddingLeft?`paddingLeft: expected ${expected.paddingLeft}, got ${getPx("padding-left")}`:expected.margin!==void 0&&getPx("margin-top")!==expected.margin?`margin: expected ${expected.margin}, got ${getPx("margin-top")}`:expected.marginTop!==void 0&&getPx("margin-top")!==expected.marginTop?`marginTop: expected ${expected.marginTop}, got ${getPx("margin-top")}`:expected.marginRight!==void 0&&getPx("margin-right")!==expected.marginRight?`marginRight: expected ${expected.marginRight}, got ${getPx("margin-right")}`:expected.marginBottom!==void 0&&getPx("margin-bottom")!==expected.marginBottom?`marginBottom: expected ${expected.marginBottom}, got ${getPx("margin-bottom")}`:expected.marginLeft!==void 0&&getPx("margin-left")!==expected.marginLeft?`marginLeft: expected ${expected.marginLeft}, got ${getPx("margin-left")}`:!0},o.recorder={active:!1,actions:[],mocks:{},initialData:{},assertions:[],observeRoot:null,strictCapture:null,_originalFetch:null,_listeners:[],_observer:null},o.recordingAssertionDebug=!1,o.startRecording=(observe,events,timeouts)=>{if(o.recorder.active)return;let observeSel,eventsOpt,timeoutsOpt,strictCapture=null;if(observe!=null&&typeof observe=="object"&&!Array.isArray(observe)&&(o.C(observe,"observe")||o.C(observe,"events")||o.C(observe,"timeouts")||o.C(observe,"strictCaptureAssertions")||o.C(observe,"strictCaptureNetwork")||o.C(observe,"strictCaptureWebSocket"))){const bag=observe;observeSel=bag.observe!=null?String(bag.observe):void 0,eventsOpt=bag.events,timeoutsOpt=bag.timeouts,(o.C(bag,"strictCaptureAssertions")||o.C(bag,"strictCaptureNetwork")||o.C(bag,"strictCaptureWebSocket"))&&(strictCapture={assertions:!!bag.strictCaptureAssertions,network:!!bag.strictCaptureNetwork,websocket:!!bag.strictCaptureWebSocket})}else observeSel=typeof observe=="string"?observe:void 0,eventsOpt=events,timeoutsOpt=timeouts;const defaultEvents=["click","mouseover","scroll","input","change","submit","keydown","focus","blur"],defaultStepDelays={click:100,mouseover:50,scroll:30,input:50,change:50,submit:100,keydown:50,focus:50,blur:50},listenEvents=eventsOpt||defaultEvents,stepDelays=Object.assign({},defaultStepDelays,timeoutsOpt||{}),captureDebounce={scroll:30,mouseover:50,keydown:50,focus:50,blur:50},rec=o.recorder;rec.active=!0,rec.actions=[],rec.mocks={},rec.stepDelays=stepDelays,rec.initialData={url:window.location.href,timestamp:Date.now()},rec.strictCapture=strictCapture,rec.observeRoot=observeSel||null,rec.assertions=[],rec.removedElements=[],o.inits.forEach((inst,idx)=>{inst?.store&&(rec.initialData["init_"+idx]=JSON.parse(JSON.stringify(inst.store)))}),rec._originalFetch=window.fetch,window.fetch=async(url,opts={})=>{const method=(opts.method||"GET").toUpperCase();let reqBody;try{reqBody=opts.body?JSON.parse(opts.body):void 0}catch{reqBody=opts.body}const response=await rec._originalFetch(url,opts),clone=response.clone();let respBody;try{respBody=await clone.json()}catch{respBody=await clone.text().catch(()=>null)}const key=method+":"+url;return rec.mocks[key]={url,method,request:reqBody,response:respBody,status:response.status},response},rec._originalXHROpen=XMLHttpRequest.prototype.open,rec._originalXHRSend=XMLHttpRequest.prototype.send,XMLHttpRequest.prototype.open=function(method,url){return this._oMethod=(method||"GET").toUpperCase(),this._oUrl=url,rec._originalXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(body){const capture=()=>{if(this.readyState!==4)return;let reqBody;try{reqBody=body?JSON.parse(body):void 0}catch{reqBody=body}let respBody;try{const text=this.responseText;respBody=text?JSON.parse(text):null}catch{respBody=this.responseText??null}const key=(this._oMethod||"GET")+":"+(this._oUrl||"");rec.mocks[key]={url:this._oUrl,method:this._oMethod,request:reqBody,response:respBody,status:this.status}};return this.addEventListener("readystatechange",capture),rec._originalXHRSend.apply(this,arguments)},rec.websocketEvents=[],rec._originalWebSocket=window.WebSocket,window.WebSocket=function(url,protocols){const ws=new rec._originalWebSocket(url,protocols),id=rec.websocketEvents.length;rec.websocketEvents.push({url:typeof url=="string"?url:String(url),protocol:Array.isArray(protocols)?protocols[0]:protocols,open:!0,messages:[]}),ws.addEventListener("message",e=>{const data=typeof e.data=="string"?e.data:String(e.data);rec.websocketEvents[id].messages.push({dir:"in",data})}),ws.addEventListener("close",()=>{rec.websocketEvents[id].open=!1});const origSend=ws.send.bind(ws);return ws.send=function(data){const d=typeof data=="string"?data:String(data);return rec.websocketEvents[id].messages.push({dir:"out",data:d}),origSend(data)},ws};const unstableDataAttrs={"data-o-init":1,"data-o-init-i":1,"data-o-state":1},qualify=(sel,fromNode)=>{if(o.D.querySelectorAll(sel).length<=1)return sel;let node=fromNode;for(;node&&node!==o.D.body;){let ancestorSel=node.id?"#"+node.id:null;if(!ancestorSel&&node.attributes){const autotagAttr=o.autotag?"data-"+o.autotag:null;if(autotagAttr){const val=node.getAttribute(autotagAttr);val!=null&&(ancestorSel=`[${autotagAttr}="${val}"]`)}if(!ancestorSel){for(const attr of node.attributes)if(attr.name.startsWith("data-")&&!unstableDataAttrs[attr.name]){ancestorSel=`[${attr.name}="${attr.value}"]`;break}}}if(ancestorSel){const q=ancestorSel+" "+sel;if(o.D.querySelectorAll(q).length===1)return q}node=node.parentElement}return sel},buildSelector=node=>{if(!node||node.nodeType!==1)return"";let sel="";if(node.dataset){const qaKey=o.autotag&&node.dataset[o.autotag];qaKey&&(sel=qualify(`[data-${o.autotag}="${qaKey}"]`,node.parentElement))}if(!sel&&node.tagName){const base=node.id?"#"+node.id:node.className?node.tagName.toLowerCase()+"."+[...node.classList].join("."):node.tagName.toLowerCase();sel=node.id?base:qualify(base,node.parentElement)}return sel},observeTarget=observeSel&&o.D.querySelector(observeSel)||o.D.body;rec._observer=new MutationObserver(mutations=>{const actionIdx=rec.actions.length-1;if(actionIdx<0)return;const lastAction=rec.actions[actionIdx];o.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[recording] MutationObserver batch:",{actionIdx,lastAction:lastAction?{type:lastAction.type,target:lastAction.target}:null,mutationTypes:mutations.map(x=>x.type),addedCount:mutations.reduce((n,x)=>n+(x.addedNodes?.length||0),0),removedCount:mutations.reduce((n,x)=>n+(x.removedNodes?.length||0),0)}),mutations.forEach(m=>{const addAssertionIndex=(sel,node)=>{let listSelector,index;if(sel&&observeTarget){const matches=observeTarget.querySelectorAll(sel);if(matches.length>1){const idxAmong=[...matches].indexOf(node);if(idxAmong!==-1)listSelector=sel,index=idxAmong;else{let n=node;for(;n&&n!==observeTarget&&n.nodeType===1;){const qaAttr=o.autotag&&n.dataset&&n.dataset[o.autotag];if(qaAttr){const itemSel=`[data-${o.autotag}="${qaAttr}"]`,itemMatches=observeTarget.querySelectorAll(itemSel);if(itemMatches.length>1){const idx=[...itemMatches].indexOf(n);if(idx!==-1){listSelector=itemSel,index=idx;break}}}n=n.parentElement}}}}return{listSelector,index}};if(m.type==="childList"&&(m.addedNodes.forEach(node=>{if(node.nodeType!==1||!node.offsetParent)return;const sel=buildSelector(node);if(!sel||rec.assertions.some(a2=>a2.actionIdx===actionIdx&&a2.selector===sel&&a2.type==="visible"))return;const text=(node.textContent?.trim()||"").slice(0,80)||void 0,{listSelector:aListSel,index:aIdx}=addAssertionIndex(sel,node),a={actionIdx,type:"visible",selector:sel,text};aListSel!=null&&(a.listSelector=aListSel),aIdx!=null&&(a.index=aIdx),rec.assertions.push(a),o.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[recording] +visible assertion:",{actionIdx,lastAction:lastAction?.type+" "+lastAction?.target,selector:sel,text:(text||"").slice(0,40),index:aIdx,listSelector:aListSel})}),m.removedNodes.forEach(node=>{if(node.nodeType!==1)return;const sel=buildSelector(node);if(!sel)return;const text=(node.textContent?.trim()||"").slice(0,80)||void 0,parent=m.target;let index;node.previousSibling?index=Array.from(parent.children).indexOf(node.previousSibling)+1:node.nextSibling?index=Array.from(parent.children).indexOf(node.nextSibling):index=0;let listSelector;if(o.autotag&&node.dataset?.[o.autotag]){const qaVal=node.dataset[o.autotag];listSelector=`[data-${o.autotag}="${qaVal}"]`}const entry={actionIdx,type:"removed",selector:sel,text};listSelector&&(entry.listSelector=listSelector),entry.index=index,rec.removedElements.push(entry),o.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[recording] +removed element:",{actionIdx,lastAction:lastAction?.type+" "+lastAction?.target,selector:sel,text:(text||"").slice(0,40),index,listSelector})})),m.type==="attributes"){const attr=m.attributeName;if(!attr)return;const sel=buildSelector(m.target);if(!sel)return;const type={class:"class",style:"style",hidden:"hidden",disabled:"disabled","aria-expanded":"aria-expanded","aria-checked":"aria-checked"}[attr];if(!type||rec.assertions.some(a2=>a2.actionIdx===actionIdx&&a2.selector===sel&&a2.type===type))return;const{listSelector:aListSel,index:aIdx}=addAssertionIndex(sel,m.target),el=m.target;let value;type==="class"?value=el.className:type==="style"?value=el.style?.cssText||el.getAttribute("style")||"":type==="hidden"?value=el.hidden:type==="disabled"?value=el.disabled===!0:type==="aria-expanded"?value=el.getAttribute("aria-expanded"):type==="aria-checked"&&(value=el.getAttribute("aria-checked"));const a={actionIdx,type,selector:sel};type==="class"?a.className=value:type==="style"?a.style=value:type==="hidden"?a.hidden=value:type==="disabled"?a.disabled=value:type==="aria-expanded"?a.ariaExpanded=value:type==="aria-checked"&&(a.ariaChecked=value),aListSel!=null&&(a.listSelector=aListSel),aIdx!=null&&(a.index=aIdx),rec.assertions.push(a),o.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[recording] +attr assertion:",{actionIdx,lastAction:lastAction?.type+" "+lastAction?.target,selector:sel,type,value,index:aIdx,listSelector:aListSel})}})}),rec._observer.observe(observeTarget,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","hidden","disabled","aria-expanded","aria-checked"]});const timers={};listenEvents.forEach(ev=>{const handler=e=>{const target=e.target;if(observeSel&&observeTarget&&target?.nodeType===1&&!observeTarget.contains(target))return;let selector="";if(target?.dataset){const qaKey=o.autotag&&target.dataset[o.autotag];qaKey&&(selector=qualify(`[data-${o.autotag}="${qaKey}"]`,target.parentElement))}if(!selector&&target?.tagName){const base=target.id?"#"+target.id:target.className?target.tagName.toLowerCase()+"."+[...target.classList].join("."):target.tagName.toLowerCase();selector=target.id?base:qualify(base,target.parentElement)}let listSelector,targetIndex;if(selector&&observeTarget){const matches=observeTarget.querySelectorAll(selector);if(matches.length>1){const idxAmongMatches=[...matches].indexOf(target);if(idxAmongMatches!==-1)listSelector=selector,targetIndex=idxAmongMatches;else{let node=target;for(;node&&node!==observeTarget&&node.nodeType===1;){const qaAttr=o.autotag&&node.dataset&&node.dataset[o.autotag];if(qaAttr){const itemSel=`[data-${o.autotag}="${qaAttr}"]`,itemMatches=observeTarget.querySelectorAll(itemSel);if(itemMatches.length>1){const idx=[...itemMatches].indexOf(node);if(idx!==-1){listSelector=itemSel,targetIndex=idx;break}}}node=node.parentElement}}}}const targetType=target?.tagName?target.tagName.toLowerCase()+(target.type?":"+target.type:""):void 0,scrollY=ev==="scroll"?window.scrollY:void 0,value=ev==="input"||ev==="change"?target?.value:void 0,checked=ev==="change"&&(target?.type==="checkbox"||target?.type==="radio")?target?.checked:void 0,key=ev==="keydown"?target?.key:void 0,code=ev==="keydown"?target?.code:void 0,delay=ev==="click"||ev==="change"||ev==="submit"?0:stepDelays[ev]!==void 0?stepDelays[ev]:captureDebounce[ev]??0,pushAction=()=>{if((ev==="blur"||ev==="focus")&&selector){const lastIdx=rec.actions.length-1,lastAction=lastIdx>=0?rec.actions[lastIdx]:null;if(lastAction){if(lastAction.target===selector&&lastAction.listSelector==null==(listSelector==null)&&lastAction.targetIndex==null==(targetIndex==null)&&(lastAction.targetIndex==null||lastAction.targetIndex===targetIndex))return;for(const r of rec.removedElements)if(r.actionIdx===lastIdx&&(r.selector===selector||selector.startsWith(r.selector+" ")||selector.startsWith(r.selector+">")))return}}const action={type:ev,target:selector,time:Date.now()};targetType&&(action.targetType=targetType),scrollY!==void 0&&(action.scrollY=scrollY),value!==void 0&&(action.value=value),checked!==void 0&&(action.checked=checked),key!==void 0&&(action.key=key),code!==void 0&&(action.code=code),listSelector!=null&&(action.listSelector=listSelector),targetIndex!=null&&(action.targetIndex=targetIndex),rec.actions.push(action)};delay===0?pushAction():(clearTimeout(timers[ev]),timers[ev]=setTimeout(pushAction,delay))};o.D.addEventListener(ev,handler,!0),rec._listeners.push({ev,handler})})},o.stopRecording=()=>{const rec=o.recorder;rec.active=!1,rec._originalFetch&&(window.fetch=rec._originalFetch,rec._originalFetch=null),rec._originalXHROpen&&(XMLHttpRequest.prototype.open=rec._originalXHROpen,XMLHttpRequest.prototype.send=rec._originalXHRSend,rec._originalXHROpen=null,rec._originalXHRSend=null),rec._originalWebSocket&&(window.WebSocket=rec._originalWebSocket,rec._originalWebSocket=null),rec._listeners.forEach(({ev,handler})=>{o.D.removeEventListener(ev,handler,!0)}),rec._listeners=[],rec._observer&&(rec._observer.disconnect(),rec._observer=null);const out={actions:[...rec.actions],mocks:{...rec.mocks},initialData:{...rec.initialData},stepDelays:{...rec.stepDelays},assertions:[...rec.assertions||[]],removedElements:[...rec.removedElements||[]],observeRoot:rec.observeRoot||null,websocketEvents:[...rec.websocketEvents||[]]};return rec.strictCapture&&(out.strictCapture={...rec.strictCapture}),out},o.clearRecording=id=>{if(id!==void 0)sessionStorage?.removeItem("oTest-Recording-"+id);else for(let i=sessionStorage?.length-1;i>=0;i--){const key=sessionStorage?.key(i);key&&key.indexOf("oTest-Recording-")===0&&sessionStorage?.removeItem(key)}},o.runRecordingAssertions=(recording,root,actionIdx,opts)=>{const strictAssertions=!!(opts&&opts.strictAssertions),strictRemoved=opts&&opts.strictRemoved!==void 0?!!opts.strictRemoved:strictAssertions,preFiltered=opts&&opts.assertions,assertions=preFiltered??(recording.assertions||[]).filter(a=>actionIdx==null||a.actionIdx===actionIdx);o.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[runRecordingAssertions] run:",{actionIdx,scope:actionIdx==null?"teardown (all)":"per-action",assertionsCount:assertions.length,assertions:assertions.map(a=>({actionIdx:a.actionIdx,type:a.type,selector:a.selector,index:a.index,text:(a.text||"").slice(0,40)}))});const seen=new Set,deduped=assertions.filter(a=>{const key=`${a.selector}|${a.type}|${a.actionIdx}|${a.index??""}`;return seen.has(key)?!1:(seen.add(key),!0)}),r=(()=>{if(root!=null)return typeof root=="string"?o.D.querySelector(root)||o.D.body:root;const sel=recording.observeRoot;return sel&&o.D.querySelector(sel)||o.D.body})(),norm=s=>(s||"").trim().replace(/\s+/g," "),styleNorm=s=>norm(String(s||"").replace(/\s*:\s*/g,": ").replace(/\s*;\s*/g,"; ")),getText=el=>el?norm(el.textContent||""):"",removedElements=opts?.removedElements||[],isRemoved=a=>{if(!removedElements.length||actionIdx==null)return!1;const expText=norm(a.text||"");for(const r2 of removedElements)if(!(r2.actionIdx>actionIdx)&&norm(r2.text||"")===expText&&r2.selector===a.selector&&!(a.listSelector!=null&&r2.listSelector!==a.listSelector)&&!(a.index!=null&&r2.index!==a.index))return!0;return!1};let passed=0;const failures=[];for(const a of deduped){if(isRemoved(a)){if(!strictRemoved){passed+=1,o.recordingAssertionDebug&&typeof console<"u"&&console.log&&console.log("[runRecordingAssertions] skip (explicit removed):",{actionIdx:a.actionIdx,selector:a.selector,text:(a.text||"").slice(0,40)});continue}let ghost=null;const expText=norm(a.text||"");if(a.listSelector!=null&&a.index!=null){const items=r.querySelectorAll(a.listSelector);let item=items[a.index];if(!item&&a.index>0&&(item=items[a.index-1]),item&&(ghost=a.selector!==a.listSelector&&item.querySelector(a.selector)||item),!ghost&&expText&&a.type==="visible")for(let j=0;j<items.length;j++){const it=items[j],cand=a.selector!==a.listSelector&&it.querySelector(a.selector)||it;if(cand&&getText(cand).indexOf(expText)!==-1){ghost=cand;break}}}else{const matches=r.querySelectorAll(a.selector);ghost=matches.length>0?matches[0]:o.D.querySelector(a.selector)}if(ghost&&a.type==="visible"){const vis=ghost.nodeType===1&&(ghost.offsetParent!==null||ghost.getBoundingClientRect&&ghost.getBoundingClientRect().width>0),gtext=getText(ghost);if(vis&&(!expText||gtext.indexOf(expText)!==-1||expText.indexOf(gtext)!==-1)){failures.push({selector:a.selector,message:"expected absent (recorded removed) but matching content still visible"});continue}}else if(ghost&&a.type!=="visible"){failures.push({selector:a.selector,message:"expected absent (recorded removed) but element still present"});continue}passed+=1;continue}let el=null,indexOutOfBounds=!1,listItemsLength=-1;if(a.listSelector!=null&&a.index!=null){const items=r.querySelectorAll(a.listSelector);listItemsLength=items.length;const expectedText=norm(a.text||""),tryItem=idx=>{const it=items[idx];return it?(a.selector!==a.listSelector?it.querySelector(a.selector):it)||(a.selector!==a.listSelector?it:null):null};let item;if(strictAssertions)item=items[a.index],item&&(el=tryItem(a.index),!el&&a.selector!==a.listSelector&&(el=item));else if(item=items[a.index],!item&&a.index>0&&(item=items[a.index-1]),item&&(el=tryItem(a.index)||(a.index>0?tryItem(a.index-1):null),!el&&a.selector!==a.listSelector&&(el=item),a.type==="visible"&&expectedText&&el)){const actualText=getText(el);if(actualText.indexOf(expectedText)===-1&&expectedText.indexOf(actualText)===-1)for(let j=0;j<items.length;j++){const candEl=tryItem(j);if(candEl&&getText(candEl).indexOf(expectedText)!==-1){el=candEl,item=items[j];break}}}item||(indexOutOfBounds=!0)}else{const matches=r.querySelectorAll(a.selector);el=matches.length>0?matches[0]:o.D.querySelector(a.selector)}if(a.type==="visible"){const visible=el&&el.nodeType===1&&(el.offsetParent!==null||el.getBoundingClientRect&&el.getBoundingClientRect().width>0),expectedText=norm(a.text||""),actualText=getText(el),textOk=strictAssertions?!expectedText||actualText===expectedText:!expectedText||actualText.indexOf(expectedText)!==-1||expectedText.length>0&&expectedText.indexOf(actualText)!==-1;if(visible&&textOk)passed+=1;else{const listCount=listItemsLength>=0?listItemsLength:r.querySelectorAll(a.listSelector||a.selector).length,message=indexOutOfBounds?`index out of bounds (list has ${listCount} items, assertion expected index ${a.index})`:el?visible?textOk?"fail":"text mismatch":"not visible":"element not found";failures.push({selector:a.selector,message}),typeof console<"u"&&console.warn&&console.warn("[runRecordingAssertions] visible failed:",{actionIdx:a.actionIdx,selector:a.selector,listSelector:a.listSelector,index:a.index,expectedText:a.text||"(any)",actualText:actualText.slice(0,80),message})}}else if(a.type==="class"){const tokens=(a.className||"").trim().split(/\s+/).filter(Boolean),hasClass=el&&(tokens.length===0||tokens.every(c=>el.classList?.contains(c))),classOrderOk=!strictAssertions||!a.className||norm((el?.className||"").trim())===norm((a.className||"").trim());if(hasClass&&classOrderOk)passed+=1;else{const msg=indexOutOfBounds?`index out of bounds (list has ${r.querySelectorAll(a.listSelector).length} items, expected index ${a.index})`:el?hasClass&&!classOrderOk?`expected exact className "${a.className}" (strict)`:`expected class "${a.className}"`:"element not found";failures.push({selector:a.selector,message:msg}),typeof console<"u"&&console.warn&&console.warn("[runRecordingAssertions] failed:",{type:a.type,selector:a.selector,actionIdx:a.actionIdx,listSelector:a.listSelector,index:a.index,itemsInRoot:a.listSelector?r.querySelectorAll(a.listSelector).length:"-",message:msg})}}else if(a.type==="style"){const expected=(a.style||"").trim(),actual=(el?.style?.cssText||el?.getAttribute?.("style")||"").trim();if(el&&(!expected||(strictAssertions?styleNorm(actual)===styleNorm(expected):actual.indexOf(expected)!==-1||expected===actual)))passed+=1;else{const msg=el?`expected style "${expected.slice(0,60)}..."`:"element not found";failures.push({selector:a.selector,message:msg})}}else if(a.type==="hidden")if(el&&el.hidden===a.hidden)passed+=1;else{const msg=el?`expected hidden=${a.hidden}`:"element not found";failures.push({selector:a.selector,message:msg})}else if(a.type==="disabled")if(el&&el.disabled===a.disabled)passed+=1;else{const msg=el?`expected disabled=${a.disabled}`:"element not found";failures.push({selector:a.selector,message:msg})}else if(a.type==="aria-expanded"){const actual=el?.getAttribute?.("aria-expanded");if(el&&(a.ariaExpanded==null||String(actual)===String(a.ariaExpanded)))passed+=1;else{const msg=el?`expected aria-expanded="${a.ariaExpanded}"`:"element not found";failures.push({selector:a.selector,message:msg})}}else if(a.type==="aria-checked"){const actual=el?.getAttribute?.("aria-checked");if(el&&(a.ariaChecked==null||String(actual)===String(a.ariaChecked)))passed+=1;else{const msg=el?`expected aria-checked="${a.ariaChecked}"`:"element not found";failures.push({selector:a.selector,message:msg})}}}return{passed,total:deduped.length,failures}},o.exportTest=(recording,options={})=>{const delay=options.delay!==void 0?options.delay:16,extensionExport=options.extensionExport===!0,recordingData={actions:recording.actions,assertions:recording.assertions||[],observeRoot:recording.observeRoot||null},rootVar=recording.observeRoot?`(o.D.querySelector('${recording.observeRoot.replace(/'/g,"\\'")}') || o.D.body)`:"o.D.body",getEl=a=>{if(a.listSelector!=null&&a.targetIndex!=null){const listSel=JSON.stringify(a.listSelector),useItem=a.target===a.listSelector,targetSel=useItem?listSel:JSON.stringify(a.target);return` const items = o.D.querySelectorAll(${listSel});
|
|
17
|
+
const item = items[${a.targetIndex}];
|
|
18
18
|
let el = null;
|
|
19
|
-
if (item) { el = ${
|
|
20
|
-
await o.sleep(${
|
|
19
|
+
if (item) { el = ${useItem?"item":`item.querySelector(${targetSel}) || item`}; }`}return` const el = o.D.querySelector(${JSON.stringify(a.target)});`},endSuffix=delay>0?`
|
|
20
|
+
await o.sleep(${delay});
|
|
21
21
|
return true;
|
|
22
22
|
`:` return true;
|
|
23
|
-
`,
|
|
24
|
-
`:"")+(
|
|
25
|
-
`:"")+` el.dispatchEvent(new Event('${
|
|
26
|
-
`+
|
|
27
|
-
if (!el && '${
|
|
28
|
-
`+
|
|
29
|
-
const r = o.runRecordingAssertions(recordingData, ${
|
|
23
|
+
`,stepFn=delay>0?"async () =>":"() =>",steps=[];for(let i=0;i<recording.actions.length;i++){const a=recording.actions[i];let body;a.type==="scroll"?body=` window.scrollTo(0, ${a.scrollY||0});${endSuffix}`:a.type==="input"||a.type==="change"?body=(a.value!==void 0?` el.value = ${JSON.stringify(a.value)};
|
|
24
|
+
`:"")+(a.checked!==void 0?` el.checked = ${a.checked};
|
|
25
|
+
`:"")+` el.dispatchEvent(new Event('${a.type}', {bubbles:true}));${endSuffix}`:a.type==="submit"?body=` (el.requestSubmit && el.requestSubmit()) || el.submit();${endSuffix}`:a.type==="keydown"?body=` el.dispatchEvent(new KeyboardEvent('keydown', {key:${JSON.stringify(a.key||"")}, code:${JSON.stringify(a.code||"")}, bubbles:true, cancelable:true}));${endSuffix}`:a.type==="focus"?body=` el.focus();${endSuffix}`:a.type==="blur"?body=` el.blur();${endSuffix}`:body=a.type==="click"?` el.click();${endSuffix}`:` el.dispatchEvent(new MouseEvent('${a.type}', {bubbles:true,cancelable:true}));${endSuffix}`;const skipIfMissing=a.type==="blur"||a.type==="focus";steps.push(` ['${a.type} on ${a.target}', ${stepFn} {
|
|
26
|
+
`+getEl(a)+`
|
|
27
|
+
if (!el && '${a.type}' !== 'scroll') { if (${skipIfMissing}) return true; return 'element not found: ${a.target.replace(/'/g,"\\'")}'; }
|
|
28
|
+
`+body+" }]"),(recording.assertions||[]).filter(x=>x.actionIdx===i).length>0&&steps.push(` ['assert after ${a.type}', () => {
|
|
29
|
+
const r = o.runRecordingAssertions(recordingData, ${rootVar}, ${i});
|
|
30
30
|
return r.passed === r.total ? true : r.failures.map(f => f.selector + ': ' + f.message).join('; ');
|
|
31
|
-
}]`)}
|
|
32
|
-
const recordingMocks = ${Object.keys(
|
|
33
|
-
const recordingData = { actions: ${JSON.stringify(
|
|
31
|
+
}]`)}const header=`// Auto-generated by o.exportTest() \u2014 review and anonymize mocks before committing
|
|
32
|
+
const recordingMocks = ${Object.keys(recording.mocks||{}).length?JSON.stringify(recording.mocks,null,2):"{}"};
|
|
33
|
+
const recordingData = { actions: ${JSON.stringify(recording.actions)}, assertions: ${JSON.stringify(recording.assertions||[])}, observeRoot: ${JSON.stringify(recording.observeRoot||null)} };
|
|
34
34
|
|
|
35
|
-
o.
|
|
36
|
-
${
|
|
35
|
+
`,manualLine=" // Add manual checks: ['Manual: label', () => o.testConfirm('label', ['item1'])],";return extensionExport?header+`const __objsExtensionTestRun = o.test('Recorded test',
|
|
36
|
+
${steps.join(`,
|
|
37
|
+
`)},
|
|
38
|
+
${manualLine}
|
|
39
|
+
{ sync: true }, () => {
|
|
40
|
+
// teardown
|
|
41
|
+
});
|
|
42
|
+
`:header+`o.addTest('Recorded test', [
|
|
43
|
+
${steps.join(`,
|
|
37
44
|
`)}
|
|
38
|
-
|
|
45
|
+
${manualLine}
|
|
39
46
|
], () => {
|
|
40
47
|
// teardown
|
|
41
48
|
});
|
|
42
|
-
`},
|
|
43
|
-
`;return
|
|
49
|
+
`},o.exportPlaywrightTest=(recording,options={})=>{const testName=options.testName||"Recorded session",rawUrl=recording.initialData?.url??"/";let path="/";try{path=new URL(rawUrl).pathname||"/"}catch{path=rawUrl}const baseUrl=options.baseUrl||path,routes=Object.values(recording.mocks).map(mock=>{let urlPath=mock.url;try{urlPath=new URL(mock.url).pathname||urlPath}catch{}urlPath.startsWith("/")||(urlPath="/"+urlPath);const respBody=JSON.stringify(mock.response),reqBody=JSON.stringify(mock.request),method=(mock.method||"GET").toUpperCase();let verify=` if (route.request().method() !== ${JSON.stringify(method)}) { await route.continue(); return; }
|
|
50
|
+
`;return mock.request!=null&&(method==="POST"||method==="PUT"||method==="PATCH")&&(verify+=` const postData = route.request().postData();
|
|
44
51
|
const body = (() => { try { return JSON.parse(postData || '{}'); } catch { return {}; } })();
|
|
45
|
-
expect(body).toEqual(${
|
|
46
|
-
`),` await page.route('**${
|
|
47
|
-
`+
|
|
48
|
-
body: JSON.stringify(${
|
|
52
|
+
expect(body).toEqual(${reqBody});
|
|
53
|
+
`),` await page.route('**${urlPath}', async route => {
|
|
54
|
+
`+verify+` await route.fulfill({ status: ${mock.status||200}, contentType: 'application/json',
|
|
55
|
+
body: JSON.stringify(${respBody}) });
|
|
49
56
|
});`}).join(`
|
|
50
|
-
`),
|
|
57
|
+
`),sd=Object.assign({click:100,mouseover:50,scroll:30,input:50,change:50,submit:100,keydown:50,focus:50,blur:50},recording.stepDelays||{}),steps=recording.actions.map((action,i)=>{const loc=action.listSelector!=null&&action.targetIndex!=null?action.target!==action.listSelector?`page.locator(${JSON.stringify(action.listSelector)}).nth(${action.targetIndex}).locator(${JSON.stringify(action.target)})`:`page.locator(${JSON.stringify(action.listSelector)}).nth(${action.targetIndex})`:`page.locator(${JSON.stringify(action.target)})`,wait=` await page.waitForTimeout(${sd[action.type]||50});`;let step;if(action.type==="scroll")step=` await page.evaluate(() => window.scrollTo(0, ${action.scrollY||0}));`;else if(action.type==="mouseover")step=` await ${loc}.hover();
|
|
51
58
|
// Pure CSS :hover \u2014 no DOM mutation to assert.
|
|
52
|
-
// Fix: toggle a class in a mouseover handler, or add a page.screenshot() visual check.`;else if(
|
|
53
|
-
await expect(${
|
|
54
|
-
`):` // class on ${
|
|
55
|
-
`);return
|
|
56
|
-
`+
|
|
57
|
-
`+
|
|
58
|
-
`),
|
|
59
|
+
// Fix: toggle a class in a mouseover handler, or add a page.screenshot() visual check.`;else if(action.type==="input")step=` await ${loc}.fill(${JSON.stringify(action.value||"")});`;else if(action.type==="change"){const tt=action.targetType||"";if(tt.indexOf(":checkbox")!==-1||tt.indexOf(":radio")!==-1){const on=action.checked!==void 0?action.checked:action.value==="true"||action.value==="on";step=` await ${loc}.${on?"check":"uncheck"}();`}else tt.indexOf("select")!==-1?step=` await ${loc}.selectOption(${JSON.stringify(action.value||"")});`:step=` await ${loc}.fill(${JSON.stringify(action.value||"")});`}else if(action.type==="submit")step=` await ${loc}.evaluate((el) => el.requestSubmit?.() || el.submit());`;else if(action.type==="keydown"){const key=action.key||"";step=key==="Enter"?` await ${loc}.press("Enter");`:key?` await ${loc}.press(${JSON.stringify(key)});`:` await ${loc}.press(${JSON.stringify(action.code||"")});`}else action.type==="focus"?step=` if (await ${loc}.count() > 0) await ${loc}.focus();`:action.type==="blur"?step=` if (await ${loc}.count() > 0) await ${loc}.blur();`:step=` await ${loc}.click();`;const asserts=(recording.assertions||[]).filter(a=>a.actionIdx===i).filter((a,j,arr)=>arr.findIndex(x=>x.selector===a.selector&&x.type===a.type&&x.index===a.index)===j).map(a=>{const aLoc=a.listSelector!=null&&a.index!=null?a.selector!==a.listSelector?`page.locator(${JSON.stringify(a.listSelector)}).nth(${a.index}).locator(${JSON.stringify(a.selector)})`:`page.locator(${JSON.stringify(a.listSelector)}).nth(${a.index})`:`page.locator(${JSON.stringify(a.selector)})`;if(a.type==="visible"){let s=` await expect(${aLoc}).toBeVisible();`;return a.text&&(s+=`
|
|
60
|
+
await expect(${aLoc}).toContainText(${JSON.stringify(a.text)});`),s}if(a.type==="class"){const classes=(a.className||"").trim().split(/\s+/).filter(Boolean);return classes.length>0?classes.map(c=>` await expect(${aLoc}).toHaveClass(${JSON.stringify(c)});`).join(`
|
|
61
|
+
`):` // class on ${a.selector} (no specific classes asserted)`}if(a.type==="style"){const style=(a.style||"").trim();if(style){const m=style.match(/(\w+)\s*:\s*([^;]+)/);return m?` await expect(${aLoc}).toHaveCSS(${JSON.stringify(m[1])}, ${JSON.stringify(m[2].trim())});`:` await expect(${aLoc}).toHaveAttribute("style", ${JSON.stringify(style)});`}return""}return a.type==="hidden"?a.hidden?` await expect(${aLoc}).toBeHidden();`:` await expect(${aLoc}).toBeVisible();`:a.type==="disabled"?a.disabled?` await expect(${aLoc}).toBeDisabled();`:` await expect(${aLoc}).toBeEnabled();`:a.type==="aria-expanded"&&a.ariaExpanded!=null?` await expect(${aLoc}).toHaveAttribute("aria-expanded", ${JSON.stringify(String(a.ariaExpanded))});`:a.type==="aria-checked"&&a.ariaChecked!=null?` await expect(${aLoc}).toHaveAttribute("aria-checked", ${JSON.stringify(String(a.ariaChecked))});`:""}).filter(Boolean).join(`
|
|
62
|
+
`);return step+`
|
|
63
|
+
`+wait+(asserts?`
|
|
64
|
+
`+asserts:"")}).join(`
|
|
65
|
+
`),hasAutoAssertions=(recording.assertions||[]).length>0,wsEvents=recording.websocketEvents||[],hasWsEvents=wsEvents.length>0&&wsEvents.some(c=>c.messages?.length>0),wsSetup=hasWsEvents?` const wsCollected = [];
|
|
59
66
|
page.on('websocket', ws => {
|
|
60
67
|
ws.on('framereceived', ev => wsCollected.push({ dir: 'in', payload: typeof ev.payload === 'string' ? ev.payload : String(ev.payload) }));
|
|
61
68
|
ws.on('framesent', ev => wsCollected.push({ dir: 'out', payload: typeof ev.payload === 'string' ? ev.payload : String(ev.payload) }));
|
|
62
69
|
});
|
|
63
70
|
|
|
64
|
-
`:"",
|
|
71
|
+
`:"",wsAssertions=hasWsEvents?wsEvents.flatMap(conn=>(conn.messages||[]).map(msg=>({dir:msg.dir,data:msg.data}))).map(msg=>` expect(wsCollected).toContainEqual({ dir: ${JSON.stringify(msg.dir)}, payload: ${JSON.stringify(msg.data)} });`).join(`
|
|
65
72
|
`)+`
|
|
66
73
|
|
|
67
74
|
`:"";return`// Auto-generated by o.exportPlaywrightTest() \u2014 review and anonymize mocks before committing
|
|
@@ -69,24 +76,26 @@ ${m.join(`,
|
|
|
69
76
|
// Run: npx playwright test recorded.spec.ts
|
|
70
77
|
import { test, expect } from '@playwright/test';
|
|
71
78
|
|
|
72
|
-
test(${JSON.stringify(
|
|
73
|
-
`+(
|
|
74
|
-
`+
|
|
79
|
+
test(${JSON.stringify(testName)}, async ({ page }) => {
|
|
80
|
+
`+(routes?` // Network mocks \u2014 edit/anonymize before committing
|
|
81
|
+
`+routes+`
|
|
75
82
|
|
|
76
|
-
`:"")+
|
|
77
|
-
await page.goto(${JSON.stringify(
|
|
83
|
+
`:"")+wsSetup+` // Set baseURL in playwright.config.ts: { use: { baseURL: 'https://staging.example.com' } }
|
|
84
|
+
await page.goto(${JSON.stringify(baseUrl)});
|
|
78
85
|
|
|
79
|
-
`+(
|
|
86
|
+
`+(steps?steps+`
|
|
80
87
|
|
|
81
|
-
`:"")+(
|
|
82
|
-
`+
|
|
88
|
+
`:"")+(wsAssertions?` // WebSocket verifications
|
|
89
|
+
`+wsAssertions:"")+(!hasAutoAssertions&&!hasWsEvents?` // TODO: Add assertions before committing, e.g.:
|
|
83
90
|
// await expect(page.locator('[data-qa="success-panel"]')).toBeVisible();
|
|
84
91
|
// await expect(page).toHaveURL(/\\/confirmation/);
|
|
85
92
|
// await expect(page.locator('[data-qa="error-banner"]')).not.toBeVisible();
|
|
86
|
-
`:
|
|
93
|
+
`:hasAutoAssertions||hasWsEvents?` // Auto-generated assertions above \u2014 review for correctness before committing
|
|
87
94
|
`:"")+`});
|
|
88
|
-
`},t.playRecording=(n,e={})=>{const i=e&&typeof e=="object"&&(e.runAssertions!==void 0||e.root!==void 0||e.manualChecks!==void 0||e.actionDelay!==void 0),r=i?e.mockOverrides||{}:e,p=i&&e.runAssertions,L=i?e.root:void 0,g=i&&e.manualChecks||[],k=i&&e.actionDelay!==void 0?e.actionDelay:16,m=Object.assign({},n.mocks,r),R=window.fetch;window.fetch=($,S={})=>{const y=(S.method||"GET").toUpperCase()+":"+$;if(m[y]){const N=m[y],q=typeof N.response=="string"?N.response:JSON.stringify(N.response);return Promise.resolve(new Response(q,{status:N.status||200}))}return R($,S)};const b=XMLHttpRequest.prototype.open,h=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function($,S){return this._oMethod=($||"GET").toUpperCase(),this._oUrl=S,b.apply(this,arguments)},XMLHttpRequest.prototype.send=function($){const S=this,A=(S._oMethod||"GET")+":"+(S._oUrl||""),y=m[A];if(y){const N=typeof y.response=="string"?y.response:JSON.stringify(y.response);setTimeout(()=>{S.readyState=4,S.status=y.status||200,S.statusText="OK",S.responseText=N,S.response=N,S.dispatchEvent(new Event("readystatechange")),S.dispatchEvent(new Event("load"))},0);return}return h.apply(this,arguments)};const v=()=>{if(L!=null)return typeof L=="string"?t.D.querySelector(L)||t.D.body:L;const $=n.observeRoot;return $&&t.D.querySelector($)||t.D.body},I=p?v():null,l=L!=null?v():t.D,T=n.actions,o=n.assertions||[],c={};for(const $ of o){const S=$.actionIdx;c[S]||(c[S]=[]),c[S].push($)}if(t.recordingAssertionDebug&&p&&typeof console<"u"&&console.log){const $=T.map((S,A)=>({i:A,action:S.type+" "+(S.target||""),assertions:(c[A]||[]).length,assertionDetails:(c[A]||[]).map(y=>({type:y.type,index:y.index,text:(y.text||"").slice(0,30)}))}));console.log("[playRecording] assertions by action:",$)}const f={};for(const $ of g){const S=$.afterAction;f[S]||(f[S]=[]),f[S].push($)}const a=[];let u={passed:0,total:0,failures:[]};for(let $=0;$<T.length;$++){const S=T[$];a.push([`${S.type} on ${S.target}`,async()=>{let y=null;const N=l;if(S.target)if(S.listSelector!=null&&S.targetIndex!=null){const j=N.querySelectorAll(S.listSelector)[S.targetIndex];j&&(y=S.target!==S.listSelector?j.querySelector(S.target):j,!y&&S.target!==S.listSelector&&(y=j))}else y=N.querySelector(S.target);return!y&&S.type!=="scroll"?S.type==="blur"||S.type==="focus"?!0:`element not found: ${S.target}`:(S.type==="scroll"?window.scrollTo(0,S.scrollY||0):S.type==="input"||S.type==="change"?(S.value!==void 0&&(y.value=S.value),S.checked!==void 0&&(y.checked=S.checked),y.dispatchEvent(new Event(S.type,{bubbles:!0}))):S.type==="submit"?typeof y.requestSubmit=="function"?y.requestSubmit():y.submit():S.type==="keydown"?y.dispatchEvent(new KeyboardEvent("keydown",{key:S.key||"",code:S.code||"",bubbles:!0,cancelable:!0})):S.type==="focus"?y.focus():S.type==="blur"?y.blur():S.type==="click"?y.click():y.dispatchEvent(new MouseEvent(S.type,{bubbles:!0,cancelable:!0})),k>0&&await t.sleep(k),!0)}]);const A=c[$];p&&A&&A.length>0&&a.push([`assert after ${S.type}`,()=>new Promise(y=>{const N=()=>{const q=t.runRecordingAssertions(n,I,$,{assertions:A,removedElements:n.removedElements});u.passed+=q.passed,u.total+=q.total,u.failures.push(...q.failures),y(q.passed===q.total?!0:q.failures.map(j=>j.selector+": "+j.message).join("; "))};requestAnimationFrame(()=>requestAnimationFrame(N))})]);for(const y of f[$]||[])a.push([`Manual: ${y.label}`,()=>typeof t.testConfirm=="function"?t.testConfirm(y.label,y.items||[]):{ok:!0}])}for(const $ of f.end||[])a.push([`Manual: ${$.label}`,()=>typeof t.testConfirm=="function"?t.testConfirm($.label,$.items||[]):{ok:!0}]);const D=i&&e.onComplete,w=t.test("Recorded playback",...a,{sync:!0},$=>{window.fetch=R,XMLHttpRequest.prototype.open=b,XMLHttpRequest.prototype.send=h;const S=p&&o.length>0?u:void 0;if(S?.failures?.length>0){t.tRes[$]=!1;const A=S.failures.map(N=>`${N.selector}: ${N.message}`).join("; "),y=t.tStyled?t.tPre+t.tXx+"Assertions failed: "+A+t.tDc:`
|
|
89
|
-
\u2718 Assertions failed: `+
|
|
95
|
+
`},o.playRecording=(recording,opts={})=>{const isOptions=opts&&typeof opts=="object"&&(opts.runAssertions!==void 0||opts.root!==void 0||opts.manualChecks!==void 0||opts.actionDelay!==void 0||opts.skipWebSocketMock!==void 0||opts.skipNetworkMocks!==void 0||opts.recordingAssertionDebug!==void 0||opts.strictPlay!==void 0||opts.strictAssertions!==void 0||opts.strictNetwork!==void 0||opts.strictWebSocket!==void 0||opts.strictRemoved!==void 0||opts.onComplete!==void 0),mockOverrides=isOptions?opts.mockOverrides||{}:opts,runAssertions=isOptions&&opts.runAssertions,rootOpt=isOptions?opts.root:void 0,manualChecks=isOptions&&opts.manualChecks||[],actionDelay=isOptions&&opts.actionDelay!==void 0?opts.actionDelay:16,skipWebSocketMock=isOptions&&opts.skipWebSocketMock,skipNetworkMocks=isOptions&&opts.skipNetworkMocks;isOptions&&opts.recordingAssertionDebug!==void 0&&(o.recordingAssertionDebug=!!opts.recordingAssertionDebug);const sc=recording.strictCapture||{},strictPlay=isOptions&&opts.strictPlay===!0,strictAssertions=isOptions&&opts.strictAssertions!==void 0?!!opts.strictAssertions:strictPlay?!0:!!sc.assertions,strictNetwork=isOptions&&opts.strictNetwork!==void 0?!!opts.strictNetwork:strictPlay?!0:!!sc.network,strictWebSocket=isOptions&&opts.strictWebSocket!==void 0?!!opts.strictWebSocket:strictPlay?!0:!!sc.websocket,strictRemoved=isOptions&&opts.strictRemoved!==void 0?!!opts.strictRemoved:strictAssertions,parseBodyLikeRecorder=body=>{if(!(body==null||body==="")){if(typeof body=="string")try{return JSON.parse(body)}catch{return body}return body}},mockRequestMatchesLive=(recordedReq,liveBody)=>{const live=parseBodyLikeRecorder(liveBody);return recordedReq===live||recordedReq==null&&live==null?!0:recordedReq==null||live==null?!1:typeof recordedReq=="object"&&typeof live=="object"?JSON.stringify(recordedReq)===JSON.stringify(live):String(recordedReq)===String(live)},normWsData=s=>String(s||"").trim().replace(/\s+/g," "),allMocks=Object.assign({},recording.mocks,mockOverrides),origFetch=window.fetch,origXHROpen=XMLHttpRequest.prototype.open,origXHRSend=XMLHttpRequest.prototype.send;skipNetworkMocks||(window.fetch=(url,fetchOpts={})=>{const key=(fetchOpts.method||"GET").toUpperCase()+":"+url;if(allMocks[key]){const mock=allMocks[key];if(strictNetwork&&o.C(mock,"request")&&!mockRequestMatchesLive(mock.request,fetchOpts.body))return Promise.reject(new Error("[Objs playRecording] strictNetwork: request body does not match recording for "+key));const body=typeof mock.response=="string"?mock.response:JSON.stringify(mock.response);return Promise.resolve(new Response(body,{status:mock.status||200}))}return origFetch(url,fetchOpts)},XMLHttpRequest.prototype.open=function(method,url){return this._oMethod=(method||"GET").toUpperCase(),this._oUrl=url,origXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(body){const xhr=this,key=(xhr._oMethod||"GET")+":"+(xhr._oUrl||""),mock=allMocks[key];if(mock){if(strictNetwork&&o.C(mock,"request")&&!mockRequestMatchesLive(mock.request,body)){setTimeout(()=>{xhr.readyState=4,xhr.status=0,xhr.statusText="Objs strictNetwork mismatch",xhr.dispatchEvent(new Event("readystatechange")),xhr.dispatchEvent(new Event("error"))},0);return}const respBody=typeof mock.response=="string"?mock.response:JSON.stringify(mock.response);setTimeout(()=>{xhr.readyState=4,xhr.status=mock.status||200,xhr.statusText="OK",xhr.responseText=respBody,xhr.response=respBody,xhr.dispatchEvent(new Event("readystatechange")),xhr.dispatchEvent(new Event("load"))},0);return}return origXHRSend.apply(this,arguments)});let origWebSocket=null;const wsEvents=recording.websocketEvents||[];if(!skipWebSocketMock&&wsEvents.length>0&&wsEvents.some(e=>e.messages&&e.messages.length>0)&&typeof window.WebSocket=="function"){origWebSocket=window.WebSocket;let wsConsumeIdx=0;const normalizeWsUrl=u=>{const s=typeof u=="string"?u:String(u);try{return new URL(s,window.location.href).href}catch{return s}},takeNextRecorded=urlStr=>{const norm=normalizeWsUrl(urlStr);for(let i=wsConsumeIdx;i<wsEvents.length;i++)if(normalizeWsUrl(wsEvents[i].url)===norm)return wsConsumeIdx=i+1,wsEvents[i];for(let i=wsConsumeIdx;i<wsEvents.length;i++)if(String(wsEvents[i].url)===String(urlStr))return wsConsumeIdx=i+1,wsEvents[i];return null},C=origWebSocket;class O_MockWebSocket extends EventTarget{constructor(url,protocols,recorded){super();const urlStr=typeof url=="string"?url:String(url);this.url=urlStr,this.readyState=C.CONNECTING;const p=protocols;this.protocol=Array.isArray(p)?p[0]||"":p?String(p):"",this.extensions="",this.binaryType="blob",this._messages=(recorded.messages||[]).slice(),this._pos=0;const self=this;setTimeout(()=>{self.readyState!==C.CLOSED&&(self.readyState=C.OPEN,self._dispatchOpen(),self._drainInbound())},0)}_dispatchOpen(){const ev=new Event("open");this.dispatchEvent(ev),typeof this.onopen=="function"&&this.onopen(ev)}_dispatchMessage(data){const ev=new MessageEvent("message",{data});this.dispatchEvent(ev),typeof this.onmessage=="function"&&this.onmessage(ev)}_drainInbound(){for(;this._pos<this._messages.length&&this._messages[this._pos].dir==="in";){const m=this._messages[this._pos++];this._dispatchMessage(m.data)}}send(data){if(this.readyState!==C.OPEN)throw typeof DOMException<"u"?new DOMException("Still in CONNECTING state.","InvalidStateError"):new Error("InvalidStateError");if(this._pos>=this._messages.length){if(strictWebSocket)throw new Error("[Objs playRecording] strictWebSocket: unexpected send() after recorded frames exhausted");this._drainInbound();return}const next=this._messages[this._pos];if(next.dir==="out"){if(strictWebSocket){const got=typeof data=="string"?data:String(data),exp=String(next.data!=null?next.data:"");if(normWsData(got)!==normWsData(exp))throw new Error("[Objs playRecording] strictWebSocket: outbound frame mismatch")}this._pos++}this._drainInbound()}close(code,reason){if(this.readyState===C.CLOSING||this.readyState===C.CLOSED)return;this.readyState=C.CLOSING;const self=this;setTimeout(()=>{self.readyState=C.CLOSED;const ev=typeof CloseEvent<"u"?new CloseEvent("close",{code:code!==void 0?code:1e3,reason:reason!==void 0?String(reason):"",wasClean:!0}):new Event("close");self.dispatchEvent(ev),typeof self.onclose=="function"&&self.onclose(ev)},0)}}const MockWebSocketCtor=function(url,protocols){const urlStr=typeof url=="string"?url:String(url),rec=takeNextRecorded(urlStr);return!rec||!rec.messages||rec.messages.length===0?new origWebSocket(url,protocols):new O_MockWebSocket(url,protocols,rec)};MockWebSocketCtor.CONNECTING=C.CONNECTING,MockWebSocketCtor.OPEN=C.OPEN,MockWebSocketCtor.CLOSING=C.CLOSING,MockWebSocketCtor.CLOSED=C.CLOSED,window.WebSocket=MockWebSocketCtor}const resolveRoot=()=>{if(rootOpt!=null)return typeof rootOpt=="string"?o.D.querySelector(rootOpt)||o.D.body:rootOpt;const sel=recording.observeRoot;return sel&&o.D.querySelector(sel)||o.D.body},rootEl=runAssertions?resolveRoot():null,actionScope=rootOpt!=null?resolveRoot():o.D,actions=recording.actions,assertions=recording.assertions||[],assertionsByAction={};for(const a of assertions){const k=a.actionIdx;assertionsByAction[k]||(assertionsByAction[k]=[]),assertionsByAction[k].push(a)}if(o.recordingAssertionDebug&&runAssertions&&typeof console<"u"&&console.log){const summary=actions.map((act,i)=>({i,action:act.type+" "+(act.target||""),assertions:(assertionsByAction[i]||[]).length,assertionDetails:(assertionsByAction[i]||[]).map(x=>({type:x.type,index:x.index,text:(x.text||"").slice(0,30)}))}));console.log("[playRecording] assertions by action:",summary)}const manualByAction={};for(const mc of manualChecks){const k=mc.afterAction;manualByAction[k]||(manualByAction[k]=[]),manualByAction[k].push(mc)}const testCases=[];let assertionAccum={passed:0,total:0,failures:[]};for(let i=0;i<actions.length;i++){const action=actions[i];testCases.push([`${action.type} on ${action.target}`,async()=>{let el=null;const scope=actionScope;if(action.target)if(action.listSelector!=null&&action.targetIndex!=null){const item=scope.querySelectorAll(action.listSelector)[action.targetIndex];item&&(el=action.target!==action.listSelector?item.querySelector(action.target):item,!el&&action.target!==action.listSelector&&(el=item))}else el=scope.querySelector(action.target);return!el&&action.type!=="scroll"?action.type==="blur"||action.type==="focus"?!0:`element not found: ${action.target}`:(action.type==="scroll"?window.scrollTo(0,action.scrollY||0):action.type==="input"||action.type==="change"?(action.value!==void 0&&(el.value=action.value),action.checked!==void 0&&(el.checked=action.checked),el.dispatchEvent(new Event(action.type,{bubbles:!0}))):action.type==="submit"?typeof el.requestSubmit=="function"?el.requestSubmit():el.submit():action.type==="keydown"?el.dispatchEvent(new KeyboardEvent("keydown",{key:action.key||"",code:action.code||"",bubbles:!0,cancelable:!0})):action.type==="focus"?el.focus():action.type==="blur"?el.blur():action.type==="click"?el.click():el.dispatchEvent(new MouseEvent(action.type,{bubbles:!0,cancelable:!0})),actionDelay>0&&await o.sleep(actionDelay),!0)}]);const asserted=assertionsByAction[i];runAssertions&&asserted&&asserted.length>0&&testCases.push([`assert after ${action.type}`,()=>new Promise(resolve=>{const run=()=>{const r=o.runRecordingAssertions(recording,rootEl,i,{assertions:asserted,removedElements:recording.removedElements,strictAssertions,strictRemoved});assertionAccum.passed+=r.passed,assertionAccum.total+=r.total,assertionAccum.failures.push(...r.failures),resolve(r.passed===r.total?!0:r.failures.map(f=>f.selector+": "+f.message).join("; "))};requestAnimationFrame(()=>requestAnimationFrame(run))})]);for(const mc of manualByAction[i]||[])testCases.push([`Manual: ${mc.label}`,()=>typeof o.testConfirm=="function"?o.testConfirm(mc.label,mc.items||[]):{ok:!0}])}for(const mc of manualByAction.end||[])testCases.push([`Manual: ${mc.label}`,()=>typeof o.testConfirm=="function"?o.testConfirm(mc.label,mc.items||[]):{ok:!0}]);const onComplete=isOptions&&opts.onComplete,testId=o.test("Recorded playback",...testCases,{sync:!0},testId2=>{window.fetch=origFetch,XMLHttpRequest.prototype.open=origXHROpen,XMLHttpRequest.prototype.send=origXHRSend,origWebSocket&&(window.WebSocket=origWebSocket);const assertionResult=runAssertions&&assertions.length>0?assertionAccum:void 0;if(assertionResult?.failures?.length>0){o.tRes[testId2]=!1;const failLines=assertionResult.failures.map(f=>`${f.selector}: ${f.message}`).join("; "),suffix=o.tStyled?o.tPre+o.tXx+"Assertions failed: "+failLines+o.tDc:`
|
|
96
|
+
\u2718 Assertions failed: `+failLines;o.tLog[testId2]=(o.tLog[testId2]||"")+suffix}typeof onComplete=="function"&&onComplete(assertionResult)});return runAssertions?{testId}:testId},o.testOverlay=()=>{const btnId="o-test-overlay-btn",panelId="o-test-overlay-panel";if(o("#"+btnId).el)return;const scrollId="o-test-overlay-scroll",exportBtnId="o-test-export-objs",copyBtnId="o-test-copy-txt",btnBarStyle="padding:6px 10px;background:#334155;color:#e2e8f0;border:none;border-radius:6px;cursor:pointer;font-size:12px;",buildListPlainText=()=>o.tLog.map((log,i)=>(log!=null&&log!==""?String(log):"Test #"+i)+(o.tRes[i]?" \u2713":" \u2717")).join(`
|
|
97
|
+
|
|
98
|
+
`),updatePanel=()=>{const scroll=o("#"+scrollId);if(!scroll.el)return;let html="";o.tLog.forEach((log,i)=>{const ok=o.tRes[i];html+=`<div style="margin:2px 0;padding:2px 4px;border-radius:3px;background:${ok?"#14532d":"#450a0a"};color:${ok?"#86efac":"#fca5a5"};font-size:11px;white-space:pre-wrap">${log||"Test #"+i}</div>`}),scroll.html(html)},innerHTML=`<div class="o-test-overlay-root" style="display:flex;flex-direction:column;gap:4px;max-height:min(88vh,560px);overflow:hidden;"><div style="display:flex;align-items:center;gap:12px;flex-shrink:0;"><span class="o-test-overlay-summary" style="flex:1;font-size:13px;cursor:grab;">Tests: 0/0</span><button type="button" class="o-test-overlay-toggle" style="${btnBarStyle}">List</button><button type="button" class="o-test-overlay-close" style="padding:4px 8px;background:transparent;color:#94a3b8;border:none;border-radius:4px;cursor:pointer;font-size:16px;line-height:1;" title="Close">\xD7</button></div><div id="${panelId}" style="display:none;flex-direction:column;margin-top:4px;max-height:min(52vh,420px);background:#0a0f1e;border:1px solid #1e293b;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,.35);overflow:hidden;"><div id="${scrollId}" style="box-sizing:border-box;height:min(48vh,380px);overflow-y:scroll;padding:8px;font-size:11px;user-select:text;cursor:text;"></div><div id="o-test-overlay-footer" style="display:flex;flex-wrap:wrap;gap:8px;padding:8px;border-top:1px solid #1e293b;background:#0f172a;flex-shrink:0;"><button type="button" id="${exportBtnId}" class="o-test-overlay-export-btn" style="${btnBarStyle}">Export (objs)</button><button type="button" id="${copyBtnId}" class="o-test-overlay-export-btn" style="${btnBarStyle}">Copy (txt)</button></div></div></div>`,box=o.overlay({innerHTML,removeExisting:!1,className:"o-test-overlay",id:btnId,excludeDragSelector:".o-test-overlay-close, .o-test-overlay-toggle, #"+panelId+", #"+scrollId+", #o-test-overlay-footer, .o-test-overlay-export-btn"});o("#"+exportBtnId).on("click",()=>{const data=JSON.stringify({results:o.tRes,logs:o.tLog},null,2),blob=new Blob([data],{type:"application/json"}),a=o.D.createElement("a");a.href=URL.createObjectURL(blob),a.download="objs-test-results.json",a.click()}),o("#"+copyBtnId).on("click",()=>{const text=buildListPlainText(),write=()=>{const ta=o.D.createElement("textarea");ta.value=text,ta.setAttribute("readonly",""),ta.style.cssText="position:fixed;left:-9999px;top:0",o.D.body.appendChild(ta),ta.select(),o.D.execCommand("copy"),ta.remove()};typeof navigator<"u"&&navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(text).catch(write):write()});const refreshSummary=()=>{const summary=o(".o-test-overlay-summary");summary.els.length&&summary.innerText(`Tests: ${o.tRes.filter(Boolean).length}/${o.tRes.length}`)};box.first(".o-test-overlay-toggle").on("click",()=>{const panel=o("#"+panelId);if(!panel.el)return;panel.el.style.display!=="none"?panel.el.style.display="none":(panel.el.style.display="flex",updatePanel())}),box.first(".o-test-overlay-close").on("click",()=>{box._overlayCleanup()}),o.testOverlay.showPanel=()=>{const panel=o("#"+panelId);panel.el&&(panel.el.style.display="flex",updatePanel(),refreshSummary())},o._testOverlayBase||(o._testOverlayBase=o.test),o.test=(...args)=>{const id=o._testOverlayBase(...args),origFn=o.tFns[id];return o.tFns[id]=n=>{typeof origFn=="function"&&origFn(n);const panel=o("#"+panelId);panel.el&&panel.el.style.display!=="none"&&updatePanel(),refreshSummary()},id}},o.overlay=(opts={})=>{const{innerHTML,onClose,timeout,excludeDragSelector,removeExisting=!0,className="o-overlay-common",id}=opts;if(removeExisting)o("."+className).remove();else if(id&&o("#"+id).el)return o("#"+id);const overlayStyle={position:"fixed",left:"50%",bottom:"50px",transform:"translateX(-50%)","z-index":"999999",width:"fit-content","max-width":"min(90vw, 420px)","font-family":"system-ui,sans-serif","user-select":"text"},countdownId="o-overlay-countdown",barHtml='<div class="o-overlay-bar" style="display:flex;flex-direction:column;align-items:stretch;padding:10px 14px;background:#1e293b;color:#e2e8f0;border:1px solid #334155;border-radius:8px;font-size:14px;min-width:200px;max-height:90vh;overflow-y:auto;">'+innerHTML+(timeout?`<div id="${countdownId}" style="margin-top:6px;font-size:11px;color:#94a3b8;"></div>`:"")+"</div>",box=o.initState({tag:"div",className,id:id||void 0,style:"position:fixed;left:50%;bottom:50px;transform:translateX(-50%);z-index:999999;width:fit-content;max-width:min(90vw,420px);font-family:system-ui,sans-serif;user-select:text;",html:barHtml}).appendInside("body"),applyStyle=()=>box.css(overlayStyle);let drag=null;const onMove=e=>{drag&&(overlayStyle.left=drag.left+(e.clientX-drag.startX)+"px",overlayStyle.top=drag.top+(e.clientY-drag.startY)+"px",delete overlayStyle.bottom,overlayStyle.transform="none",applyStyle())},onUp=()=>{drag&&(delete overlayStyle.cursor,applyStyle()),drag=null};box.on("mousedown",e=>{if(excludeDragSelector&&e.target.closest(excludeDragSelector))return;const r=box.el.getBoundingClientRect();drag={startX:e.clientX,startY:e.clientY,left:r.left,top:r.top},overlayStyle.cursor="grabbing",applyStyle()}),o.D.addEventListener("mousemove",onMove),o.D.addEventListener("mouseup",onUp);let timerId;const cleanup=()=>{o.D.removeEventListener("mousemove",onMove),o.D.removeEventListener("mouseup",onUp),timerId&&clearInterval(timerId),box.remove()};if(timeout&&timeout>0){let remaining=Math.ceil(timeout/1e3);const cd=o("#"+countdownId);cd.el&&(cd.el.textContent=remaining?`Continue in ${remaining}s`:""),timerId=setInterval(()=>{remaining-=1,cd.el&&(cd.el.textContent=remaining>0?`Continue in ${remaining}s`:""),remaining<=0&&(clearInterval(timerId),timerId=null,cleanup(),typeof onClose=="function"&&onClose({ok:!1,errors:["timeout"]}))},1e3)}return box._overlayCleanup=cleanup,box._overlayOnClose=onClose,box},o.testConfirm=(label,items=[],opts={})=>new Promise(resolve=>{const btnLabel=opts.confirm||"Continue",hasCheckboxes=items.length>0,btnBg=hasCheckboxes?"#dc2626":"#2563eb",itemIds=items.map((_,idx)=>"o-tc-cb-"+idx),itemsHtml=hasCheckboxes?`<style>.o-tc-item-cb{appearance:none;-webkit-appearance:none;width:16px;height:16px;border:2px solid #ef4444;border-radius:3px;background:#fef2f2;flex-shrink:0;cursor:pointer;}.o-tc-item-cb:checked{border-color:#22c55e;background:#22c55e;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");background-size:12px 12px;background-position:center;}</style><ul class="o-tc-list" style="margin:8px 0 0;padding:0;list-style:none;font-size:13px;color:#cbd5e1;cursor:grab;">`+items.map((i,idx)=>`<li style="margin-bottom:4px;"><label for="${itemIds[idx]}" style="display:flex;align-items:center;gap:8px;cursor:pointer;user-select:none;"><input type="checkbox" id="${itemIds[idx]}" class="o-tc-item-cb"> <span>${i}</span></label></li>`).join("")+"</ul>":"",innerHTML=`<div style="display:flex;align-items:center;gap:12px;"><span class="o-tc-label" style="flex:1;cursor:grab;">${label}: Paused</span><button type="button" class="o-tc-ok" style="padding:6px 14px;background:${btnBg};color:#fff;border:none;border-radius:6px;font-weight:600;cursor:pointer;font-size:13px;flex-shrink:0;">${btnLabel}</button></div>`+itemsHtml,box=o.overlay({innerHTML,timeout:opts.timeout,excludeDragSelector:".o-tc-ok",onClose:r=>resolve(r||{ok:!0})}),okBtnStyles={padding:"6px 14px",background:hasCheckboxes?"#dc2626":"#2563eb",color:"#fff",border:"none","border-radius":"6px","font-weight":"600",cursor:"pointer","font-size":"13px","flex-shrink":"0"};if(hasCheckboxes){const okBtn=box.first(".o-tc-ok"),cbs=o(".o-overlay-common .o-tc-item-cb"),updateBtn=()=>{const allChecked=cbs.length>0&&cbs.els.every(el=>el.checked);okBtn.css({...okBtnStyles,background:allChecked?"#16a34a":"#dc2626"})};cbs.on("change",updateBtn)}box.first(".o-tc-ok").on("click",()=>{let unchecked=[];if(hasCheckboxes){const cbsList=o(".o-overlay-common .o-tc-item-cb");cbsList.els.length&&cbsList.els.forEach((el,idx)=>{!el.checked&&items[idx]!==void 0&&unchecked.push(items[idx])})}box._overlayCleanup(),resolve(unchecked.length===0?{ok:!0}:{ok:!1,errors:unchecked})})});
|
|
90
99
|
|
|
91
100
|
export { o };
|
|
92
101
|
export default o;
|